~ubuntu-branches/ubuntu/trusty/net-snmp/trusty

« back to all changes in this revision

Viewing changes to apps/snmpnetstat/if.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-13 12:06:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040913120621-g952ntonlleihcvm
Tags: upstream-5.1.1
ImportĀ upstreamĀ versionĀ 5.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************
 
2
        Copyright 1989, 1991, 1992 by Carnegie Mellon University
 
3
 
 
4
                      All Rights Reserved
 
5
 
 
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.  
 
13
 
 
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
 
20
SOFTWARE.
 
21
******************************************************************/
 
22
/*
 
23
 * Copyright (c) 1983,1988 Regents of the University of California.
 
24
 * All rights reserved.
 
25
 *
 
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.
 
32
 */
 
33
 
 
34
#include <net-snmp/net-snmp-config.h>
 
35
 
 
36
#if HAVE_STDLIB_H
 
37
#include <stdlib.h>
 
38
#endif
 
39
#if HAVE_UNISTD_H
 
40
#include <unistd.h>
 
41
#endif
 
42
#if HAVE_STRING_H
 
43
#include <string.h>
 
44
#else
 
45
#include <strings.h>
 
46
#endif
 
47
 
 
48
#include <sys/types.h>
 
49
#if TIME_WITH_SYS_TIME
 
50
# ifdef WIN32
 
51
#  include <sys/timeb.h>
 
52
# else
 
53
#  include <sys/time.h>
 
54
# endif
 
55
# include <time.h>
 
56
#else
 
57
# if HAVE_SYS_TIME_H
 
58
#  include <sys/time.h>
 
59
# else
 
60
#  include <time.h>
 
61
# endif
 
62
#endif
 
63
#if HAVE_SYS_SELECT_H
 
64
#include <sys/select.h>
 
65
#endif
 
66
#if HAVE_NETINET_IN_H
 
67
#include <netinet/in.h>
 
68
#endif
 
69
 
 
70
#include <stdio.h>
 
71
#include <signal.h>
 
72
 
 
73
#if HAVE_WINSOCK_H
 
74
#include <winsock.h>
 
75
#endif
 
76
#if HAVE_SYS_SOCKET_H
 
77
#include <sys/socket.h>
 
78
#endif
 
79
#if HAVE_NETDB_H
 
80
#include <netdb.h>
 
81
#endif
 
82
 
 
83
#include "main.h"
 
84
#include <net-snmp/net-snmp-includes.h>
 
85
#include "netstat.h"
 
86
 
 
87
#define YES     1
 
88
#define NO      0
 
89
 
 
90
static void     sidewaysintpr(unsigned int);
 
91
static void     timerSet(int interval_seconds);
 
92
static void     timerPause(void);
 
93
 
 
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 };
 
99
 
 
100
#define IFINDEX         1
 
101
#define IFNAME          2
 
102
#define IFMTU           4
 
103
#define IFOPERSTATUS    8
 
104
#define INOCTETS        10
 
105
#define INUCASTPKTS     11
 
106
#define INNUCASTPKTS    12
 
107
#define INERRORS        14
 
108
#define OUTOCTETS       16
 
109
#define OUTUCASTPKTS    17
 
110
#define OUTNUCASTPKTS   18
 
111
#define OUTERRORS       20
 
112
#define OUTQLEN         21
 
113
 
 
114
#define IPADDR          1
 
115
#define IPIFINDEX       2
 
116
#define IPNETMASK       3
 
117
 
 
118
 
 
119
/*
 
120
 * Print a description of the network interfaces.
 
121
 */
 
122
void
 
123
intpr(int interval)
 
