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);