--- embedaddon/arping/src/unix.c 2016/10/18 13:16:10 1.1.1.2 +++ embedaddon/arping/src/unix.c 2021/03/16 23:40:57 1.1.1.3 @@ -20,19 +20,83 @@ #include "config.h" #endif +#include #include +#include +#if HAVE_SYS_SOCKET_H +#include +#endif + +#if HAVE_NETINET_IN_H +#include +#endif + #include #include "arping.h" +#define UNUSED(x) (void)(x) + /** * Fall back on getting device name from pcap. */ const char * arping_lookupdev_default(uint32_t srcip, uint32_t dstip, char *ebuf) { +#ifdef HAVE_PCAP_FINDALLDEVS + UNUSED(srcip); + pcap_if_t *ifs = NULL; + int rc = pcap_findalldevs(&ifs, ebuf); + if (rc) { + return NULL; + } + + pcap_if_t *t; + char* ifname = NULL; + for (t = ifs; !ifname && t; t = t->next) { +#ifdef PCAP_IF_LOOPBACK + if (t->flags & PCAP_IF_LOOPBACK) { + continue; + } +#endif +#ifdef PCAP_IF_UP + if (!(t->flags & PCAP_IF_UP)) { + continue; + } +#endif + + // This code is only called when using -F, which is "don't try + // to be smart". If we wanted to be smart we would have used + // findif_*.c. + if (1) { + ifname = strdup(t->name); // Memory leak. + break; + } + + // UNREACHABLE + pcap_addr_t *a; + for (a = t->addresses; !ifname && a; a = a->next) { + if (a->addr->sa_family != AF_INET) { + continue; + } + const struct sockaddr_in* sa = (struct sockaddr_in*)a->addr; + const struct sockaddr_in* smask = (struct sockaddr_in*)a->netmask; + const uint32_t addr = sa->sin_addr.s_addr; + const uint32_t mask = smask->sin_addr.s_addr; + if ((addr & mask) != (dstip & mask)) { + // Not optimal: memory leak. + ifname = strdup(t->name); + } + } + } + pcap_freealldevs(ifs); + return ifname; +#else + UNUSED(srcip); + UNUSED(dstip); return pcap_lookupdev(ebuf); +#endif } /** @@ -41,7 +105,10 @@ arping_lookupdev_default(uint32_t srcip, uint32_t dsti void do_signal_init() { - signal(SIGINT, sigint); + if (SIG_ERR == signal(SIGINT, sigint)) { + fprintf(stderr, "arping: failed to set SIGINT handler: %s\n", + strerror(errno)); + } } /* ---- Emacs Variables ---- * Local Variables: