Note by jsynacek: This patch should be rewritten. There's no reason to be using a static variable and returning its content from a function (in iterate_dev()). Also, some things should be simplified (like iterate_dev()). diff -up ./arpwatch.c.iselect ./arpwatch.c --- ./arpwatch.c.iselect 2012-10-15 16:01:24.701335291 +0200 +++ ./arpwatch.c 2012-10-15 16:07:18.626322639 +0200 @@ -162,50 +162,52 @@ void dropprivileges(const char* user) } char * -get_first_dev(pcap_t **pd, int *linktype, char *errbuf) +try_dev(char *interface, pcap_t **pd, int *linktype, char *errbuf) { - static char interface[IF_NAMESIZE + 1]; register int snaplen, timeout; - pcap_if_t *alldevs; - pcap_if_t *dev; - char *ret = NULL; snaplen = max(sizeof(struct ether_header), sizeof(struct fddi_header)) + sizeof(struct ether_arp); timeout = 1000; - if (pcap_findalldevs(&alldevs, errbuf) == -1) { - (void)fprintf(stderr, "%s: lookup_device: %s\n", - prog, errbuf); - exit(1); + *pd = pcap_open_live(interface, snaplen, 1, timeout, errbuf); + if (NULL == *pd) { + syslog(LOG_ERR, "pcap open %s: %s", interface, errbuf); + return NULL; } + *linktype = pcap_datalink(*pd); + /* Must be ethernet or fddi */ + if (*linktype != DLT_EN10MB && *linktype != DLT_FDDI) { + syslog(LOG_ERR, "(%s) Link layer type %d not ethernet or fddi", + interface, *linktype); + pcap_close(*pd); + return NULL; + } + return interface; +} - for (dev = alldevs; dev; dev = dev->next) { - strncpy(interface, dev->name, strlen(dev->name)+1); - - *pd = pcap_open_live(interface, snaplen, 1, timeout, errbuf); - if (*pd == NULL) { - syslog(LOG_ERR, "pcap open %s: %s, trying next...", interface, errbuf); - continue; - /* exit(1); */ - } +char * +iterate_dev(char *arginterface, pcap_t **pd, int *linktype, char *errbuf) +{ + static char interface[64 + 1]; + pcap_if_t *alldevs; + pcap_if_t *dev; - *linktype = pcap_datalink(*pd); - /* Must be ethernet or fddi */ - if (*linktype != DLT_EN10MB && *linktype != DLT_FDDI) { - syslog(LOG_ERR, "(%s) Link layer type %d not ethernet or fddi, trying next...", - interface, *linktype); - pcap_close(*pd); + if (NULL != arginterface) { + return try_dev(arginterface, pd, linktype, errbuf); + } else { + if (pcap_findalldevs(&alldevs, errbuf) == -1) { + (void)fprintf(stderr, "%s: lookup_device: %s\n", + prog, errbuf); + exit(1); } - else { - /* First match, use it */ - ret = interface; - break; + for (dev = alldevs; dev && (arginterface == NULL); dev = dev->next) { + strncpy(interface, dev->name, strlen(dev->name)+1); + arginterface = try_dev(interface, pd, linktype, errbuf); } - + pcap_freealldevs(alldevs); + return arginterface; } - pcap_freealldevs(alldevs); - return (ret); } int @@ -315,8 +317,8 @@ main(int argc, char **argv) } else { /* Determine interface if not specified */ - if (interface == NULL && - (interface = get_first_dev(&pd, &linktype, errbuf)) == NULL) { + interface = iterate_dev(interface, &pd, &linktype, errbuf); + if (interface == NULL) { (void)fprintf(stderr, "%s: lookup_device: no suitable interface found\n", prog); exit(1);