summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib/libpcap/fad-getad.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/contrib/libpcap/fad-getad.c')
-rw-r--r--freebsd/contrib/libpcap/fad-getad.c138
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;