summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Roberts <vieuxtech@gmail.com>2012-11-01 13:08:55 -0700
committerSam Roberts <vieuxtech@gmail.com>2012-11-01 13:08:55 -0700
commit9c744c8e212184571ee804cc9f580f9704325bc8 (patch)
tree7059f8a669ade5f4bf16b98843febe092ede661e
parent18cbe497dd84afc471a5320e4ef3a7cde87c2c4e (diff)
downloadlibnet-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.
-rw-r--r--libnet/src/libnet_if_addr.c65
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);