diff options
Diffstat (limited to 'freebsd/contrib/libpcap/fad-getad.c')
-rw-r--r-- | freebsd/contrib/libpcap/fad-getad.c | 138 |
1 files changed, 72 insertions, 66 deletions
diff --git a/freebsd/contrib/libpcap/fad-getad.c b/freebsd/contrib/libpcap/fad-getad.c index dc478fa1..cd7ac3e6 100644 --- a/freebsd/contrib/libpcap/fad-getad.c +++ b/freebsd/contrib/libpcap/fad-getad.c @@ -34,11 +34,6 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.12 2007-09-14 00:44:55 guy Exp $ (LBL)"; -#endif - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -62,9 +57,15 @@ static const char rcsid[] _U_ = #include "os-proto.h" #endif -#ifdef AF_PACKET +/* + * We don't do this on Solaris 11 and later, as it appears there aren't + * any AF_PACKET addresses on interfaces, so we don't need this, and + * we end up including both the OS's <net/bpf.h> and our <pcap/bpf.h>, + * and their definitions of some data structures collide. + */ +#if (defined(linux) || defined(__Lynx__)) && defined(AF_PACKET) # ifdef HAVE_NETPACKET_PACKET_H -/* Solaris 11 and later, Linux distributions with newer glibc */ +/* Linux distributions with newer glibc */ # include <netpacket/packet.h> # else /* HAVE_NETPACKET_PACKET_H */ /* LynxOS, Linux distributions with older glibc */ @@ -77,7 +78,7 @@ static const char rcsid[] _U_ = # include <linux/if_packet.h> # endif /* __Lynx__ */ # endif /* HAVE_NETPACKET_PACKET_H */ -#endif /* AF_PACKET */ +#endif /* (defined(linux) || defined(__Lynx__)) && defined(AF_PACKET) */ /* * This is fun. @@ -122,7 +123,7 @@ get_sa_len(struct sockaddr *addr) return (sizeof (struct sockaddr_in6)); #endif -#ifdef AF_PACKET +#if (defined(linux) || defined(__Lynx__)) && defined(AF_PACKET) case AF_PACKET: return (sizeof (struct sockaddr_ll)); #endif @@ -142,10 +143,11 @@ get_sa_len(struct sockaddr *addr) * Get a list of all interfaces that are up and that we can open. * Returns -1 on error, 0 otherwise. * The list, as returned through "alldevsp", may be null if no interfaces - * were up and could be opened. + * could be opened. */ int -pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) +pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf, + int (*check_usable)(const char *)) { pcap_if_t *devlist = NULL; struct ifaddrs *ifap, *ifa; @@ -158,10 +160,10 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) * Get the list of interface addresses. * * Note: this won't return information about interfaces - * with no addresses; are there any such interfaces - * that would be capable of receiving packets? - * (Interfaces incapable of receiving packets aren't - * very interesting from libpcap's point of view.) + * with no addresses, so, if a platform has interfaces + * with no interfaces on which traffic can be captured, + * we must check for those interfaces as well (see, for + * example, what's done on Linux). * * LAN interfaces will probably have link-layer * addresses; I don't know whether all implementations @@ -169,40 +171,56 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) * those. */ if (getifaddrs(&ifap) != 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, + (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "getifaddrs: %s", pcap_strerror(errno)); return (-1); } for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { /* - * Is this interface up? + * If this entry has a colon followed by a number at + * the end, we assume it's a logical interface. Those + * are just the way you assign multiple IP addresses to + * a real interface on Linux, so an entry for a logical + * interface should be treated like the entry for the + * real interface; we do that by stripping off the ":" + * and the number. + * + * XXX - should we do this only on Linux? */ - if (!(ifa->ifa_flags & IFF_UP)) { + p = strchr(ifa->ifa_name, ':'); + if (p != NULL) { /* - * No, so don't add it to the list. + * We have a ":"; is it followed by a number? + */ + q = p + 1; + while (isdigit((unsigned char)*q)) + q++; + if (*q == '\0') { + /* + * All digits after the ":" until the end. + * Strip off the ":" and everything after + * it. + */ + *p = '\0'; + } + } + + /* + * Can we capture on this device? + */ + if (!(*check_usable)(ifa->ifa_name)) { + /* + * No. */ continue; } /* * "ifa_addr" was apparently null on at least one - * interface on some system. - * - * "ifa_broadaddr" may be non-null even on - * non-broadcast interfaces, and was null on - * at least one OpenBSD 3.4 system on at least - * one interface with IFF_BROADCAST set. - * - * "ifa_dstaddr" was, on at least one FreeBSD 4.1 - * system, non-null on a non-point-to-point - * interface. - * - * Therefore, we supply the address and netmask only - * if "ifa_addr" is non-null (if there's no address, - * there's obviously no netmask), and supply the - * broadcast and destination addresses if the appropriate - * flag is set *and* the appropriate "ifa_" entry doesn't - * evaluate to a null pointer. + * interface on some system. Therefore, we supply + * the address and netmask only if "ifa_addr" is + * non-null (if there's no address, there's obviously + * no netmask). */ if (ifa->ifa_addr != NULL) { addr = ifa->ifa_addr; @@ -213,6 +231,22 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) addr_size = 0; netmask = NULL; } + + /* + * Note that, on some platforms, ifa_broadaddr and + * ifa_dstaddr could be the same field (true on at + * least some versions of *BSD and OS X), so we + * can't just check whether the broadcast address + * is null and add it if so and check whether the + * destination address is null and add it if so. + * + * Therefore, we must also check the IFF_BROADCAST + * flag, and only add a broadcast address if it's + * set, and check the IFF_POINTTOPOINT flag, and + * only add a destination address if it's set (as + * per man page recommendations on some of those + * platforms). + */ if (ifa->ifa_flags & IFF_BROADCAST && ifa->ifa_broadaddr != NULL) { broadaddr = ifa->ifa_broadaddr; @@ -231,39 +265,11 @@ pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) } /* - * If this entry has a colon followed by a number at - * the end, we assume it's a logical interface. Those - * are just the way you assign multiple IP addresses to - * a real interface on Linux, so an entry for a logical - * interface should be treated like the entry for the - * real interface; we do that by stripping off the ":" - * and the number. - * - * XXX - should we do this only on Linux? - */ - p = strchr(ifa->ifa_name, ':'); - if (p != NULL) { - /* - * We have a ":"; is it followed by a number? - */ - q = p + 1; - while (isdigit((unsigned char)*q)) - q++; - if (*q == '\0') { - /* - * All digits after the ":" until the end. - * Strip off the ":" and everything after - * it. - */ - *p = '\0'; - } - } - - /* * Add information for this address to the list. */ if (add_addr_to_iflist(&devlist, ifa->ifa_name, - ifa->ifa_flags, addr, addr_size, netmask, addr_size, + if_flags_to_pcap_flags(ifa->ifa_name, ifa->ifa_flags), + addr, addr_size, netmask, addr_size, broadaddr, broadaddr_size, dstaddr, dstaddr_size, errbuf) < 0) { ret = -1; |