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