diff options
Diffstat (limited to 'contrib/libpcap/inet.c')
-rw-r--r-- | contrib/libpcap/inet.c | 700 |
1 files changed, 164 insertions, 536 deletions
diff --git a/contrib/libpcap/inet.c b/contrib/libpcap/inet.c index fa97aaf..43eafe7 100644 --- a/contrib/libpcap/inet.c +++ b/contrib/libpcap/inet.c @@ -33,14 +33,18 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.45 2001/10/28 20:40:43 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.58.2.1 2003/11/15 23:26:41 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif +#ifdef WIN32 +#include <pcap-stdinc.h> +#else /* WIN32 */ + #include <sys/param.h> #include <sys/file.h> #include <sys/ioctl.h> @@ -50,10 +54,11 @@ static const char rcsid[] = #endif #include <sys/time.h> /* concession to AIX */ -struct mbuf; -struct rtentry; +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in <net/if.h> */ #include <net/if.h> #include <netinet/in.h> +#endif /* WIN32 */ #include <ctype.h> #include <errno.h> @@ -61,7 +66,9 @@ struct rtentry; #include <stdio.h> #include <stdlib.h> #include <string.h> +#ifndef WIN32 #include <unistd.h> +#endif /* WIN32 */ #ifdef HAVE_LIMITS_H #include <limits.h> #else @@ -85,53 +92,20 @@ struct rtentry; (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, and some might 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 */ -#define SA_LEN(addr) (sizeof (struct sockaddr)) -#endif /* HAVE_SOCKADDR_SA_LEN */ -#endif /* SA_LEN */ - -/* - * Description string for the "any" device. - */ -static const char any_descr[] = "Pseudo-device that captures on all interfaces"; - -static struct sockaddr * -dup_sockaddr(struct sockaddr *sa) +struct sockaddr * +dup_sockaddr(struct sockaddr *sa, size_t sa_length) { struct sockaddr *newsa; - unsigned int size; - - size = SA_LEN(sa); - if ((newsa = malloc(size)) == NULL) + + if ((newsa = malloc(sa_length)) == NULL) return (NULL); - return (memcpy(newsa, sa, size)); + return (memcpy(newsa, sa, sa_length)); } static int -get_instance(char *name) +get_instance(const char *name) { - char *cp, *endcp; + const char *cp, *endcp; int n; if (strcmp(name, "any") == 0) { @@ -154,29 +128,14 @@ get_instance(char *name) return (n); } -static int -add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name, +int +add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, u_int flags, const char *description, char *errbuf) { - pcap_t *p; pcap_if_t *curdev, *prevdev, *nextdev; int this_instance; /* - * Can we open this interface for live capture? - */ - p = pcap_open_live(name, 68, 0, 0, errbuf); - if (p == NULL) { - /* - * No. Don't bother including it. - * Don't treat this as an error, though. - */ - *curdev_ret = NULL; - return (0); - } - pcap_close(p); - - /* * Is there already an entry in the list for this interface? */ for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { @@ -194,7 +153,7 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name, "malloc: %s", pcap_strerror(errno)); return (-1); } - + /* * Fill in the entry. */ @@ -317,15 +276,18 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name, } else prevdev->next = curdev; } - + *curdev_ret = curdev; return (0); } -static int +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 +321,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 +332,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)); @@ -379,9 +341,9 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, } } else 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)); @@ -390,9 +352,9 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, } } else 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)); @@ -401,7 +363,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, } } else curaddr->dstaddr = NULL; - + /* * Find the end of the list of addresses. */ @@ -431,7 +393,7 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, return (0); } -static int +int pcap_add_if(pcap_if_t **devlist, char *name, u_int flags, const char *description, char *errbuf) { @@ -441,464 +403,6 @@ pcap_add_if(pcap_if_t **devlist, char *name, u_int flags, errbuf)); } -/* - * 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. - */ -#ifdef HAVE_IFADDRS_H -int -pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -{ - pcap_if_t *devlist = NULL; - struct ifaddrs *ifap, *ifa; - struct sockaddr *broadaddr, *dstaddr; - int ret = 0; - - /* - * 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.) - * - * LAN interfaces will probably have link-layer - * addresses; I don't know whether all implementations - * of "getifaddrs()" now, or in the future, will return - * those. - */ - if (getifaddrs(&ifap) != 0) { - (void)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 (!(ifa->ifa_flags & IFF_UP)) { - /* - * No, so don't add it to the list. - */ - continue; - } - - /* - * "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 - * interface. - */ - if (ifa->ifa_flags & IFF_BROADCAST) - broadaddr = ifa->ifa_broadaddr; - else - broadaddr = NULL; - if (ifa->ifa_flags & IFF_POINTOPOINT) - dstaddr = ifa->ifa_dstaddr; - else - dstaddr = NULL; - - /* - * 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) { - ret = -1; - break; - } - } - - freeifaddrs(ifap); - - if (ret != -1) { - /* - * We haven't had any errors yet; add the "any" device, - * if we can open it. - */ - if (pcap_add_if(&devlist, "any", 0, any_descr, errbuf) < 0) - ret = -1; - } - - if (ret == -1) { - /* - * We had an error; free the list we've been constructing. - */ - if (devlist != NULL) { - pcap_freealldevs(devlist); - devlist = NULL; - } - } - - *alldevsp = devlist; - return (ret); -} -#else /* HAVE_IFADDRS_H */ -#ifdef HAVE_PROC_NET_DEV -/* - * Get from "/proc/net/dev" all interfaces listed there; if they're - * already in the list of interfaces we have, that won't add another - * instance, but if they're not, that'll add them. - * - * We don't bother getting any addresses for them; it appears you can't - * use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and, - * although some other types of addresses can be fetched with SIOCGIFADDR, - * we don't bother with them for now. - * - * We also don't fail if we couldn't open "/proc/net/dev"; we just leave - * the list of interfaces as is. - */ -static int -scan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf) -{ - FILE *proc_net_f; - char linebuf[512]; - int linenum; - unsigned char *p; - char name[512]; /* XXX - pick a size */ - char *q, *saveq; - struct ifreq ifrflags; - int ret = 0; - - proc_net_f = fopen("/proc/net/dev", "r"); - if (proc_net_f == NULL) - return (0); - - for (linenum = 1; - fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) { - /* - * Skip the first two lines - they're headers. - */ - if (linenum <= 2) - continue; - - p = &linebuf[0]; - - /* - * Skip leading white space. - */ - while (*p != '\0' && isspace(*p)) - p++; - if (*p == '\0' || *p == '\n') - continue; /* blank line */ - - /* - * Get the interface name. - */ - q = &name[0]; - while (*p != '\0' && !isspace(*p)) { - if (*p == ':') { - /* - * This could be the separator between a - * name and an alias number, or it could be - * the separator between a name with no - * alias number and the next field. - * - * If there's a colon after digits, it - * separates the name and the alias number, - * otherwise it separates the name and the - * next field. - */ - saveq = q; - while (isdigit(*p)) - *q++ = *p++; - if (*p != ':') { - /* - * That was the next field, - * not the alias number. - */ - q = saveq; - } - break; - } else - *q++ = *p++; - } - *q = '\0'; - - /* - * Get the flags for this interface, and skip it if - * it's not up. - */ - strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name)); - if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { - if (errno == ENXIO) - continue; - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFFLAGS: %.*s: %s", - (int)sizeof(ifrflags.ifr_name), - ifrflags.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - if (!(ifrflags.ifr_flags & IFF_UP)) - continue; - - /* - * Add an entry for this interface, with no addresses. - */ - if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL, - errbuf) == -1) { - /* - * Failure. - */ - ret = -1; - break; - } - } - if (ret != -1) { - /* - * Well, we didn't fail for any other reason; did we - * fail due to an error reading the file? - */ - if (ferror(proc_net_f)) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "Error reading /proc/net/dev: %s", - pcap_strerror(errno)); - ret = -1; - } - } - - (void)fclose(proc_net_f); - return (ret); -} -#endif /* HAVE_PROC_NET_DEV */ - -int -pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -{ - pcap_if_t *devlist = NULL; - register int fd; - register struct ifreq *ifrp, *ifend, *ifnext; - int n; - struct ifconf ifc; - char *buf = NULL; - unsigned buf_size; - struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr; - struct sockaddr *netmask, *broadaddr, *dstaddr; - int ret = 0; - - /* - * Create a socket from which to fetch the list of interfaces. - */ - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "socket: %s", pcap_strerror(errno)); - return (-1); - } - - /* - * Start with an 8K buffer, and keep growing the buffer until - * we get the entire interface list or fail to get it for some - * reason other than EINVAL (which is presumed here to mean - * "buffer is too small"). - */ - buf_size = 8192; - for (;;) { - buf = malloc(buf_size); - if (buf == NULL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "malloc: %s", pcap_strerror(errno)); - (void)close(fd); - return (-1); - } - - ifc.ifc_len = buf_size; - ifc.ifc_buf = buf; - memset(buf, 0, buf_size); - if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 - && errno != EINVAL) { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFCONF: %s", pcap_strerror(errno)); - (void)close(fd); - free(buf); - return (-1); - } - if (ifc.ifc_len < buf_size) - break; - free(buf); - buf_size *= 2; - } - - ifrp = (struct ifreq *)buf; - ifend = (struct ifreq *)(buf + ifc.ifc_len); - - for (; ifrp < ifend; ifrp = ifnext) { - n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name); - if (n < sizeof(*ifrp)) - ifnext = ifrp + 1; - else - ifnext = (struct ifreq *)((char *)ifrp + n); - - /* - * Get the flags for this interface, and skip it if it's - * not up. - */ - strncpy(ifrflags.ifr_name, ifrp->ifr_name, - sizeof(ifrflags.ifr_name)); - if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { - if (errno == ENXIO) - continue; - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFFLAGS: %.*s: %s", - (int)sizeof(ifrflags.ifr_name), - ifrflags.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - if (!(ifrflags.ifr_flags & IFF_UP)) - continue; - - /* - * Get the netmask for this address on this interface. - */ - strncpy(ifrnetmask.ifr_name, ifrp->ifr_name, - sizeof(ifrnetmask.ifr_name)); - memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr, - sizeof(ifrnetmask.ifr_addr)); - if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - netmask = NULL; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFNETMASK: %.*s: %s", - (int)sizeof(ifrnetmask.ifr_name), - ifrnetmask.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else - netmask = &ifrnetmask.ifr_addr; - - /* - * Get the broadcast address for this address on this - * interface (if any). - */ - if (ifrflags.ifr_flags & IFF_BROADCAST) { - strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name, - sizeof(ifrbroadaddr.ifr_name)); - memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr, - sizeof(ifrbroadaddr.ifr_addr)); - if (ioctl(fd, SIOCGIFBRDADDR, - (char *)&ifrbroadaddr) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - broadaddr = NULL; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFBRDADDR: %.*s: %s", - (int)sizeof(ifrbroadaddr.ifr_name), - ifrbroadaddr.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else - broadaddr = &ifrbroadaddr.ifr_broadaddr; - } else { - /* - * Not a broadcast interface, so no broadcast - * address. - */ - broadaddr = NULL; - } - - /* - * Get the destination address for this address on this - * interface (if any). - */ - if (ifrflags.ifr_flags & IFF_POINTOPOINT) { - strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name, - sizeof(ifrdstaddr.ifr_name)); - memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr, - sizeof(ifrdstaddr.ifr_addr)); - if (ioctl(fd, SIOCGIFDSTADDR, - (char *)&ifrdstaddr) < 0) { - if (errno == EADDRNOTAVAIL) { - /* - * Not available. - */ - dstaddr = NULL; - } else { - (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, - "SIOCGIFDSTADDR: %.*s: %s", - (int)sizeof(ifrdstaddr.ifr_name), - ifrdstaddr.ifr_name, - pcap_strerror(errno)); - ret = -1; - break; - } - } else - dstaddr = &ifrdstaddr.ifr_dstaddr; - } else - dstaddr = NULL; - - /* - * 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) { - ret = -1; - break; - } - } - free(buf); - -#ifdef HAVE_PROC_NET_DEV - if (ret != -1) { - /* - * We haven't had any errors yet; now read "/proc/net/dev", - * and add to the list of interfaces all interfaces listed - * there that we don't already have, because, on Linux, - * SIOCGIFCONF reports only interfaces with IPv4 addresses, - * so you need to read "/proc/net/dev" to get the names of - * the rest of the interfaces. - */ - ret = scan_proc_net_dev(&devlist, fd, errbuf); - } -#endif - (void)close(fd); - - if (ret != -1) { - /* - * We haven't had any errors yet; add the "any" device, - * if we can open it. - */ - if (pcap_add_if(&devlist, "any", 0, any_descr, errbuf) < 0) { - /* - * Oops, we had a fatal error. - */ - ret = -1; - } - } - - if (ret == -1) { - /* - * We had an error; free the list we've been constructing. - */ - if (devlist != NULL) { - pcap_freealldevs(devlist); - devlist = NULL; - } - } - - *alldevsp = devlist; - return (ret); -} -#endif /* HAVE_IFADDRS_H */ /* * Free a list of interfaces. @@ -946,6 +450,8 @@ pcap_freealldevs(pcap_if_t *alldevs) } } +#ifndef WIN32 + /* * Return the name of a network interface attached to the system, or NULL * if none can be found. The interface must be configured up; the @@ -965,7 +471,7 @@ pcap_lookupdev(errbuf) if (pcap_findalldevs(&alldevs, errbuf) == -1) return (NULL); - + if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) { /* * There are no devices on the list, or the first device @@ -995,7 +501,7 @@ pcap_lookupdev(errbuf) int pcap_lookupnet(device, netp, maskp, errbuf) - register char *device; + register const char *device; register bpf_u_int32 *netp, *maskp; register char *errbuf; { @@ -1003,12 +509,16 @@ pcap_lookupnet(device, netp, maskp, errbuf) register struct sockaddr_in *sin; struct ifreq ifr; - /* + /* * The pseudo-device "any" listens on all interfaces and therefore * has the network address and -mask "0.0.0.0" therefore catching * all traffic. Using NULL for the interface is the same as "any". */ - if (!device || strcmp(device, "any") == 0) { + if (!device || strcmp(device, "any") == 0 +#ifdef HAVE_DAG_API + || strstr(device, "dag") != NULL +#endif + ) { *netp = *maskp = 0; return 0; } @@ -1063,3 +573,121 @@ pcap_lookupnet(device, netp, maskp, errbuf) *netp &= *maskp; return (0); } + +#else /* WIN32 */ + +/* + * Return the name of a network interface attached to the system, or NULL + * if none can be found. The interface must be configured up; the + * lowest unit number is preferred; loopback is ignored. + */ +char * +pcap_lookupdev(errbuf) + register char *errbuf; +{ + DWORD dwVersion; + DWORD dwWindowsMajorVersion; + dwVersion = GetVersion(); /* get the OS version */ + dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); + + if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { + /* + * Windows 95, 98, ME. + */ + ULONG NameLength = 8192; + static char AdaptersName[8192]; + + PacketGetAdapterNames(AdaptersName,&NameLength); + + return (AdaptersName); + } else { + /* + * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility + */ + ULONG NameLength = 8192; + static WCHAR AdaptersName[8192]; + char *tAstr; + WCHAR *tUstr; + WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR)); + int NAdapts = 0; + + if(TAdaptersName == NULL) + { + (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure"); + return NULL; + } + + PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength); + + tAstr = (char*)TAdaptersName; + tUstr = (WCHAR*)AdaptersName; + + /* + * Convert and copy the device names + */ + while(sscanf(tAstr, "%S", tUstr) > 0) + { + tAstr += strlen(tAstr) + 1; + tUstr += wcslen(tUstr) + 1; + NAdapts ++; + } + + tAstr++; + *tUstr = 0; + tUstr++; + + /* + * Copy the descriptions + */ + while(NAdapts--) + { + strcpy((char*)tUstr, tAstr); + (char*)tUstr += strlen(tAstr) + 1;; + tAstr += strlen(tAstr) + 1; + } + + return (char *)(AdaptersName); + } +} + + +int +pcap_lookupnet(device, netp, maskp, errbuf) + const register char *device; + register bpf_u_int32 *netp, *maskp; + register char *errbuf; +{ + /* + * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo() + * in order to skip non IPv4 (i.e. IPv6 addresses) + */ + npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES]; + LONG if_addr_size = 1; + struct sockaddr_in *t_addr; + unsigned int i; + + if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) { + *netp = *maskp = 0; + return (0); + } + + for(i=0; i<MAX_NETWORK_ADDRESSES; i++) + { + if(if_addrs[i].IPAddress.ss_family == AF_INET) + { + t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress); + *netp = t_addr->sin_addr.S_un.S_addr; + t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask); + *maskp = t_addr->sin_addr.S_un.S_addr; + + *netp &= *maskp; + return (0); + } + + } + + *netp = *maskp = 0; + return (0); +} + +#endif /* WIN32 */ |