On Thu, Aug 30, 2012 at 06:42:07PM +0200, Nikola Pajkovsky wrote:
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);
NAK, I've sent an explanation in private mail (in czech).
Vita
Signed-off-by: Nikola Pajkovsky npajkovs@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@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