X-Git-Url: https://unix4lyfe.org/gitweb/darkstat-debian/blobdiff_plain/4da209d9116b41ab59eeedc5823bc2cb64b5bc3e..HEAD:/cap.c diff --git a/cap.c b/cap.c index 7e1c41b..e5f3a3e 100644 --- a/cap.c +++ b/cap.c @@ -1,5 +1,5 @@ /* darkstat 3 - * copyright (c) 2001-2011 Emil Mikulic. + * copyright (c) 2001-2014 Emil Mikulic. * * cap.c: capture packets, and hand them off to decode and acct. * @@ -112,6 +112,7 @@ static void cap_set_filter(pcap_t *pcap, const char *filter) { free(tmp_filter); } +/* Start capturing on just one interface. Called from cap_start(). */ static void cap_start_one(struct cap_iface *iface, const int promisc) { char errbuf[PCAP_ERRBUF_SIZE], *tmp_device; int linktype, snaplen, waited; @@ -395,15 +396,26 @@ static void callback(u_char *user, acct_for(&sm, &iface->local_ips); } -/* Process any packets currently in the capture buffer. */ -void cap_poll(fd_set *read_set _unused_on_linux_) { +/* Process any packets currently in the capture buffer. + * Returns 0 on error (usually means the interface went down). + */ +int cap_poll(fd_set *read_set _unused_on_linux_) { struct cap_iface *iface; + static int told = 0; STAILQ_FOREACH(iface, &cap_ifs, entries) { /* Once per capture poll, check our IP address. It's used in accounting * for traffic graphs. */ localip_update(iface->name, &iface->local_ips); + if (!told && iface->local_ips.num_addrs == 0) { + verbosef("interface '%s' has no addresses, " + "your graphs will be blank", + iface->name); + verbosef("please read the darkstat manpage, " + "and consider using the -l option"); + told = 1; + } for (;;) { struct timespec t; @@ -415,18 +427,19 @@ void cap_poll(fd_set *read_set _unused_on_linux_) { -1, /* count = entire buffer */ callback, (u_char*)iface); /* user = struct to pass to callback */ + timer_stop(&t, + 2 * CAP_TIMEOUT_MSEC * 1000000, + "pcap_dispatch took too long"); if (ret < 0) { warnx("pcap_dispatch('%s'): %s", iface->name, pcap_geterr(iface->pcap)); - continue; + return 0; } - timer_stop(&t, - 2 * CAP_TIMEOUT_MSEC * 1000000, - "pcap_dispatch took too long"); - if (0) /* debugging */ - verbosef("iface '%s' got %d pkts", iface->name, ret); +#if 0 /* debugging */ + verbosef("iface '%s' got %d pkts", iface->name, ret); +#endif #ifdef linux /* keep looping until we've dispatched all the outstanding packets */ @@ -439,6 +452,7 @@ void cap_poll(fd_set *read_set _unused_on_linux_) { } } cap_stats_update(); + return 1; } void cap_stop(void) { @@ -454,6 +468,23 @@ void cap_stop(void) { title_interfaces = NULL; } +/* This is only needed by the DNS child. In the main process, the deallocation + * happens in cap_start(). + */ +void cap_free_args(void) { + while (!STAILQ_EMPTY(&cli_ifnames)) { + struct strnode *ifname = STAILQ_FIRST(&cli_ifnames); + STAILQ_REMOVE_HEAD(&cli_ifnames, entries); + free(ifname); + } + + while (!STAILQ_EMPTY(&cli_filters)) { + struct strnode *filter = STAILQ_FIRST(&cli_filters); + STAILQ_REMOVE_HEAD(&cli_filters, entries); + free(filter); + } +} + /* Run through entire capfile. */ void cap_from_file(const char *capfile) { char errbuf[PCAP_ERRBUF_SIZE];