spoon

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

netspeed.c (2379B)


      1 #include <ctype.h>
      2 #include <err.h>
      3 #include <inttypes.h>
      4 #include <limits.h>
      5 #include <stdint.h>
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 #include <string.h>
      9 #include "util.h"
     10 
     11 extern int delay;
     12 
     13 static const char *humansztbl[] = { " B", "kB", "MB", "GB", "TB", "PB", "EB",
     14     "ZB", "YB" };
     15 
     16 static int
     17 humansz(size_t n)
     18 {
     19 	int i;
     20 	for (i = 0; i < LEN(humansztbl) && n >= 1024; i++)
     21 		n /= 1024;
     22 	return i;
     23 }
     24 
     25 static void
     26 updatenetspeed(char *buf, size_t len, uint64_t rxbytes, uint64_t txbytes)
     27 {
     28 	static uint64_t oldrxbytes, oldtxbytes;
     29 	uint64_t rx, tx;
     30 	int irx, itx;
     31 	rx = (rxbytes - oldrxbytes) / delay;
     32 	tx = (txbytes - oldtxbytes) / delay;
     33 	irx = humansz(rx);
     34 	itx = humansz(tx);
     35 	snprintf(buf, len, "D:%6.1f%s/s U:%6.1f%s/s", rx
     36 	    / (double)(1 << (10 * irx)), humansztbl[irx], tx
     37 	    / (double)(1 << (10 * itx)), humansztbl[itx]);
     38 	oldrxbytes = rxbytes;
     39 	oldtxbytes = txbytes;
     40 }
     41 
     42 #ifdef __OpenBSD__
     43 #include <sys/socket.h>
     44 #include <sys/types.h>
     45 #include <net/if.h> /* struct if_data */
     46 #include <ifaddrs.h>
     47 
     48 int
     49 netspeedread(void *arg, char *buf, size_t len)
     50 {
     51 	char *ifa_name = arg;
     52 	struct if_data *ifa_data;
     53 	struct ifaddrs *ifa, *ifap;
     54 	uint64_t rxbytes, txbytes;
     55 
     56 	if (getifaddrs(&ifap) == -1) {
     57 		warn("getifaddrs");
     58 		return -1;
     59 	}
     60 
     61 	rxbytes = txbytes = 0;
     62 
     63 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
     64 		if (strcmp(ifa_name, ifa->ifa_name) != 0)
     65 			continue;
     66 		if (ifa->ifa_data == NULL)
     67 			continue;
     68 		ifa_data = ifa->ifa_data;
     69 		rxbytes += ifa_data->ifi_ibytes;
     70 		txbytes += ifa_data->ifi_obytes;
     71 	}
     72 
     73 	updatenetspeed(buf, len, rxbytes, txbytes);
     74 	freeifaddrs(ifap);
     75 
     76 	return 0;
     77 }
     78 #elif __linux__
     79 int
     80 netspeedread(void *arg, char *buf, size_t len)
     81 {
     82 	char path[PATH_MAX];
     83 	FILE *fp;
     84 	char *ifname = arg;
     85 	unsigned long long rxbytes, txbytes;
     86 
     87 	(void)snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/rx_bytes", ifname);
     88 	if (!(fp = fopen(path, "r"))) {
     89 		warn("fopen %s", path);
     90 		return -1;
     91 	}
     92 	if (fscanf(fp, "%llu", &rxbytes) != 1) {
     93 		warn("fscanf %s", path);
     94 		fclose(fp);
     95 		return -1;
     96 	}
     97 	fclose(fp);
     98 	(void)snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/tx_bytes", ifname);
     99 	if (!(fp = fopen(path, "r"))) {
    100 		warn("fopen %s", path);
    101 		return -1;
    102 	}
    103 	if (fscanf(fp, "%llu", &txbytes) != 1) {
    104 		warn("fscanf %s", path);
    105 		fclose(fp);
    106 		return -1;
    107 	}
    108 	fclose(fp);
    109 
    110 	updatenetspeed(buf, len, rxbytes, txbytes);
    111 	return 0;
    112 }
    113 #endif