124
{
 
125
    oid             varname[MAX_OID_LEN], *instance, *ifentry;
 
126
    size_t          varname_len;
 
127
    int             ifnum, cfg_nnets;
 
128
    oid             curifip[4];
 
129
    netsnmp_variable_list *var;
 
130
    netsnmp_pdu    *request, *response;
 
131
    int             status;
 
132
    int             ifindex, oldindex = 0;
 
133
    struct _if_info {
 
134
        char            name[128];
 
135
        char            ip[128], route[128];
 
136
        int             mtu;
 
137
        int             ifindex;
 
138
        char            s_ipkts[20], s_ierrs[20], s_opkts[20], s_oerrs[20],
 
139
            s_outq[20];
 
140
        unsigned long   ipkts, opkts;
 
141
        int             operstatus;
 
142
        u_long          netmask;
 
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;
 
147
    int             i;
 
148
 
 
149
    if (interval) {
 
150
        sidewaysintpr((unsigned) interval);
 
151
        return;
 
152
    }
 
153
    var =
 
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;
 
158
        snmp_free_var(var);
 
159
    } else {
 
160
        fprintf(stderr,
 
161
                "No response when requesting number of interfaces.\n");
 
162
        return;
 
163
    }
 
164
    DEBUGMSGTL(("netstat:if", "cfg_nnets = %d\n", cfg_nnets));
 
165
 
 
166
    memset(curifip, 0, sizeof(curifip));
 
167
    if_table = (struct _if_info *) calloc(cfg_nnets, sizeof(*if_table));
 
168
    cur_if = if_table;
 
169
 
 
170
    for (ifnum = 1; ifnum <= cfg_nnets; ifnum++) {
 
171
        register char  *cp;
 
172
 
 
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);
 
180
        *instance = IPADDR;
 
181
        snmp_add_null_var(request, varname, varname_len);
 
182
        *instance = IPNETMASK;
 
183
        snmp_add_null_var(request, varname, varname_len);
 
184
 
 
185
        status = snmp_synch_response(Session, request, &response);
 
186
        if (status != STAT_SUCCESS
 
187
            || response->errstat != SNMP_ERR_NOERROR) {
 
188
            fprintf(stderr,
 
189
                    "SNMP request failed after %d out of %d interfaces (IP)\n",
 
190
                    ifnum, cfg_nnets);
 
191
            if (snmp_get_do_debugging()) {
 
192
                fprintf(stderr,
 
193
                        "status = %d, errstat = %ld, errindex = %ld\n",
 
194
                        status, response->errstat, response->errindex);
 
195
            }
 
196
            cfg_nnets = ifnum;
 
197
            break;
 
198
        }
 
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);
 
202
            }
 
203
            switch (var->name[9]) {
 
204
            case IPIFINDEX:
 
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)) {
 
211
                    fprintf(stderr,
 
212
                            "Inconsistent reponse from server. Aborting.\n");
 
213
                    exit(0);
 
214
                }
 
215
                cur_if->ifindex = ifindex;
 
216
                break;
 
217
            case IPADDR:
 
218
                memmove(curifip, var->name + 10, sizeof(curifip));
 
219
                memmove(&cur_if->ifip, var->val.string, sizeof(u_long));
 
220
                break;
 
221
            case IPNETMASK:
 
222
                memmove(&cur_if->netmask, var->val.string, sizeof(u_long));
 
223
            }
 
224
        }
 
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));
 
229
        else
 
230
            strcpy(cur_if->route, "none");
 
231
        if ((i = strlen(cur_if->route)) > max_route)
 
232
            max_route = i;
 
233
        if (cur_if->ifip.s_addr)
 
234
            strcpy(cur_if->ip, routename(cur_if->ifip));
 
235
        else
 
236
            strcpy(cur_if->ip, "none");
 
237
        if ((i = strlen(cur_if->ip)) > max_ip)
 
238
            max_ip = i;
 
239
 
 
240
        snmp_free_pdu(response);
 
241
 
 
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);
 
247
 
 
248
        *instance = oldindex;
 
249
        *ifentry = IFINDEX;
 
250
        snmp_add_null_var(request, varname, varname_len);
 
251
        *ifentry = IFNAME;
 
252
        snmp_add_null_var(request, varname, varname_len);
 
253
        *ifentry = IFMTU;
 
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);
 
261
        *ifentry = INERRORS;
 
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);
 
269
        *ifentry = OUTQLEN;
 
270
        snmp_add_null_var(request, varname, varname_len);
 
