/* For terms of usage/redistribution/modification see the LICENSE file */ /* For authors and contributors see the AUTHORS file */ /*** promisc.c - handles the promiscuous mode flag for the Ethernet/FDDI/ Token Ring interfaces ***/ #include "iptraf-ng-compat.h" #include "ifaces.h" #include "error.h" #include "promisc.h" static void promisc_add_dev(struct list_head *promisc, const char *dev_name) { struct promisc_list *p = xmallocz(sizeof(*p)); strcpy(p->ifname, dev_name); INIT_LIST_HEAD(&p->list); list_add_tail(&p->list, promisc); } void promisc_init(struct list_head *promisc, const char *device_name) { if (device_name) { int flags = dev_promisc_flag(device_name); if (flags < 0) return; promisc_add_dev(promisc, device_name); return; } FILE *fp = open_procnetdev(); if (!fp) die_errno("%s: open_procnetdev", __func__); char dev_name[IFNAMSIZ]; while (get_next_iface(fp, dev_name, sizeof(dev_name))) { if (!strcmp(dev_name, "")) continue; int flags = dev_promisc_flag(dev_name); if (flags < 0) continue; promisc_add_dev(promisc, dev_name); } fclose(fp); } void promisc_set_list(struct list_head *promisc) { struct promisc_list *entry = NULL; list_for_each_entry(entry, promisc, list) { int r = dev_set_promisc(entry->ifname); if (r < 0) write_error("Failed to set promiscuous mode on %s", entry->ifname); } } void promisc_restore_list(struct list_head *promisc) { struct promisc_list *entry = NULL; list_for_each_entry(entry, promisc, list) { int r = dev_clr_promisc(entry->ifname); if (r < 0) write_error("Failed to clear promiscuous mode on %s", entry->ifname); } } void promisc_destroy(struct list_head *promisc) { struct promisc_list *entry, *tmp; list_for_each_entry_safe(entry, tmp, promisc, list) { list_del(&entry->list); free(entry); } }