--- embedaddon/libnet/src/libnet_if_addr.c 2021/03/16 23:47:28 1.1.1.3 +++ embedaddon/libnet/src/libnet_if_addr.c 2023/09/27 11:11:38 1.1.1.4 @@ -1,5 +1,5 @@ /* - * $Id: libnet_if_addr.c,v 1.1.1.3 2021/03/16 23:47:28 misho Exp $ + * $Id: libnet_if_addr.c,v 1.1.1.4 2023/09/27 11:11:38 misho Exp $ * * libnet * libnet_if_addr.c - interface selection code @@ -30,17 +30,12 @@ * */ -#if (HAVE_CONFIG_H) -#include "../include/config.h" -#endif -#if (!(_WIN32) || (__CYGWIN__)) -#include "../include/libnet.h" -#else -#include "../include/win32/libnet.h" -#endif +#include "common.h" + #ifdef HAVE_SYS_SOCKIO_H #include #endif + #include "../include/ifaddrlist.h" #define MAX_IPADDR 512 @@ -60,7 +55,7 @@ libnet_check_iface(libnet_t *l) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { - snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s() socket: %s\n", __func__, + snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s() socket: %s", __func__, strerror(errno)); return (-1); } @@ -69,26 +64,75 @@ libnet_check_iface(libnet_t *l) ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; res = ioctl(fd, SIOCGIFFLAGS, (int8_t *)&ifr); - if (res < 0) { - snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s() ioctl: %s\n", __func__, + snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s() ioctl: %s", __func__, strerror(errno)); } else { if ((ifr.ifr_flags & IFF_UP) == 0) { - snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %s is down\n", + snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): %s is down", __func__, l->device); res = -1; } } close(fd); + return (res); } +#endif +#if defined(__OpenBSD__) || defined(__linux__) +#include + #ifdef __OpenBSD__ + #include + #endif +#include + +int +libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, register char *errbuf) +{ + static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR]; + struct ifaddrs *ifap, *ifa; + int i = 0; + memset (ifaddrlist, 0 , sizeof(ifaddrlist)); + + if (getifaddrs(&ifap) != 0) + { + snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): getifaddrs: %s", + __func__, strerror(errno)); + return 0; + } + for (ifa = ifap; ifa; ifa = ifa->ifa_next) + { + if (ifa->ifa_flags & IFF_LOOPBACK) + continue; + + if (ifa->ifa_addr->sa_family == AF_INET ) + { + ifaddrlist[i].device = strdup(ifa->ifa_name); + if (ifaddrlist[i].device == NULL) { + snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): OOM", __func__); + continue; + } + ifaddrlist[i].addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; + ++i; + } + } + + freeifaddrs(ifap); + *ipaddrp = ifaddrlist; + return (i); +} + + +#else +#if !(__WIN32__) + + /* * Return the interface list */ @@ -109,8 +153,7 @@ libnet_check_iface(libnet_t *l) #endif int -libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, -register char *errbuf) +libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, register char *errbuf) { register struct libnet_ifaddr_list *al; struct ifreq *ifr, *lifr, *pifr, nifr; @@ -130,18 +173,19 @@ register char *errbuf) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { - snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): socket error: %s\n", + snprintf(errbuf, LIBNET_ERRBUF_SIZE, "%s(): socket error: %s", __func__, strerror(errno)); return (-1); } #ifdef HAVE_LINUX_PROCFS - if ((fp = fopen(PROC_DEV_FILE, "r")) == NULL) + fp = fopen(PROC_DEV_FILE, "r"); + if (!fp) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, - "%s(): fopen(proc_dev_file) failed: %s\n", __func__, + "%s(): fopen(proc_dev_file) failed: %s", __func__, strerror(errno)); - return (-1); + goto bad; } #endif @@ -149,15 +193,12 @@ register char *errbuf) ifc.ifc_len = sizeof(ibuf); ifc.ifc_buf = (caddr_t)ibuf; - if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) + if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, - "%s(): ioctl(SIOCGIFCONF) error: %s\n", + "%s(): ioctl(SIOCGIFCONF) error: %s", __func__, strerror(errno)); -#ifdef HAVE_LINUX_PROCFS - fclose(fp); -#endif - return(-1); + goto bad; } pifr = NULL; @@ -169,12 +210,13 @@ register char *errbuf) #ifdef HAVE_LINUX_PROCFS while (fgets(buf, sizeof(buf), fp)) { - if ((p = strchr(buf, ':')) == NULL) - { + p = strchr(buf, ':'); + if (!p) continue; - } + *p = '\0'; - for(p = buf; *p == ' '; p++) ; + for (p = buf; *p == ' '; p++) + ; strncpy(nifr.ifr_name, p, sizeof(nifr.ifr_name) - 1); nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0'; @@ -184,14 +226,13 @@ register char *errbuf) for (ifr = ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr)) { /* XXX LINUX SOLARIS ifalias */ - if((p = strchr(ifr->ifr_name, ':'))) - { - *p='\0'; - } + p = strchr(ifr->ifr_name, ':'); + if (p) + *p = '\0'; + if (pifr && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) - { continue; - } + strncpy(nifr.ifr_name, ifr->ifr_name, sizeof(nifr.ifr_name) - 1); nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0'; #endif @@ -224,13 +265,9 @@ register char *errbuf) if (errno != EADDRNOTAVAIL) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, - "%s(): SIOCGIFADDR: dev=%s: %s\n", __func__, device, + "%s(): SIOCGIFADDR: dev=%s: %s", __func__, device, strerror(errno)); - close(fd); -#ifdef HAVE_LINUX_PROCFS - fclose(fp); -#endif - return (-1); + goto bad; } else /* device has no IP address => set to 0 */ { @@ -243,16 +280,13 @@ register char *errbuf) } free(al->device); - al->device = NULL; - if ((al->device = strdup(device)) == NULL) + al->device = strdup(device); + if (al->device == NULL) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, - "%s(): strdup not enough memory\n", __func__); -#ifdef HAVE_LINUX_PROCFS - fclose(fp); -#endif - return(-1); + "%s(): strdup not enough memory", __func__); + goto bad; } ++al; @@ -268,17 +302,29 @@ register char *errbuf) if (ferror(fp)) { snprintf(errbuf, LIBNET_ERRBUF_SIZE, - "%s(): ferror: %s\n", __func__, strerror(errno)); - fclose(fp); - return (-1); + "%s(): ferror: %s", __func__, strerror(errno)); + goto bad; } fclose(fp); #endif + close(fd); *ipaddrp = ifaddrlist; + return (nipaddr); + + bad: +#ifdef HAVE_LINUX_PROCFS + if (fp) + fclose(fp); +#endif + close(fd); + return (-1); } #else +/* WIN32 support * + * TODO move win32 support into win32 specific source file */ + /* From tcptraceroute, convert a numeric IP address to a string */ #define IPTOSBUFFERS 12 static int8_t *iptos(uint32_t in) @@ -295,48 +341,63 @@ 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; - + int nipaddr = 0; + int i = 0; static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR]; - pcap_if_t *alldevs; - pcap_if_t *d; + 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); + "%s(): error in pcap_findalldevs: %s", __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) || (d->addresses->addr->sa_family != AF_INET)) - continue; - if(d->flags & PCAP_IF_LOOPBACK) - continue; - - /* XXX - strdup */ - ifaddrlist[i].device = strdup(d->name); - ifaddrlist[i].addr = (uint32_t) - strdup(iptos(((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__ */ +#endif /* __OpenBSD__ */ + int libnet_select_device(libnet_t *l) { @@ -368,29 +429,27 @@ libnet_select_device(libnet_t *l) c = libnet_ifaddrlist(&address_list, l->device, l->err_buf); if (c < 0) { - /* err msg set in libnet_ifaddrlist() */ return (-1); } else if (c == 0) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, - "%s(): no network interface found\n", __func__); + "%s(): no network interface found", __func__); return (-1); } al = address_list; if (l->device) { - /* - * Then we have an IP address in l->device => do lookup - */ - addr = libnet_name2addr4(l, l->device, 0); + addr = libnet_name2addr4(l, l->device, LIBNET_DONT_RESOLVE); 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); @@ -401,7 +460,7 @@ libnet_select_device(libnet_t *l) if (i <= 0) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, - "%s(): can't find interface for IP %s\n", __func__, + "%s(): can't find interface for IP %s", __func__, l->device); goto bad; } @@ -428,4 +487,9 @@ bad: return (-1); } -/* EOF */ +/** + * Local Variables: + * indent-tabs-mode: nil + * c-file-style: "stroustrup" + * End: + */