slstatus

Fork of suckless' slstatus with my personal patches
git clone https://git.instinctive.eu/slstatus.git
Log | Files | Refs | README | LICENSE

netspeeds.c (2890B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <limits.h>
      3 #include <stdio.h>
      4 
      5 #include "../slstatus.h"
      6 #include "../util.h"
      7 
      8 #if defined(__linux__)
      9 	#include <stdint.h>
     10 
     11 	#define NET_RX_BYTES "/sys/class/net/%s/statistics/rx_bytes"
     12 	#define NET_TX_BYTES "/sys/class/net/%s/statistics/tx_bytes"
     13 
     14 	const char *
     15 	netspeed_rx(const char *interface)
     16 	{
     17 		uintmax_t oldrxbytes;
     18 		static uintmax_t rxbytes;
     19 		extern const unsigned int interval;
     20 		char path[PATH_MAX];
     21 
     22 		oldrxbytes = rxbytes;
     23 
     24 		if (esnprintf(path, sizeof(path), NET_RX_BYTES, interface) < 0)
     25 			return NULL;
     26 		if (pscanf(path, "%ju", &rxbytes) != 1)
     27 			return NULL;
     28 		if (oldrxbytes == 0)
     29 			return NULL;
     30 
     31 		return fmt_human((rxbytes - oldrxbytes) * 1000 / interval,
     32 		                 1024);
     33 	}
     34 
     35 	const char *
     36 	netspeed_tx(const char *interface)
     37 	{
     38 		uintmax_t oldtxbytes;
     39 		static uintmax_t txbytes;
     40 		extern const unsigned int interval;
     41 		char path[PATH_MAX];
     42 
     43 		oldtxbytes = txbytes;
     44 
     45 		if (esnprintf(path, sizeof(path), NET_TX_BYTES, interface) < 0)
     46 			return NULL;
     47 		if (pscanf(path, "%ju", &txbytes) != 1)
     48 			return NULL;
     49 		if (oldtxbytes == 0)
     50 			return NULL;
     51 
     52 		return fmt_human((txbytes - oldtxbytes) * 1000 / interval,
     53 		                 1024);
     54 	}
     55 #elif defined(__OpenBSD__) | defined(__FreeBSD__)
     56 	#include <ifaddrs.h>
     57 	#include <net/if.h>
     58 	#include <string.h>
     59 	#include <sys/types.h>
     60 	#include <sys/socket.h>
     61 
     62 	const char *
     63 	netspeed_rx(const char *interface)
     64 	{
     65 		struct ifaddrs *ifal, *ifa;
     66 		struct if_data *ifd;
     67 		uintmax_t oldrxbytes;
     68 		static uintmax_t rxbytes;
     69 		extern const unsigned int interval;
     70 		int if_ok = 0;
     71 
     72 		oldrxbytes = rxbytes;
     73 
     74 		if (getifaddrs(&ifal) < 0) {
     75 			warn("getifaddrs failed");
     76 			return NULL;
     77 		}
     78 		rxbytes = 0;
     79 		for (ifa = ifal; ifa; ifa = ifa->ifa_next)
     80 			if (!strcmp(ifa->ifa_name, interface) &&
     81 			   (ifd = (struct if_data *)ifa->ifa_data))
     82 				rxbytes += ifd->ifi_ibytes, if_ok = 1;
     83 
     84 		freeifaddrs(ifal);
     85 		if (!if_ok) {
     86 			warn("reading 'if_data' failed");
     87 			return NULL;
     88 		}
     89 		if (oldrxbytes == 0)
     90 			return NULL;
     91 
     92 		return fmt_human((rxbytes - oldrxbytes) * 1000 / interval,
     93 		                 1024);
     94 	}
     95 
     96 	const char *
     97 	netspeed_tx(const char *interface)
     98 	{
     99 		struct ifaddrs *ifal, *ifa;
    100 		struct if_data *ifd;
    101 		uintmax_t oldtxbytes;
    102 		static uintmax_t txbytes;
    103 		extern const unsigned int interval;
    104 		int if_ok = 0;
    105 
    106 		oldtxbytes = txbytes;
    107 
    108 		if (getifaddrs(&ifal) < 0) {
    109 			warn("getifaddrs failed");
    110 			return NULL;
    111 		}
    112 		txbytes = 0;
    113 		for (ifa = ifal; ifa; ifa = ifa->ifa_next)
    114 			if (!strcmp(ifa->ifa_name, interface) &&
    115 			   (ifd = (struct if_data *)ifa->ifa_data))
    116 				txbytes += ifd->ifi_obytes, if_ok = 1;
    117 
    118 		freeifaddrs(ifal);
    119 		if (!if_ok) {
    120 			warn("reading 'if_data' failed");
    121 			return NULL;
    122 		}
    123 		if (oldtxbytes == 0)
    124 			return NULL;
    125 
    126 		return fmt_human((txbytes - oldtxbytes) * 1000 / interval,
    127 		                 1024);
    128 	}
    129 #endif