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