version 1.1.1.3, 2021/03/16 23:47:28
|
version 1.1.1.4, 2023/09/27 11:11:38
|
Line 30
|
Line 30
|
* |
* |
*/ |
*/ |
|
|
#if (HAVE_CONFIG_H) | #include "common.h" |
#include "../include/config.h" | |
#endif | |
#if (!(_WIN32) || (__CYGWIN__)) | |
#include "../include/libnet.h" | |
#else | |
#include "../include/win32/libnet.h" | |
#endif | |
#ifdef HAVE_SYS_SOCKIO_H |
#ifdef HAVE_SYS_SOCKIO_H |
#include <sys/sockio.h> |
#include <sys/sockio.h> |
#endif |
#endif |
|
|
#include "../include/ifaddrlist.h" |
#include "../include/ifaddrlist.h" |
|
|
#define MAX_IPADDR 512 |
#define MAX_IPADDR 512 |
Line 60 libnet_check_iface(libnet_t *l)
|
Line 55 libnet_check_iface(libnet_t *l)
|
fd = socket(AF_INET, SOCK_DGRAM, 0); |
fd = socket(AF_INET, SOCK_DGRAM, 0); |
if (fd < 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)); |
strerror(errno)); |
return (-1); |
return (-1); |
} |
} |
Line 69 libnet_check_iface(libnet_t *l)
|
Line 64 libnet_check_iface(libnet_t *l)
|
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; |
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; |
|
|
res = ioctl(fd, SIOCGIFFLAGS, (int8_t *)&ifr); |
res = ioctl(fd, SIOCGIFFLAGS, (int8_t *)&ifr); |
|
|
if (res < 0) |
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)); |
strerror(errno)); |
} |
} |
else |
else |
{ |
{ |
if ((ifr.ifr_flags & IFF_UP) == 0) |
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); |
__func__, l->device); |
res = -1; |
res = -1; |
} |
} |
} |
} |
close(fd); |
close(fd); |
|
|
return (res); |
return (res); |
} |
} |
|
|
|
#endif |
|
|
|
#if defined(__OpenBSD__) || defined(__linux__) |
|
#include <sys/types.h> |
|
#ifdef __OpenBSD__ |
|
#include <sys/socket.h> |
|
#endif |
|
#include <ifaddrs.h> |
|
|
|
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 |
* Return the interface list |
*/ |
*/ |
Line 109 libnet_check_iface(libnet_t *l)
|
Line 153 libnet_check_iface(libnet_t *l)
|
#endif |
#endif |
|
|
int |
int |
libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, | libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, register char *errbuf) |
register char *errbuf) | |
{ |
{ |
register struct libnet_ifaddr_list *al; |
register struct libnet_ifaddr_list *al; |
struct ifreq *ifr, *lifr, *pifr, nifr; |
struct ifreq *ifr, *lifr, *pifr, nifr; |
Line 130 register char *errbuf)
|
Line 173 register char *errbuf)
|
fd = socket(AF_INET, SOCK_DGRAM, 0); |
fd = socket(AF_INET, SOCK_DGRAM, 0); |
if (fd < 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)); |
__func__, strerror(errno)); |
return (-1); |
return (-1); |
} |
} |
|
|
#ifdef HAVE_LINUX_PROCFS |
#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, |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
"%s(): fopen(proc_dev_file) failed: %s\n", __func__, | "%s(): fopen(proc_dev_file) failed: %s", __func__, |
strerror(errno)); |
strerror(errno)); |
return (-1); | goto bad; |
} |
} |
#endif |
#endif |
|
|
Line 149 register char *errbuf)
|
Line 193 register char *errbuf)
|
ifc.ifc_len = sizeof(ibuf); |
ifc.ifc_len = sizeof(ibuf); |
ifc.ifc_buf = (caddr_t)ibuf; |
ifc.ifc_buf = (caddr_t)ibuf; |
|
|
if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) | if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) |
{ |
{ |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
"%s(): ioctl(SIOCGIFCONF) error: %s\n", | "%s(): ioctl(SIOCGIFCONF) error: %s", |
__func__, strerror(errno)); |
__func__, strerror(errno)); |
#ifdef HAVE_LINUX_PROCFS | goto bad; |
fclose(fp); | |
#endif | |
return(-1); | |
} |
} |
|
|
pifr = NULL; |
pifr = NULL; |
Line 169 register char *errbuf)
|
Line 210 register char *errbuf)
|
#ifdef HAVE_LINUX_PROCFS |
#ifdef HAVE_LINUX_PROCFS |
while (fgets(buf, sizeof(buf), fp)) |
while (fgets(buf, sizeof(buf), fp)) |
{ |
{ |
if ((p = strchr(buf, ':')) == NULL) | p = strchr(buf, ':'); |
{ | if (!p) |
continue; |
continue; |
} | |
*p = '\0'; |
*p = '\0'; |
for(p = buf; *p == ' '; p++) ; | for (p = buf; *p == ' '; p++) |
| ; |
|
|
strncpy(nifr.ifr_name, p, sizeof(nifr.ifr_name) - 1); |
strncpy(nifr.ifr_name, p, sizeof(nifr.ifr_name) - 1); |
nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0'; |
nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0'; |
Line 184 register char *errbuf)
|
Line 226 register char *errbuf)
|
for (ifr = ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr)) |
for (ifr = ifc.ifc_req; ifr < lifr; ifr = NEXTIFR(ifr)) |
{ |
{ |
/* XXX LINUX SOLARIS ifalias */ |
/* XXX LINUX SOLARIS ifalias */ |
if((p = strchr(ifr->ifr_name, ':'))) | p = strchr(ifr->ifr_name, ':'); |
{ | if (p) |
*p='\0'; | *p = '\0'; |
} | |
if (pifr && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) |
if (pifr && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) |
{ |
|
continue; |
continue; |
} | |
strncpy(nifr.ifr_name, ifr->ifr_name, sizeof(nifr.ifr_name) - 1); |
strncpy(nifr.ifr_name, ifr->ifr_name, sizeof(nifr.ifr_name) - 1); |
nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0'; |
nifr.ifr_name[sizeof(nifr.ifr_name) - 1] = '\0'; |
#endif |
#endif |
Line 224 register char *errbuf)
|
Line 265 register char *errbuf)
|
if (errno != EADDRNOTAVAIL) |
if (errno != EADDRNOTAVAIL) |
{ |
{ |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
"%s(): SIOCGIFADDR: dev=%s: %s\n", __func__, device, | "%s(): SIOCGIFADDR: dev=%s: %s", __func__, device, |
strerror(errno)); |
strerror(errno)); |
close(fd); | goto bad; |
#ifdef HAVE_LINUX_PROCFS | |
fclose(fp); | |
#endif | |
return (-1); | |
} |
} |
else /* device has no IP address => set to 0 */ |
else /* device has no IP address => set to 0 */ |
{ |
{ |
Line 243 register char *errbuf)
|
Line 280 register char *errbuf)
|
} |
} |
|
|
free(al->device); |
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, |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
"%s(): strdup not enough memory\n", __func__); | "%s(): strdup not enough memory", __func__); |
#ifdef HAVE_LINUX_PROCFS | goto bad; |
fclose(fp); | |
#endif | |
return(-1); | |
} |
} |
|
|
++al; |
++al; |
Line 268 register char *errbuf)
|
Line 302 register char *errbuf)
|
if (ferror(fp)) |
if (ferror(fp)) |
{ |
{ |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
"%s(): ferror: %s\n", __func__, strerror(errno)); | "%s(): ferror: %s", __func__, strerror(errno)); |
fclose(fp); | goto bad; |
return (-1); | |
} |
} |
fclose(fp); |
fclose(fp); |
#endif |
#endif |
|
|
|
close(fd); |
*ipaddrp = ifaddrlist; |
*ipaddrp = ifaddrlist; |
|
|
return (nipaddr); |
return (nipaddr); |
|
|
|
bad: |
|
#ifdef HAVE_LINUX_PROCFS |
|
if (fp) |
|
fclose(fp); |
|
#endif |
|
close(fd); |
|
return (-1); |
} |
} |
#else |
#else |
|
/* WIN32 support * |
|
* TODO move win32 support into win32 specific source file */ |
|
|
/* From tcptraceroute, convert a numeric IP address to a string */ |
/* From tcptraceroute, convert a numeric IP address to a string */ |
#define IPTOSBUFFERS 12 |
#define IPTOSBUFFERS 12 |
static int8_t *iptos(uint32_t in) |
static int8_t *iptos(uint32_t in) |
Line 295 static int8_t *iptos(uint32_t in)
|
Line 341 static int8_t *iptos(uint32_t in)
|
} |
} |
|
|
int |
int |
libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev, | libnet_ifaddrlist(register struct libnet_ifaddr_list **ipaddrp, char *dev_unused, register char *errbuf) |
register char *errbuf) | |
{ |
{ |
int nipaddr = 0; int i = 0; | int nipaddr = 0; |
| int i = 0; |
static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR]; |
static struct libnet_ifaddr_list ifaddrlist[MAX_IPADDR]; |
pcap_if_t *alldevs; | pcap_if_t *devlist = NULL; |
pcap_if_t *d; | pcap_if_t *dev = NULL; |
int8_t err[PCAP_ERRBUF_SIZE]; |
int8_t err[PCAP_ERRBUF_SIZE]; |
|
|
/* Retrieve the interfaces list */ |
/* Retrieve the interfaces list */ |
if (pcap_findalldevs(&alldevs, err) == -1) | if (pcap_findalldevs(&devlist, err) == -1) |
{ |
{ |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
snprintf(errbuf, LIBNET_ERRBUF_SIZE, |
"%s(): error in pcap_findalldevs: %s\n", __func__, err); | "%s(): error in pcap_findalldevs: %s", __func__, err); |
return (-1); |
return (-1); |
} |
} |
|
|
/* Scan the list printing every entry */ | for (dev = devlist; dev; dev = dev->next) |
for (d = alldevs; d; d = d->next) | |
{ |
{ |
if((!d->addresses) || (d->addresses->addr->sa_family != AF_INET)) | struct pcap_addr* pcapaddr; |
continue; | for(pcapaddr = dev->addresses; pcapaddr; pcapaddr = pcapaddr->next) { |
if(d->flags & PCAP_IF_LOOPBACK) | struct sockaddr* addr = pcapaddr->addr; |
continue; | #if 0 |
| printf("if name '%s' description '%s' loop? %d\n", dev->name, dev->description, dev->flags); |
/* XXX - strdup */ | { |
ifaddrlist[i].device = strdup(d->name); | char p[NI_MAXHOST] = ""; |
ifaddrlist[i].addr = (uint32_t) | int sz = sizeof(struct sockaddr_storage); |
strdup(iptos(((struct sockaddr_in *) | int r; |
d->addresses->addr)->sin_addr.s_addr)); | r = getnameinfo(addr, sz, p, sizeof(p), NULL,0, NI_NUMERICHOST); |
++i; | printf(" addr %s\n", r ? gai_strerror(r) : p); |
++nipaddr; | } |
| #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; |
*ipaddrp = ifaddrlist; |
return (nipaddr); | |
| return nipaddr; |
} |
} |
#endif /* __WIN32__ */ |
#endif /* __WIN32__ */ |
|
|
|
#endif /* __OpenBSD__ */ |
|
|
int |
int |
libnet_select_device(libnet_t *l) |
libnet_select_device(libnet_t *l) |
{ |
{ |
Line 368 libnet_select_device(libnet_t *l)
|
Line 429 libnet_select_device(libnet_t *l)
|
c = libnet_ifaddrlist(&address_list, l->device, l->err_buf); |
c = libnet_ifaddrlist(&address_list, l->device, l->err_buf); |
if (c < 0) |
if (c < 0) |
{ |
{ |
/* err msg set in libnet_ifaddrlist() */ |
|
return (-1); |
return (-1); |
} |
} |
else if (c == 0) |
else if (c == 0) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): no network interface found\n", __func__); | "%s(): no network interface found", __func__); |
return (-1); |
return (-1); |
} |
} |
|
|
al = address_list; |
al = address_list; |
if (l->device) |
if (l->device) |
{ |
{ |
/* | addr = libnet_name2addr4(l, l->device, LIBNET_DONT_RESOLVE); |
* 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) |
for (i = c; i; --i, ++address_list) |
{ |
{ |
if (((addr == -1) && !(strncmp(l->device, address_list->device, | if ( |
strlen(l->device)))) || | 0 == strcmp(l->device, address_list->device) |
(address_list->addr == addr)) | || |
| address_list->addr == addr |
| ) |
{ |
{ |
/* free the "user supplied device" - see libnet_init() */ |
/* free the "user supplied device" - see libnet_init() */ |
free(l->device); |
free(l->device); |
Line 401 libnet_select_device(libnet_t *l)
|
Line 460 libnet_select_device(libnet_t *l)
|
if (i <= 0) |
if (i <= 0) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
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); |
l->device); |
goto bad; |
goto bad; |
} |
} |
Line 428 bad:
|
Line 487 bad:
|
return (-1); |
return (-1); |
} |
} |
|
|
/* EOF */ | /** |
| * Local Variables: |
| * indent-tabs-mode: nil |
| * c-file-style: "stroustrup" |
| * End: |
| */ |