diff options
author | guy <guy> | 2004-03-11 23:04:24 +0000 |
---|---|---|
committer | guy <guy> | 2004-03-11 23:04:24 +0000 |
commit | bd53902d4aaaf16ed9df30bf61ccc125dd636a1b (patch) | |
tree | 17971a98449f3e2a6ee80b1553b77dd81599a724 /fad-getad.c | |
parent | 9876992f2c8d3964140edbe0641fa4218d0cf9d6 (diff) |
Don't rely on SA_LEN to check whether it's passed a null pointer (it
might be supplied by the OS, and the OS might supply a version that
doesn't check); instead, check for null pointers before doing anything
with the address at all. This also means we don't supply a netmask if
the address is null; that makes sense, as a netmask makes no sense
without an address.
Diffstat (limited to 'fad-getad.c')
-rw-r--r-- | fad-getad.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/fad-getad.c b/fad-getad.c index 9c41217..3bbf54a 100644 --- a/fad-getad.c +++ b/fad-getad.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.8 2003-11-15 23:23:58 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.9 2004-03-11 23:04:24 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -83,14 +83,12 @@ static const char rcsid[] _U_ = */ #ifndef SA_LEN #ifdef HAVE_SOCKADDR_SA_LEN -#define SA_LEN(addr) (addr ? (addr)->sa_len : 0) +#define SA_LEN(addr) ((addr)->sa_len) #else /* HAVE_SOCKADDR_SA_LEN */ #ifdef HAVE_SOCKADDR_STORAGE static size_t get_sa_len(struct sockaddr *addr) { - if (!addr) - return (0); switch (addr->sa_family) { #ifdef AF_INET @@ -127,8 +125,8 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) { pcap_if_t *devlist = NULL; struct ifaddrs *ifap, *ifa; - struct sockaddr *broadaddr, *dstaddr; - size_t broadaddr_size, dstaddr_size; + struct sockaddr *addr, *netmask, *broadaddr, *dstaddr; + size_t addr_size, broadaddr_size, dstaddr_size; int ret = 0; /* @@ -162,20 +160,44 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) } /* + * "ifa_addr" was apparently null on at least one + * interface on some system. + * * "ifa_broadaddr" may be non-null even on - * non-broadcast interfaces; "ifa_dstaddr" - * was, on at least one FreeBSD 4.1 system, - * non-null on a non-point-to-point + * 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. */ - if (ifa->ifa_flags & IFF_BROADCAST) { + if (ifa->ifa_addr != NULL) { + addr = ifa->ifa_addr; + addr_size = SA_LEN(addr); + netmask = ifa->ifa_netmask; + } else { + addr = NULL; + addr_size = 0; + netmask = NULL; + } + if (ifa->ifa_flags & IFF_BROADCAST && + ifa->ifa_broadaddr != NULL) { broadaddr = ifa->ifa_broadaddr; broadaddr_size = SA_LEN(broadaddr); } else { broadaddr = NULL; broadaddr_size = 0; } - if (ifa->ifa_flags & IFF_POINTOPOINT) { + if (ifa->ifa_flags & IFF_POINTOPOINT && + ifa->ifa_dstaddr != NULL) { dstaddr = ifa->ifa_dstaddr; dstaddr_size = SA_LEN(ifa->ifa_dstaddr); } else { @@ -187,8 +209,7 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) * Add information for this address to the list. */ if (add_addr_to_iflist(&devlist, ifa->ifa_name, - ifa->ifa_flags, ifa->ifa_addr, SA_LEN(ifa->ifa_addr), - ifa->ifa_netmask, SA_LEN(ifa->ifa_addr), + ifa->ifa_flags, addr, addr_size, netmask, addr_size, broadaddr, broadaddr_size, dstaddr, dstaddr_size, errbuf) < 0) { ret = -1; |