code was so difficult to read, that I had to rewrite it from scratch.
Original code was using list structure designed only for promisc code, and
that means it has to have its own adding / removing / traversing code.
Not smart idea. Also I removed the code which stores and loads from disk
state of promosic mode. Code does:
init path
init_promisc_list(&promisc_list);
save_promisc_list(promisc_list);
srpromisc(1, promisc_list);
destroy_promisc_list(&promisc_list);
...
...
exit/error path
load_promisc_list(&promisc_list);
srpromisc(0, promisc_list);
destroy_promisc_list(&promisc_list);
now it does
init path
init_promisc_list(&promisc_list);
promisc_set(promisc_list);
...
...
exit/error path
promisc_restore(promisc_list);
destroy_promisc_list(&promisc_list);
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
src/detstats.c | 15 ++---
src/hostmon.c | 16 ++---
src/ifstats.c | 16 ++---
src/itrafmon.c | 14 ++--
src/list.h | 6 ++
src/pktsize.c | 14 ++--
src/promisc.c | 200 +++++++++++++--------------------------------------------
src/promisc.h | 28 +++-----
src/serv.c | 14 ++--
9 files changed, 92 insertions(+), 231 deletions(-)
diff --git a/src/detstats.c b/src/detstats.c
index c1e415f..02b243e 100644
--- a/src/detstats.c
+++ b/src/detstats.c
@@ -291,7 +291,6 @@ void detstats(char *iface, time_t facilitytime)
unsigned long peakpps_in = 0;
unsigned long peakpps_out = 0;
- struct promisc_states *promisc_list;
int fd;
/*
@@ -312,11 +311,10 @@ void detstats(char *iface, time_t facilitytime)
return;
}
- if (first_active_facility() && options.promisc) {
- init_promisc_list(&promisc_list);
- save_promisc_list(promisc_list);
- srpromisc(1, promisc_list);
- destroy_promisc_list(&promisc_list);
+ LIST_HEAD(promisc);
+ if (options.promisc && first_active_facility()) {
+ init_promisc_list(&promisc);
+ promisc_set(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, 1);
@@ -594,9 +592,8 @@ err:
rate_destroy(&rate);
if (options.promisc && is_last_instance()) {
- load_promisc_list(&promisc_list);
- srpromisc(0, promisc_list);
- destroy_promisc_list(&promisc_list);
+ promisc_restore(&promisc);
+ promisc_destroy(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, -1);
diff --git a/src/hostmon.c b/src/hostmon.c
index 21b1797..8b98cef 100644
--- a/src/hostmon.c
+++ b/src/hostmon.c
@@ -778,8 +778,6 @@ void hostmon(time_t facilitytime, char *ifptr)
int fd;
- struct promisc_states *promisc_list;
-
if (!facility_active(LANMONIDFILE, ifptr))
mark_facility(LANMONIDFILE, "LAN monitor", ifptr);
else {
@@ -796,11 +794,10 @@ void hostmon(time_t facilitytime, char *ifptr)
}
}
- if (first_active_facility() && options.promisc) {
- init_promisc_list(&promisc_list);
- save_promisc_list(promisc_list);
- srpromisc(1, promisc_list);
- destroy_promisc_list(&promisc_list);
+ LIST_HEAD(promisc);
+ if (options.promisc && first_active_facility()) {
+ init_promisc_list(&promisc);
+ promisc_set(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, 1);
@@ -1031,9 +1028,8 @@ err_close:
err:
if (options.promisc && is_last_instance()) {
- load_promisc_list(&promisc_list);
- srpromisc(0, promisc_list);
- destroy_promisc_list(&promisc_list);
+ promisc_restore(&promisc);
+ promisc_destroy(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, -1);
diff --git a/src/ifstats.c b/src/ifstats.c
index 8214838..6712ed5 100644
--- a/src/ifstats.c
+++ b/src/ifstats.c
@@ -451,8 +451,6 @@ void ifstats(time_t facilitytime)
time_t startlog = 0;
struct timeval updtime;
- struct promisc_states *promisc_list;
-
if (!facility_active(GSTATIDFILE, ""))
mark_facility(GSTATIDFILE, "general interface statistics", "");
else {
@@ -469,11 +467,10 @@ void ifstats(time_t facilitytime)
initiftab(&table);
- if (first_active_facility() && options.promisc) {
- init_promisc_list(&promisc_list);
- save_promisc_list(promisc_list);
- srpromisc(1, promisc_list);
- destroy_promisc_list(&promisc_list);
+ LIST_HEAD(promisc);
+ if (options.promisc && first_active_facility()) {
+ init_promisc_list(&promisc);
+ promisc_set(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, 1);
@@ -630,9 +627,8 @@ void ifstats(time_t facilitytime)
err:
if (options.promisc && is_last_instance()) {
- load_promisc_list(&promisc_list);
- srpromisc(0, promisc_list);
- destroy_promisc_list(&promisc_list);
+ promisc_restore(&promisc);
+ promisc_destroy(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, -1);
diff --git a/src/itrafmon.c b/src/itrafmon.c
index b35468f..b27722e 100644
--- a/src/itrafmon.c
+++ b/src/itrafmon.c
@@ -599,8 +599,6 @@ void ipmon(time_t facilitytime, char *ifptr)
int keymode = 0;
char msgstring[80];
- struct promisc_states *promisc_list;
-
int rvnfd = 0;
int instance_id;
@@ -628,11 +626,12 @@ void ipmon(time_t facilitytime, char *ifptr)
}
}
+ LIST_HEAD(promisc);
+
if (options.promisc) {
if (first_active_facility()) {
- init_promisc_list(&promisc_list);
- save_promisc_list(promisc_list);
- srpromisc(1, promisc_list);
+ init_promisc_list(&promisc);
+ promisc_set(&promisc);
}
}
@@ -1188,9 +1187,8 @@ err:
close_rvn_socket(rvnfd);
if (options.promisc && is_last_instance()) {
- load_promisc_list(&promisc_list);
- srpromisc(0, promisc_list);
- destroy_promisc_list(&promisc_list);
+ promisc_restore(&promisc);
+ promisc_destroy(&promisc);
}
attrset(STDATTR);
diff --git a/src/list.h b/src/list.h
index daa7628..a7b495e 100644
--- a/src/list.h
+++ b/src/list.h
@@ -80,4 +80,10 @@ static inline int list_empty(const struct list_head *head)
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
#endif /* IPTRAF_NG_LIST_H */
diff --git a/src/pktsize.c b/src/pktsize.c
index 44bc61f..c5af7fa 100644
--- a/src/pktsize.c
+++ b/src/pktsize.c
@@ -161,8 +161,6 @@ void packet_size_breakdown(char *ifname, time_t facilitytime)
int logging = options.logging;
FILE *logfile = NULL;
- struct promisc_states *promisc_list;
-
int fd;
if (!facility_active(PKTSIZEIDFILE, ifname))
@@ -241,11 +239,10 @@ void packet_size_breakdown(char *ifname, time_t facilitytime)
updtime = tv;
now = starttime = startlog = timeint = tv.tv_sec;
+ LIST_HEAD(promisc);
if (first_active_facility() && options.promisc) {
- init_promisc_list(&promisc_list);
- save_promisc_list(promisc_list);
- srpromisc(1, promisc_list);
- destroy_promisc_list(&promisc_list);
+ init_promisc_list(&promisc);
+ promisc_set(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, 1);
@@ -337,9 +334,8 @@ err:
}
if (options.promisc && is_last_instance()) {
- load_promisc_list(&promisc_list);
- srpromisc(0, promisc_list);
- destroy_promisc_list(&promisc_list);
+ promisc_restore(&promisc);
+ promisc_destroy(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, -1);
diff --git a/src/promisc.c b/src/promisc.c
index a0f5364..bc0e1fb 100644
--- a/src/promisc.c
+++ b/src/promisc.c
@@ -17,178 +17,66 @@ promisc.c - handles the promiscuous mode flag for the Ethernet/FDDI/
#define PROMISC_MSG_MAX 80
-void init_promisc_list(struct promisc_states **list)
+void init_promisc_list(struct list_head *promisc)
{
- FILE *fd;
char buf[IFNAMSIZ];
- struct promisc_states *ptmp;
- struct promisc_states *tail = NULL;
-
- *list = NULL;
- fd = open_procnetdev();
-
- while (get_next_iface(fd, buf, sizeof(buf))) {
- if (strcmp(buf, "") != 0) {
- ptmp = xmalloc(sizeof(struct promisc_states));
- strcpy(ptmp->params.ifname, buf);
-
- if (*list == NULL) {
- *list = ptmp;
- } else
- tail->next_entry = ptmp;
-
- tail = ptmp;
- ptmp->next_entry = NULL;
-
- /*
- * Retrieve and save interface flags
- */
-
- if ((strncmp(buf, "eth", 3) == 0)
- || (strncmp(buf, "ra", 2) == 0)
- || (strncmp(buf, "fddi", 4) == 0)
- || (strncmp(buf, "tr", 2) == 0)
- || (strncmp(buf, "ath", 3) == 0)
- || (strncmp(buf, "bnep", 4) == 0)
- || (strncmp(buf, "ni", 2) == 0)
- || (strncmp(buf, "tap", 3) == 0)
- || (strncmp(buf, "dummy", 5) == 0)
- || (strncmp(buf, "br", 2) == 0)
- || (strncmp(buf, "vmnet", 5) == 0)
- || (strncmp(ptmp->params.ifname, "wvlan", 4) == 0)
- || (strncmp(ptmp->params.ifname, "lec", 3) == 0)) {
- int flags = dev_get_flags(buf);
-
- if (flags < 0) {
- write_error("Unable to obtain interface parameters for %s",
- buf);
- ptmp->params.state_valid = 0;
- } else {
- ptmp->params.saved_state = flags;
- ptmp->params.state_valid = 1;
- }
- }
- }
- }
-}
-
-/*
- * Save interfaces and their states to a temporary file. Used only by the
- * first IPTraf instance. Needed in case there are subsequent, simultaneous
- * instances of IPTraf, which may still need promiscuous mode even after
- * the first instance exits. These subsequent instances will need to restore
- * the promiscuous state from this file.
- */
-
-void save_promisc_list(struct promisc_states *list)
-{
- int fd;
- struct promisc_states *ptmp = list;
-
- fd = open(PROMISCLISTFILE, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
- if (fd < 0) {
- write_error("Unable to save interface flags");
- return;
- }
+ FILE *fp = open_procnetdev();
+ if (!fp)
+ die_errno("%s: open_procnetdev", __func__);
+
+ while (get_next_iface(fp, buf, sizeof(buf))) {
+ if (!strcmp(buf, ""))
+ continue;
+
+ struct promisc_list *p = xmallocz(sizeof(*p));
+ strcpy(p->ifname, buf);
+ INIT_LIST_HEAD(&p->list);
+
+ int flags = dev_get_flags(buf);
+ if (flags < 0) {
+ write_error("Unable to obtain interface parameters for %s",
+ buf);
+ } else {
+ p->flags = flags;
+ p->state_valid = 1;
+ }
- while (ptmp != NULL) {
- write(fd, &(ptmp->params), sizeof(struct promisc_params));
- ptmp = ptmp->next_entry;
+ list_add_tail(&p->list, promisc);
}
- close(fd);
+ fclose(fp);
}
-/*
- * Load promiscuous states into list
- */
-
-void load_promisc_list(struct promisc_states **list)
+void promisc_set(struct list_head *promisc)
{
- int fd;
- struct promisc_states *ptmp = NULL;
- struct promisc_states *tail = NULL;
- int br;
-
- fd = open(PROMISCLISTFILE, O_RDONLY);
-
- if (fd < 0) {
- write_error("Unable to retrieve saved interface flags");
- *list = NULL;
- return;
+ 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);
}
-
- do {
- ptmp = xmalloc(sizeof(struct promisc_states));
- br = read(fd, &(ptmp->params), sizeof(struct promisc_params));
-
- if (br > 0) {
- if (tail != NULL)
- tail->next_entry = ptmp;
- else
- *list = ptmp;
-
- ptmp->next_entry = NULL;
- tail = ptmp;
- } else
- free(ptmp);
- } while (br > 0);
-
- close(fd);
}
-/*
- * Set/restore interface promiscuous mode.
- */
-
-void srpromisc(int mode, struct promisc_states *list)
+void promisc_restore(struct list_head *promisc)
{
- struct promisc_states *ptmp;
-
- ptmp = list;
-
- while (ptmp != NULL) {
- if (((strncmp(ptmp->params.ifname, "eth", 3) == 0)
- || (strncmp(ptmp->params.ifname, "fddi", 4) == 0)
- || (strncmp(ptmp->params.ifname, "tr", 2) == 0)
- || (strncmp(ptmp->params.ifname, "ra", 2) == 0)
- || (strncmp(ptmp->params.ifname, "ath", 3) == 0)
- || (strncmp(ptmp->params.ifname, "wvlan", 4) == 0)
- || (strncmp(ptmp->params.ifname, "lec", 3) == 0))
- && (ptmp->params.state_valid)) {
- if (mode) {
- /* set promiscuous */
- int r = dev_set_promisc(ptmp->params.ifname);
- if(r < 0)
- write_error("Failed to set promiscuous mode on %s", ptmp->params.ifname);
- } else {
- /* restore saved state */
- if (ptmp->params.saved_state & IFF_PROMISC)
- /* was promisc, so leave it as is */
- continue;
- /* wasn't promisc, clear it */
- int r = dev_clear_promisc(ptmp->params.ifname);
- if(r < 0)
- write_error("Failed to clear promiscuous mode on %s", ptmp->params.ifname);
- }
- }
- ptmp = ptmp->next_entry;
+ struct promisc_list *entry = NULL;
+ list_for_each_entry(entry, promisc, list) {
+ if (entry->flags & IFF_PROMISC)
+ continue;
+
+ int r = dev_clear_promisc(entry->ifname);
+ if (r < 0)
+ write_error("Failed to clear promiscuous mode on %s", entry->ifname);
}
}
-void destroy_promisc_list(struct promisc_states **list)
+void promisc_destroy(struct list_head *promisc)
{
- struct promisc_states *ptmp = *list;
- struct promisc_states *ctmp;
-
- if (ptmp != NULL)
- ctmp = ptmp->next_entry;
-
- while (ptmp != NULL) {
- free(ptmp);
- ptmp = ctmp;
- if (ctmp != NULL)
- ctmp = ctmp->next_entry;
+ struct promisc_list *entry, *tmp;
+ list_for_each_entry_safe(entry, tmp, promisc, list) {
+ list_del(&entry->list);
+ free(entry);
}
}
diff --git a/src/promisc.h b/src/promisc.h
index f062ca1..c4150b3 100644
--- a/src/promisc.h
+++ b/src/promisc.h
@@ -1,31 +1,19 @@
#ifndef IPTRAF_NG_PROMISC_H
#define IPTRAF_NG_PROMISC_H
-/*
- * promisc.h - definitions for promiscuous state save/recovery
- *
- * Thanks to Holger Friese
- * <evildead(a)bs-pc5.et-inf.fho-emden.de> for the base patch.
- * Applied it, but then additional issues came up and I ended up doing more
- * than slight modifications. struct iflist is becoming way too large for
- * comfort and for something as little as this.
- */
+#include "list.h"
-struct promisc_params {
+struct promisc_list {
+ struct list_head list;
char ifname[IFNAMSIZ];
- int saved_state;
+ int flags;
int state_valid;
};
-struct promisc_states {
- struct promisc_params params;
- struct promisc_states *next_entry;
-};
-void init_promisc_list(struct promisc_states **list);
-void save_promisc_list(struct promisc_states *list);
-void load_promisc_list(struct promisc_states **list);
-void srpromisc(int mode, struct promisc_states *promisc_list);
-void destroy_promisc_list(struct promisc_states **list);
+void init_promisc_list(struct list_head *promisc);
+void promisc_set(struct list_head *promisc);
+void promisc_restore(struct list_head *promisc);
+void promisc_destroy(struct list_head *promisc);
#endif /* IPTRAF_NG_PROMISC_H */
diff --git a/src/serv.c b/src/serv.c
index 513cc94..f0bbd46 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -779,8 +779,6 @@ void servmon(char *ifname, time_t facilitytime)
FILE *logfile = NULL;
- struct promisc_states *promisc_list;
-
WINDOW *sortwin;
PANEL *sortpanel;
@@ -812,11 +810,10 @@ void servmon(char *ifname, time_t facilitytime)
loadaddports(&ports);
+ LIST_HEAD(promisc);
if (first_active_facility() && options.promisc) {
- init_promisc_list(&promisc_list);
- save_promisc_list(promisc_list);
- srpromisc(1, promisc_list);
- destroy_promisc_list(&promisc_list);
+ init_promisc_list(&promisc);
+ promisc_set(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, 1);
@@ -1091,9 +1088,8 @@ err:
endservent();
if (options.promisc && is_last_instance()) {
- load_promisc_list(&promisc_list);
- srpromisc(0, promisc_list);
- destroy_promisc_list(&promisc_list);
+ promisc_restore(&promisc);
+ promisc_destroy(&promisc);
}
adjust_instance_count(PROCCOUNTFILE, -1);
--
1.7.11.5