spoon

set dwm status
git clone git://git.2f30.org/spoon.git
Log | Files | Refs | LICENSE

commit 54051f89a96e8bd68c71e56edffbdac50a62df8e
parent 4fea6b3b6c7b0effabba4f157548ef7c6d83676b
Author: Lucas Gabriel Vuotto <lvuotto92@gmail.com>
Date:   Wed, 13 Sep 2017 10:24:43 -0300

Implement network speed monitoring

Signed-off-by: Lucas Gabriel Vuotto <lvuotto92@gmail.com>
Signed-off-by: sin <sin@2f30.org>

Diffstat:
Makefile | 4++--
netspeed.c | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
spoon.c | 1+
stub.c | 7+++++++
4 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,9 +1,9 @@ VERSION = 0.4 PREFIX = /usr/local SRC = spoon.c batt.c wifi.c cpu.c temp.c date.c load.c file.c key.c\ - strlcpy.c strlcat.c stub.c mix.c xkblayout.c mpd.c + netspeed.c strlcpy.c strlcat.c stub.c mix.c xkblayout.c mpd.c OBJ = spoon.o batt.o wifi.o cpu.o temp.o date.o load.o file.o key.o\ - strlcpy.o strlcat.o stub.o + netspeed.o strlcpy.o strlcat.o stub.o BIN = spoon DISTFILES = $(SRC) types.h util.h config.def.h Makefile LICENSE configure diff --git a/netspeed.c b/netspeed.c @@ -0,0 +1,126 @@ +#include <ctype.h> +#include <err.h> +#include <inttypes.h> +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "util.h" + +extern int delay; + +static const char *humansztbl[] = { " B", "kB", "MB", "GB", "TB", "PB", "EB", + "ZB", "YB" }; + +static int +humansz(size_t n) +{ + int i; + for (i = 0; i < LEN(humansztbl) && n >= 1024; i++) + n /= 1024; + return i; +} + +static void +updatenetspeed(char *buf, size_t len, uint64_t rxbytes, uint64_t txbytes) +{ + static uint64_t oldrxbytes, oldtxbytes; + uint64_t rx, tx; + int irx, itx; + rx = (rxbytes - oldrxbytes) / delay; + tx = (txbytes - oldtxbytes) / delay; + irx = humansz(rx); + itx = humansz(tx); + snprintf(buf, len, "v%6.1f%s/s ^%6.1f%s/s", rx + / (double)(1 << (10 * irx)), humansztbl[irx], tx + / (double)(1 << (10 * itx)), humansztbl[itx]); + oldrxbytes = rxbytes; + oldtxbytes = txbytes; +} + +#ifdef __OpenBSD__ +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_dl.h> +#include <net/route.h> +#include <sys/sysctl.h> + +int +netspeedread(void *arg, char *buf, size_t len) +{ + int mib[6] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; + char *ifname = arg; + struct rt_msghdr *rtm; + struct if_msghdr *ifm; + struct sockaddr_dl *sdl; + void *lim, *next, *rtmraw; + uint64_t rxbytes, txbytes; + size_t sz; + + if (sysctl(mib, 6, NULL, &sz, NULL, 0) < 0) + return -1; + if (!(rtmraw = malloc(sz))) + return -1; + if (sysctl(mib, 6, rtmraw, &sz, NULL, 0) < 0) { + free(rtmraw); + return -1; + } + lim = rtmraw + sz; + rxbytes = txbytes = 0; + for (next = rtmraw; next < lim; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)next; + if (rtm->rtm_version != RTM_VERSION || rtm->rtm_type + != RTM_IFINFO) + continue; + ifm = (struct if_msghdr *)next; + sdl = (struct sockaddr_dl *)(next + ifm->ifm_hdrlen); + if (sdl->sdl_family != AF_LINK + || strncmp(ifname, sdl->sdl_data, sdl->sdl_nlen) != 0) + continue; + rxbytes = ifm->ifm_data.ifi_ibytes; + txbytes = ifm->ifm_data.ifi_obytes; + } + updatenetspeed(buf, len, rxbytes, txbytes); + free(rtmraw); + + return 0; +} +#elif __linux__ +int +netspeedread(void *arg, char *buf, size_t len) +{ + char path[PATH_MAX]; + FILE *fp; + char *ifname = arg; + unsigned long long rxbytes, txbytes; + + (void)snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/rx_bytes", ifname); + if (!(fp = fopen(path, "r"))) { + warn("fopen %s", path); + goto closeandfree; + } + if (fscanf(fp, "%llu", &rxbytes) != 1) { + warn("fscanf %s", path); + goto closeandfree; + } + fclose(fp); + (void)snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/tx_bytes", ifname); + if (!(fp = fopen(path, "r"))) { + warn("fopen %s", path); + goto closeandfree; + } + if (fscanf(fp, "%llu", &txbytes) != 1) { + warn("fscanf %s", path); + goto closeandfree; + } + fclose(fp); + + updatenetspeed(buf, len, rxbytes, txbytes); + return 0; + +closeandfree: + fclose(fp); + return -1; +} +#endif diff --git a/spoon.c b/spoon.c @@ -20,6 +20,7 @@ int wifiread(void *, char *, size_t); int xkblayoutread(void *, char *, size_t); int fileread(void *, char *, size_t); int keyread(void *, char *, size_t); +int netspeedread(void *, char *, size_t); struct ent { char *fmt; diff --git a/stub.c b/stub.c @@ -62,3 +62,10 @@ keyread(void *arg, char *buf, size_t len) { return -1; } + +#pragma weak netspeedread +int +netspeedread(void *arg, char *buf, size_t len) +{ + return -1; +}