119 lines
3.3 KiB
Diff
119 lines
3.3 KiB
Diff
--- arpwatch-2.1a15-dist/arpwatch.c 2012-07-23 09:55:35.832458313 +0200
|
|
+++ arpwatch-2.1a15-new/arpwatch.c 2012-07-24 11:36:59.013953071 +0200
|
|
@@ -161,15 +161,63 @@ void dropprivileges(const char* user)
|
|
syslog(LOG_DEBUG, "Running as uid=%d gid=%d", getuid(), getgid());
|
|
}
|
|
|
|
+char *
|
|
+get_first_dev(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);
|
|
+ }
|
|
+
|
|
+ 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); */
|
|
+ }
|
|
+
|
|
+ *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);
|
|
+ }
|
|
+ else {
|
|
+ /* First match, use it */
|
|
+ ret = interface;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ }
|
|
+ pcap_freealldevs(alldevs);
|
|
+ return (ret);
|
|
+}
|
|
+
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
register char *cp;
|
|
- register int op, pid, snaplen, timeout, linktype, status;
|
|
+ register int op, pid, status;
|
|
+ int linktype;
|
|
#ifdef TIOCNOTTY
|
|
register int fd;
|
|
#endif
|
|
- register pcap_t *pd;
|
|
+ pcap_t *pd;
|
|
register char *interface, *rfilename;
|
|
struct bpf_program code;
|
|
char errbuf[PCAP_ERRBUF_SIZE];
|
|
@@ -189,6 +237,7 @@ main(int argc, char **argv)
|
|
|
|
opterr = 0;
|
|
interface = NULL;
|
|
+ linktype = -1;
|
|
rfilename = NULL;
|
|
pd = NULL;
|
|
while ((op = getopt(argc, argv, "df:i:n:Nr:u:e:s:")) != EOF)
|
|
@@ -264,11 +313,12 @@ main(int argc, char **argv)
|
|
net = 0;
|
|
netmask = 0;
|
|
} else {
|
|
+
|
|
/* Determine interface if not specified */
|
|
if (interface == NULL &&
|
|
- (interface = pcap_lookupdev(errbuf)) == NULL) {
|
|
- (void)fprintf(stderr, "%s: lookup_device: %s\n",
|
|
- prog, errbuf);
|
|
+ (interface = get_first_dev(&pd, &linktype, errbuf)) == NULL) {
|
|
+ (void)fprintf(stderr, "%s: lookup_device: no suitable interface found\n",
|
|
+ prog);
|
|
exit(1);
|
|
}
|
|
|
|
@@ -317,10 +367,6 @@ main(int argc, char **argv)
|
|
}
|
|
swapped = pcap_is_swapped(pd);
|
|
} else {
|
|
- snaplen = max(sizeof(struct ether_header),
|
|
- sizeof(struct fddi_header)) + sizeof(struct ether_arp);
|
|
- timeout = 1000;
|
|
- pd = pcap_open_live(interface, snaplen, 1, timeout, errbuf);
|
|
if (pd == NULL) {
|
|
syslog(LOG_ERR, "pcap open %s: %s", interface, errbuf);
|
|
exit(1);
|
|
@@ -340,14 +386,6 @@ main(int argc, char **argv)
|
|
dropprivileges( serveruser );
|
|
}
|
|
|
|
- /* Must be ethernet or fddi */
|
|
- linktype = pcap_datalink(pd);
|
|
- if (linktype != DLT_EN10MB && linktype != DLT_FDDI) {
|
|
- syslog(LOG_ERR, "Link layer type %d not ethernet or fddi",
|
|
- linktype);
|
|
- exit(1);
|
|
- }
|
|
-
|
|
/* Compile and install filter */
|
|
if (pcap_compile(pd, &code, "arp or rarp", 1, netmask) < 0) {
|
|
syslog(LOG_ERR, "pcap_compile: %s", pcap_geterr(pd));
|