271
 
 
272
        while ((status =
 
273
                snmp_synch_response(Session, request,
 
274
                                    &response)) == STAT_SUCCESS) {
 
275
            if (response->errstat != SNMP_ERR_NOSUCHNAME)
 
276
                break;
 
277
            if ((request =
 
278
                 snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) == NULL)
 
279
                break;
 
280
            snmp_free_pdu(response);
 
281
        }
 
282
        if (status != STAT_SUCCESS
 
283
            || response->errstat != SNMP_ERR_NOERROR) {
 
284
            fprintf(stderr,
 
285
                    "SNMP request failed after %d out of %d interfaces (IF)\n",
 
286
                    ifnum, cfg_nnets);
 
287
            cfg_nnets = ifnum;
 
288
            break;
 
289
        }
 
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);
 
294
            }
 
295
            if (!var->val.integer)
 
296
                continue;
 
297
            if (memcmp(var->name, oid_ifname, 8 * sizeof(oid)))
 
298
                continue;
 
299
            switch (var->name[9]) {
 
300
            case IFINDEX:
 
301
                ifindex = *var->val.integer;
 
302
                for (cur_if = if_table;
 
303
                     cur_if->ifindex != ifindex && cur_if->ifindex != 0;
 
304
                     cur_if++);
 
305
                if (cur_if >= (if_table + cfg_nnets)) {
 
306
                    fprintf(stderr,
 
307
                            "Inconsistent reponse from server. Aborting\n");
 
308
                    exit(0);
 
309
                }
 
310
                cur_if->ifindex = ifindex;
 
311
                break;
 
312
            case OUTQLEN:
 
313
                sprintf(cur_if->s_outq, "%lu", *var->val.integer);
 
314
                i = strlen(cur_if->s_outq);
 
315
                if (i > max_outq)
 
316
                    max_outq = i;
 
317
                break;
 
318
            case OUTERRORS:
 
319
                sprintf(cur_if->s_oerrs, "%lu", *var->val.integer);
 
320
                i = strlen(cur_if->s_oerrs);
 
321
                if (i > max_oerrs)
 
322
                    max_oerrs = i;
 
323
                break;
 
324
            case INERRORS:
 
325
                sprintf(cur_if->s_ierrs, "%lu", *var->val.integer);
 
326
                i = strlen(cur_if->s_ierrs);
 
327
                if (i > max_ierrs)
 
328
                    max_ierrs = i;
 
329
                break;
 
330
            case IFMTU:
 
331
                cur_if->mtu = *var->val.integer;
 
332
                break;
 
333
            case INUCASTPKTS:
 
334
                cur_if->ipkts += *var->val.integer;
 
335
                sprintf(cur_if->s_ipkts, "%lu", cur_if->ipkts);
 
336
                i = strlen(cur_if->s_ipkts);
 
337
                if (i > max_ipkts)
 
338
                    max_ipkts = i;
 
339
                break;
 
340
            case INNUCASTPKTS:
 
341
                cur_if->ipkts += *var->val.integer;
 
342
                sprintf(cur_if->s_ipkts, "%lu", cur_if->ipkts);
 
343
                i = strlen(cur_if->s_ipkts);
 
344
                if (i > max_ipkts)
 
345
                    max_ipkts = i;
 
346
                break;
 
347
            case OUTUCASTPKTS:
 
348
                cur_if->opkts += *var->val.integer;
 
349
                sprintf(cur_if->s_opkts, "%lu", cur_if->opkts);
 
350
                i = strlen(cur_if->s_opkts);
 
351
                if (i > max_opkts)
 
352
                    max_opkts = i;
 
353
                break;
 
354
            case OUTNUCASTPKTS:
 
355
                cur_if->opkts += *var->val.integer;
 
356
                sprintf(cur_if->s_opkts, "%lu", cur_if->opkts);
 
357
                i = strlen(cur_if->s_opkts);
 
358
                if (i > max_opkts)
 
359
                    max_opkts = i;
 
360
                break;
 
361
            case IFNAME:
 
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)
 
368
                    max_name = i;
 
369
                break;
 
370
            case IFOPERSTATUS:
 
371
                cur_if->operstatus = *var->val.integer;
 
372
                break;
 
373
            }
 
