slstatus

status monitor
git clone git://git.suckless.org/slstatus
Log | Files | Refs | README | LICENSE

netspeeds.c (2934B)


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