diff options
author | Sam Roberts <vieuxtech@gmail.com> | 2012-11-01 13:08:55 -0700 |
---|---|---|
committer | Sam Roberts <vieuxtech@gmail.com> | 2012-11-01 13:08:55 -0700 |
commit | 9c744c8e212184571ee804cc9f580f9704325bc8 (patch) | |
tree | 7059f8a669ade5f4bf16b98843febe092ede661e /libnet/src | |
parent | 18cbe497dd84afc471a5320e4ef3a7cde87c2c4e (diff) | |
download | libnet-9c744c8e212184571ee804cc9f580f9704325bc8.tar.gz |
Make interface selection work for interfaces with multiple addresses on them.
Windows supports IPv4 and IPv6 by default, so interfaces will have
two addresses, and libnet failed when the first address was IPv6.
Diffstat (limited to 'libnet/src')
-rw-r--r-- | libnet/src/libnet_if_addr.c | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/libnet/src/libnet_if_addr.c b/libnet/src/libnet_if_addr.c index d97d2e1..9807539 100644 --- a/libnet/src/libnet_if_addr.c +++ b/libnet/src/libnet_if_addr.c @@ -292,43 +292,58 @@ static int8_t *iptos(uint32_t in) } int -libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, register char *errbuf) +libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev_unused, register char *errbuf) { int nipaddr = 0; int i = 0; static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR]; - pcap_if_t *alldevs = NULL; - pcap_if_t *d = NULL; + pcap_if_t *devlist = NULL; + pcap_if_t *dev = NULL; int8_t err[PCAP_ERRBUF_SIZE]; /* Retrieve the interfaces list */ - if (pcap_findalldevs(&alldevs, err) == -1) + if (pcap_findalldevs(&devlist, err) == -1) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): error in pcap_findalldevs: %s\n", __func__, err); return (-1); } - /* Scan the list printing every entry */ - for (d = alldevs; d; d = d->next) + for (dev = devlist; dev; dev = dev->next) { - if(!d->addresses) - continue; - if(d->addresses->addr->sa_family != AF_INET && d->addresses->addr->sa_family != AF_INET6) - continue; - if(d->flags & PCAP_IF_LOOPBACK) - continue; - - ifaddrlist[i].device = strdup(d->name); - ifaddrlist[i].addr = ((struct sockaddr_in *)d->addresses->addr)->sin_addr.s_addr; - ++i; - ++nipaddr; + struct pcap_addr* pcapaddr; + for(pcapaddr = dev->addresses; pcapaddr; pcapaddr = pcapaddr->next) { + struct sockaddr* addr = pcapaddr->addr; +#if 0 + printf("if name '%s' description '%s' loop? %d\n", dev->name, dev->description, dev->flags); + { + char p[NI_MAXHOST] = ""; + int sz = sizeof(struct sockaddr_storage); + int r; + r = getnameinfo(addr, sz, p, sizeof(p), NULL,0, NI_NUMERICHOST); + printf(" addr %s\n", r ? gai_strerror(r) : p); + } +#endif + + if(dev->flags & PCAP_IF_LOOPBACK) + continue; + + /* this code ignores IPv6 addresses, a limitation of the libnet_ifaddr_list struct */ + + if(addr->sa_family == AF_INET) { + ifaddrlist[i].device = strdup(dev->name); + ifaddrlist[i].addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; + ++i; + ++nipaddr; + } + } } - pcap_freealldevs(alldevs); + pcap_freealldevs(devlist); *ipaddrp = ifaddrlist; - return (nipaddr); + + return nipaddr; } #endif /* __WIN32__ */ @@ -364,7 +379,6 @@ libnet_select_device(libnet_t *l) c = libnet_ifaddrlist(&address_list, l->device, err_buf); if (c < 0) { - /* err msg set in libnet_ifaddrlist() */ return (-1); } else if (c == 0) @@ -377,16 +391,15 @@ libnet_select_device(libnet_t *l) al = address_list; if (l->device) { - /* - * Then we have an IP address in l->device => do lookup - */ addr = libnet_name2addr4(l, l->device, 0); for (i = c; i; --i, ++address_list) { - if (((addr == -1) && !(strncmp(l->device, address_list->device, - strlen(l->device)))) || - (address_list->addr == addr)) + if ( + 0 == strcmp(l->device, address_list->device) + || + address_list->addr == addr + ) { /* free the "user supplied device" - see libnet_init() */ free(l->device); |