luci-mod-status: refactor luci-bwc
authorJo-Philipp Wich <jo@mein.io>
Mon, 20 Jan 2020 17:55:05 +0000 (18:55 +0100)
committerJo-Philipp Wich <jo@mein.io>
Mon, 20 Jan 2020 17:55:05 +0000 (18:55 +0100)
 - Read interface statistics from /sys/class/net/
 - Discover all wireless interfaces, not just specifically named ones

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-mod-status/src/Makefile
modules/luci-mod-status/src/luci-bwc.c

index d6ed8c6e4676813ce8d2c730ffc8e525188f959e..90dcf745364d66083791c834b0327655d124c7fd 100644 (file)
@@ -1,5 +1,5 @@
 %.o: %.c
-       $(CC) $(CPPFLAGS) $(CFLAGS) $(FPIC) -c -o $@ $<
+       $(CC) $(CPPFLAGS) $(CFLAGS) $(FPIC) -Wall -c -o $@ $<
 
 clean:
        rm -f luci-bwc *.o
index dc68a2e4dbaf3eb9bc3c7c23c40bc2c5a99d8b11..9a57fa23a8f75b24ea746db71a0e1ec88cbd69ac 100644 (file)
 #include <unistd.h>
 #include <signal.h>
 #include <endian.h>
+#include <dirent.h>
 
 #include <sys/stat.h>
 #include <sys/mman.h>
+#include <sys/types.h>
 #include <arpa/inet.h>
 
 #include <dlfcn.h>
 #define DB_CN_FILE     DB_PATH "/connections"
 #define DB_LD_FILE     DB_PATH "/load"
 
-#define IF_SCAN_PATTERN \
-       " %[^ :]:%" SCNu64 " %" SCNu64 \
-       " %*u %*u %*u %*u %*u %*u" \
-       " %" SCNu64 " %" SCNu64
-
 #define LD_SCAN_PATTERN \
        "%f %f %f"
 
@@ -415,6 +412,7 @@ static int update_ldstat(uint16_t load1, uint16_t load5, uint16_t load15)
 
 static int run_daemon(void)
 {
+       DIR *dir;
        FILE *info;
        uint64_t rxb, txb, rxp, txp;
        uint32_t udp, tcp, other;
@@ -422,15 +420,27 @@ static int run_daemon(void)
        uint8_t rssi, noise;
        float lf1, lf5, lf15;
        char line[1024];
-       char ifname[16];
+       char path[64];
+       char buf[32];
        int i;
        void *iw;
        struct sigaction sa;
+       struct dirent *e;
 
        struct stat s;
        const char *ipc = stat("/proc/net/nf_conntrack", &s)
                ? "/proc/net/ip_conntrack" : "/proc/net/nf_conntrack";
 
+       const struct {
+               const char *file;
+               uint64_t *value;
+       } sysfs_stats[] = {
+               { "rx_packets", &rxp },
+               { "tx_packets", &txp },
+               { "rx_bytes",   &rxb },
+               { "tx_bytes",   &txb }
+       };
+
        switch (fork())
        {
                case -1:
@@ -476,41 +486,39 @@ static int run_daemon(void)
                memset(progname, 0, prognamelen);
                snprintf(progname, prognamelen, "luci-bwc %d", countdown);
 
-               if ((info = fopen("/proc/net/dev", "r")) != NULL)
+               dir = opendir("/sys/class/net");
+
+               if (dir)
                {
-                       while (fgets(line, sizeof(line), info))
+                       while ((e = readdir(dir)) != NULL)
                        {
-                               if (strchr(line, '|'))
+                               if (iw && iw_update(iw, e->d_name, &rate, &rssi, &noise))
+                                       update_radiostat(e->d_name, rate, rssi, noise);
+
+                               if (!strcmp(e->d_name, "lo"))
                                        continue;
 
-                               if (sscanf(line, IF_SCAN_PATTERN, ifname, &rxb, &rxp, &txb, &txp))
+                               for (i = 0; i < sizeof(sysfs_stats)/sizeof(sysfs_stats[0]); i++)
                                {
-                                       if (strncmp(ifname, "lo", sizeof(ifname)))
-                                               update_ifstat(ifname, rxb, rxp, txb, txp);
-                               }
-                       }
+                                       *sysfs_stats[i].value = 0;
 
-                       fclose(info);
-               }
+                                       snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/%s",
+                                               e->d_name, sysfs_stats[i].file);
 
-               if (iw)
-               {
-                       for (i = 0; i < 5; i++)
-                       {
-#define iw_checkif(pattern) \
-                               do {                                                      \
-                                       snprintf(ifname, sizeof(ifname), pattern, i);         \
-                                       if (iw_update(iw, ifname, &rate, &rssi, &noise))  \
-                                       {                                                     \
-                                               update_radiostat(ifname, rate, rssi, noise);      \
-                                               continue;                                         \
-                                       }                                                     \
-                               } while(0)
-
-                               iw_checkif("wlan%d");
-                               iw_checkif("ath%d");
-                               iw_checkif("wl%d");
+                                       if ((info = fopen(path, "r")) != NULL)
+                                       {
+                                               memset(buf, 0, sizeof(buf));
+                                               fread(buf, 1, sizeof(buf) - 1, info);
+                                               fclose(info);
+
+                                               *sysfs_stats[i].value = (uint64_t)strtoull(buf, NULL, 10);
+                                       }
+                               }
+
+                               update_ifstat(e->d_name, rxb, rxp, txb, txp);
                        }
+
+                       closedir(dir);
                }
 
                if ((info = fopen(ipc, "r")) != NULL)
@@ -528,11 +536,11 @@ static int run_daemon(void)
                                || (strstr(line, "src=::1 ") && strstr(line, "dst=::1 ")))
                                        continue;
 
-                               if (sscanf(line, "%*s %*d %s", ifname) || sscanf(line, "%s %*d", ifname))
+                               if (sscanf(line, "%*s %*d %s", buf) || sscanf(line, "%s %*d", buf))
                                {
-                                       if (!strcmp(ifname, "tcp"))
+                                       if (!strcmp(buf, "tcp"))
                                                tcp++;
-                                       else if (!strcmp(ifname, "udp"))
+                                       else if (!strcmp(buf, "udp"))
                                                udp++;
                                        else
                                                other++;