From 3d856fe86501030f034ae6db80bf0072b439e097 Mon Sep 17 00:00:00 2001 From: guy Date: Tue, 30 Jul 2002 08:12:13 +0000 Subject: [PATCH] Leave it up to the platform-dependent "get interface list" code to figure out how big the addresses are, as the way that's done is, well, platform-dependent.... --- fad-getad.c | 54 +++++++++++++++++++++++++++---- fad-gifc.c | 93 ++++++++++++++++++++++++++++++++--------------------- fad-glifc.c | 7 ++-- inet.c | 56 ++++++++------------------------ pcap-int.h | 5 +-- 5 files changed, 124 insertions(+), 91 deletions(-) diff --git a/fad-getad.c b/fad-getad.c index 7ffd484..bb2395c 100644 --- a/fad-getad.c +++ b/fad-getad.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.1 2002-07-27 18:46:21 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.2 2002-07-30 08:12:13 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -55,6 +55,37 @@ static const char rcsid[] = #include "os-proto.h" #endif +/* + * This is fun. + * + * In older BSD systems, socket addresses were fixed-length, and + * "sizeof (struct sockaddr)" gave the size of the structure. + * All addresses fit within a "struct sockaddr". + * + * In newer BSD systems, the socket address is variable-length, and + * there's an "sa_len" field giving the length of the structure; + * this allows socket addresses to be longer than 2 bytes of family + * and 14 bytes of data. + * + * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 + * variant of the old BSD scheme (with "struct sockaddr_storage" rather + * than "struct sockaddr"), and some use the new BSD scheme. + * + * GNU libc uses neither scheme, but has an "SA_LEN()" macro that + * determines the size based on the address family. + */ +#ifndef SA_LEN +#ifdef HAVE_SOCKADDR_SA_LEN +#define SA_LEN(addr) ((addr)->sa_len) +#else /* HAVE_SOCKADDR_SA_LEN */ +#ifdef HAVE_SOCKADDR_STORAGE +#define SA_LEN(addr) (sizeof (struct sockaddr_storage)) +#else /* HAVE_SOCKADDR_STORAGE */ +#define SA_LEN(addr) (sizeof (struct sockaddr)) +#endif /* HAVE_SOCKADDR_STORAGE */ +#endif /* HAVE_SOCKADDR_SA_LEN */ +#endif /* SA_LEN */ + /* * Get a list of all interfaces that are up and that we can open. * Returns -1 on error, 0 otherwise. @@ -69,6 +100,7 @@ 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; int ret = 0; /* @@ -108,21 +140,29 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) * non-null on a non-point-to-point * interface. */ - if (ifa->ifa_flags & IFF_BROADCAST) + if (ifa->ifa_flags & IFF_BROADCAST) { broadaddr = ifa->ifa_broadaddr; - else + broadaddr_size = SA_LEN(broadaddr); + } else { broadaddr = NULL; - if (ifa->ifa_flags & IFF_POINTOPOINT) + broadaddr_size = 0; + } + if (ifa->ifa_flags & IFF_POINTOPOINT) { dstaddr = ifa->ifa_dstaddr; - else + dstaddr_size = SA_LEN(ifa->ifa_dstaddr); + } else { dstaddr = NULL; + dstaddr_size = 0; + } /* * Add information for this address to the list. */ if (add_addr_to_iflist(&devlist, ifa->ifa_name, - ifa->ifa_flags, ifa->ifa_addr, ifa->ifa_netmask, - broadaddr, dstaddr, errbuf) < 0) { + ifa->ifa_flags, ifa->ifa_addr, SA_LEN(ifa->ifa_addr), + ifa->ifa_netmask, SA_LEN(ifa->ifa_netmask), + broadaddr, broadaddr_size, dstaddr, dstaddr_size, + errbuf) < 0) { ret = -1; break; } diff --git a/fad-gifc.c b/fad-gifc.c index 69da023..93a27f8 100644 --- a/fad-gifc.c +++ b/fad-gifc.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.1 2002-07-27 18:46:21 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.2 2002-07-30 08:12:13 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -69,6 +69,37 @@ struct rtentry; /* declarations in */ #include "os-proto.h" #endif +/* + * This is fun. + * + * In older BSD systems, socket addresses were fixed-length, and + * "sizeof (struct sockaddr)" gave the size of the structure. + * All addresses fit within a "struct sockaddr". + * + * In newer BSD systems, the socket address is variable-length, and + * there's an "sa_len" field giving the length of the structure; + * this allows socket addresses to be longer than 2 bytes of family + * and 14 bytes of data. + * + * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 + * variant of the old BSD scheme (with "struct sockaddr_storage" rather + * than "struct sockaddr"), and some use the new BSD scheme. + * + * GNU libc uses neither scheme, but has an "SA_LEN()" macro that + * determines the size based on the address family. + * + * We assume that a UNIX that doesn't have "getifaddrs()" and doesn't have + * SIOCGLIFCONF, but has SIOCGIFCONF, uses "struct sockaddr" for the + * address in an entry returned by SIOCGIFCONF. + */ +#ifndef SA_LEN +#ifdef HAVE_SOCKADDR_SA_LEN +#define SA_LEN(addr) ((addr)->sa_len) +#else /* HAVE_SOCKADDR_SA_LEN */ +#define SA_LEN(addr) (sizeof (struct sockaddr)) +#endif /* HAVE_SOCKADDR_SA_LEN */ +#endif /* SA_LEN */ + #ifdef HAVE_PROC_NET_DEV /* * Get from "/proc/net/dev" all interfaces listed there; if they're @@ -199,37 +230,6 @@ scan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf) } #endif /* HAVE_PROC_NET_DEV */ -/* - * This is fun. - * - * In older BSD systems, socket addresses were fixed-length, and - * "sizeof (struct sockaddr)" gave the size of the structure. - * All addresses fit within a "struct sockaddr". - * - * In newer BSD systems, the socket address is variable-length, and - * there's an "sa_len" field giving the length of the structure; - * this allows socket addresses to be longer than 2 bytes of family - * and 14 bytes of data. - * - * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 - * variant of the old BSD scheme (with "struct sockaddr_storage" rather - * than "struct sockaddr"), and some use the new BSD scheme. - * - * GNU libc uses neither scheme, but has an "SA_LEN()" macro that - * determines the size based on the address family. - */ -#ifndef SA_LEN -#ifdef HAVE_SOCKADDR_SA_LEN -#define SA_LEN(addr) ((addr)->sa_len) -#else /* HAVE_SOCKADDR_SA_LEN */ -#ifdef HAVE_SOCKADDR_STORAGE -#define SA_LEN(addr) (sizeof (struct sockaddr_storage)) -#else /* HAVE_SOCKADDR_STORAGE */ -#define SA_LEN(addr) (sizeof (struct sockaddr)) -#endif /* HAVE_SOCKADDR_STORAGE */ -#endif /* HAVE_SOCKADDR_SA_LEN */ -#endif /* SA_LEN */ - /* * Get a list of all interfaces that are up and that we can open. * Returns -1 on error, 0 otherwise. @@ -255,6 +255,7 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) unsigned buf_size; struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr; struct sockaddr *netmask, *broadaddr, *dstaddr; + size_t netmask_size, broadaddr_size, dstaddr_size; int ret = 0; /* @@ -343,6 +344,7 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) * Not available. */ netmask = NULL; + netmask_size = 0; } else { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFNETMASK: %.*s: %s", @@ -352,8 +354,10 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) ret = -1; break; } - } else + } else { netmask = &ifrnetmask.ifr_addr; + netmask_size = SA_LEN(netmask); + } /* * Get the broadcast address for this address on this @@ -371,6 +375,7 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) * Not available. */ broadaddr = NULL; + broadaddr_size = 0; } else { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFBRDADDR: %.*s: %s", @@ -380,14 +385,17 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) ret = -1; break; } - } else + } else { broadaddr = &ifrbroadaddr.ifr_broadaddr; + broadaddr_size = SA_LEN(broadaddr); + } } else { /* * Not a broadcast interface, so no broadcast * address. */ broadaddr = NULL; + broadaddr_size = 0; } /* @@ -406,6 +414,7 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) * Not available. */ dstaddr = NULL; + dstaddr_size = 0; } else { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFDSTADDR: %.*s: %s", @@ -415,17 +424,27 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) ret = -1; break; } - } else + } else { dstaddr = &ifrdstaddr.ifr_dstaddr; - } else + dstaddr_size = SA_LEN(dstaddr); + } + } else { + /* + * Not a point-to-point interface, so no destination + * address. + */ dstaddr = NULL; + dstaddr_size = 0; + } /* * Add information for this address to the list. */ if (add_addr_to_iflist(&devlist, ifrp->ifr_name, ifrflags.ifr_flags, &ifrp->ifr_addr, - netmask, broadaddr, dstaddr, errbuf) < 0) { + SA_LEN(&ifrp->ifr_addr), netmask, netmask_size, + broadaddr, broadaddr_size, dstaddr, dstaddr_size, + errbuf) < 0) { ret = -1; break; } diff --git a/fad-glifc.c b/fad-glifc.c index 76c25fe..b777a02 100644 --- a/fad-glifc.c +++ b/fad-glifc.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.1 2002-07-27 18:46:21 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.2 2002-07-30 08:12:13 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -289,7 +289,10 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) */ if (add_addr_to_iflist(&devlist, ifrp->lifr_name, ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr, - netmask, broadaddr, dstaddr, errbuf) < 0) { + sizeof (struct sockaddr_storage), + netmask, sizeof (struct sockaddr_storage), + broadaddr, sizeof (struct sockaddr_storage), + dstaddr, sizeof (struct sockaddr_storage), errbuf) < 0) { ret = -1; break; } diff --git a/inet.c b/inet.c index 75ecc12..159b5c5 100644 --- a/inet.c +++ b/inet.c @@ -34,7 +34,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.49 2002-07-27 18:45:35 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.50 2002-07-30 08:12:14 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -85,47 +85,14 @@ struct rtentry; /* declarations in */ (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0')) #endif -/* - * This is fun. - * - * In older BSD systems, socket addresses were fixed-length, and - * "sizeof (struct sockaddr)" gave the size of the structure. - * All addresses fit within a "struct sockaddr". - * - * In newer BSD systems, the socket address is variable-length, and - * there's an "sa_len" field giving the length of the structure; - * this allows socket addresses to be longer than 2 bytes of family - * and 14 bytes of data. - * - * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 - * variant of the old BSD scheme (with "struct sockaddr_storage" rather - * than "struct sockaddr"), and some use the new BSD scheme. - * - * GNU libc uses neither scheme, but has an "SA_LEN()" macro that - * determines the size based on the address family. - */ -#ifndef SA_LEN -#ifdef HAVE_SOCKADDR_SA_LEN -#define SA_LEN(addr) ((addr)->sa_len) -#else /* HAVE_SOCKADDR_SA_LEN */ -#ifdef HAVE_SOCKADDR_STORAGE -#define SA_LEN(addr) (sizeof (struct sockaddr_storage)) -#else /* HAVE_SOCKADDR_STORAGE */ -#define SA_LEN(addr) (sizeof (struct sockaddr)) -#endif /* HAVE_SOCKADDR_STORAGE */ -#endif /* HAVE_SOCKADDR_SA_LEN */ -#endif /* SA_LEN */ - static struct sockaddr * -dup_sockaddr(struct sockaddr *sa) +dup_sockaddr(struct sockaddr *sa, size_t sa_len) { struct sockaddr *newsa; - unsigned int size; - size = SA_LEN(sa); - if ((newsa = malloc(size)) == NULL) + if ((newsa = malloc(sa_len)) == NULL) return (NULL); - return (memcpy(newsa, sa, size)); + return (memcpy(newsa, sa, sa_len)); } static int @@ -324,8 +291,11 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name, int add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, - struct sockaddr *addr, struct sockaddr *netmask, - struct sockaddr *broadaddr, struct sockaddr *dstaddr, char *errbuf) + struct sockaddr *addr, size_t addr_size, + struct sockaddr *netmask, size_t netmask_size, + struct sockaddr *broadaddr, size_t broadaddr_size, + struct sockaddr *dstaddr, size_t dstaddr_size, + char *errbuf) { pcap_if_t *curdev; pcap_addr_t *curaddr, *prevaddr, *nextaddr; @@ -359,7 +329,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, curaddr->next = NULL; if (addr != NULL) { - curaddr->addr = dup_sockaddr(addr); + curaddr->addr = dup_sockaddr(addr, addr_size); if (curaddr->addr == NULL) { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); @@ -370,7 +340,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, curaddr->addr = NULL; if (netmask != NULL) { - curaddr->netmask = dup_sockaddr(netmask); + curaddr->netmask = dup_sockaddr(netmask, netmask_size); if (curaddr->netmask == NULL) { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); @@ -381,7 +351,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, curaddr->netmask = NULL; if (broadaddr != NULL) { - curaddr->broadaddr = dup_sockaddr(broadaddr); + curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size); if (curaddr->broadaddr == NULL) { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); @@ -392,7 +362,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, curaddr->broadaddr = NULL; if (dstaddr != NULL) { - curaddr->dstaddr = dup_sockaddr(dstaddr); + curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size); if (curaddr->dstaddr == NULL) { (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); diff --git a/pcap-int.h b/pcap-int.h index 7b86969..87b2a48 100644 --- a/pcap-int.h +++ b/pcap-int.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.36 2002-07-27 18:45:35 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.37 2002-07-30 08:12:14 guy Exp $ (LBL) */ #ifndef pcap_int_h @@ -204,7 +204,8 @@ int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *); */ int pcap_platform_finddevs(pcap_if_t **, char *); int add_addr_to_iflist(pcap_if_t **, char *, u_int, struct sockaddr *, - struct sockaddr *, struct sockaddr *, struct sockaddr *, char *); + size_t, struct sockaddr *, size_t, struct sockaddr *, size_t, + struct sockaddr *, size_t, char *); int pcap_add_if(pcap_if_t **, char *, u_int, const char *, char *);