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;
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;
if (ret < 0) {
warnx("pcap_dispatch('%s'): %s",
iface->name, pcap_geterr(iface->pcap));
- continue;
+ return 0;
}
#if 0 /* debugging */
}
}
cap_stats_update();
+ return 1;
}
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];