1
/*****************************************************************
2
Copyright 1989, 1991, 1992 by Carnegie Mellon University
6
Permission to use, copy, modify, and distribute this software and its
7
documentation for any purpose and without fee is hereby granted,
8
provided that the above copyright notice appear in all copies and that
9
both that copyright notice and this permission notice appear in
10
supporting documentation, and that the name of CMU not be
11
used in advertising or publicity pertaining to distribution of the
12
software without specific, written prior permission.
14
CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16
CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21
******************************************************************/
23
* Copyright (c) 1983,1988 Regents of the University of California.
24
* All rights reserved.
26
* Redistribution and use in source and binary forms are permitted
27
* provided that this notice is preserved and that due credit is given
28
* to the University of California at Berkeley. The name of the University
29
* may not be used to endorse or promote products derived from this
30
* software without specific prior written permission. This software
31
* is provided ``as is'' without express or implied warranty.
34
#include <net-snmp/net-snmp-config.h>
48
#include <sys/types.h>
49
#if TIME_WITH_SYS_TIME
51
# include <sys/timeb.h>
53
# include <sys/time.h>
58
# include <sys/time.h>
64
#include <sys/select.h>
67
#include <netinet/in.h>
77
#include <sys/socket.h>
84
#include <net-snmp/net-snmp-includes.h>
90
static void sidewaysintpr(unsigned int);
91
static void timerSet(int interval_seconds);
92
static void timerPause(void);
94
static oid oid_ifname[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 2, 1 };
95
static oid oid_ifinucastpkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 11, 1 };
96
static oid oid_cfg_nnets[] = { 1, 3, 6, 1, 2, 1, 2, 1, 0 };
97
static oid oid_ipadentaddr[] =
98
{ 1, 3, 6, 1, 2, 1, 4, 20, 1, 1, 0, 0, 0, 0 };
103
#define IFOPERSTATUS 8
105
#define INUCASTPKTS 11
106
#define INNUCASTPKTS 12
109
#define OUTUCASTPKTS 17
110
#define OUTNUCASTPKTS 18
120
* Print a description of the network interfaces.
125
oid varname[MAX_OID_LEN], *instance, *ifentry;
127
int ifnum, cfg_nnets;
129
netsnmp_variable_list *var;
130
netsnmp_pdu *request, *response;
132
int ifindex, oldindex = 0;
135
char ip[128], route[128];
138
char s_ipkts[20], s_ierrs[20], s_opkts[20], s_oerrs[20],
140
unsigned long ipkts, opkts;
143
struct in_addr ifip, ifroute;
144
} *if_table, *cur_if;
145
int max_name = 4, max_ip = 7, max_route = 7, max_ipkts = 5,
146
max_ierrs = 5, max_opkts = 5, max_oerrs = 5, max_outq = 5;
150
sidewaysintpr((unsigned) interval);
154
getvarbyname(Session, oid_cfg_nnets,
155
sizeof(oid_cfg_nnets) / sizeof(oid));
156
if (var && var->val.integer) {
157
cfg_nnets = *var->val.integer;
161
"No response when requesting number of interfaces.\n");
164
DEBUGMSGTL(("netstat:if", "cfg_nnets = %d\n", cfg_nnets));
166
memset(curifip, 0, sizeof(curifip));
167
if_table = (struct _if_info *) calloc(cfg_nnets, sizeof(*if_table));
170
for (ifnum = 1; ifnum <= cfg_nnets; ifnum++) {
173
request = snmp_pdu_create(SNMP_MSG_GETNEXT);
174
memmove(varname, oid_ipadentaddr, sizeof(oid_ipadentaddr));
175
varname_len = sizeof(oid_ipadentaddr) / sizeof(oid);
176
instance = varname + 9;
177
memmove(varname + 10, curifip, sizeof(curifip));
178
*instance = IPIFINDEX;
179
snmp_add_null_var(request, varname, varname_len);
181
snmp_add_null_var(request, varname, varname_len);
182
*instance = IPNETMASK;
183
snmp_add_null_var(request, varname, varname_len);
185
status = snmp_synch_response(Session, request, &response);
186
if (status != STAT_SUCCESS
187
|| response->errstat != SNMP_ERR_NOERROR) {
189
"SNMP request failed after %d out of %d interfaces (IP)\n",
191
if (snmp_get_do_debugging()) {
193
"status = %d, errstat = %ld, errindex = %ld\n",
194
status, response->errstat, response->errindex);
199
for (var = response->variables; var; var = var->next_variable) {
200
if (snmp_get_do_debugging()) {
201
print_variable(var->name, var->name_length, var);
203
switch (var->name[9]) {
205
ifindex = *var->val.integer;
206
for (cur_if = if_table;
207
cur_if < (if_table + cfg_nnets) &&
208
cur_if->ifindex != ifindex &&
209
cur_if->ifindex != 0; cur_if++);
210
if (cur_if >= (if_table + cfg_nnets)) {
212
"Inconsistent reponse from server. Aborting.\n");
215
cur_if->ifindex = ifindex;
218
memmove(curifip, var->name + 10, sizeof(curifip));
219
memmove(&cur_if->ifip, var->val.string, sizeof(u_long));
222
memmove(&cur_if->netmask, var->val.string, sizeof(u_long));
225
cur_if->ifroute.s_addr = cur_if->ifip.s_addr & cur_if->netmask;
226
if (cur_if->ifroute.s_addr)
227
strcpy(cur_if->route,
228
netname(cur_if->ifroute, cur_if->netmask));
230
strcpy(cur_if->route, "none");
231
if ((i = strlen(cur_if->route)) > max_route)
233
if (cur_if->ifip.s_addr)
234
strcpy(cur_if->ip, routename(cur_if->ifip));
236
strcpy(cur_if->ip, "none");
237
if ((i = strlen(cur_if->ip)) > max_ip)
240
snmp_free_pdu(response);
242
memmove(varname, oid_ifname, sizeof(oid_ifname));
243
varname_len = sizeof(oid_ifname) / sizeof(oid);
244
ifentry = varname + 9;
245
instance = varname + 10;
246
request = snmp_pdu_create(SNMP_MSG_GETNEXT);
248
*instance = oldindex;
250
snmp_add_null_var(request, varname, varname_len);
252
snmp_add_null_var(request, varname, varname_len);
254
snmp_add_null_var(request, varname, varname_len);
255
*ifentry = IFOPERSTATUS;
256
snmp_add_null_var(request, varname, varname_len);
257
*ifentry = INUCASTPKTS;
258
snmp_add_null_var(request, varname, varname_len);
259
*ifentry = INNUCASTPKTS;
260
snmp_add_null_var(request, varname, varname_len);
262
snmp_add_null_var(request, varname, varname_len);
263
*ifentry = OUTUCASTPKTS;
264
snmp_add_null_var(request, varname, varname_len);
265
*ifentry = OUTNUCASTPKTS;
266
snmp_add_null_var(request, varname, varname_len);
267
*ifentry = OUTERRORS;
268
snmp_add_null_var(request, varname, varname_len);
270
snmp_add_null_var(request, varname, varname_len);
273
snmp_synch_response(Session, request,
274
&response)) == STAT_SUCCESS) {
275
if (response->errstat != SNMP_ERR_NOSUCHNAME)
278
snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) == NULL)
280
snmp_free_pdu(response);
282
if (status != STAT_SUCCESS
283
|| response->errstat != SNMP_ERR_NOERROR) {
285
"SNMP request failed after %d out of %d interfaces (IF)\n",
290
cur_if = if_table + ifnum - 1;
291
for (var = response->variables; var; var = var->next_variable) {
292
if (snmp_get_do_debugging()) {
293
print_variable(var->name, var->name_length, var);
295
if (!var->val.integer)
297
if (memcmp(var->name, oid_ifname, 8 * sizeof(oid)))
299
switch (var->name[9]) {
301
ifindex = *var->val.integer;
302
for (cur_if = if_table;
303
cur_if->ifindex != ifindex && cur_if->ifindex != 0;
305
if (cur_if >= (if_table + cfg_nnets)) {
307
"Inconsistent reponse from server. Aborting\n");
310
cur_if->ifindex = ifindex;
313
sprintf(cur_if->s_outq, "%lu", *var->val.integer);
314
i = strlen(cur_if->s_outq);
319
sprintf(cur_if->s_oerrs, "%lu", *var->val.integer);
320
i = strlen(cur_if->s_oerrs);
325
sprintf(cur_if->s_ierrs, "%lu", *var->val.integer);
326
i = strlen(cur_if->s_ierrs);
331
cur_if->mtu = *var->val.integer;
334
cur_if->ipkts += *var->val.integer;
335
sprintf(cur_if->s_ipkts, "%lu", cur_if->ipkts);
336
i = strlen(cur_if->s_ipkts);
341
cur_if->ipkts += *var->val.integer;
342
sprintf(cur_if->s_ipkts, "%lu", cur_if->ipkts);
343
i = strlen(cur_if->s_ipkts);
348
cur_if->opkts += *var->val.integer;
349
sprintf(cur_if->s_opkts, "%lu", cur_if->opkts);
350
i = strlen(cur_if->s_opkts);
355
cur_if->opkts += *var->val.integer;
356
sprintf(cur_if->s_opkts, "%lu", cur_if->opkts);
357
i = strlen(cur_if->s_opkts);
362
oldindex = var->name[10];
363
if (var->val_len >= sizeof(cur_if->name))
364
var->val_len = sizeof(cur_if->name) - 1;
365
memmove(cur_if->name, var->val.string, var->val_len);
366
cur_if->name[var->val_len] = 0;
367
if ((i = strlen(cur_if->name) + 1) > max_name)
371
cur_if->operstatus = *var->val.integer;
376
snmp_free_pdu(response);
378
if (intrface != NULL && strcmp(cur_if->name, intrface) != 0) {
382
if (cur_if->operstatus != MIB_IFSTATUS_UP) {
383
cp = strchr(cur_if->name, '\0');
389
printf("%*.*s %5.5s %*.*s %*.*s %*s %*s %*s %*s %*s",
390
-max_name, max_name, "Name", "Mtu",
391
-max_route, max_route, "Network",
392
-max_ip, max_ip, "Address",
395
max_opkts, "Opkts", max_oerrs, "Oerrs", max_outq, "Queue");
397
for (ifnum = 0, cur_if = if_table; ifnum < cfg_nnets;
399
if (cur_if->name[0] == 0)
401
printf("%*.*s %5d ", -max_name, max_name, cur_if->name,
403
printf("%*.*s ", -max_route, max_route, cur_if->route);
404
printf("%*.*s ", -max_ip, max_ip, cur_if->ip);
405
printf("%*s %*s %*s %*s %*s",
406
max_ipkts, cur_if->s_ipkts, max_ierrs, cur_if->s_ierrs,
407
max_opkts, cur_if->s_opkts, max_oerrs, cur_if->s_oerrs,
408
max_outq, cur_if->s_outq);
415
* Print a description of the network interfaces.
420
oid varname[MAX_OID_LEN], *instance, *ifentry;
422
int ifnum, cfg_nnets;
424
netsnmp_variable_list *var;
425
netsnmp_pdu *request, *response;
427
int ifindex, oldindex = 0;
431
char ip[128], route[128];
432
char ioctets[20], ierrs[20], ooctets[20], oerrs[20],
436
struct in_addr ifip, ifroute;
437
} *if_table, *cur_if;
438
int max_name = 4, max_route = 7, max_ip = 7, max_ioctets =
443
sidewaysintpr((unsigned) interval);
447
getvarbyname(Session, oid_cfg_nnets,
448
sizeof(oid_cfg_nnets) / sizeof(oid));
449
if (var && var->val.integer) {
450
cfg_nnets = *var->val.integer;
454
"No response when requesting number of interfaces.\n");
457
DEBUGMSGTL(("netstat:if", "cfg_nnets = %d\n", cfg_nnets));
459
memset(curifip, 0, sizeof(curifip));
460
if_table = (struct _if_info *) calloc(cfg_nnets, sizeof(*if_table));
463
for (ifnum = 1; ifnum <= cfg_nnets; ifnum++) {
466
request = snmp_pdu_create(SNMP_MSG_GETNEXT);
467
memmove(varname, oid_ipadentaddr, sizeof(oid_ipadentaddr));
468
varname_len = sizeof(oid_ipadentaddr) / sizeof(oid);
469
instance = varname + 9;
470
memmove(varname + 10, curifip, sizeof(curifip));
471
*instance = IPIFINDEX;
472
snmp_add_null_var(request, varname, varname_len);
474
snmp_add_null_var(request, varname, varname_len);
475
*instance = IPNETMASK;
476
snmp_add_null_var(request, varname, varname_len);
478
status = snmp_synch_response(Session, request, &response);
479
if (status != STAT_SUCCESS
480
|| response->errstat != SNMP_ERR_NOERROR) {
482
"SNMP request failed for interface %d, variable %ld out of %d interfaces (IP)\n",
483
ifnum, response->errindex, cfg_nnets);
487
for (var = response->variables; var; var = var->next_variable) {
488
if (snmp_get_do_debugging()) {
489
print_variable(var->name, var->name_length, var);
491
switch (var->name[9]) {
493
ifindex = *var->val.integer;
494
for (cur_if = if_table;
495
cur_if->ifindex != ifindex && cur_if->ifindex != 0;
497
cur_if->ifindex = ifindex;
500
memmove(curifip, var->name + 10, sizeof(curifip));
501
memmove(&cur_if->ifip, var->val.string, sizeof(u_long));
504
memmove(&cur_if->netmask, var->val.string, sizeof(u_long));
507
cur_if->ifroute.s_addr = cur_if->ifip.s_addr & cur_if->netmask;
508
if (cur_if->ifroute.s_addr)
509
strcpy(cur_if->route,
510
netname(cur_if->ifroute, cur_if->netmask));
512
strcpy(cur_if->route, "none");
513
if ((i = strlen(cur_if->route)) > max_route)
515
if (cur_if->ifip.s_addr)
516
strcpy(cur_if->ip, routename(cur_if->ifip));
518
strcpy(cur_if->ip, "none");
519
if ((i = strlen(cur_if->ip)) > max_ip)
522
snmp_free_pdu(response);
524
memmove(varname, oid_ifname, sizeof(oid_ifname));
525
varname_len = sizeof(oid_ifname) / sizeof(oid);
526
ifentry = varname + 9;
527
instance = varname + 10;
528
request = snmp_pdu_create(SNMP_MSG_GETNEXT);
530
*instance = oldindex;
532
snmp_add_null_var(request, varname, varname_len);
534
snmp_add_null_var(request, varname, varname_len);
535
*ifentry = IFOPERSTATUS;
536
snmp_add_null_var(request, varname, varname_len);
538
snmp_add_null_var(request, varname, varname_len);
539
*ifentry = OUTOCTETS;
540
snmp_add_null_var(request, varname, varname_len);
543
snmp_synch_response(Session, request,
544
&response)) == STAT_SUCCESS) {
545
if (response->errstat != SNMP_ERR_NOSUCHNAME)
548
snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) == NULL)
550
snmp_free_pdu(response);
552
if (status != STAT_SUCCESS
553
|| response->errstat != SNMP_ERR_NOERROR) {
555
"SNMP request failed for interface %d, variable %ld out of %d interfaces (IF)\n",
556
ifnum, response->errindex, cfg_nnets);
560
for (var = response->variables; var; var = var->next_variable) {
561
if (snmp_get_do_debugging()) {
562
print_variable(var->name, var->name_length, var);
564
if (!var->val.integer)
566
switch (var->name[9]) {
568
ifindex = *var->val.integer;
569
for (cur_if = if_table;
570
cur_if->ifindex != ifindex && cur_if->ifindex != 0;
572
cur_if->ifindex = ifindex;
575
sprintf(cur_if->ioctets, "%lu", *var->val.integer);
576
i = strlen(cur_if->ioctets);
581
sprintf(cur_if->ooctets, "%lu", *var->val.integer);
582
i = strlen(cur_if->ooctets);
587
oldindex = var->name[10];
588
if (var->val_len >= sizeof(cur_if->name))
589
var->val_len = sizeof(cur_if->name) - 1;
590
memmove(cur_if->name, var->val.string, var->val_len);
591
cur_if->name[var->val_len] = 0;
592
if ((i = strlen(cur_if->name) + 1) > max_name)
596
cur_if->operstatus = *var->val.integer;
601
snmp_free_pdu(response);
603
if (intrface != NULL && strcmp(cur_if->name, intrface) != 0) {
607
if (cur_if->operstatus != MIB_IFSTATUS_UP) {
608
cp = strchr(cur_if->name, '\0');
614
printf("%*.*s %*.*s %*.*s %*.*s %*.*s ",
615
-max_name, max_name, "Name",
616
-max_route, max_route, "Network",
617
-max_ip, max_ip, "Address",
618
max_ioctets, max_ioctets, "Ioctets",
619
max_ooctets, max_ooctets, "Ooctets");
621
for (ifnum = 0, cur_if = if_table; ifnum < cfg_nnets;
623
if (cur_if->name[0] == 0)
625
printf("%*.*s ", -max_name, max_name, cur_if->name);
626
printf("%*.*s ", -max_route, max_route, cur_if->route);
627
printf("%*.*s ", -max_ip, max_ip, cur_if->ip);
628
printf("%*s %*s", max_ioctets, cur_if->ioctets,
629
max_ioctets, cur_if->ooctets);
637
char ift_name[128]; /* interface name */
638
unsigned int ift_ip; /* input packets */
639
unsigned int ift_ie; /* input errors */
640
unsigned int ift_op; /* output packets */
641
unsigned int ift_oe; /* output errors */
642
unsigned int ift_co; /* collisions */
645
u_char signalled; /* set if alarm goes off "early" */
648
* timerSet sets or resets the timer to fire in "interval" seconds.
649
* timerPause waits only if the timer has not fired.
650
* timing precision is not considered important.
653
#if (defined(WIN32) || defined(cygwin))
655
static time_t timezup;
657
timerSet(int interval_seconds)
659
sav_int = interval_seconds;
660
timezup = time(0) + interval_seconds;
664
* you can do better than this !
670
while (time(&now) < timezup)
677
tx.tv_usec = 400 * 1000; /* 400 milliseconds */
678
select(0, 0, 0, 0, &tx);
686
* Called if an interval expires before sidewaysintpr has completed a loop.
687
* Sets a flag to not wait for the alarm.
696
timerSet(int interval_seconds)
699
(void) sigset(SIGALRM, catchalarm);
701
(void) signal(SIGALRM, catchalarm);
704
(void) alarm(interval_seconds);
717
oldmask = sigblock(sigmask(SIGALRM));
725
#endif /* !WIN32 && !cygwin */
728
* Print a running summary of interface statistics.
729
* Repeat display every interval seconds, showing statistics
730
* collected over that interval. Assumes that interval is non-zero.
731
* First line printed at top of screen is always cumulative.
734
sidewaysintpr(unsigned int interval)
736
register struct iftot *ip, *total;
738
struct iftot *lastif, *sum, *interesting, ifnow, *now = &ifnow;
739
netsnmp_variable_list *var;
740
oid varname[MAX_OID_LEN], *instance, *ifentry;
742
int ifnum, cfg_nnets;
745
sum = iftot + MAXIF - 1;
749
getvarbyname(Session, oid_cfg_nnets,
750
sizeof(oid_cfg_nnets) / sizeof(oid));
752
cfg_nnets = *var->val.integer;
756
memmove(varname, oid_ifname, sizeof(oid_ifname));
757
varname_len = sizeof(oid_ifname) / sizeof(oid);
758
for (ifnum = 1, ip = iftot; ifnum <= cfg_nnets; ifnum++) {
761
ip->ift_name[0] = '(';
763
var = getvarbyname(Session, varname, varname_len);
765
if (var->val_len >= (sizeof(ip->ift_name) - 3))
766
var->val_len = (sizeof(ip->ift_name) - 4);
767
memmove(ip->ift_name + 1, var->val.string, var->val_len);
770
cp = (char *) strchr(ip->ift_name, ' ');
773
if (intrface && strcmp(ip->ift_name + 1, intrface) == 0)
775
ip->ift_name[15] = '\0';
776
cp = (char *) strchr(ip->ift_name, '\0');
779
if (ip >= iftot + MAXIF - 2)
787
printf(" input %-6.6s output ", interesting->ift_name);
788
if (lastif - iftot > 0)
789
printf(" input (Total) output");
790
for (ip = iftot; ip < iftot + MAXIF; ip++) {
798
printf("%10.10s %8.8s %10.10s %8.8s %8.8s ",
799
"packets", "errs", "packets", "errs", "colls");
800
if (lastif - iftot > 0)
801
printf("%10.10s %8.8s %10.10s %8.8s %8.8s ",
802
"packets", "errs", "packets", "errs", "colls");
812
memmove(varname, oid_ifinucastpkts, sizeof(oid_ifinucastpkts));
813
varname_len = sizeof(oid_ifinucastpkts) / sizeof(oid);
814
ifentry = varname + 9;
815
instance = varname + 10;
816
for (ifnum = 1, ip = iftot; ifnum <= cfg_nnets && ip < lastif;
818
memset(now, 0, sizeof(*now));
820
*ifentry = INUCASTPKTS;
821
var = getvarbyname(Session, varname, varname_len);
823
now->ift_ip = *var->val.integer;
826
*ifentry = INNUCASTPKTS;
827
var = getvarbyname(Session, varname, varname_len);
829
now->ift_ip += *var->val.integer;
833
var = getvarbyname(Session, varname, varname_len);
835
now->ift_ie = *var->val.integer;
838
*ifentry = OUTUCASTPKTS;
839
var = getvarbyname(Session, varname, varname_len);
841
now->ift_op = *var->val.integer;
844
*ifentry = OUTNUCASTPKTS;
845
var = getvarbyname(Session, varname, varname_len);
847
now->ift_op += *var->val.integer;
850
*ifentry = OUTERRORS;
851
var = getvarbyname(Session, varname, varname_len);
853
now->ift_oe = *var->val.integer;
857
if (ip == interesting)
858
printf("%10d %8d %10d %8d %8d ",
859
now->ift_ip - ip->ift_ip,
860
now->ift_ie - ip->ift_ie,
861
now->ift_op - ip->ift_op,
862
now->ift_oe - ip->ift_oe, now->ift_co - ip->ift_co);
863
ip->ift_ip = now->ift_ip;
864
ip->ift_ie = now->ift_ie;
865
ip->ift_op = now->ift_op;
866
ip->ift_oe = now->ift_oe;
867
ip->ift_co = now->ift_co;
868
sum->ift_ip += ip->ift_ip;
869
sum->ift_ie += ip->ift_ie;
870
sum->ift_op += ip->ift_op;
871
sum->ift_oe += ip->ift_oe;
872
sum->ift_co += ip->ift_co;
874
if (lastif - iftot > 0)
875
printf("%10d %8d %10d %8d %8d ",
876
sum->ift_ip - total->ift_ip,
877
sum->ift_ie - total->ift_ie,
878
sum->ift_op - total->ift_op,
879
sum->ift_oe - total->ift_oe, sum->ift_co - total->ift_co);