374
        }
 
375
 
 
376
        snmp_free_pdu(response);
 
377
 
 
378
        if (intrface != NULL && strcmp(cur_if->name, intrface) != 0) {
 
379
            cur_if->name[0] = 0;
 
380
            continue;
 
381
        }
 
382
        if (cur_if->operstatus != MIB_IFSTATUS_UP) {
 
383
            cp = strchr(cur_if->name, '\0');
 
384
            *cp++ = '*';
 
385
            *cp = '\0';
 
386
        }
 
387
    }
 
388
 
 
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",
 
393
           max_ipkts, "Ipkts",
 
394
           max_ierrs, "Ierrs",
 
395
           max_opkts, "Opkts", max_oerrs, "Oerrs", max_outq, "Queue");
 
396
    putchar('\n');
 
397
    for (ifnum = 0, cur_if = if_table; ifnum < cfg_nnets;
 
398
         ifnum++, cur_if++) {
 
399
        if (cur_if->name[0] == 0)
 
400
            continue;
 
401
        printf("%*.*s %5d ", -max_name, max_name, cur_if->name,
 
402
               cur_if->mtu);
 
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);
 
409
        putchar('\n');
 
410
    }
 
411
    free(if_table);
 
412
}
 
413
 
 
414
/*
 
415
 * Print a description of the network interfaces.
 
416
 */
 
417
void
 
418
intpro(int interval)
 
419
{
 
420
    oid             varname[MAX_OID_LEN], *instance, *ifentry;
 
421
    size_t          varname_len;
 
422
    int             ifnum, cfg_nnets;
 
423
    oid             curifip[4];
 
424
    netsnmp_variable_list *var;
 
425
    netsnmp_pdu    *request, *response;
 
426
    int             status;
 
427
    int             ifindex, oldindex = 0;
 
428
    struct _if_info {
 
429
        int             ifindex;
 
430
        char            name[128];
 
431
        char            ip[128], route[128];
 
432
        char            ioctets[20], ierrs[20], ooctets[20], oerrs[20],
 
433
            outqueue[20];
 
434
        int             operstatus;
 
435
        u_long          netmask;
 
436
        struct in_addr  ifip, ifroute;
 
437
    }              *if_table, *cur_if;
 
438
    int             max_name = 4, max_route = 7, max_ip = 7, max_ioctets =
 
439
        7, max_ooctets = 7;
 
440
    int             i;
 
441
 
 
442
    if (interval) {
 
443
        sidewaysintpr((unsigned) interval);
 
444
        return;
 
445
    }
 
446
    var =
 
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;
 
451
        snmp_free_var(var);
 
452
    } else {
 
453
        fprintf(stderr,
 
454
                "No response when requesting number of interfaces.\n");
 
455
        return;
 
456
    }
 
457
    DEBUGMSGTL(("netstat:if", "cfg_nnets = %d\n", cfg_nnets));
 
458
 
 
459
    memset(curifip, 0, sizeof(curifip));
 
460
    if_table = (struct _if_info *) calloc(cfg_nnets, sizeof(*if_table));
 
461
    cur_if = if_table;
 
462
 
 
463
    for (ifnum = 1; ifnum <= cfg_nnets; ifnum++) {
 
464
        register char  *cp;
 
465
 
 
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);
 
473
        *instance = IPADDR;
 
474
        snmp_add_null_var(request, varname, varname_len);
 
475
        *instance = IPNETMASK;
 
476
        snmp_add_null_var(request, varname, varname_len);
 
477
 
 
478
        status = snmp_synch_response(Session, request, &response);
 
479
        if (status != STAT_SUCCESS
 
480
            || response->errstat != SNMP_ERR_NOERROR) {
 
481
            fprintf(stderr,
 
482
                    "SNMP request failed for interface %d, variable %ld out of %d interfaces (IP)\n",
 
483
                    ifnum, response->errindex, cfg_nnets);
 
484
            cfg_nnets = ifnum;
 
485
            break;
 
486
        }
 
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);
 
490
            }
 
