From cd4947f139309f758130ea27d673ce7742d6486a Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Sun, 11 Jan 2015 12:20:02 +0000 Subject: [PATCH] wmnet: Cope with interface name longer than 6 characters After a recent change in the kernel (their commit 6e094bd) my wireless interface name is 8 characters long, wlp3s0b1. But the wmnet code to read the received bytes totalbytes_in = strtoul(&buffer[7], NULL, 10); assumed that the interface name in /proc/net/dev would be 6 characters long (and would start reading at position 7). In the linux kernel mailing list I reported the regression and none other than Al Viro replied, > I am not sure if 'wmnet' could do this better (any suggestions?), *snort* well, yes - it's called scanf(). And if one is really, really nervous about the overhead of parsing a bunch of integers (as if fopen/ fgets/fclose alone won't cost enough to make constantly calling that sucker a bad idea), just use ptr + - 6 instead of &buffer[] in there. That thing has just found where the colon was (and replaced it with NUL), so dealing with "the first field turned out to be too long and shifted everything past it" isn't hard. ****** I also took the oportunity to remove the unused variables diffpackets_{in,out} --- wmnet/drivers.c | 36 +++++++++++++----------------------- wmnet/wmnet.h | 6 +++--- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/wmnet/drivers.c b/wmnet/drivers.c index d74f32e..4b798e7 100644 --- a/wmnet/drivers.c +++ b/wmnet/drivers.c @@ -59,9 +59,9 @@ static struct ifpppstatsreq ppp_stats_req; extern char buffer[256]; extern char *in_rule_string, *out_rule_string, *device; -extern unsigned long totalbytes_in, totalbytes_out, lastbytes_in, lastbytes_out; -extern unsigned long totalpackets_in, totalpackets_out, lastpackets_in, lastpackets_out; -extern unsigned int diffpackets_in, diffpackets_out, diffbytes_in, diffbytes_out; +extern unsigned long long int totalbytes_in, totalbytes_out, lastbytes_in, lastbytes_out; +extern unsigned long long int totalpackets_in, totalpackets_out, lastpackets_in, lastpackets_out; +extern unsigned int diffbytes_in, diffbytes_out; extern unsigned int out_rule, in_rule; /* number of rule in /proc/net/ip_acct to use */ extern Bool current_tx, current_rx, rx, tx; @@ -199,7 +199,6 @@ int updateStats_ipfwadm(void) { totalpackets_in = strtoul(&buffer[offset], &ptr, 10); if (totalpackets_in == lastpackets_in) break; totalbytes_in = strtoul(ptr, NULL, 10); - diffpackets_in += totalpackets_in - lastpackets_in; diffbytes_in += totalbytes_in - lastbytes_in; lastpackets_in = totalpackets_in; lastbytes_in = totalbytes_in; @@ -213,7 +212,6 @@ int updateStats_ipfwadm(void) { totalpackets_out = strtoul(&buffer[offset], &ptr, 10); if (totalpackets_out == lastpackets_out) break; totalbytes_out = strtoul(ptr, NULL, 10); - diffpackets_out += totalpackets_out - lastpackets_out; diffbytes_out += totalbytes_out - lastbytes_out; lastpackets_out = totalpackets_out; lastbytes_out = totalbytes_out; @@ -278,7 +276,6 @@ int updateStats_ipchains(void) { totalpackets_in = pack; if (totalpackets_in != lastpackets_in) { totalbytes_in = bytes; - diffpackets_in += totalpackets_in - lastpackets_in; diffbytes_in += totalbytes_in - lastbytes_in; lastpackets_in = totalpackets_in; lastbytes_in = totalbytes_in; @@ -291,7 +288,6 @@ int updateStats_ipchains(void) { totalpackets_out = pack; if (totalpackets_out != lastpackets_out) { totalbytes_out = bytes; - diffpackets_out += totalpackets_out - lastpackets_out; diffbytes_out += totalbytes_out - lastbytes_out; lastpackets_out = totalpackets_out; lastbytes_out = totalbytes_out; @@ -322,7 +318,7 @@ int updateStats_dev(void) { FILE *dev; char *ptr; unsigned int flag = 0; - char *name; + static char interface[16]; rx = False; tx = False; @@ -338,31 +334,27 @@ int updateStats_dev(void) { /* IP Chain Rules for Linux kernel 2_1.x */ while(flag != (ACCOUNT_IN_FOUND|ACCOUNT_OUT_FOUND) && fgets(buffer, 256, dev)) { - ptr = buffer; - while(*ptr == ' ') ptr++; - name = ptr; - while(*ptr != ':') ptr++; - *ptr = '\0'; - if (!strcmp(name, device)) { + sscanf(buffer, "%16s %llu %llu %*d %*d %*d %*d %*d %*d %llu %llu %*d %*d %*d %*d %*d %*d", + interface, &totalbytes_in, &totalpackets_in, &totalbytes_out, &totalpackets_out); + + /* strip trailing colon */ + ptr = interface; + while(*ptr != ':') ptr++; + *ptr = '\0'; + + if (!strcmp(interface, device)) { flag = (ACCOUNT_IN_FOUND|ACCOUNT_OUT_FOUND); - totalpackets_in = strtoul(&buffer[15], NULL, 10); if (totalpackets_in != lastpackets_in) { - totalbytes_in = strtoul(&buffer[7], NULL, 10); - diffpackets_in += totalpackets_in - lastpackets_in; diffbytes_in += totalbytes_in - lastbytes_in; lastpackets_in = totalpackets_in; lastbytes_in = totalbytes_in; rx = True; } - - totalpackets_out = strtoul(&buffer[74], NULL, 10); if (totalpackets_out != lastpackets_out) { - totalbytes_out = strtoul(&buffer[66], NULL, 10); - diffpackets_out += totalpackets_out - lastpackets_out; diffbytes_out += totalbytes_out - lastbytes_out; lastpackets_out = totalpackets_out; lastbytes_out = totalbytes_out; @@ -409,7 +401,6 @@ int updateStats_ppp(void) { totalpackets_in = ppp_stats_req.stats.p.ppp_ipackets; if (totalpackets_in != lastpackets_in) { totalbytes_in = ppp_stats_req.stats.p.ppp_ibytes; - diffpackets_in += totalpackets_in - lastpackets_in; diffbytes_in += totalbytes_in - lastbytes_in; lastpackets_in = totalpackets_in; lastbytes_in = totalbytes_in; @@ -420,7 +411,6 @@ int updateStats_ppp(void) { totalpackets_out = ppp_stats_req.stats.p.ppp_opackets; if (totalpackets_out != lastpackets_out) { totalbytes_out =ppp_stats_req.stats.p.ppp_obytes; - diffpackets_out += totalpackets_out - lastpackets_out; diffbytes_out += totalbytes_out - lastbytes_out; lastpackets_out = totalpackets_out; lastbytes_out = totalbytes_out; diff --git a/wmnet/wmnet.h b/wmnet/wmnet.h index ce3dfc7..32280eb 100644 --- a/wmnet/wmnet.h +++ b/wmnet/wmnet.h @@ -75,9 +75,9 @@ typedef int (*parser_func)(void); /* I know statically declared buffers are against GNU coding standards, so sue me */ char buffer[256], *click_command = NULL, *label = NULL; struct timeval timenow, timelast; -unsigned long totalbytes_in, totalbytes_out, lastbytes_in, lastbytes_out; -unsigned long totalpackets_in, totalpackets_out, lastpackets_in, lastpackets_out; -unsigned int diffpackets_in, diffpackets_out, diffbytes_in, diffbytes_out; +unsigned long long int totalbytes_in, totalbytes_out, lastbytes_in, lastbytes_out; +unsigned long long int totalpackets_in, totalpackets_out, lastpackets_in, lastpackets_out; +unsigned int diffbytes_in, diffbytes_out; unsigned int delayTime = 25000, displayDelay = 55000, maxRate = 6000; unsigned int out_rule = 2, in_rule = 1, graphbox_height = 44; /* number of rule in /proc/net/ip_acct to use */ char *in_rule_string = NULL, *out_rule_string = NULL, *device=NULL;