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