1 #include "common.h"
2 #include "ifinfo.h"
3 #include "misc.h"
4 #include "traffic.h"
5
trafficmeter(const char * iface,unsigned int sampletime)6 void trafficmeter(const char *iface, unsigned int sampletime)
7 {
8 /* received bytes packets errs drop fifo frame compressed multicast */
9 /* transmitted bytes packets errs drop fifo colls carrier compressed */
10 uint64_t rx, tx, rxp, txp;
11 int json = 0;
12 IFINFO firstinfo;
13 char buffer[256];
14
15 if (cfg.qmode == 10) {
16 json = 1;
17 }
18
19 #ifndef CHECK_VNSTAT
20 /* less than 2 seconds doesn't produce good results */
21 if (sampletime < 2) {
22 printf("Error: Time for sampling too short.\n");
23 exit(EXIT_FAILURE);
24 }
25 #endif
26
27 /* read interface info and get values to the first list */
28 if (!getifinfo(iface)) {
29 printf("Error: Interface \"%s\" not available, exiting.\n", iface);
30 exit(EXIT_FAILURE);
31 }
32 firstinfo.rx = ifinfo.rx;
33 firstinfo.tx = ifinfo.tx;
34 firstinfo.rxp = ifinfo.rxp;
35 firstinfo.txp = ifinfo.txp;
36
37 /* wait sampletime and print some nice dots so that the user thinks
38 something is done :) */
39 if (!json) {
40 snprintf(buffer, 256, "Sampling %s (%u seconds average)", iface, sampletime);
41 printf("%s", buffer);
42 fflush(stdout);
43 sleep(sampletime / 3);
44 printf(".");
45 fflush(stdout);
46 sleep(sampletime / 3);
47 printf(".");
48 fflush(stdout);
49 sleep(sampletime / 3);
50 printf(".");
51 fflush(stdout);
52 if ((sampletime / 3) * 3 != sampletime) {
53 sleep(sampletime - ((sampletime / 3) * 3));
54 }
55
56 cursortocolumn(1);
57 eraseline();
58 } else {
59 sleep(sampletime);
60 }
61
62 #ifdef CHECK_VNSTAT
63 sampletime = 1;
64 #endif
65
66 /* read those values again... */
67 if (!getifinfo(iface)) {
68 printf("Error: Interface \"%s\" not available, exiting.\n", iface);
69 exit(EXIT_FAILURE);
70 }
71
72 /* calculate traffic and packets seen between updates */
73 rx = countercalc(&firstinfo.rx, &ifinfo.rx, ifinfo.is64bit);
74 tx = countercalc(&firstinfo.tx, &ifinfo.tx, ifinfo.is64bit);
75 rxp = countercalc(&firstinfo.rxp, &ifinfo.rxp, ifinfo.is64bit);
76 txp = countercalc(&firstinfo.txp, &ifinfo.txp, ifinfo.is64bit);
77
78 /* show the difference in a readable format or json */
79 if (!json) {
80 printf("%" PRIu64 " packets sampled in %d seconds\n", rxp + txp, sampletime);
81 printf("Traffic average for %s\n", iface);
82 printf("\n rx %s %5" PRIu64 " packets/s\n", gettrafficrate(rx, sampletime, 15), (uint64_t)(rxp / sampletime));
83 printf(" tx %s %5" PRIu64 " packets/s\n\n", gettrafficrate(tx, sampletime, 15), (uint64_t)(txp / sampletime));
84 } else {
85 printf("{\"jsonversion\":\"%d\",", JSONVERSION_TR);
86 printf("\"vnstatversion\":\"%s\",", getversion());
87 printf("\"interface\":\"%s\",", iface);
88 printf("\"sampletime\":%u,", sampletime);
89 printf("\"rx\":{");
90 printf("\"ratestring\":\"%s\",", gettrafficrate(rx, sampletime, 0));
91 printf("\"bytespersecond\":%" PRIu64 ",", (uint64_t)(rx / sampletime));
92 printf("\"packetspersecond\":%" PRIu64 ",", (uint64_t)(rxp / sampletime));
93 printf("\"bytes\":%" PRIu64 ",", rx);
94 printf("\"packets\":%" PRIu64 "", rxp);
95 printf("},");
96 printf("\"tx\":{");
97 printf("\"ratestring\":\"%s\",", gettrafficrate(tx, sampletime, 0));
98 printf("\"bytespersecond\":%" PRIu64 ",", (uint64_t)(tx / sampletime));
99 printf("\"packetspersecond\":%" PRIu64 ",", (uint64_t)(txp / sampletime));
100 printf("\"bytes\":%" PRIu64 ",", tx);
101 printf("\"packets\":%" PRIu64 "", txp);
102 printf("}}\n");
103 }
104 }
105
livetrafficmeter(const char * iface,const int mode)106 void livetrafficmeter(const char *iface, const int mode)
107 {
108 /* received bytes packets errs drop fifo frame compressed multicast */
109 /* transmitted bytes packets errs drop fifo colls carrier compressed */
110 uint64_t rx, tx, rxp, txp, timespent, timeslept;
111 uint64_t rxtotal, txtotal, rxptotal, txptotal;
112 uint64_t rxpmin, txpmin, rxpmax, txpmax;
113 uint64_t rxmin, txmin, rxmax, txmax;
114 uint64_t index = 1;
115 int ratewidth, ppswidth, paddingwidth, json = 0;
116 char buffer[256], buffer2[256];
117 IFINFO previnfo;
118
119 if (cfg.qmode == 10) {
120 json = 1;
121 }
122
123 if (!json) {
124 printf("Monitoring %s... (press CTRL-C to stop)\n\n", iface);
125 if (cfg.ostyle != 4) {
126 printf(" getting traffic...");
127 fflush(stdout);
128 }
129 }
130
131 /* enable signal trap */
132 intsignal = 0;
133 if (signal(SIGINT, sighandler) == SIG_ERR) {
134 perror("signal");
135 exit(EXIT_FAILURE);
136 }
137
138 /* set some defaults */
139 rxtotal = txtotal = rxptotal = txptotal = rxpmax = txpmax = 0;
140 rxpmin = txpmin = rxmin = txmin = MAX64;
141 rxmax = txmax = 0;
142 timeslept = 0;
143
144 timespent = (uint64_t)time(NULL);
145
146 /* read /proc/net/dev and get values to the first list */
147 if (!getifinfo(iface)) {
148 printf("Error: Interface \"%s\" not available, exiting.\n", iface);
149 exit(EXIT_FAILURE);
150 }
151
152 ratewidth = 15;
153 ppswidth = 5;
154 paddingwidth = 8;
155
156 /* narrow output mode */
157 if (cfg.ostyle == 0) {
158 ratewidth = 12;
159 ppswidth = 3;
160 paddingwidth = 4;
161 }
162
163 if (!json) {
164 cursorhide();
165 } else {
166 printf("{\"jsonversion\":\"%d\",", JSONVERSION_LIVE);
167 printf("\"vnstatversion\":\"%s\",", getversion());
168 printf("\"interface\":\"%s\",", iface);
169 printf("\"sampletime\":%d}\n", LIVETIME);
170 }
171
172 /* loop until user gets bored */
173 while (intsignal == 0) {
174
175 timeslept = (uint64_t)time(NULL);
176
177 #ifndef CHECK_VNSTAT
178 /* wait 2 seconds for more traffic */
179 sleep(LIVETIME);
180 #endif
181
182 timeslept = (uint64_t)time(NULL) - timeslept;
183
184 /* break loop without calculations because sleep was probably interrupted */
185 if (intsignal) {
186 break;
187 }
188
189 /* use values from previous loop if this isn't the first time */
190 previnfo.rx = ifinfo.rx;
191 previnfo.tx = ifinfo.tx;
192 previnfo.rxp = ifinfo.rxp;
193 previnfo.txp = ifinfo.txp;
194
195 /* read those values again... */
196 if (!getifinfo(iface)) {
197 cursorshow();
198 printf("Error: Interface \"%s\" not available, exiting.\n", iface);
199 exit(EXIT_FAILURE);
200 }
201
202 /* calculate traffic and packets seen between updates */
203 rx = countercalc(&previnfo.rx, &ifinfo.rx, ifinfo.is64bit);
204 tx = countercalc(&previnfo.tx, &ifinfo.tx, ifinfo.is64bit);
205 rxp = countercalc(&previnfo.rxp, &ifinfo.rxp, ifinfo.is64bit);
206 txp = countercalc(&previnfo.txp, &ifinfo.txp, ifinfo.is64bit);
207
208 /* update totals */
209 rxtotal += rx;
210 txtotal += tx;
211 rxptotal += rxp;
212 txptotal += txp;
213
214 /* update min & max */
215 if (rxmin > rx) {
216 rxmin = rx;
217 }
218 if (txmin > tx) {
219 txmin = tx;
220 }
221 if (rxmax < rx) {
222 rxmax = rx;
223 }
224 if (txmax < tx) {
225 txmax = tx;
226 }
227 if (rxpmin > rxp) {
228 rxpmin = rxp;
229 }
230 if (txpmin > txp) {
231 txpmin = txp;
232 }
233 if (rxpmax < rxp) {
234 rxpmax = rxp;
235 }
236 if (txpmax < txp) {
237 txpmax = txp;
238 }
239
240 /* show the difference in a readable format or json */
241 if (!json) {
242 if (mode == 0) {
243 /* packets per second visible */
244 snprintf(buffer, 128, " rx: %s %*" PRIu64 " p/s", gettrafficrate(rx, LIVETIME, ratewidth), ppswidth, rxp / LIVETIME);
245 snprintf(buffer2, 128, " %*s tx: %s %*" PRIu64 " p/s", paddingwidth, " ", gettrafficrate(tx, LIVETIME, ratewidth), ppswidth, txp / LIVETIME);
246 } else {
247 /* total transfer amount visible */
248 snprintf(buffer, 128, " rx: %s %s", gettrafficrate(rx, LIVETIME, ratewidth), getvalue(rxtotal, 1, RT_Normal));
249 snprintf(buffer2, 128, " %*s tx: %s %s", paddingwidth, " ", gettrafficrate(tx, LIVETIME, ratewidth), getvalue(txtotal, 1, RT_Normal));
250 }
251 strcat(buffer, buffer2);
252
253 if (cfg.ostyle != 4 || !debug) {
254 cursortocolumn(1);
255 eraseline();
256 }
257 if (cfg.ostyle != 4) {
258 printf("%s", buffer);
259 } else {
260 printf("%s\n", buffer);
261 }
262 } else {
263 printf("{\"index\":%" PRIu64 ",", index);
264 printf("\"seconds\":%" PRIu64 ",", (uint64_t)time(NULL) - timespent);
265 printf("\"rx\":{");
266 printf("\"ratestring\":\"%s\",", gettrafficrate(rx, LIVETIME, 0));
267 printf("\"bytespersecond\":%" PRIu64 ",", (uint64_t)(rx / LIVETIME));
268 printf("\"packetspersecond\":%" PRIu64 ",", (uint64_t)(rxp / LIVETIME));
269 printf("\"bytes\":%" PRIu64 ",", rx);
270 printf("\"packets\":%" PRIu64 ",", rxp);
271 printf("\"totalbytes\":%" PRIu64 ",", rxtotal);
272 printf("\"totalpackets\":%" PRIu64 "", rxptotal);
273 printf("},");
274 printf("\"tx\":{");
275 printf("\"ratestring\":\"%s\",", gettrafficrate(tx, LIVETIME, 0));
276 printf("\"bytespersecond\":%" PRIu64 ",", (uint64_t)(tx / LIVETIME));
277 printf("\"packetspersecond\":%" PRIu64 ",", (uint64_t)(txp / LIVETIME));
278 printf("\"bytes\":%" PRIu64 ",", tx);
279 printf("\"packets\":%" PRIu64 ",", txp);
280 printf("\"totalbytes\":%" PRIu64 ",", txtotal);
281 printf("\"totalpackets\":%" PRIu64 "", txptotal);
282 printf("}}\n");
283 index++;
284 }
285 fflush(stdout);
286 #ifdef CHECK_VNSTAT
287 break;
288 #endif
289 }
290
291 timespent = (uint64_t)time(NULL) - timespent - timeslept;
292
293 #ifdef CHECK_VNSTAT
294 timespent = 10;
295 #endif
296
297 if (!json) {
298 cursorshow();
299 printf("\n\n");
300 }
301
302 /* print some statistics if enough time did pass */
303 if (!json && timespent >= 10) {
304
305 printf("\n %s / traffic statistics\n\n", iface);
306
307 printf(" rx | tx\n");
308 printf("--------------------------------------+------------------\n");
309 printf(" bytes %s", getvalue(rxtotal, 15, RT_Normal));
310 printf(" | %s", getvalue(txtotal, 15, RT_Normal));
311 printf("\n");
312 printf("--------------------------------------+------------------\n");
313 printf(" max %s", gettrafficrate(rxmax, LIVETIME, 15));
314 printf(" | %s\n", gettrafficrate(txmax, LIVETIME, 15));
315 printf(" average %s", gettrafficrate(rxtotal, (time_t)timespent, 15));
316 printf(" | %s\n", gettrafficrate(txtotal, (time_t)timespent, 15));
317 printf(" min %s", gettrafficrate(rxmin, LIVETIME, 15));
318 printf(" | %s\n", gettrafficrate(txmin, LIVETIME, 15));
319 printf("--------------------------------------+------------------\n");
320 printf(" packets %12" PRIu64 " | %12" PRIu64 "\n", rxptotal, txptotal);
321 printf("--------------------------------------+------------------\n");
322 printf(" max %9" PRIu64 " p/s | %9" PRIu64 " p/s\n", rxpmax / LIVETIME, txpmax / LIVETIME);
323 printf(" average %9" PRIu64 " p/s | %9" PRIu64 " p/s\n", rxptotal / timespent, txptotal / timespent);
324 printf(" min %9" PRIu64 " p/s | %9" PRIu64 " p/s\n", rxpmin / LIVETIME, txpmin / LIVETIME);
325 printf("--------------------------------------+------------------\n");
326
327 if (timespent <= 60) {
328 printf(" time %9" PRIu64 " seconds\n", timespent);
329 } else {
330 printf(" time %7.2f minutes\n", (double)timespent / (double)60);
331 }
332
333 printf("\n");
334 } else if (json) {
335 printf("{\"seconds\":%" PRIu64 ",", timespent);
336 printf("\"rx\":{");
337 printf("\"maxratestring\":\"%s\",", gettrafficrate(rxmax, LIVETIME, 0));
338 printf("\"averageratestring\":\"%s\",", gettrafficrate(rxtotal, (time_t)timespent, 0));
339 printf("\"minratestring\":\"%s\",", gettrafficrate(rxmin, LIVETIME, 0));
340 printf("\"totalbytes\":%" PRIu64 ",", rxtotal);
341 printf("\"maxbytes\":%" PRIu64 ",", rxmax);
342 printf("\"minbytes\":%" PRIu64 ",", rxmin);
343 printf("\"totalpackets\":%" PRIu64 ",", rxptotal);
344 printf("\"maxpackets\":%" PRIu64 ",", rxpmax);
345 printf("\"minpackets\":%" PRIu64 "", rxpmin);
346 printf("},");
347 printf("\"tx\":{");
348 printf("\"maxratestring\":\"%s\",", gettrafficrate(txmax, LIVETIME, 0));
349 printf("\"averageratestring\":\"%s\",", gettrafficrate(txtotal, (time_t)timespent, 0));
350 printf("\"minratestring\":\"%s\",", gettrafficrate(txmin, LIVETIME, 0));
351 printf("\"totalbytes\":%" PRIu64 ",", txtotal);
352 printf("\"maxbytes\":%" PRIu64 ",", txmax);
353 printf("\"minbytes\":%" PRIu64 ",", txmin);
354 printf("\"totalpackets\":%" PRIu64 ",", txptotal);
355 printf("\"maxpackets\":%" PRIu64 ",", txpmax);
356 printf("\"minpackets\":%" PRIu64 "", txpmin);
357 printf("}}\n");
358 }
359 }
360