diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-11-09 07:44:51 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-11-09 07:44:51 +0000 |
commit | 40b22f317b55ecd98cfbd7eeca2015a09de76e86 (patch) | |
tree | a629cd7ba4581f6eea83a274230336a2c98b7f92 /util.c | |
parent | e6b12dd801e086d437777e8d3163b5e2e0dceb7a (diff) |
Wrap calls to "pcap_datalink()" in a routine that attempts to compensate
for AIX 5.x's non-standard libpcap, where "pcap_datalink()" doesn't
return DLT_ values, it returns RFC 1573 ifType values.
Put that wrapper, and the routine to get the interface list, in a
separate file, for packet-capture utility routines, so not everybody who
includes "util.h" needs to include <pcap.h>.
Fix up the Wiretap hack for dealing with said incompatibility to use the
correct ifType value for Token Ring.
svn path=/trunk/; revision=4184
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 304 |
1 files changed, 2 insertions, 302 deletions
@@ -1,7 +1,7 @@ /* util.c * Utility routines * - * $Id: util.c,v 1.53 2001/10/26 18:28:17 gram Exp $ + * $Id: util.c,v 1.54 2001/11/09 07:44:48 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -49,44 +49,16 @@ # include "snprintf.h" #endif -#ifndef WIN32 -#include <pwd.h> -#endif - #ifdef NEED_MKSTEMP #include "mkstemp.h" #endif -#include "util.h" - #ifdef HAVE_IO_H #include <io.h> typedef int mode_t; /* for win32 */ #endif -#ifdef HAVE_LIBPCAP - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif - -#include <pcap.h> - -#ifndef WIN32 -#include <net/if.h> -#endif - -#ifdef HAVE_SYS_SOCKIO_H -# include <sys/sockio.h> -#endif - -#include "globals.h" - -#endif +#include "util.h" /* * Collect command-line arguments as a string consisting of the arguments, @@ -339,278 +311,6 @@ EBCDIC_to_ASCII1(guint8 c) return EBCDIC_translate_ASCII[c]; } -#ifdef HAVE_LIBPCAP - -/* - * If the ability to capture packets is added to Wiretap, these - * routines should be moved to the Wiretap source (with - * "get_interface_list()" and "free_interface_list()" renamed to - * "wtap_get_interface_list()" and "wtap_free_interface_list()", - * and modified to use Wiretap routines to attempt to open the - * interface. - */ - -struct search_user_data { - char *name; - int found; -}; - -static void -search_for_if_cb(gpointer data, gpointer user_data); - -static void -free_if_cb(gpointer data, gpointer user_data); - -#ifndef WIN32 -GList * -get_interface_list(int *err, char *err_str) -{ - GList *il = NULL; - gint nonloopback_pos = 0; - struct ifreq *ifr, *last; - struct ifconf ifc; - struct ifreq ifrflags; - 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", - strerror(errno)); - return NULL; - } - - /* - * This code came from: W. Richard Stevens: "UNIX Network Programming", - * Networking APIs: Sockets and XTI, Vol 1, page 434. - */ - 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 ((unsigned) 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) { - /* - * Skip addresses that begin with "dummy", or that include - * a ":" (the latter are Solaris virtuals). - */ - if (strncmp(ifr->ifr_name, "dummy", 5) == 0 || - strchr(ifr->ifr_name, ':') != NULL) - goto next; - - /* - * If we already have this interface name on the list, - * don't add it (SIOCGIFCONF returns, at least on - * BSD-flavored systems, one entry per interface *address*; - * if an interface has multiple addresses, we get multiple - * entries for it). - */ - user_data.name = ifr->ifr_name; - user_data.found = FALSE; - g_list_foreach(il, search_for_if_cb, &user_data); - if (user_data.found) - goto next; - - /* - * Get the interface flags. - */ - memset(&ifrflags, 0, sizeof ifrflags); - strncpy(ifrflags.ifr_name, ifr->ifr_name, - sizeof ifrflags.ifr_name); - if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { - if (errno == ENXIO) - goto next; - sprintf(err_str, "SIOCGIFFLAGS error getting flags for interface %s: %s", - ifr->ifr_name, strerror(errno)); - goto fail; - } - - /* - * Skip interfaces that aren't up. - */ - if (!(ifrflags.ifr_flags & IFF_UP)) - goto next; - - /* - * Skip interfaces that we can't open with "libpcap". - * Open with the minimum packet size - it appears that the - * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length - * supplied is too large, rather than just truncating it. - */ - pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0, - err_str); - if (pch == NULL) - goto next; - pcap_close(pch); - - /* - * If it's a loopback interface, add it at the end of the - * list, otherwise add it after the last non-loopback - * interface, so all loopback interfaces go at the end - we - * don't want a loopback interface to be the default capture - * device unless there are no non-loopback devices. - */ - if ((ifrflags.ifr_flags & IFF_LOOPBACK) || - strncmp(ifr->ifr_name, "lo", 2) == 0) - il = g_list_insert(il, g_strdup(ifr->ifr_name), -1); - else { - il = g_list_insert(il, g_strdup(ifr->ifr_name), - nonloopback_pos); - /* - * Insert the next non-loopback interface after this - * one. - */ - nonloopback_pos++; - } - - next: -#ifdef HAVE_SA_LEN - ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ); -#else - ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq)); -#endif - } - -#ifdef linux - /* - * OK, maybe we have support for the "any" device, to do a cooked - * capture on all interfaces at once. - * Try opening it and, if that succeeds, add it to the end of - * the list of interfaces. - */ - pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, err_str); - if (pch != NULL) { - /* - * It worked; we can use the "any" device. - */ - il = g_list_insert(il, g_strdup("any"), -1); - pcap_close(pch); - } -#endif - - g_free(ifc.ifc_buf); - close(sock); - - if (il == NULL) { - /* - * No interfaces found. - */ - *err = NO_INTERFACES_FOUND; - } - return il; - -fail: - if (il != NULL) { - g_list_foreach(il, free_if_cb, NULL); - g_list_free(il); - } - g_free(ifc.ifc_buf); - close(sock); - *err = CANT_GET_INTERFACE_LIST; - return NULL; -} - -static void -search_for_if_cb(gpointer data, gpointer user_data) -{ - struct search_user_data *search_user_data = user_data; - - if (strcmp((char *)data, search_user_data->name) == 0) - search_user_data->found = TRUE; -} -#else -GList * -get_interface_list(int *err, char *err_str) { - GList *il = NULL; - wchar_t *names; - char *win95names; - char newname[255]; - int i, j, done; - - names = (wchar_t *)pcap_lookupdev(err_str); - i = done = 0; - - if (names) { - if (names[0]<256) { - /* If names[0] is less than 256 it means the first byte is 0 - This implies that we are using unicode characters */ - do - { - j = 0; - while (names[i] != 0) - newname[j++] = names[i++]; - i++; - if (names[i] == 0) - done = 1; - newname[j++] = 0; - il = g_list_append(il, g_strdup(newname)); - } while (!done); - } - else { - /* Otherwise we are in Windows 95/98 and using ascii(8 bit) - characters */ - do - { - win95names=(char *)names; - j = 0; - while (win95names[i] != 0) - newname[j++] = win95names[i++]; - i++; - if (win95names[i] == 0) - done = 1; - newname[j++] = 0; - il = g_list_append(il, g_strdup(newname)); - } while (!done); - } - } - return(il); -} -#endif - -static void -free_if_cb(gpointer data, gpointer user_data) -{ - g_free(data); -} - -void -free_interface_list(GList *if_list) -{ - while (if_list != NULL) { - g_free(if_list->data); - if_list = g_list_remove_link(if_list, if_list); - } -} - -#endif /* HAVE_LIBPCAP */ - - /* Compute the difference between two seconds/microseconds time stamps. */ void compute_timestamp_diff(gint *diffsec, gint *diffusec, |