suckless/slstatus

components/netspeeds.c in master
Repositories | Summary | Log | Files | README | LICENSE

netspeeds.c (2890B) download


  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