-
Notifications
You must be signed in to change notification settings - Fork 1
/
bwmon.c
145 lines (112 loc) · 3.05 KB
/
bwmon.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
bwmon - Simple bandwidth monitor for linux.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#define CLS "\033[2J\033[1;1H"
typedef struct {
char dev[32];
long rxBytes;
long txBytes;
long rxPackets;
long txPackets;
} bwinfo;
int fetchData(bwinfo **bwi, const char* iface) {
bwinfo* p;
FILE *fp = NULL;
char buf[1024], *bufp, c, *tok, *tmp;
int ifCount = 0, i;
*bwi = (bwinfo*)malloc(sizeof(bwinfo));
p = *bwi;
fp = fopen("/proc/net/dev", "r");
if (fp == NULL) {
perror("Could not open /proc/net/dev");
exit(1);
}
while (!feof(fp)) {
/* fgets() seems to ignore the last line for some reason, so we'll roll our own instead. */
for (bufp = buf; (fread(&c, 1, 1, fp)) > 0 && c != '\n' && bufp < buf+1024; *bufp++ = c);
*bufp++ = '\0';
if (buf[0]== '\0') break; /* No data. */
if (!strchr(buf, ':')) continue; /* No interface name. */
tok = strtok(buf, " ");
if (tok == NULL) {
fprintf(stderr, "Error, no tokens in buffer.\n", buf);
exit(1);
}
i = 1;
do {
switch(i) {
case 1: /* Interface name. */
tmp = strchr(tok, ':');
if (tmp == NULL) {
fprintf(stderr, "Error fetching interface name, token: %s.\n", tok);
exit(1);
}
if ( tmp-tok > 32 ) {
fprintf(stderr, "Error fetcing interface name, buffer to small. Token: %s\n", tok);
exit(1);
}
strncpy(p->dev, tok, tmp-tok);
p->dev[tmp-tok] = '\0';
/* Grr, seems like the format of /proc/net/dev is not consistent.. so we need this extra code. */
if (tmp != tok+strlen(tok)-1) {
tmp++;
p->rxBytes = strtoul(tmp, NULL, 10);
i = 3;
continue;
}
break;
case 2: /* Recvbytes. */
p->rxBytes = strtoul(tok, NULL, 10);
break;
case 3: /* Recvpackets. */
p->rxPackets = strtoul(tok, NULL, 10);
break;
case 10: /* Txbytes. */
p->txBytes = strtoul(tok, NULL, 10);
break;
case 11: /* Txpackets. */
p->txPackets = strtoul(tok, NULL, 10);
break;
}
if (errno == ERANGE) {
fprintf(stderr, "Error converting data with at token %i.\n", i);
perror("strtol");
exit(1);
}
tok = strtok(NULL, " ");
i++;
} while(tok != NULL);
ifCount++;
*bwi = (bwinfo*)realloc(*bwi, sizeof(bwinfo) * (ifCount + 1));
p = *(bwi)+ifCount;
}
/* Set up dummy values for the last element. */
memset(p->dev, 0, 32);
p->rxBytes = p->rxPackets = p->txBytes = p->txPackets = -1;
fclose(fp);
return ifCount;
}
int main(int argc, char* argv[]) {
bwinfo *bwi_first = NULL, *bwi_second = NULL, *p1, *p2;
int ifCount, i;
while(1) {
ifCount = fetchData(&bwi_first, NULL);
usleep(1000 * 1000);
fetchData(&bwi_second, NULL);
printf(CLS);
for (p1 = bwi_first, p2 = bwi_second; p1 < (bwi_first+ifCount); p1++, p2++) {
printf("%s:\tRX: %.2f\tkB/s\tTX: %.2f\tkB/s\n", p1->dev,
(double)(p2->rxBytes - p1->rxBytes) / 1024,
(double)(p2->txBytes - p1->txBytes) / 1024,
p1->txBytes, p2->txBytes);
}
free(bwi_first);
free(bwi_second);
}
return 0;
}