491
            switch (var->name[9]) {
 
492
            case IPIFINDEX:
 
493
                ifindex = *var->val.integer;
 
494
                for (cur_if = if_table;
 
495
                     cur_if->ifindex != ifindex && cur_if->ifindex != 0;
 
496
                     cur_if++);
 
497
                cur_if->ifindex = ifindex;
 
498
                break;
 
499
            case IPADDR:
 
500
                memmove(curifip, var->name + 10, sizeof(curifip));
 
501
                memmove(&cur_if->ifip, var->val.string, sizeof(u_long));
 
502
                break;
 
503
            case IPNETMASK:
 
504
                memmove(&cur_if->netmask, var->val.string, sizeof(u_long));
 
505
            }
 
506
        }
 
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));
 
511
        else
 
512
            strcpy(cur_if->route, "none");
 
513
        if ((i = strlen(cur_if->route)) > max_route)
 
514
            max_route = i;
 
515
        if (cur_if->ifip.s_addr)
 
516
            strcpy(cur_if->ip, routename(cur_if->ifip));
 
517
        else
 
518
            strcpy(cur_if->ip, "none");
 
519
        if ((i = strlen(cur_if->ip)) > max_ip)
 
520
            max_ip = i;
 
521
 
 
522
        snmp_free_pdu(response);
 
523
 
 
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);
 
529
 
 
530
        *instance = oldindex;
 
531
        *ifentry = IFINDEX;
 
532
        snmp_add_null_var(request, varname, varname_len);
 
533
        *ifentry = IFNAME;
 
534
        snmp_add_null_var(request, varname, varname_len);
 
535
        *ifentry = IFOPERSTATUS;
 
536
        snmp_add_null_var(request, varname, varname_len);
 
537
        *ifentry = INOCTETS;
 
538
        snmp_add_null_var(request, varname, varname_len);
 
539
        *ifentry = OUTOCTETS;
 
540
        snmp_add_null_var(request, varname, varname_len);
 
541
 
 
542
        while ((status =
 
543
                snmp_synch_response(Session, request,
 
544
                                    &response)) == STAT_SUCCESS) {
 
545
            if (response->errstat != SNMP_ERR_NOSUCHNAME)
 
546
                break;
 
547
            if ((request =
 
548
                 snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) == NULL)
 
549
                break;
 
550
            snmp_free_pdu(response);
 
551
        }
 
552
        if (status != STAT_SUCCESS
 
553
            || response->errstat != SNMP_ERR_NOERROR) {
 
554
            fprintf(stderr,
 
555
                    "SNMP request failed for interface %d, variable %ld out of %d interfaces (IF)\n",
 
556
                    ifnum, response->errindex, cfg_nnets);
 
557
            cfg_nnets = ifnum;
 
558
            break;
 
559
        }
 
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);
 
563
            }
 
564
            if (!var->val.integer)
 
565
                continue;
 
566
            switch (var->name[9]) {
 
567
            case IFINDEX:
 
568
                ifindex = *var->val.integer;
 
569
                for (cur_if = if_table;
 
570
                     cur_if->ifindex != ifindex && cur_if->ifindex != 0;
 
571
                     cur_if++);
 
572
                cur_if->ifindex = ifindex;
 
573
                break;
 
574
            case INOCTETS:
 
575
                sprintf(cur_if->ioctets, "%lu", *var->val.integer);
 
576
                i = strlen(cur_if->ioctets);
 
577
                if (i > max_ioctets)
 
578
                    max_ioctets = i;
 
579
                break;
 
580
            case OUTOCTETS:
 
581
                sprintf(cur_if->ooctets, "%lu", *var->val.integer);
 
582
                i = strlen(cur_if->ooctets);
 
583
                if (i > max_ooctets)
 
584
                    max_ooctets = i;
 
585
                break;
 
586
            case IFNAME:
 
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)
 
593
                    max_name = i;
 
594
                break;
 
595
            case IFOPERSTATUS:
 
596
                cur_if->operstatus = *var->val.integer;
 
597
                break;
 
598
            }
 
599
        }
 
600
 
 
601
        snmp_free_pdu(response);
 
