|
Lines 37-42
Link Here
|
| 37 |
#include <net/if.h> |
37 |
#include <net/if.h> |
| 38 |
#include <net/if_mib.h> |
38 |
#include <net/if_mib.h> |
| 39 |
|
39 |
|
|
|
40 |
#include <stdbool.h> |
| 40 |
#include <stdlib.h> |
41 |
#include <stdlib.h> |
| 41 |
#include <string.h> |
42 |
#include <string.h> |
| 42 |
#include <err.h> |
43 |
#include <err.h> |
|
Lines 67-73
Link Here
|
| 67 |
|
68 |
|
| 68 |
struct if_stat { |
69 |
struct if_stat { |
| 69 |
SLIST_ENTRY(if_stat) link; |
70 |
SLIST_ENTRY(if_stat) link; |
| 70 |
char if_name[IF_NAMESIZE]; |
71 |
char display_name[IF_NAMESIZE]; |
|
|
72 |
char dev_name[IFNAMSIZ]; /* copied from ifmibdata */ |
| 71 |
struct ifmibdata if_mib; |
73 |
struct ifmibdata if_mib; |
| 72 |
struct timeval tv; |
74 |
struct timeval tv; |
| 73 |
struct timeval tv_lastchanged; |
75 |
struct timeval tv_lastchanged; |
|
Lines 81-87
Link Here
|
| 81 |
uint64_t if_out_pps_peak; |
83 |
uint64_t if_out_pps_peak; |
| 82 |
u_int if_row; /* Index into ifmib sysctl */ |
84 |
u_int if_row; /* Index into ifmib sysctl */ |
| 83 |
int if_ypos; /* -1 if not being displayed */ |
85 |
int if_ypos; /* -1 if not being displayed */ |
| 84 |
u_int display; |
86 |
bool display; |
| 85 |
u_int match; |
87 |
u_int match; |
| 86 |
}; |
88 |
}; |
| 87 |
|
89 |
|
|
Lines 91-101
Link Here
|
| 91 |
extern int needsort; |
93 |
extern int needsort; |
| 92 |
|
94 |
|
| 93 |
static int needclear = 0; |
95 |
static int needclear = 0; |
|
|
96 |
static bool displayall = false; |
| 94 |
|
97 |
|
| 95 |
static void right_align_string(struct if_stat *); |
98 |
static void format_device_name(struct if_stat *); |
| 96 |
static void getifmibdata(const int, struct ifmibdata *); |
99 |
static int getifmibdata(const int, struct ifmibdata *); |
| 97 |
static void sort_interface_list(void); |
100 |
static void sort_interface_list(void); |
| 98 |
static u_int getifnum(void); |
101 |
static u_int getifnum(void); |
|
|
102 |
static void clearifstat(void); |
| 99 |
|
103 |
|
| 100 |
#define IFSTAT_ERR(n, s) do { \ |
104 |
#define IFSTAT_ERR(n, s) do { \ |
| 101 |
putchar('\014'); \ |
105 |
putchar('\014'); \ |
|
Lines 165-171
Link Here
|
| 165 |
} while (0) |
169 |
} while (0) |
| 166 |
|
170 |
|
| 167 |
#define PUTNAME(p) do { \ |
171 |
#define PUTNAME(p) do { \ |
| 168 |
mvprintw(p->if_ypos, 0, "%s", p->if_name); \ |
172 |
mvprintw(p->if_ypos, 0, "%s", p->display_name); \ |
| 169 |
mvprintw(p->if_ypos, col2-3, "%s", (const char *)"in"); \ |
173 |
mvprintw(p->if_ypos, col2-3, "%s", (const char *)"in"); \ |
| 170 |
mvprintw(p->if_ypos+1, col2-3, "%s", (const char *)"out"); \ |
174 |
mvprintw(p->if_ypos+1, col2-3, "%s", (const char *)"out"); \ |
| 171 |
} while (0) |
175 |
} while (0) |
|
Lines 214-220
Link Here
|
| 214 |
|
218 |
|
| 215 |
SLIST_FOREACH(ifp, &curlist, link) { |
219 |
SLIST_FOREACH(ifp, &curlist, link) { |
| 216 |
if (ifp->if_ypos < LINES - 3 && ifp->if_ypos != -1) |
220 |
if (ifp->if_ypos < LINES - 3 && ifp->if_ypos != -1) |
| 217 |
if (ifp->display == 0 || ifp->match == 0) { |
221 |
if (!ifp->display || ifp->match == 0) { |
| 218 |
wmove(wnd, ifp->if_ypos, 0); |
222 |
wmove(wnd, ifp->if_ypos, 0); |
| 219 |
wclrtoeol(wnd); |
223 |
wclrtoeol(wnd); |
| 220 |
wmove(wnd, ifp->if_ypos + 1, 0); |
224 |
wmove(wnd, ifp->if_ypos + 1, 0); |
|
Lines 235-241
Link Here
|
| 235 |
initifstat(void) |
239 |
initifstat(void) |
| 236 |
{ |
240 |
{ |
| 237 |
struct if_stat *p = NULL; |
241 |
struct if_stat *p = NULL; |
| 238 |
u_int n = 0, i = 0; |
242 |
u_int n, i; |
| 239 |
|
243 |
|
| 240 |
n = getifnum(); |
244 |
n = getifnum(); |
| 241 |
if (n <= 0) |
245 |
if (n <= 0) |
|
Lines 247-264
Link Here
|
| 247 |
p = (struct if_stat *)calloc(1, sizeof(struct if_stat)); |
251 |
p = (struct if_stat *)calloc(1, sizeof(struct if_stat)); |
| 248 |
if (p == NULL) |
252 |
if (p == NULL) |
| 249 |
IFSTAT_ERR(1, "out of memory"); |
253 |
IFSTAT_ERR(1, "out of memory"); |
|
|
254 |
p->if_row = i+1; |
| 255 |
if (getifmibdata(p->if_row, &p->if_mib) == -1) { |
| 256 |
free(p); |
| 257 |
continue; |
| 258 |
} |
| 250 |
SLIST_INSERT_HEAD(&curlist, p, link); |
259 |
SLIST_INSERT_HEAD(&curlist, p, link); |
| 251 |
p->if_row = i+1; |
260 |
format_device_name(p); |
| 252 |
getifmibdata(p->if_row, &p->if_mib); |
|
|
| 253 |
right_align_string(p); |
| 254 |
p->match = 1; |
261 |
p->match = 1; |
| 255 |
|
262 |
|
| 256 |
/* |
263 |
/* |
| 257 |
* Initially, we only display interfaces that have |
264 |
* Initially, we only display interfaces that have |
| 258 |
* received some traffic. |
265 |
* received some traffic unless display-all is on. |
| 259 |
*/ |
266 |
*/ |
| 260 |
if (p->if_mib.ifmd_data.ifi_ibytes != 0) |
267 |
if (displayall || p->if_mib.ifmd_data.ifi_ibytes != 0) |
| 261 |
p->display = 1; |
268 |
p->display = true; |
| 262 |
} |
269 |
} |
| 263 |
|
270 |
|
| 264 |
sort_interface_list(); |
271 |
sort_interface_list(); |
|
Lines 269-281
Link Here
|
| 269 |
void |
276 |
void |
| 270 |
fetchifstat(void) |
277 |
fetchifstat(void) |
| 271 |
{ |
278 |
{ |
| 272 |
struct if_stat *ifp = NULL; |
279 |
struct if_stat *ifp = NULL, *temp_var; |
| 273 |
struct timeval tv, new_tv, old_tv; |
280 |
struct timeval tv, new_tv, old_tv; |
| 274 |
double elapsed = 0.0; |
281 |
double elapsed = 0.0; |
| 275 |
uint64_t new_inb, new_outb, old_inb, old_outb = 0; |
282 |
uint64_t new_inb, new_outb, old_inb, old_outb = 0; |
| 276 |
uint64_t new_inp, new_outp, old_inp, old_outp = 0; |
283 |
uint64_t new_inp, new_outp, old_inp, old_outp = 0; |
| 277 |
|
284 |
|
| 278 |
SLIST_FOREACH(ifp, &curlist, link) { |
285 |
SLIST_FOREACH_SAFE(ifp, &curlist, link, temp_var) { |
| 279 |
/* |
286 |
/* |
| 280 |
* Grab a copy of the old input/output values before we |
287 |
* Grab a copy of the old input/output values before we |
| 281 |
* call getifmibdata(). |
288 |
* call getifmibdata(). |
|
Lines 287-293
Link Here
|
| 287 |
ifp->tv_lastchanged = ifp->if_mib.ifmd_data.ifi_lastchange; |
294 |
ifp->tv_lastchanged = ifp->if_mib.ifmd_data.ifi_lastchange; |
| 288 |
|
295 |
|
| 289 |
(void)gettimeofday(&new_tv, NULL); |
296 |
(void)gettimeofday(&new_tv, NULL); |
| 290 |
(void)getifmibdata(ifp->if_row, &ifp->if_mib); |
297 |
if (getifmibdata(ifp->if_row, &ifp->if_mib) == -1 ) { |
|
|
298 |
/* if a device was removed */ |
| 299 |
SLIST_REMOVE(&curlist, ifp, if_stat, link); |
| 300 |
free(ifp); |
| 301 |
needsort = 1; |
| 302 |
clearifstat(); |
| 303 |
} else if (strcmp(ifp->dev_name, ifp->if_mib.ifmd_name) != 0 ) { |
| 304 |
/* a device was removed and another one was added */ |
| 305 |
format_device_name(ifp); |
| 306 |
/* clear to the current value for the new device */ |
| 307 |
old_inb = ifp->if_mib.ifmd_data.ifi_ibytes; |
| 308 |
old_outb = ifp->if_mib.ifmd_data.ifi_obytes; |
| 309 |
old_inp = ifp->if_mib.ifmd_data.ifi_ipackets; |
| 310 |
old_outp = ifp->if_mib.ifmd_data.ifi_opackets; |
| 311 |
needsort = 1; |
| 312 |
} |
| 291 |
|
313 |
|
| 292 |
new_inb = ifp->if_mib.ifmd_data.ifi_ibytes; |
314 |
new_inb = ifp->if_mib.ifmd_data.ifi_ibytes; |
| 293 |
new_outb = ifp->if_mib.ifmd_data.ifi_obytes; |
315 |
new_outb = ifp->if_mib.ifmd_data.ifi_obytes; |
|
Lines 295-302
Link Here
|
| 295 |
new_outp = ifp->if_mib.ifmd_data.ifi_opackets; |
317 |
new_outp = ifp->if_mib.ifmd_data.ifi_opackets; |
| 296 |
|
318 |
|
| 297 |
/* Display interface if it's received some traffic. */ |
319 |
/* Display interface if it's received some traffic. */ |
| 298 |
if (new_inb > 0 && old_inb == 0) { |
320 |
if (!ifp->display && new_inb > 0 && old_inb == 0) { |
| 299 |
ifp->display = 1; |
321 |
ifp->display = true; |
| 300 |
needsort = 1; |
322 |
needsort = 1; |
| 301 |
} |
323 |
} |
| 302 |
|
324 |
|
|
Lines 351-378
Link Here
|
| 351 |
/* |
373 |
/* |
| 352 |
* We want to right justify our interface names against the first column |
374 |
* We want to right justify our interface names against the first column |
| 353 |
* (first sixteen or so characters), so we need to do some alignment. |
375 |
* (first sixteen or so characters), so we need to do some alignment. |
|
|
376 |
* We save original name so that we can find a same spot is take by a |
| 377 |
* different device. |
| 354 |
*/ |
378 |
*/ |
| 355 |
static void |
379 |
static void |
| 356 |
right_align_string(struct if_stat *ifp) |
380 |
format_device_name(struct if_stat *ifp) |
| 357 |
{ |
381 |
{ |
| 358 |
int str_len = 0, pad_len = 0; |
|
|
| 359 |
char *newstr = NULL, *ptr = NULL; |
| 360 |
|
382 |
|
| 361 |
if (ifp == NULL || ifp->if_mib.ifmd_name == NULL) |
383 |
if (ifp != NULL || ifp->if_mib.ifmd_name != NULL) { |
| 362 |
return; |
384 |
snprintf(ifp->display_name, IF_NAMESIZE, "%*s", IF_NAMESIZE-1, |
| 363 |
else { |
385 |
ifp->if_mib.ifmd_name); |
| 364 |
/* string length + '\0' */ |
386 |
strcpy(ifp->dev_name, ifp->if_mib.ifmd_name); |
| 365 |
str_len = strlen(ifp->if_mib.ifmd_name)+1; |
|
|
| 366 |
pad_len = IF_NAMESIZE-(str_len); |
| 367 |
|
| 368 |
newstr = ifp->if_name; |
| 369 |
ptr = newstr + pad_len; |
| 370 |
(void)memset((void *)newstr, (int)' ', IF_NAMESIZE); |
| 371 |
(void)strncpy(ptr, (const char *)&ifp->if_mib.ifmd_name, |
| 372 |
str_len); |
| 373 |
} |
387 |
} |
| 374 |
|
|
|
| 375 |
return; |
| 376 |
} |
388 |
} |
| 377 |
|
389 |
|
| 378 |
static int |
390 |
static int |
|
Lines 461-469
Link Here
|
| 461 |
return (data); |
473 |
return (data); |
| 462 |
} |
474 |
} |
| 463 |
|
475 |
|
| 464 |
static void |
476 |
static int |
| 465 |
getifmibdata(int row, struct ifmibdata *data) |
477 |
getifmibdata(int row, struct ifmibdata *data) |
| 466 |
{ |
478 |
{ |
|
|
479 |
int ret = 0; |
| 467 |
size_t datalen = 0; |
480 |
size_t datalen = 0; |
| 468 |
static int name[] = { CTL_NET, |
481 |
static int name[] = { CTL_NET, |
| 469 |
PF_LINK, |
482 |
PF_LINK, |
|
Lines 474-482
Link Here
|
| 474 |
datalen = sizeof(*data); |
487 |
datalen = sizeof(*data); |
| 475 |
name[4] = row; |
488 |
name[4] = row; |
| 476 |
|
489 |
|
| 477 |
if ((sysctl(name, 6, (void *)data, (size_t *)&datalen, (void *)NULL, |
490 |
ret = sysctl(name, 6, (void *)data, (size_t *)&datalen, (void *)NULL, |
| 478 |
(size_t)0) != 0) && (errno != ENOENT)) |
491 |
(size_t)0); |
|
|
492 |
if ((ret != 0) && (errno != ENOENT)) |
| 479 |
IFSTAT_ERR(2, "sysctl error getting interface data"); |
493 |
IFSTAT_ERR(2, "sysctl error getting interface data"); |
|
|
494 |
|
| 495 |
return (ret); |
| 480 |
} |
496 |
} |
| 481 |
|
497 |
|
| 482 |
int |
498 |
int |
|
Lines 487-499
Link Here
|
| 487 |
retval = ifcmd(cmd, args); |
503 |
retval = ifcmd(cmd, args); |
| 488 |
/* ifcmd() returns 1 on success */ |
504 |
/* ifcmd() returns 1 on success */ |
| 489 |
if (retval == 1) { |
505 |
if (retval == 1) { |
| 490 |
if (needclear) { |
506 |
if (needclear) |
| 491 |
showifstat(); |
507 |
clearifstat(); |
| 492 |
refresh(); |
|
|
| 493 |
werase(wnd); |
| 494 |
labelifstat(); |
| 495 |
needclear = 0; |
| 496 |
} |
| 497 |
} |
508 |
} |
|
|
509 |
else if (prefix(cmd, "all")) { |
| 510 |
retval = 1; |
| 511 |
displayall = true; |
| 512 |
} |
| 498 |
return (retval); |
513 |
return (retval); |
| 499 |
} |
514 |
} |
|
|
515 |
|
| 516 |
void |
| 517 |
clearifstat(void) |
| 518 |
{ |
| 519 |
|
| 520 |
showifstat(); |
| 521 |
refresh(); |
| 522 |
werase(wnd); |
| 523 |
labelifstat(); |
| 524 |
needclear = 0; |
| 525 |
} |