diff options
author | Uwe Girlich <Uwe.Girlich@philosys.de> | 2000-08-31 11:12:19 +0000 |
---|---|---|
committer | Uwe Girlich <Uwe.Girlich@philosys.de> | 2000-08-31 11:12:19 +0000 |
commit | 3ab7bc97617b7b887ae3df164353c1668a89bb05 (patch) | |
tree | 0a9ed851b881ac8c134f4b28491d53490de4d4b2 /util.c | |
parent | 8d0ca23802a8720bbafd83d3605386da1a753247 (diff) | |
download | wireshark-3ab7bc97617b7b887ae3df164353c1668a89bb05.tar.gz |
The interface list will now be get into an dynamic growing buffer and not
the (too big) buffer for 1024 network cards.
The code comes directly after the ideas in Steven's book (UNIX network
programming).
svn path=/trunk/; revision=2385
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 47 |
1 files changed, 33 insertions, 14 deletions
@@ -1,7 +1,7 @@ /* util.c * Utility routines * - * $Id: util.c,v 1.41 2000/08/11 13:34:53 deniel Exp $ + * $Id: util.c,v 1.42 2000/08/31 11:12:19 girlich Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -508,6 +508,8 @@ get_interface_list(int *err, char *err_str) int sock = socket(AF_INET, SOCK_DGRAM, 0); struct search_user_data user_data; pcap_t *pch; + int len, lastlen; + char *buf; if (sock < 0) { sprintf(err_str, "Error opening socket: %s", @@ -516,19 +518,36 @@ get_interface_list(int *err, char *err_str) } /* - * Since we have to grab the interface list all at once, we'll - * make plenty of room. + * This code came from: W. Richard Stevens: "UNIX Network Programming", + * Networking APIs: Sockets and XTI, Vol 1, page 434. */ - ifc.ifc_len = 1024 * sizeof(struct ifreq); - ifc.ifc_buf = malloc(ifc.ifc_len); - - if (ioctl(sock, SIOCGIFCONF, &ifc) < 0 || - ifc.ifc_len < sizeof(struct ifreq)) { - sprintf(err_str, "SIOCGIFCONF error getting list of interfaces: %s", - strerror(errno)); - goto fail; - } - + lastlen = 0; + len = 100 * sizeof(struct ifreq); + for ( ; ; ) { + buf = g_malloc(len); + ifc.ifc_len = len; + ifc.ifc_buf = buf; + memset (buf, 0, len); + if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { + if (errno != EINVAL || lastlen != 0) { + sprintf(err_str, + "SIOCGIFCONF ioctl error getting list of interfaces: %s", + strerror(errno)); + goto fail; + } + } else { + if (ifc.ifc_len < sizeof(struct ifreq)) { + sprintf(err_str, + "SIOCGIFCONF ioctl gave too small return buffer"); + goto fail; + } + if (ifc.ifc_len == lastlen) + break; /* success, len has not changed */ + lastlen = ifc.ifc_len; + } + len += 10 * sizeof(struct ifreq); /* increment */ + g_free(buf); + } ifr = (struct ifreq *) ifc.ifc_req; last = (struct ifreq *) ((char *) ifr + ifc.ifc_len); while (ifr < last) { @@ -629,7 +648,7 @@ fail: g_list_foreach(il, free_if_cb, NULL); g_list_free(il); } - free(ifc.ifc_buf); + g_free(ifc.ifc_buf); close(sock); *err = CANT_GET_INTERFACE_LIST; return NULL; |