602
 
 
603
        if (intrface != NULL && strcmp(cur_if->name, intrface) != 0) {
 
604
            cur_if->name[0] = 0;
 
605
            continue;
 
606
        }
 
607
        if (cur_if->operstatus != MIB_IFSTATUS_UP) {
 
608
            cp = strchr(cur_if->name, '\0');
 
609
            *cp++ = '*';
 
610
            *cp = '\0';
 
611
        }
 
612
    }
 
613
 
 
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");
 
620
    putchar('\n');
 
621
    for (ifnum = 0, cur_if = if_table; ifnum < cfg_nnets;
 
622
         ifnum++, cur_if++) {
 
623
        if (cur_if->name[0] == 0)
 
624
            continue;
 
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);
 
630
        putchar('\n');
 
631
    }
 
632
    free(if_table);
 
633
}
 
634
 
 
635
#define MAXIF   128
 
636
struct iftot {
 
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 */
 
643
} iftot[MAXIF];
 
644
 
 
645
u_char          signalled;      /* set if alarm goes off "early" */
 
646
 
 
647
/*
 
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.
 
651
 */
 
652
 
 
653
#if (defined(WIN32) || defined(cygwin))
 
654
static int      sav_int;
 
655
static time_t   timezup;
 
656
static void
 
657
timerSet(int interval_seconds)
 
658
{
 
659
    sav_int = interval_seconds;
 
660
    timezup = time(0) + interval_seconds;
 
661
}
 
662
 
 
663
/*
 
664
 * you can do better than this ! 
 
665
 */
 
666
static void
 
667
timerPause(void)
 
668
{
 
669
    time_t          now;
 
670
    while (time(&now) < timezup)
 
671
#ifdef WIN32
 
672
        Sleep(400);
 
673
#else
 
674
    {
 
675
        struct timeval  tx;
 
676
        tx.tv_sec = 0;
 
677
        tx.tv_usec = 400 * 1000;        /* 400 milliseconds */
 
678
        select(0, 0, 0, 0, &tx);
 
679
    }
 
680
#endif
 
681
}
 
682
 
 
683
#else
 
684
 
 
685
/*
 
686
 * Called if an interval expires before sidewaysintpr has completed a loop.
 
687
 * Sets a flag to not wait for the alarm.
 
688
 */
 
689
RETSIGTYPE
 
690
catchalarm(int sig)
 
691
{
 
692
    signalled = YES;
 
693
}
 
694
 
 
695
static void
 
696
timerSet(int interval_seconds)
 
697
{
 
698
#ifdef HAVE_SIGSET
 
699
    (void) sigset(SIGALRM, catchalarm);
 
700
#else
 
701
    (void) signal(SIGALRM, catchalarm);
 
702
#endif
 
703
    signalled = NO;
 
704
    (void) alarm(interval_seconds);
 
705
}
 
706
 
 
707
static void
 
708
timerPause(void)
 
709
{
 
710
#ifdef HAVE_SIGHOLD
 
711
    sighold(SIGALRM);
 
712
    if (!signalled) {
 
713
        sigpause(SIGALRM);
 
714
    }
 
715
#else
 
716
    int             oldmask;
 
717
    oldmask = sigblock(sigmask(SIGALRM));
 
718
    if (!signalled) {
 
719
        sigpause(0);
 
720
    }
 
721
    sigsetmask(oldmask);
 
722
#endif
 
723
}
 
724
 
 
725
#endif                          /* !WIN32 && !cygwin */
 
726
 
 
727
/*
 
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.
 
732
 */
 
733
static void
 
734
sidewaysintpr(unsigned int interval)
 
