luci-mod-status: refactor luci-bwc
- 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>
(cherry picked from commit 8b1d831935
)
This commit is contained in:
parent
c395d43807
commit
3aeda2a2ea
2 changed files with 45 additions and 37 deletions
|
@ -1,5 +1,5 @@
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(FPIC) -c -o $@ $<
|
$(CC) $(CPPFLAGS) $(CFLAGS) $(FPIC) -Wall -c -o $@ $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f luci-bwc *.o
|
rm -f luci-bwc *.o
|
||||||
|
|
|
@ -29,9 +29,11 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -49,11 +51,6 @@
|
||||||
#define DB_CN_FILE DB_PATH "/connections"
|
#define DB_CN_FILE DB_PATH "/connections"
|
||||||
#define DB_LD_FILE DB_PATH "/load"
|
#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 \
|
#define LD_SCAN_PATTERN \
|
||||||
"%f %f %f"
|
"%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)
|
static int run_daemon(void)
|
||||||
{
|
{
|
||||||
|
DIR *dir;
|
||||||
FILE *info;
|
FILE *info;
|
||||||
uint64_t rxb, txb, rxp, txp;
|
uint64_t rxb, txb, rxp, txp;
|
||||||
uint32_t udp, tcp, other;
|
uint32_t udp, tcp, other;
|
||||||
|
@ -422,15 +420,27 @@ static int run_daemon(void)
|
||||||
uint8_t rssi, noise;
|
uint8_t rssi, noise;
|
||||||
float lf1, lf5, lf15;
|
float lf1, lf5, lf15;
|
||||||
char line[1024];
|
char line[1024];
|
||||||
char ifname[16];
|
char path[64];
|
||||||
|
char buf[32];
|
||||||
int i;
|
int i;
|
||||||
void *iw;
|
void *iw;
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
struct dirent *e;
|
||||||
|
|
||||||
struct stat s;
|
struct stat s;
|
||||||
const char *ipc = stat("/proc/net/nf_conntrack", &s)
|
const char *ipc = stat("/proc/net/nf_conntrack", &s)
|
||||||
? "/proc/net/ip_conntrack" : "/proc/net/nf_conntrack";
|
? "/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())
|
switch (fork())
|
||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
|
@ -476,41 +486,39 @@ static int run_daemon(void)
|
||||||
memset(progname, 0, prognamelen);
|
memset(progname, 0, prognamelen);
|
||||||
snprintf(progname, prognamelen, "luci-bwc %d", countdown);
|
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;
|
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)))
|
*sysfs_stats[i].value = 0;
|
||||||
update_ifstat(ifname, rxb, rxp, txb, txp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/%s",
|
||||||
|
e->d_name, sysfs_stats[i].file);
|
||||||
|
|
||||||
|
if ((info = fopen(path, "r")) != NULL)
|
||||||
|
{
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
fread(buf, 1, sizeof(buf) - 1, info);
|
||||||
fclose(info);
|
fclose(info);
|
||||||
|
|
||||||
|
*sysfs_stats[i].value = (uint64_t)strtoull(buf, NULL, 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iw)
|
update_ifstat(e->d_name, rxb, rxp, txb, txp);
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((info = fopen(ipc, "r")) != NULL)
|
if ((info = fopen(ipc, "r")) != NULL)
|
||||||
|
@ -528,11 +536,11 @@ static int run_daemon(void)
|
||||||
|| (strstr(line, "src=::1 ") && strstr(line, "dst=::1 ")))
|
|| (strstr(line, "src=::1 ") && strstr(line, "dst=::1 ")))
|
||||||
continue;
|
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++;
|
tcp++;
|
||||||
else if (!strcmp(ifname, "udp"))
|
else if (!strcmp(buf, "udp"))
|
||||||
udp++;
|
udp++;
|
||||||
else
|
else
|
||||||
other++;
|
other++;
|
||||||
|
|
Loading…
Reference in a new issue