735
{
 
736
    register struct iftot *ip, *total;
 
737
    register int    line;
 
738
    struct iftot   *lastif, *sum, *interesting, ifnow, *now = &ifnow;
 
739
    netsnmp_variable_list *var;
 
740
    oid             varname[MAX_OID_LEN], *instance, *ifentry;
 
741
    size_t          varname_len;
 
742
    int             ifnum, cfg_nnets;
 
743
 
 
744
    lastif = iftot;
 
745
    sum = iftot + MAXIF - 1;
 
746
    total = sum - 1;
 
747
    interesting = iftot;
 
748
    var =
 
749
        getvarbyname(Session, oid_cfg_nnets,
 
750
                     sizeof(oid_cfg_nnets) / sizeof(oid));
 
751
    if (var) {
 
752
        cfg_nnets = *var->val.integer;
 
753
        snmp_free_var(var);
 
754
    } else
 
755
        return;
 
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++) {
 
759
        char           *cp;
 
760
 
 
761
        ip->ift_name[0] = '(';
 
762
        varname[10] = ifnum;
 
763
        var = getvarbyname(Session, varname, varname_len);
 
764
        if (var) {
 
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);
 
768
            snmp_free_var(var);
 
769
        }
 
770
        cp = (char *) strchr(ip->ift_name, ' ');
 
771
        if (cp != NULL)
 
772
            *cp = '\0';
 
773
        if (intrface && strcmp(ip->ift_name + 1, intrface) == 0)
 
774
            interesting = ip;
 
775
        ip->ift_name[15] = '\0';
 
776
        cp = (char *) strchr(ip->ift_name, '\0');
 
777
        sprintf(cp, ")");
 
778
        ip++;
 
779
        if (ip >= iftot + MAXIF - 2)
 
780
            break;
 
781
    }
 
782
    lastif = ip;
 
783
 
 
784
    timerSet(interval);
 
785
 
 
786
  banner:
 
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++) {
 
791
        ip->ift_ip = 0;
 
792
        ip->ift_ie = 0;
 
793
        ip->ift_op = 0;
 
794
        ip->ift_oe = 0;
 
795
        ip->ift_co = 0;
 
796
    }
 
797
    putchar('\n');
 
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");
 
803
    putchar('\n');
 
804
    fflush(stdout);
 
805
    line = 0;
 
806
  loop:
 
807
    sum->ift_ip = 0;
 
808
    sum->ift_ie = 0;
 
809
    sum->ift_op = 0;
 
810
    sum->ift_oe = 0;
 
811
    sum->ift_co = 0;
 
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;
 
817
         ip++, ifnum++) {
 
818
        memset(now, 0, sizeof(*now));
 
819
        *instance = ifnum;
 
820
        *ifentry = INUCASTPKTS;
 
821
        var = getvarbyname(Session, varname, varname_len);
 
822
        if (var) {
 
823
            now->ift_ip = *var->val.integer;
 
824
            snmp_free_var(var);
 
825
        }
 
826
        *ifentry = INNUCASTPKTS;
 
827
        var = getvarbyname(Session, varname, varname_len);
 
828
        if (var) {
 
829
            now->ift_ip += *var->val.integer;
 
830
            snmp_free_var(var);
 
831
        }
 
832
        *ifentry = INERRORS;
 
833
        var = getvarbyname(Session, varname, varname_len);
 
834
        if (var) {
 
835
            now->ift_ie = *var->val.integer;
 
836
            snmp_free_var(var);
 
837
        }
 
838
        *ifentry = OUTUCASTPKTS;
 
839
        var = getvarbyname(Session, varname, varname_len);
 
840
        if (var) {
 
841
            now->ift_op = *var->val.integer;
 
842
            snmp_free_var(var);
 
843
        }
 
844
        *ifentry = OUTNUCASTPKTS;
 
845
        var = getvarbyname(Session, varname, varname_len);
 
846
        if (var) {
 
847
            now->ift_op += *var->val.integer;
 
848
            snmp_free_var(var);
 
849
        }
 
850
        *ifentry = OUTERRORS;
 
851
        var = getvarbyname(Session, varname, varname_len);
 
852
        if (var) {
 
853
            now->ift_oe = *var->val.integer;
 
854
            snmp_free_var(var);
 
855
        }
 
856
 
 
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;
 
873
    }
 
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);
 
880
    *total = *sum;
 
881
    putchar('\n');
 
882
    fflush(stdout);
 
883
    line++;
 
884
 
 
885
    timerPause();
 
886
    timerSet(interval);
 
887
 
 
888
    if (line == 21)
 
889
        goto banner;
 
890
    goto loop;
 
891
 /*NOTREACHED*/}