~ubuntu-branches/ubuntu/wily/net-snmp/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/02_statistics.patch/agent/mibgroup/mibII/interfaces.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2010-06-28 14:59:36 UTC
  • mfrom: (1.2.3 upstream) (1.1.12 sid)
  • Revision ID: james.westby@ubuntu.com-20100628145936-cbiallic69pn044g
Tags: 5.4.3~dfsg-1ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Set Ubuntu maintainer address.
  - net-snmp-config: Use bash. (LP: #104738)
  - Removed multiuser option when calling update-rc.d. (LP: #254261)
  - debian/snmpd.init: LSBify the init script.
  - debian/patches/52_fix_snmpcmd_1_typo.patch: Adjust a typo in snmpcmd.1
    (LP: #250459)
  - debian/snmpd.postinst: source debconf before doing work, LP: #589056
  - debian/snmp.preinst, debian/snmp.prerm: kill any/all processes owned by
    snmp user before install/uninstall, LP: #573391
  - Add apport hook (LP: #533603):
  - debian/{snmp,snmpd}.apport: Added.
  - debian/control: Build-depends on dh-apport.
  - debian/rules: 
    + Add --with apport.
    + override_dh_apport to install hook on snmpd package only.
 * Dropped patches:
   - debian/patches/99-fix-ubuntu-div0.patch: Fix dvision by zero.. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Interfaces MIB group implementation - interfaces.c
 
3
 *
 
4
 */
 
5
 
 
6
/* Portions of this file are subject to the following copyright(s).  See
 
7
 * the Net-SNMP's COPYING file for more details and other copyrights
 
8
 * that may apply:
 
9
 */
 
10
/*
 
11
 * Portions of this file are copyrighted by:
 
12
 * Copyright � 2003 Sun Microsystems, Inc. All rights reserved.
 
13
 * Use is subject to license terms specified in the COPYING file
 
14
 * distributed with the Net-SNMP package.
 
15
 */
 
16
 
 
17
#include <net-snmp/net-snmp-config.h>
 
18
 
 
19
#if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL) && !defined(IFNET_NEEDS_KERNEL_LATE)
 
20
#define _KERNEL 1
 
21
#define _I_DEFINED_KERNEL
 
22
#endif
 
23
 
 
24
#if HAVE_STRING_H
 
25
#include <string.h>
 
26
#else
 
27
#include <strings.h>
 
28
#endif
 
29
 
 
30
#if HAVE_STDLIB_H
 
31
#include <stdlib.h>
 
32
#endif
 
33
#if HAVE_UNISTD_H
 
34
#include <unistd.h>
 
35
#endif
 
36
#if HAVE_SYS_PARAM_H
 
37
#include <sys/param.h>
 
38
#endif
 
39
#include <sys/types.h>
 
40
#if HAVE_WINSOCK_H
 
41
#include <winsock.h>
 
42
#endif
 
43
#if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL) && defined(IFNET_NEEDS_KERNEL_LATE)
 
44
#define _KERNEL 1
 
45
#define _I_DEFINED_KERNEL
 
46
#endif
 
47
#if HAVE_SYS_SOCKET_H
 
48
#include <sys/socket.h>
 
49
#endif
 
50
#ifndef STREAM_NEEDS_KERNEL_ISLANDS
 
51
#if HAVE_SYS_STREAM_H
 
52
#include <sys/stream.h>
 
53
#endif
 
54
#endif
 
55
#if HAVE_SYS_SOCKETVAR_H
 
56
#include <sys/socketvar.h>
 
57
#endif
 
58
 
 
59
#if TIME_WITH_SYS_TIME
 
60
# if defined (WIN32) || defined (cygwin)
 
61
#  include <sys/timeb.h>
 
62
# else
 
63
# include <sys/time.h>
 
64
# endif
 
65
# include <time.h>
 
66
#else
 
67
# if HAVE_SYS_TIME_H
 
68
#  include <sys/time.h>
 
69
# else
 
70
#  include <time.h>
 
71
# endif
 
72
#endif
 
73
#if HAVE_SYS_SOCKIO_H
 
74
#include <sys/sockio.h>
 
75
#endif
 
76
#if HAVE_FCNTL_H
 
77
#include <fcntl.h>
 
78
#endif
 
79
#if HAVE_SYS_IOCTL_H
 
80
#include <sys/ioctl.h>
 
81
#endif
 
82
#if HAVE_NETINET_IN_H
 
83
#include <netinet/in.h>
 
84
#endif
 
85
#if HAVE_NET_IF_H
 
86
#include <net/if.h>
 
87
#endif
 
88
#if HAVE_NETINET_IN_VAR_H
 
89
#include <netinet/in_var.h>
 
90
#endif
 
91
#if HAVE_NET_IF_VAR_H
 
92
#include <net/if_var.h>
 
93
#endif
 
94
#ifdef _I_DEFINED_KERNEL
 
95
#undef _KERNEL
 
96
#endif
 
97
#ifdef STREAM_NEEDS_KERNEL_ISLANDS
 
98
#if HAVE_SYS_STREAM_H
 
99
#include <sys/stream.h>
 
100
#endif
 
101
#endif
 
102
#if HAVE_NET_ROUTE_H
 
103
#include <net/route.h>
 
104
#endif
 
105
#if HAVE_NETINET_IN_SYSTM_H
 
106
#include <netinet/in_systm.h>
 
107
#endif
 
108
#if HAVE_SYS_HASHING_H
 
109
#include <sys/hashing.h>
 
110
#endif
 
111
#if HAVE_NETINET_IN_VAR_H
 
112
#include <netinet/in_var.h>
 
113
#endif
 
114
#if HAVE_NETINET_IP_H
 
115
#include <netinet/ip.h>
 
116
#endif
 
117
#ifdef NETSNMP_ENABLE_IPV6
 
118
#if HAVE_NETINET_IP6_H
 
119
#include <netinet/ip6.h>
 
120
#endif
 
121
#endif
 
122
#if HAVE_SYS_QUEUE_H
 
123
#include <sys/queue.h>
 
124
#endif
 
125
#if HAVE_NETINET_IP_VAR_H
 
126
#include <netinet/ip_var.h>
 
127
#endif
 
128
#ifdef NETSNMP_ENABLE_IPV6
 
129
#if HAVE_NETNETSNMP_ENABLE_IPV6_IP6_VAR_H
 
130
#include <netinet6/ip6_var.h>
 
131
#endif
 
132
#endif
 
133
#if HAVE_NETINET_IN_PCB_H
 
134
#include <netinet/in_pcb.h>
 
135
#endif
 
136
#if HAVE_NETINET_IF_ETHER_H
 
137
#include <netinet/if_ether.h>
 
138
#endif
 
139
#if HAVE_NET_IF_TYPES_H
 
140
#include <net/if_types.h>
 
141
#endif
 
142
#if HAVE_NET_IF_DL_H
 
143
#ifndef dynix
 
144
#include <net/if_dl.h>
 
145
#else
 
146
#include <sys/net/if_dl.h>
 
147
#endif
 
148
#endif
 
149
#if HAVE_INET_MIB2_H
 
150
#include <inet/mib2.h>
 
151
#endif
 
152
#if HAVE_IOCTLS_H
 
153
#include <ioctls.h>
 
154
#endif
 
155
 
 
156
#ifdef solaris2
 
157
# include <errno.h>
 
158
#include "kernel_sunos5.h"
 
159
#else
 
160
#include "kernel.h"
 
161
#endif
 
162
 
 
163
#ifdef hpux
 
164
#include <sys/mib.h>
 
165
#include <netinet/mib_kern.h>
 
166
#endif                          /* hpux */
 
167
 
 
168
#ifdef cygwin
 
169
#include <windows.h>
 
170
#endif
 
171
 
 
172
#if HAVE_SYS_SYSCTL_H
 
173
#include <sys/sysctl.h>
 
174
 
 
175
#if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
 
176
#    define USE_SYSCTL_IFLIST
 
177
#else
 
178
# if defined(CTL_NET) && !defined(freebsd2) && !defined(netbsd1)
 
179
#  ifdef PF_ROUTE
 
180
#   ifdef NET_RT_IFLIST
 
181
#    ifndef netbsd1
 
182
#     define USE_SYSCTL_IFLIST
 
183
#    endif
 
184
#   endif
 
185
#  endif
 
186
# endif
 
187
#endif                          /* defined(freebsd3) */
 
188
#endif                          /* HAVE_SYS_SYSCTL_H */
 
189
 
 
190
#if HAVE_OSRELDATE_H
 
191
#include <osreldate.h>
 
192
#endif
 
193
#ifdef NETSNMP_CAN_USE_SYSCTL
 
194
#include <sys/sysctl.h>
 
195
#endif
 
196
 
 
197
#include <net-snmp/net-snmp-includes.h>
 
198
#include <net-snmp/agent/net-snmp-agent-includes.h>
 
199
#include <net-snmp/agent/auto_nlist.h>
 
200
#include <net-snmp/data_access/interface.h>
 
201
 
 
202
#include "interfaces.h"
 
203
#include "struct.h"
 
204
#include "util_funcs.h"
 
205
#include "sysORTable.h"
 
206
 
 
207
/* if you want caching enabled for speed retrival purposes, set this to 5?*/
 
208
#define MINLOADFREQ 0                     /* min reload frequency in seconds */
 
209
#ifdef linux
 
210
static unsigned long LastLoad = 0;        /* ET in secs at last table load */
 
211
#endif
 
212
 
 
213
extern struct timeval starttime;
 
214
 
 
215
struct variable3 interfaces_variables[] = {
 
216
    {IFNUMBER, ASN_INTEGER, RONLY, var_interfaces, 1, {1}},
 
217
    {IFINDEX, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 1}},
 
218
    {IFDESCR, ASN_OCTET_STR, RONLY, var_ifEntry, 3, {2, 1, 2}},
 
219
    {NETSNMP_IFTYPE, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 3}},
 
220
    {IFMTU, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 4}},
 
221
    {IFSPEED, ASN_GAUGE, RONLY, var_ifEntry, 3, {2, 1, 5}},
 
222
    {IFPHYSADDRESS, ASN_OCTET_STR, RONLY, var_ifEntry, 3, {2, 1, 6}},
 
223
#if defined (WIN32) || defined (cygwin)
 
224
    {IFADMINSTATUS, ASN_INTEGER, RWRITE, var_ifEntry, 3, {2, 1, 7}},
 
225
#else
 
226
    {IFADMINSTATUS, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 7}},
 
227
#endif
 
228
    {IFOPERSTATUS, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 8}},
 
229
    {IFLASTCHANGE, ASN_TIMETICKS, RONLY, var_ifEntry, 3, {2, 1, 9}},
 
230
    {IFINOCTETS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 10}},
 
231
    {IFINUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 11}},
 
232
    {IFINNUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 12}},
 
233
    {IFINDISCARDS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 13}},
 
234
    {IFINERRORS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 14}},
 
235
    {IFINUNKNOWNPROTOS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 15}},
 
236
    {IFOUTOCTETS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 16}},
 
237
    {IFOUTUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 17}},
 
238
    {IFOUTNUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 18}},
 
239
    {IFOUTDISCARDS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 19}},
 
240
    {IFOUTERRORS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 20}},
 
241
    {IFOUTQLEN, ASN_GAUGE, RONLY, var_ifEntry, 3, {2, 1, 21}},
 
242
    {IFSPECIFIC, ASN_OBJECT_ID, RONLY, var_ifEntry, 3, {2, 1, 22}}
 
243
};
 
244
 
 
245
/*
 
246
 * Define the OID pointer to the top of the mib tree that we're
 
247
 * registering underneath, and the OID of the MIB module 
 
248
 */
 
249
oid             interfaces_variables_oid[] = { SNMP_OID_MIB2, 2 };
 
250
oid             interfaces_module_oid[] = { SNMP_OID_MIB2, 31 };
 
251
 
 
252
void
 
253
init_interfaces(void)
 
254
{
 
255
    /*
 
256
     * register ourselves with the agent to handle our mib tree 
 
257
     */
 
258
    REGISTER_MIB("mibII/interfaces", interfaces_variables, variable3,
 
259
                 interfaces_variables_oid);
 
260
    REGISTER_SYSOR_ENTRY(interfaces_module_oid,
 
261
                         "The MIB module to describe generic objects for network interface sub-layers");
 
262
 
 
263
#ifndef USE_SYSCTL_IFLIST
 
264
#if HAVE_NET_IF_MIB_H
 
265
    init_interfaces_setup();
 
266
#endif
 
267
#endif
 
268
#ifdef solaris2
 
269
    init_kernel_sunos5();
 
270
#endif
 
271
}
 
272
 
 
273
#ifdef linux
 
274
/*
 
275
 * if_type_from_name
 
276
 * Return interface type using the interface name as a clue.
 
277
 * Returns 1 to imply "other" type if name not recognized. 
 
278
 */
 
279
static int
 
280
if_type_from_name(const char *pcch)
 
281
{
 
282
    typedef struct _match_if {
 
283
        int             mi_type;
 
284
        const char     *mi_name;
 
285
    }              *pmatch_if, match_if;
 
286
 
 
287
    static match_if lmatch_if[] = {
 
288
        {24, "lo"},
 
289
        {6, "eth"},
 
290
        {9, "tr"},
 
291
        {23, "ppp"},
 
292
        {28, "sl"},
 
293
        {0, 0}                  /* end of list */
 
294
    };
 
295
 
 
296
    int             ii, len;
 
297
    register pmatch_if pm;
 
298
 
 
299
    for (ii = 0, pm = lmatch_if; pm->mi_name; pm++) {
 
300
        len = strlen(pm->mi_name);
 
301
        if (0 == strncmp(pcch, pm->mi_name, len)) {
 
302
            return (pm->mi_type);
 
303
        }
 
304
    }
 
305
    return (1);                 /* in case search fails */
 
306
}
 
307
#endif
 
308
 
 
309
 
 
310
#ifdef linux
 
311
static struct ifnet *ifnetaddr_list;
 
312
#endif
 
313
 
 
314
 
 
315
/*
 
316
 * header_ifEntry(...
 
317
 * Arguments:
 
318
 * vp     IN      - pointer to variable entry that points here
 
319
 * name    IN/OUT  - IN/name requested, OUT/name found
 
320
 * length  IN/OUT  - length of IN/OUT oid's 
 
321
 * exact   IN      - TRUE if an exact match was requested
 
322
 * var_len OUT     - length of variable or 0 if function returned
 
323
 * write_method
 
324
 * 
 
325
 */
 
326
#if !defined (WIN32) && !defined (cygwin)
 
327
static int
 
328
header_ifEntry(struct variable *vp,
 
329
               oid * name,
 
330
               size_t * length,
 
331
               int exact, size_t * var_len, WriteMethod ** write_method)
 
332
{
 
333
#define IFENTRY_NAME_LENGTH     10
 
334
    oid             newname[MAX_OID_LEN];
 
335
    register int    interface;
 
336
    int             result, count;
 
337
 
 
338
    DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: "));
 
339
    DEBUGMSGOID(("mibII/interfaces", name, *length));
 
340
    DEBUGMSG(("mibII/interfaces", " %d\n", exact));
 
341
 
 
342
    memcpy((char *) newname, (char *) vp->name,
 
343
           (int) vp->namelen * sizeof(oid));
 
344
    /*
 
345
     * find "next" interface 
 
346
     */
 
347
    count = Interface_Scan_Get_Count();
 
348
    for (interface = 1; interface <= count; interface++) {
 
349
        newname[IFENTRY_NAME_LENGTH] = (oid) interface;
 
350
        result =
 
351
            snmp_oid_compare(name, *length, newname,
 
352
                             (int) vp->namelen + 1);
 
353
        if ((exact && (result == 0)) || (!exact && (result < 0)))
 
354
            break;
 
355
    }
 
356
    if (interface > count) {
 
357
        DEBUGMSGTL(("mibII/interfaces", "... index out of range\n"));
 
358
        return MATCH_FAILED;
 
359
    }
 
360
 
 
361
 
 
362
    memcpy((char *) name, (char *) newname,
 
363
           ((int) vp->namelen + 1) * sizeof(oid));
 
364
    *length = vp->namelen + 1;
 
365
    *write_method = 0;
 
366
    *var_len = sizeof(long);    /* default to 'long' results */
 
367
 
 
368
    DEBUGMSGTL(("mibII/interfaces", "... get I/F stats "));
 
369
    DEBUGMSGOID(("mibII/interfaces", name, *length));
 
370
    DEBUGMSG(("mibII/interfaces", "\n"));
 
371
 
 
372
    return interface;
 
373
}
 
374
 
 
375
 
 
376
 
 
377
u_char         *
 
378
var_interfaces(struct variable * vp,
 
379
               oid * name,
 
380
               size_t * length,
 
381
               int exact, size_t * var_len, WriteMethod ** write_method)
 
382
{
 
383
    if (header_generic(vp, name, length, exact, var_len, write_method) ==
 
384
        MATCH_FAILED)
 
385
        return NULL;
 
386
 
 
387
    switch (vp->magic) {
 
388
    case IFNUMBER:
 
389
        long_return = Interface_Scan_Get_Count();
 
390
        return (u_char *) & long_return;
 
391
    default:
 
392
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n",
 
393
                    vp->magic));
 
394
    }
 
395
    return NULL;
 
396
}
 
397
 
 
398
#ifdef USE_SYSCTL_IFLIST
 
399
 
 
400
static u_char  *if_list = 0;
 
401
static const u_char *if_list_end;
 
402
static size_t   if_list_size = 0;
 
403
 
 
404
struct small_ifaddr {
 
405
    struct in_addr  sifa_addr;
 
406
    struct in_addr  sifa_netmask;
 
407
    struct in_addr  sifa_broadcast;
 
408
};
 
409
 
 
410
extern const struct sockaddr *get_address(const void *, int, int);
 
411
extern const struct in_addr *get_in_address(const void *, int, int);
 
412
static int      Interface_Scan_By_Index(int, struct if_msghdr *, char *,
 
413
                                        struct small_ifaddr *);
 
414
static int      Interface_Get_Ether_By_Index(int, u_char *);
 
415
 
 
416
static int
 
417
Interface_Scan_By_Index(int iindex,
 
418
                        struct if_msghdr *if_msg,
 
419
                        char *if_name, struct small_ifaddr *sifa)
 
420
{
 
421
    u_char         *cp;
 
422
    struct if_msghdr *ifp;
 
423
    int             have_ifinfo = 0, have_addr = 0;
 
424
 
 
425
    if (NULL != sifa)
 
426
        memset(sifa, 0, sizeof(*sifa));
 
427
    for (cp = if_list; cp < if_list_end; cp += ifp->ifm_msglen) {
 
428
        ifp = (struct if_msghdr *) cp;
 
429
        DEBUGMSGTL(("mibII/interfaces", "ifm_type = %d, ifm_index = %d\n",
 
430
                    ifp->ifm_type, ifp->ifm_index));
 
431
 
 
432
        switch (ifp->ifm_type) {
 
433
        case RTM_IFINFO:
 
434
            {
 
435
                const struct sockaddr *a;
 
436
 
 
437
                if (ifp->ifm_index == iindex) {
 
438
                    a = get_address(ifp + 1, ifp->ifm_addrs, RTA_IFP);
 
439
                    if (a == NULL)
 
440
                        return 0;
 
441
                    strncpy(if_name,
 
442
                            ((const struct sockaddr_in *) a)->sin_zero,
 
443
                            ((const u_char *) a)[5]);
 
444
                    if_name[((const u_char *) a)[5]] = 0;
 
445
                    *if_msg = *ifp;
 
446
                    ++have_ifinfo;
 
447
                }
 
448
            }
 
449
            break;
 
450
        case RTM_NEWADDR:
 
451
            {
 
452
                struct ifa_msghdr *ifap = (struct ifa_msghdr *) cp;
 
453
 
 
454
                if ((NULL != sifa) && (ifap->ifam_index == iindex)) {
 
455
                    const struct in_addr *ia;
 
456
 
 
457
                    /*
 
458
                     * I don't know why the normal get_address() doesn't
 
459
                     * work on IRIX 6.2.  Maybe this has to do with the
 
460
                     * existence of struct sockaddr_new.  Hopefully, on
 
461
                     * other systems we can simply use get_in_address
 
462
                     * three times, with (ifap+1) as the starting
 
463
                     * address. 
 
464
                     */
 
465
 
 
466
                    sifa->sifa_netmask =
 
467
                        *((struct in_addr *) ((char *) (ifap + 1) + 4));
 
468
                    ia = get_in_address((char *) (ifap + 1) + 8,
 
469
                                        ifap->ifam_addrs &=
 
470
                                        ~RTA_NETMASK, RTA_IFA);
 
471
                    if (ia == NULL)
 
472
                        return 0;
 
473
 
 
474
                    sifa->sifa_addr = *ia;
 
475
                    ia = get_in_address((char *) (ifap + 1) + 8,
 
476
                                        ifap->ifam_addrs &= ~RTA_NETMASK,
 
477
                                        RTA_BRD);
 
478
                    if (ia == NULL)
 
479
                        return 0;
 
480
 
 
481
                    sifa->sifa_broadcast = *ia;
 
482
                    ++have_addr;
 
483
                }
 
484
            }
 
485
            break;
 
486
        default:
 
487
            DEBUGMSGTL(("mibII/interfaces",
 
488
                        "routing socket: unknown message type %d\n",
 
489
                        ifp->ifm_type));
 
490
        }
 
491
    }
 
492
    if (have_ifinfo && (NULL == sifa) || (have_addr)) {
 
493
        return 0;
 
494
    } else if (have_ifinfo && !(if_msg->ifm_flags & IFF_UP))
 
495
        return 0;
 
496
    else {
 
497
        return -1;
 
498
    }
 
499
}
 
500
 
 
501
int
 
502
Interface_Scan_Get_Count(void)
 
503
{
 
504
    u_char         *cp;
 
505
    struct if_msghdr *ifp;
 
506
    long            n = 0;
 
507
 
 
508
    Interface_Scan_Init();
 
509
 
 
510
    if (if_list_size) {
 
511
        for (cp = if_list, n = 0; cp < if_list_end; cp += ifp->ifm_msglen) {
 
512
            ifp = (struct if_msghdr *) cp;
 
513
    
 
514
            if (ifp->ifm_type == RTM_IFINFO) {
 
515
                ++n;
 
516
            }
 
517
        }
 
518
    }
 
519
    return n;
 
520
}
 
521
 
 
522
void
 
523
Interface_Scan_Init(void)
 
524
{
 
525
    int             name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
 
526
    size_t          size;
 
527
 
 
528
    if (sysctl(name, sizeof(name) / sizeof(int), 0, &size, 0, 0) == -1) {
 
529
        snmp_log(LOG_ERR, "sysctl size fail\n");
 
530
    } else {
 
531
        if (if_list == 0 || if_list_size < size) {
 
532
            if (if_list != 0) {
 
533
                free(if_list);
 
534
            }
 
535
            if_list      = NULL;
 
536
            if_list_size = 0;
 
537
            if_list_end  = 0;
 
538
            if ((if_list = malloc(size)) == NULL) {
 
539
                snmp_log(LOG_ERR,
 
540
                         "out of memory allocating route table (size = %d)\n", size);
 
541
                return;
 
542
            }
 
543
            if_list_size = size;
 
544
        } else {
 
545
            size = if_list_size;
 
546
        }
 
547
        if (sysctl(name, sizeof(name) / sizeof(int),
 
548
                   if_list, &size, 0, 0) == -1) {
 
549
            snmp_log(LOG_ERR, "sysctl get fail\n");
 
550
        }
 
551
        if_list_end = if_list + size;
 
552
    }
 
553
}
 
554
 
 
555
u_char         *
 
556
var_ifEntry(struct variable *vp,
 
557
            oid * name,
 
558
            size_t * length,
 
559
            int exact, size_t * var_len, WriteMethod ** write_method)
 
560
{
 
561
    int             interface;
 
562
    struct if_msghdr if_msg;
 
563
    static char     if_name[100];
 
564
    conf_if_list   *if_ptr;
 
565
    char           *cp;
 
566
 
 
567
    interface =
 
568
        header_ifEntry(vp, name, length, exact, var_len, write_method);
 
569
    if (interface == MATCH_FAILED)
 
570
        return NULL;
 
571
 
 
572
    if (Interface_Scan_By_Index(interface, &if_msg, if_name, NULL) != 0)
 
573
        return NULL;
 
574
    if_ptr = netsnmp_access_interface_entry_overrides_get(if_name);
 
575
 
 
576
    switch (vp->magic) {
 
577
    case IFINDEX:
 
578
        long_return = interface;
 
579
        return (u_char *) & long_return;
 
580
    case IFDESCR:
 
581
        cp = if_name;
 
582
        *var_len = strlen(if_name);
 
583
        return (u_char *) cp;
 
584
    case NETSNMP_IFTYPE:
 
585
        if (if_ptr)
 
586
            long_return = if_ptr->type;
 
587
        else
 
588
        long_return = (long) if_msg.ifm_data.ifi_type;
 
589
        return (u_char *) & long_return;
 
590
    case IFMTU:
 
591
        long_return = (long) if_msg.ifm_data.ifi_mtu;
 
592
        return (u_char *) & long_return;
 
593
    case IFSPEED:
 
594
        if (if_ptr)
 
595
            long_return = if_ptr->speed;
 
596
        else {
 
597
#if STRUCT_IFNET_HAS_IF_BAUDRATE_IFS_VALUE
 
598
        long_return = (u_long) if_msg.ifm_data.ifi_baudrate.ifs_value <<
 
599
            if_msg.ifm_data.ifi_baudrate.ifs_log2;
 
600
#else
 
601
        long_return = (u_long) if_msg.ifm_data.ifi_baudrate;
 
602
#endif
 
603
        }
 
604
        return (u_char *) & long_return;
 
605
    case IFPHYSADDRESS:
 
606
        /*
 
607
         * XXX 
 
608
         */
 
609
        return NULL;
 
610
    case IFADMINSTATUS:
 
611
        long_return = if_msg.ifm_flags & IFF_UP ? 1 : 2;
 
612
        return (u_char *) & long_return;
 
613
    case IFOPERSTATUS:
 
614
        long_return = if_msg.ifm_flags & IFF_RUNNING ? 1 : 2;
 
615
        return (u_char *) & long_return;
 
616
        /*
 
617
         * ifLastChange 
 
618
         */
 
619
    case IFINOCTETS:
 
620
        long_return = (u_long) if_msg.ifm_data.ifi_ibytes;
 
621
        return (u_char *) & long_return;
 
622
    case IFINUCASTPKTS:
 
623
        long_return =
 
624
            (u_long) if_msg.ifm_data.ifi_ipackets -
 
625
            if_msg.ifm_data.ifi_imcasts;
 
626
        return (u_char *) & long_return;
 
627
    case IFINNUCASTPKTS:
 
628
        long_return = (u_long) if_msg.ifm_data.ifi_imcasts;
 
629
        return (u_char *) & long_return;
 
630
    case IFINDISCARDS:
 
631
        long_return = (u_long) if_msg.ifm_data.ifi_iqdrops;
 
632
        return (u_char *) & long_return;
 
633
    case IFINERRORS:
 
634
        long_return = (u_long) if_msg.ifm_data.ifi_ierrors;
 
635
        return (u_char *) & long_return;
 
636
    case IFINUNKNOWNPROTOS:
 
637
        long_return = (u_long) if_msg.ifm_data.ifi_noproto;
 
638
        return (u_char *) & long_return;
 
639
    case IFOUTOCTETS:
 
640
        long_return = (u_long) if_msg.ifm_data.ifi_obytes;
 
641
        return (u_char *) & long_return;
 
642
    case IFOUTUCASTPKTS:
 
643
        long_return =
 
644
            (u_long) if_msg.ifm_data.ifi_opackets -
 
645
            if_msg.ifm_data.ifi_omcasts;
 
646
        return (u_char *) & long_return;
 
647
    case IFOUTNUCASTPKTS:
 
648
        long_return = (u_long) if_msg.ifm_data.ifi_omcasts;
 
649
        return (u_char *) & long_return;
 
650
    case IFOUTDISCARDS:
 
651
#ifdef if_odrops
 
652
        long_return = (u_long) if_msg.ifm_data.ifi_odrops;
 
653
#else
 
654
#if NETSNMP_NO_DUMMY_VALUES
 
655
        return NULL;
 
656
#endif
 
657
        long_return = 0;
 
658
#endif
 
659
        return (u_char *) & long_return;
 
660
    case IFOUTERRORS:
 
661
        long_return = (u_long) if_msg.ifm_data.ifi_oerrors;
 
662
        return (u_char *) & long_return;
 
663
    case IFLASTCHANGE:
 
664
#ifdef irix6
 
665
        long_return = 0;
 
666
#else
 
667
        if (if_msg.ifm_data.ifi_lastchange.tv_sec == 0 &&
 
668
            if_msg.ifm_data.ifi_lastchange.tv_usec == 0)
 
669
            long_return = 0;
 
670
        else if (if_msg.ifm_data.ifi_lastchange.tv_sec < starttime.tv_sec)
 
671
            long_return = 0;
 
672
        else {
 
673
            long_return = (u_long)
 
674
                ((if_msg.ifm_data.ifi_lastchange.tv_sec -
 
675
                  starttime.tv_sec) * 100 +
 
676
                 (if_msg.ifm_data.ifi_lastchange.tv_usec -
 
677
                  starttime.tv_usec) / 10000);
 
678
        }
 
679
#endif
 
680
        return (u_char *) & long_return;
 
681
    default:
 
682
        return 0;
 
683
    }
 
684
}
 
685
 
 
686
int
 
687
Interface_Scan_Next(short *Index,
 
688
                    char *Name,
 
689
                    struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr)
 
690
{
 
691
    return 0;
 
692
}
 
693
 
 
694
#else                           /* not USE_SYSCTL_IFLIST */
 
695
 
 
696
        /*********************
 
697
         *
 
698
         *  Kernel & interface information,
 
699
         *   and internal forward declarations
 
700
         *
 
701
         *********************/
 
702
 
 
703
#ifndef HAVE_NET_IF_MIB_H
 
704
 
 
705
#ifndef solaris2
 
706
#ifndef hpux11
 
707
static int      Interface_Scan_By_Index(int, char *, struct ifnet *,
 
708
                                        struct in_ifaddr *);
 
709
static int      Interface_Get_Ether_By_Index(int, u_char *);
 
710
#else
 
711
static int      Interface_Scan_By_Index(int, char *, nmapi_phystat *);
 
712
#endif
 
713
#endif
 
714
 
 
715
 
 
716
 
 
717
        /*********************
 
718
         *
 
719
         *  System specific implementation functions
 
720
         *
 
721
         *********************/
 
722
 
 
723
 
 
724
#ifndef solaris2
 
725
#ifndef hpux
 
726
 
 
727
u_char         *
 
728
var_ifEntry(struct variable *vp,
 
729
            oid * name,
 
730
            size_t * length,
 
731
            int exact, size_t * var_len, WriteMethod ** write_method)
 
732
{
 
733
    static struct ifnet ifnet;
 
734
    int             interface;
 
735
    static struct in_ifaddr in_ifaddr;
 
736
    static char     Name[16];
 
737
    char           *cp;
 
738
    conf_if_list   *if_ptr;
 
739
#if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC
 
740
    struct timeval  now;
 
741
#endif
 
742
 
 
743
    interface =
 
744
        header_ifEntry(vp, name, length, exact, var_len, write_method);
 
745
    if (interface == MATCH_FAILED)
 
746
        return NULL;
 
747
 
 
748
    Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddr);
 
749
    if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
 
750
 
 
751
    switch (vp->magic) {
 
752
    case IFINDEX:
 
753
        long_return = interface;
 
754
        return (u_char *) & long_return;
 
755
    case IFDESCR:
 
756
        cp = Name;
 
757
        *var_len = strlen(cp);
 
758
        return (u_char *) cp;
 
759
    case NETSNMP_IFTYPE:
 
760
        if (if_ptr)
 
761
            long_return = if_ptr->type;
 
762
        else {
 
763
#if STRUCT_IFNET_HAS_IF_TYPE
 
764
            long_return = ifnet.if_type;
 
765
#else
 
766
            long_return = 1;    /* OTHER */
 
767
#endif
 
768
        }
 
769
        return (u_char *) & long_return;
 
770
    case IFMTU:{
 
771
            long_return = (long) ifnet.if_mtu;
 
772
            return (u_char *) & long_return;
 
773
        }
 
774
    case IFSPEED:
 
775
        if (if_ptr)
 
776
            long_return = if_ptr->speed;
 
777
        else {
 
778
#if STRUCT_IFNET_HAS_IF_BAUDRATE
 
779
            long_return = ifnet.if_baudrate;
 
780
#elif STRUCT_IFNET_HAS_IF_SPEED
 
781
            long_return = ifnet.if_speed;
 
782
#elif STRUCT_IFNET_HAS_IF_TYPE && defined(IFT_ETHER)
 
783
            if (ifnet.if_type == IFT_ETHER)
 
784
                long_return = 10000000;
 
785
            if (ifnet.if_type == IFT_P10)
 
786
                long_return = 10000000;
 
787
            if (ifnet.if_type == IFT_P80)
 
788
                long_return = 80000000;
 
789
            if (ifnet.if_type == IFT_ISDNBASIC)
 
790
                long_return = 64000;    /* EDSS1 only */
 
791
            if (ifnet.if_type == IFT_ISDNPRIMARY)
 
792
                long_return = 64000 * 30;
 
793
#else
 
794
#if NETSNMP_NO_DUMMY_VALUES
 
795
            return NULL;
 
796
#endif
 
797
            long_return = (u_long) 10000000;
 
798
#endif
 
799
        }
 
800
        return (u_char *) & long_return;
 
801
    case IFPHYSADDRESS:
 
802
        Interface_Get_Ether_By_Index(interface, return_buf);
 
803
#if defined(aix4) || defined(aix5) || defined(aix6)
 
804
        *var_len = 0;
 
805
#else
 
806
        if ((return_buf[0] == 0) && (return_buf[1] == 0) &&
 
807
            (return_buf[2] == 0) && (return_buf[3] == 0) &&
 
808
            (return_buf[4] == 0) && (return_buf[5] == 0))
 
809
            *var_len = 0;
 
810
        else
 
811
            *var_len = 6;
 
812
#endif
 
813
        return (u_char *) return_buf;
 
814
    case IFADMINSTATUS:
 
815
        long_return = ifnet.if_flags & IFF_UP ? 1 : 2;
 
816
        return (u_char *) & long_return;
 
817
    case IFOPERSTATUS:
 
818
        long_return = ifnet.if_flags & IFF_RUNNING ? 1 : 2;
 
819
        return (u_char *) & long_return;
 
820
    case IFLASTCHANGE:
 
821
#if defined(STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC) && !(defined(freebsd2) && __FreeBSD_version < 199607)
 
822
        /*
 
823
         * XXX - SNMP's ifLastchange is time when op. status changed
 
824
         * * FreeBSD's if_lastchange is time when packet was input or output
 
825
         * * (at least in 2.1.0-RELEASE. Changed in later versions of the kernel?)
 
826
         */
 
827
        /*
 
828
         * FreeBSD's if_lastchange before the 2.1.5 release is the time when
 
829
         * * a packet was last input or output.  In the 2.1.5 and later releases,
 
830
         * * this is fixed, thus the 199607 comparison.
 
831
         */
 
832
        if (ifnet.if_lastchange.tv_sec == 0 &&
 
833
            ifnet.if_lastchange.tv_usec == 0)
 
834
            long_return = 0;
 
835
        else if (ifnet.if_lastchange.tv_sec < starttime.tv_sec)
 
836
            long_return = 0;
 
837
        else {
 
838
            long_return = (u_long)
 
839
                ((ifnet.if_lastchange.tv_sec - starttime.tv_sec) * 100
 
840
                 + (ifnet.if_lastchange.tv_usec -
 
841
                    starttime.tv_usec) / 10000);
 
842
        }
 
843
#else
 
844
#if NETSNMP_NO_DUMMY_VALUES
 
845
        return NULL;
 
846
#endif
 
847
        long_return = 0;        /* XXX */
 
848
#endif
 
849
        return (u_char *) & long_return;
 
850
    case IFINOCTETS:
 
851
#ifdef STRUCT_IFNET_HAS_IF_IBYTES
 
852
#if defined(aix4) || defined(aix5) || defined(aix6)
 
853
        long_return = (u_long) ifnet.if_ibytes & 0xffffffff;
 
854
#else
 
855
        long_return = (u_long) ifnet.if_ibytes;
 
856
#endif
 
857
#else
 
858
#if NETSNMP_NO_DUMMY_VALUES
 
859
        return NULL;
 
860
#endif
 
861
        long_return = (u_long) ifnet.if_ipackets * 308; /* XXX */
 
862
#endif
 
863
        return (u_char *) & long_return;
 
864
    case IFINUCASTPKTS:
 
865
        {
 
866
#if defined(aix4) || defined(aix5) || defined(aix6)
 
867
            long_return = (u_long) ifnet.if_ipackets & 0xffffffff;
 
868
#else
 
869
            long_return = (u_long) ifnet.if_ipackets;
 
870
#endif
 
871
#if STRUCT_IFNET_HAS_IF_IMCASTS
 
872
#if defined(aix4) || defined(aix5) || defined(aix6)
 
873
            long_return -= (u_long) ifnet.if_imcasts & 0xffffffff;
 
874
#else
 
875
            long_return -= (u_long) ifnet.if_imcasts;
 
876
#endif
 
877
#endif
 
878
        }
 
879
        return (u_char *) & long_return;
 
880
    case IFINNUCASTPKTS:
 
881
#if STRUCT_IFNET_HAS_IF_IMCASTS
 
882
#if defined(aix4) || defined(aix5) || defined(aix6)
 
883
        long_return = (u_long) ifnet.if_imcasts & 0xffffffff;
 
884
#else
 
885
        long_return = (u_long) ifnet.if_imcasts;
 
886
#endif
 
887
#else
 
888
#if NETSNMP_NO_DUMMY_VALUES
 
889
        return NULL;
 
890
#endif
 
891
        long_return = (u_long) 0;       /* XXX */
 
892
#endif
 
893
        return (u_char *) & long_return;
 
894
    case IFINDISCARDS:
 
895
#if STRUCT_IFNET_HAS_IF_IQDROPS
 
896
#if defined(aix4) || defined(aix5) || defined(aix6)
 
897
        long_return = (u_long) ifnet.if_iqdrops & 0xffffffff;
 
898
#else
 
899
        long_return = (u_long) ifnet.if_iqdrops;
 
900
#endif
 
901
#else
 
902
#if NETSNMP_NO_DUMMY_VALUES
 
903
        return NULL;
 
904
#endif
 
905
        long_return = (u_long) 0;       /* XXX */
 
906
#endif
 
907
        return (u_char *) & long_return;
 
908
    case IFINERRORS:
 
909
#if defined(aix4) || defined(aix5) || defined(aix6)
 
910
        long_return = (u_long) ifnet.if_ierrors & 0xffffffff;
 
911
#else
 
912
        long_return = (u_long) ifnet.if_ierrors;
 
913
#endif
 
914
        return (u_char *) & long_return;
 
915
    case IFINUNKNOWNPROTOS:
 
916
#if STRUCT_IFNET_HAS_IF_NOPROTO
 
917
#if defined(aix4) || defined(aix5) || defined(aix6)
 
918
        long_return = (u_long) ifnet.if_noproto & 0xffffffff;
 
919
#else
 
920
        long_return = (u_long) ifnet.if_noproto;
 
921
#endif
 
922
#else
 
923
#if NETSNMP_NO_DUMMY_VALUES
 
924
        return NULL;
 
925
#endif
 
926
        long_return = (u_long) 0;       /* XXX */
 
927
#endif
 
928
        return (u_char *) & long_return;
 
929
    case IFOUTOCTETS:
 
930
#ifdef STRUCT_IFNET_HAS_IF_OBYTES
 
931
#if defined(aix4) || defined(aix5) || defined(aix6)
 
932
        long_return = (u_long) ifnet.if_obytes & 0xffffffff;
 
933
#else
 
934
        long_return = (u_long) ifnet.if_obytes;
 
935
#endif
 
936
#else
 
937
#if NETSNMP_NO_DUMMY_VALUES
 
938
        return NULL;
 
939
#endif
 
940
        long_return = (u_long) ifnet.if_opackets * 308; /* XXX */
 
941
#endif
 
942
        return (u_char *) & long_return;
 
943
    case IFOUTUCASTPKTS:
 
944
        {
 
945
#if defined(aix4) || defined(aix5) || defined(aix6)
 
946
            long_return = (u_long) ifnet.if_opackets & 0xffffffff;
 
947
#else
 
948
            long_return = (u_long) ifnet.if_opackets;
 
949
#endif
 
950
#if STRUCT_IFNET_HAS_IF_OMCASTS
 
951
#if defined(aix4) || defined(aix5) || defined(aix6)
 
952
            long_return -= (u_long) ifnet.if_omcasts & 0xffffffff;
 
953
#else
 
954
            long_return -= (u_long) ifnet.if_omcasts;
 
955
#endif
 
956
#endif
 
957
        }
 
958
        return (u_char *) & long_return;
 
959
    case IFOUTNUCASTPKTS:
 
960
#if STRUCT_IFNET_HAS_IF_OMCASTS
 
961
#if defined(aix4) || defined(aix5) || defined(aix6)
 
962
        long_return = (u_long) ifnet.if_omcasts & 0xffffffff;
 
963
#else
 
964
        long_return = (u_long) ifnet.if_omcasts;
 
965
#endif
 
966
#else
 
967
#if NETSNMP_NO_DUMMY_VALUES
 
968
        return NULL;
 
969
#endif
 
970
        long_return = (u_long) 0;       /* XXX */
 
971
#endif
 
972
        return (u_char *) & long_return;
 
973
    case IFOUTDISCARDS:
 
974
#if defined(aix4) || defined(aix5) || defined(aix6)
 
975
        long_return = ifnet.if_snd.ifq_drops & 0xffffffff;
 
976
#else
 
977
        long_return = ifnet.if_snd.ifq_drops;
 
978
#endif
 
979
        return (u_char *) & long_return;
 
980
    case IFOUTERRORS:
 
981
#if defined(aix4) || defined(aix5) || defined(aix6)
 
982
        long_return = ifnet.if_oerrors & 0xffffffff;
 
983
#else
 
984
        long_return = ifnet.if_oerrors;
 
985
#endif
 
986
        return (u_char *) & long_return;
 
987
    case IFOUTQLEN:
 
988
#if defined(aix4) || defined(aix5) || defined(aix6)
 
989
        long_return = ifnet.if_snd.ifq_len & 0xffffffff;
 
990
#else
 
991
        long_return = ifnet.if_snd.ifq_len;
 
992
#endif
 
993
        return (u_char *) & long_return;
 
994
    case IFSPECIFIC:
 
995
        *var_len = nullOidLen;
 
996
        return (u_char *) nullOid;
 
997
    default:
 
998
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
 
999
                    vp->magic));
 
1000
    }
 
1001
    return NULL;
 
1002
}
 
1003
 
 
1004
#else                           /* hpux */
 
1005
 
 
1006
u_char         *
 
1007
var_ifEntry(struct variable *vp,
 
1008
            oid * name,
 
1009
            size_t * length,
 
1010
            int exact, size_t * var_len, WriteMethod ** write_method)
 
1011
{
 
1012
#if defined(hpux11)
 
1013
    static nmapi_phystat ifnet;
 
1014
#else
 
1015
    static struct ifnet ifnet;
 
1016
#endif
 
1017
    register int    interface;
 
1018
#if !defined(hpux11)
 
1019
    static struct in_ifaddr in_ifaddrVar;
 
1020
#endif
 
1021
#if defined(hpux11)
 
1022
    static char     Name[MAX_PHYSADDR_LEN];
 
1023
#else
 
1024
    static char     Name[16];
 
1025
#endif
 
1026
    register char  *cp;
 
1027
#if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC
 
1028
    struct timeval  now;
 
1029
#endif
 
1030
#if !defined(hpux11)
 
1031
    struct nmparms  hp_nmparms;
 
1032
    static mib_ifEntry hp_ifEntry;
 
1033
    int             hp_fd;
 
1034
    int             hp_len = sizeof(hp_ifEntry);
 
1035
#endif
 
1036
    conf_if_list   *if_ptr;
 
1037
 
 
1038
    interface =
 
1039
        header_ifEntry(vp, name, length, exact, var_len, write_method);
 
1040
    if (interface == MATCH_FAILED)
 
1041
        return NULL;
 
1042
 
 
1043
#if defined(hpux11)
 
1044
    Interface_Scan_By_Index(interface, Name, &ifnet);
 
1045
#else
 
1046
    Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddrVar);
 
1047
#endif
 
1048
 
 
1049
#if !defined(hpux11)
 
1050
    /*
 
1051
     * Additional information about the interfaces is available under
 
1052
     * HP-UX through the network management interface '/dev/netman'
 
1053
     */
 
1054
    hp_ifEntry.ifIndex = interface;
 
1055
    hp_nmparms.objid = ID_ifEntry;
 
1056
    hp_nmparms.buffer = (char *) &hp_ifEntry;
 
1057
    hp_nmparms.len = &hp_len;
 
1058
    if ((hp_fd = open("/dev/netman", O_RDONLY)) != -1) {
 
1059
        if (ioctl(hp_fd, NMIOGET, &hp_nmparms) != -1) {
 
1060
            close(hp_fd);
 
1061
        } else {
 
1062
            close(hp_fd);
 
1063
            hp_fd = -1;         /* failed */
 
1064
        }
 
1065
    }
 
1066
#endif
 
1067
    if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
 
1068
 
 
1069
    switch (vp->magic) {
 
1070
    case IFINDEX:
 
1071
        long_return = interface;
 
1072
        return (u_char *) & long_return;
 
1073
    case IFDESCR:
 
1074
#if defined(hpux11)
 
1075
        cp = ifnet.if_entry.ifDescr;
 
1076
#else
 
1077
        if (hp_fd != -1)
 
1078
            cp = hp_ifEntry.ifDescr;
 
1079
        else
 
1080
            cp = Name;
 
1081
#endif
 
1082
        *var_len = strlen(cp);
 
1083
        return (u_char *) cp;
 
1084
    case NETSNMP_IFTYPE:
 
1085
        if (if_ptr)
 
1086
            long_return = if_ptr->type;
 
1087
        else {
 
1088
#if defined(hpux11)
 
1089
        long_return = ifnet.if_entry.ifType;
 
1090
#else
 
1091
        if (hp_fd != -1)
 
1092
            long_return = hp_ifEntry.ifType;
 
1093
        else
 
1094
            long_return = 1;    /* OTHER */
 
1095
#endif
 
1096
        }
 
1097
        return (u_char *) & long_return;
 
1098
    case IFMTU:{
 
1099
#if defined(hpux11)
 
1100
            long_return = (long) ifnet.if_entry.ifMtu;
 
1101
#else
 
1102
            long_return = (long) ifnet.if_mtu;
 
1103
#endif
 
1104
            return (u_char *) & long_return;
 
1105
        }
 
1106
    case IFSPEED:
 
1107
        if (if_ptr)
 
1108
            long_return = if_ptr->speed;
 
1109
        else {
 
1110
#if defined(hpux11)
 
1111
        long_return = ifnet.if_entry.ifSpeed;
 
1112
#else
 
1113
        if (hp_fd != -1)
 
1114
            long_return = hp_ifEntry.ifSpeed;
 
1115
        else
 
1116
            long_return = (u_long) 1;   /* OTHER */
 
1117
#endif
 
1118
        }
 
1119
        return (u_char *) & long_return;
 
1120
    case IFPHYSADDRESS:
 
1121
#if defined(hpux11)
 
1122
        *var_len = ifnet.if_entry.ifPhysAddress.o_length;
 
1123
        return (u_char *) ifnet.if_entry.ifPhysAddress.o_bytes;
 
1124
#else
 
1125
        Interface_Get_Ether_By_Index(interface, return_buf);
 
1126
        if ((return_buf[0] == 0) && (return_buf[1] == 0) &&
 
1127
            (return_buf[2] == 0) && (return_buf[3] == 0) &&
 
1128
            (return_buf[4] == 0) && (return_buf[5] == 0))
 
1129
            *var_len = 0;
 
1130
        else
 
1131
            *var_len = 6;
 
1132
        return (u_char *) return_buf;
 
1133
#endif
 
1134
    case IFADMINSTATUS:
 
1135
#if defined(hpux11)
 
1136
        long_return = ifnet.if_entry.ifAdmin;
 
1137
#else
 
1138
        long_return = ifnet.if_flags & IFF_UP ? 1 : 2;
 
1139
#endif
 
1140
        return (u_char *) & long_return;
 
1141
    case IFOPERSTATUS:
 
1142
#if defined(hpux11)
 
1143
        long_return = ifnet.if_entry.ifOper;
 
1144
#else
 
1145
        long_return = ifnet.if_flags & IFF_RUNNING ? 1 : 2;
 
1146
#endif
 
1147
        return (u_char *) & long_return;
 
1148
    case IFLASTCHANGE:
 
1149
#if defined(hpux11)
 
1150
        long_return = ifnet.if_entry.ifLastChange;
 
1151
#else
 
1152
        if (hp_fd != -1)
 
1153
            long_return = hp_ifEntry.ifLastChange;
 
1154
        else
 
1155
            long_return = 0;    /* XXX */
 
1156
#endif
 
1157
        return (u_char *) & long_return;
 
1158
    case IFINOCTETS:
 
1159
#if defined(hpux11)
 
1160
        long_return = ifnet.if_entry.ifInOctets;
 
1161
#else
 
1162
        if (hp_fd != -1)
 
1163
            long_return = hp_ifEntry.ifInOctets;
 
1164
        else
 
1165
            long_return = (u_long) ifnet.if_ipackets * 308;     /* XXX */
 
1166
#endif
 
1167
        return (u_char *) & long_return;
 
1168
    case IFINUCASTPKTS:
 
1169
#if defined(hpux11)
 
1170
        long_return = ifnet.if_entry.ifInUcastPkts;
 
1171
#else
 
1172
        if (hp_fd != -1)
 
1173
            long_return = hp_ifEntry.ifInUcastPkts;
 
1174
        else
 
1175
            long_return = (u_long) ifnet.if_ipackets;
 
1176
#endif
 
1177
        return (u_char *) & long_return;
 
1178
    case IFINNUCASTPKTS:
 
1179
#if defined(hpux11)
 
1180
        long_return = ifnet.if_entry.ifInNUcastPkts;
 
1181
#else
 
1182
        if (hp_fd != -1)
 
1183
            long_return = hp_ifEntry.ifInNUcastPkts;
 
1184
        else
 
1185
            long_return = (u_long) 0;   /* XXX */
 
1186
#endif
 
1187
        return (u_char *) & long_return;
 
1188
    case IFINDISCARDS:
 
1189
#if defined(hpux11)
 
1190
        long_return = ifnet.if_entry.ifInDiscards;
 
1191
#else
 
1192
        if (hp_fd != -1)
 
1193
            long_return = hp_ifEntry.ifInDiscards;
 
1194
        else
 
1195
            long_return = (u_long) 0;   /* XXX */
 
1196
#endif
 
1197
        return (u_char *) & long_return;
 
1198
    case IFINERRORS:
 
1199
#if defined(hpux11)
 
1200
        long_return = ifnet.if_entry.ifInErrors;
 
1201
#else
 
1202
        long_return = ifnet.if_ierrors;
 
1203
#endif
 
1204
        return (u_char *) & long_return;
 
1205
    case IFINUNKNOWNPROTOS:
 
1206
#if defined(hpux11)
 
1207
        long_return = ifnet.if_entry.ifInUnknownProtos;
 
1208
#else
 
1209
        if (hp_fd != -1)
 
1210
            long_return = hp_ifEntry.ifInUnknownProtos;
 
1211
        else
 
1212
            long_return = (u_long) 0;   /* XXX */
 
1213
#endif
 
1214
        return (u_char *) & long_return;
 
1215
    case IFOUTOCTETS:
 
1216
#if defined(hpux11)
 
1217
        long_return = ifnet.if_entry.ifOutOctets;
 
1218
#else
 
1219
        if (hp_fd != -1)
 
1220
            long_return = hp_ifEntry.ifOutOctets;
 
1221
        else
 
1222
            long_return = (u_long) ifnet.if_opackets * 308;     /* XXX */
 
1223
#endif
 
1224
        return (u_char *) & long_return;
 
1225
    case IFOUTUCASTPKTS:
 
1226
#if defined(hpux11)
 
1227
        long_return = ifnet.if_entry.ifOutUcastPkts;
 
1228
#else
 
1229
        if (hp_fd != -1)
 
1230
            long_return = hp_ifEntry.ifOutUcastPkts;
 
1231
        else
 
1232
            long_return = (u_long) ifnet.if_opackets;
 
1233
#endif
 
1234
        return (u_char *) & long_return;
 
1235
    case IFOUTNUCASTPKTS:
 
1236
#if defined(hpux11)
 
1237
        long_return = ifnet.if_entry.ifOutNUcastPkts;
 
1238
#else
 
1239
        if (hp_fd != -1)
 
1240
            long_return = hp_ifEntry.ifOutNUcastPkts;
 
1241
        else
 
1242
            long_return = (u_long) 0;   /* XXX */
 
1243
#endif
 
1244
        return (u_char *) & long_return;
 
1245
    case IFOUTDISCARDS:
 
1246
#if defined(hpux11)
 
1247
        long_return = ifnet.if_entry.ifOutDiscards;
 
1248
#else
 
1249
        long_return = ifnet.if_snd.ifq_drops;
 
1250
#endif
 
1251
        return (u_char *) & long_return;
 
1252
    case IFOUTERRORS:
 
1253
#if defined(hpux11)
 
1254
        long_return = ifnet.if_entry.ifOutErrors;
 
1255
#else
 
1256
        long_return = ifnet.if_oerrors;
 
1257
#endif
 
1258
        return (u_char *) & long_return;
 
1259
    case IFOUTQLEN:
 
1260
#if defined(hpux11)
 
1261
        long_return = ifnet.if_entry.ifOutQlen;
 
1262
#else
 
1263
        long_return = ifnet.if_snd.ifq_len;
 
1264
#endif
 
1265
        return (u_char *) & long_return;
 
1266
    case IFSPECIFIC:
 
1267
        *var_len = nullOidLen;
 
1268
        return (u_char *) nullOid;
 
1269
    default:
 
1270
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
 
1271
                    vp->magic));
 
1272
    }
 
1273
    return NULL;
 
1274
}
 
1275
 
 
1276
#endif                          /* hpux */
 
1277
#else                           /* solaris2 */
 
1278
 
 
1279
static int
 
1280
IF_cmp(void *addr, void *ep)
 
1281
{
 
1282
    DEBUGMSGTL(("mibII/interfaces", "... IF_cmp %d %d\n",
 
1283
                ((mib2_ifEntry_t *) ep)->ifIndex,
 
1284
                ((mib2_ifEntry_t *) addr)->ifIndex));
 
1285
    if (((mib2_ifEntry_t *) ep)->ifIndex ==
 
1286
        ((mib2_ifEntry_t *) addr)->ifIndex)
 
1287
        return (0);
 
1288
    else
 
1289
        return (1);
 
1290
}
 
1291
 
 
1292
u_char         *
 
1293
var_ifEntry(struct variable * vp,
 
1294
            oid * name,
 
1295
            size_t * length,
 
1296
            int exact, size_t * var_len, WriteMethod ** write_method)
 
1297
{
 
1298
    int             interface;
 
1299
    mib2_ifEntry_t  ifstat;
 
1300
    conf_if_list   *if_ptr = NULL;
 
1301
 
 
1302
    interface =
 
1303
        header_ifEntry(vp, name, length, exact, var_len, write_method);
 
1304
    if (interface == MATCH_FAILED)
 
1305
        return NULL;
 
1306
 
 
1307
    if (getMibstat(MIB_INTERFACES, &ifstat, sizeof(mib2_ifEntry_t),
 
1308
                   GET_EXACT, &IF_cmp, &interface) != 0) {
 
1309
        DEBUGMSGTL(("mibII/interfaces", "... no mib stats\n"));
 
1310
        return NULL;
 
1311
    }
 
1312
    /*
 
1313
     * hmmm.. where to get the interface name to check overrides?
 
1314
     *
 
1315
     * if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
 
1316
     */
 
1317
    switch (vp->magic) {
 
1318
    case IFINDEX:
 
1319
        long_return = ifstat.ifIndex;
 
1320
        return (u_char *) & long_return;
 
1321
    case IFDESCR:
 
1322
        *var_len = ifstat.ifDescr.o_length;
 
1323
        (void) memcpy(return_buf, ifstat.ifDescr.o_bytes, *var_len);
 
1324
        return (u_char *) return_buf;
 
1325
    case NETSNMP_IFTYPE:
 
1326
        if (if_ptr)
 
1327
            long_return = if_ptr->type;
 
1328
        else
 
1329
        long_return = (u_long) ifstat.ifType;
 
1330
        return (u_char *) & long_return;
 
1331
    case IFMTU:
 
1332
        long_return = (u_long) ifstat.ifMtu;
 
1333
        return (u_char *) & long_return;
 
1334
    case IFSPEED:
 
1335
        if (if_ptr)
 
1336
            long_return = if_ptr->speed;
 
1337
        else
 
1338
        long_return = (u_long) ifstat.ifSpeed;
 
1339
        return (u_char *) & long_return;
 
1340
    case IFPHYSADDRESS:
 
1341
        *var_len = ifstat.ifPhysAddress.o_length;
 
1342
        (void) memcpy(return_buf, ifstat.ifPhysAddress.o_bytes, *var_len);
 
1343
        return (u_char *) return_buf;
 
1344
    case IFADMINSTATUS:
 
1345
        long_return = (u_long) ifstat.ifAdminStatus;
 
1346
        return (u_char *) & long_return;
 
1347
    case IFOPERSTATUS:
 
1348
        long_return = (u_long) ifstat.ifOperStatus;
 
1349
        return (u_char *) & long_return;
 
1350
    case IFLASTCHANGE:
 
1351
        long_return = (u_long) ifstat.ifLastChange;
 
1352
        return (u_char *) & long_return;
 
1353
    case IFINOCTETS:
 
1354
        long_return = (u_long) ifstat.ifInOctets;
 
1355
        return (u_char *) & long_return;
 
1356
    case IFINUCASTPKTS:
 
1357
        long_return = (u_long) ifstat.ifInUcastPkts;
 
1358
        return (u_char *) & long_return;
 
1359
    case IFINNUCASTPKTS:
 
1360
        long_return = (u_long) ifstat.ifInNUcastPkts;
 
1361
        return (u_char *) & long_return;
 
1362
    case IFINDISCARDS:
 
1363
        long_return = (u_long) ifstat.ifInDiscards;
 
1364
        return (u_char *) & long_return;
 
1365
    case IFINERRORS:
 
1366
        long_return = (u_long) ifstat.ifInErrors;
 
1367
        return (u_char *) & long_return;
 
1368
    case IFINUNKNOWNPROTOS:
 
1369
        long_return = (u_long) ifstat.ifInUnknownProtos;
 
1370
        return (u_char *) & long_return;
 
1371
    case IFOUTOCTETS:
 
1372
        long_return = (u_long) ifstat.ifOutOctets;
 
1373
        return (u_char *) & long_return;
 
1374
    case IFOUTUCASTPKTS:
 
1375
        long_return = (u_long) ifstat.ifOutUcastPkts;
 
1376
        return (u_char *) & long_return;
 
1377
    case IFOUTNUCASTPKTS:
 
1378
        long_return = (u_long) ifstat.ifOutNUcastPkts;
 
1379
        return (u_char *) & long_return;
 
1380
    case IFOUTDISCARDS:
 
1381
        long_return = (u_long) ifstat.ifOutDiscards;
 
1382
        return (u_char *) & long_return;
 
1383
    case IFOUTERRORS:
 
1384
        long_return = (u_long) ifstat.ifOutErrors;
 
1385
        return (u_char *) & long_return;
 
1386
    case IFOUTQLEN:
 
1387
        long_return = (u_long) ifstat.ifOutQLen;
 
1388
        return (u_char *) & long_return;
 
1389
    case IFSPECIFIC:
 
1390
        long_return = (u_long) ifstat.ifSpecific;
 
1391
        return (u_char *) & long_return;
 
1392
    default:
 
1393
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
 
1394
                    vp->magic));
 
1395
    }
 
1396
    return NULL;
 
1397
}
 
1398
 
 
1399
#endif                          /* solaris2 */
 
1400
 
 
1401
 
 
1402
 
 
1403
        /*********************
 
1404
         *
 
1405
         *  Internal implementation functions
 
1406
         *
 
1407
         *********************/
 
1408
 
 
1409
 
 
1410
#ifndef solaris2
 
1411
 
 
1412
#if !defined(sunV3) && !defined(linux) && !defined(hpux11)
 
1413
static struct in_ifaddr savein_ifaddr;
 
1414
#endif
 
1415
#if !defined(hpux11)
 
1416
static struct ifnet *ifnetaddr, saveifnet, *saveifnetaddr;
 
1417
static char     saveName[16];
 
1418
#endif
 
1419
static int      saveIndex = 0;
 
1420
 
 
1421
/**
 
1422
* Determines network interface speed. It is system specific. Only linux
 
1423
* realization is made. 
 
1424
*/
 
1425
unsigned int getIfSpeed(int fd, struct ifreq ifr, unsigned int defaultspeed)
 
1426
{
 
1427
#ifdef linux
 
1428
    /** temporary expose internal until this module can be re-written */
 
1429
    extern unsigned int
 
1430
        netsnmp_linux_interface_get_if_speed(int fd, const char *name,
 
1431
                unsigned long long defaultspeed);
 
1432
 
 
1433
    return netsnmp_linux_interface_get_if_speed(fd, ifr.ifr_name, defaultspeed);
 
1434
#else /*!linux*/                           
 
1435
    return defaultspeed;
 
1436
#endif 
 
1437
}
 
1438
 
 
1439
void
 
1440
Interface_Scan_Init(void)
 
1441
{
 
1442
#ifdef linux
 
1443
    char            line[256], ifname_buf[64], *ifname, *ptr;
 
1444
    struct ifreq    ifrq;
 
1445
    struct ifnet  **ifnetaddr_ptr;
 
1446
    FILE           *devin;
 
1447
    int             i, fd;
 
1448
    conf_if_list   *if_ptr;
 
1449
    /*
 
1450
     * scanline_2_2:
 
1451
     *  [               IN                        ]
 
1452
     *   byte pkts errs drop fifo frame cmprs mcst |
 
1453
     *  [               OUT                               ]
 
1454
     *   byte pkts errs drop fifo colls carrier compressed
 
1455
     */
 
1456
#ifdef SCNuMAX
 
1457
    uintmax_t       rec_pkt, rec_oct, rec_err, rec_drop;
 
1458
    uintmax_t       snd_pkt, snd_oct, snd_err, snd_drop, coll;
 
1459
    const char     *scan_line_2_2 =
 
1460
        "%"   SCNuMAX " %"  SCNuMAX " %"  SCNuMAX " %"  SCNuMAX
 
1461
        " %*" SCNuMAX " %*" SCNuMAX " %*" SCNuMAX " %*" SCNuMAX
 
1462
        " %"  SCNuMAX " %"  SCNuMAX " %"  SCNuMAX " %"  SCNuMAX
 
1463
        " %*" SCNuMAX " %"  SCNuMAX;
 
1464
    const char     *scan_line_2_0 =
 
1465
        "%"   SCNuMAX " %"  SCNuMAX " %*" SCNuMAX " %*" SCNuMAX
 
1466
        " %*" SCNuMAX " %"  SCNuMAX " %"  SCNuMAX " %*" SCNuMAX
 
1467
        " %*" SCNuMAX " %"  SCNuMAX;
 
1468
#else
 
1469
    unsigned long   rec_pkt, rec_oct, rec_err, rec_drop;
 
1470
    unsigned long   snd_pkt, snd_oct, snd_err, snd_drop, coll;
 
1471
    const char     *scan_line_2_2 =
 
1472
        "%lu %lu %lu %lu %*lu %*lu %*lu %*lu %lu %lu %lu %lu %*lu %lu";
 
1473
    const char     *scan_line_2_0 =
 
1474
        "%lu %lu %*lu %*lu %*lu %lu %lu %*lu %*lu %lu";
 
1475
#endif
 
1476
    const char     *scan_line_to_use;
 
1477
    struct timeval et;                              /* elapsed time */
 
1478
 
 
1479
#endif
 
1480
 
 
1481
#if !defined(hpux11) && defined(IFNET_SYMBOL)
 
1482
    auto_nlist(IFNET_SYMBOL, (char *) &ifnetaddr, sizeof(ifnetaddr));
 
1483
#endif
 
1484
    saveIndex = 0;
 
1485
 
 
1486
 
 
1487
#ifdef linux
 
1488
    /*  disallow reloading of structures too often */
 
1489
    gettimeofday ( &et, ( struct timezone * ) 0 );  /*  get time-of-day */
 
1490
    if ( et.tv_sec < LastLoad + MINLOADFREQ ) {     /*  only reload so often */
 
1491
      ifnetaddr = ifnetaddr_list;                   /*  initialize pointer */
 
1492
      return;
 
1493
    }
 
1494
    LastLoad = et.tv_sec;
 
1495
 
 
1496
    /*
 
1497
     * free old list: 
 
1498
     */
 
1499
    while (ifnetaddr_list) {
 
1500
        struct ifnet   *old = ifnetaddr_list;
 
1501
        ifnetaddr_list = ifnetaddr_list->if_next;
 
1502
        free(old->if_name);
 
1503
        free(old->if_unit);
 
1504
        free(old);
 
1505
    }
 
1506
 
 
1507
    ifnetaddr = 0;
 
1508
    ifnetaddr_ptr = &ifnetaddr_list;
 
1509
 
 
1510
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 
1511
        DEBUGMSGTL(("snmpd",
 
1512
                    "socket open failure in Interface_Scan_Init\n"));
 
1513
        return; /** exit (1); **/
 
1514
    }
 
1515
 
 
1516
    /*
 
1517
     * build up ifnetaddr list by hand: 
 
1518
     */
 
1519
 
 
1520
    /*
 
1521
     * at least linux v1.3.53 says EMFILE without reason... 
 
1522
     */
 
1523
    if (!(devin = fopen("/proc/net/dev", "r"))) {
 
1524
        close(fd);
 
1525
        snmp_log(LOG_ERR, "cannot open /proc/net/dev - continuing...\n");
 
1526
        return; /** exit (1); **/
 
1527
    }
 
1528
 
 
1529
    i = 0;
 
1530
 
 
1531
    /*
 
1532
     * read the second line (a header) and determine the fields we
 
1533
     * should read from.  This should be done in a better way by
 
1534
     * actually looking for the field names we want.  But thats too
 
1535
     * much work for today.  -- Wes 
 
1536
     */
 
1537
    fgets(line, sizeof(line), devin);
 
1538
    fgets(line, sizeof(line), devin);
 
1539
    if (strstr(line, "compressed")) {
 
1540
        scan_line_to_use = scan_line_2_2;
 
1541
        DEBUGMSGTL(("mibII/interfaces",
 
1542
                    "using linux 2.2 kernel /proc/net/dev\n"));
 
1543
    } else {
 
1544
        scan_line_to_use = scan_line_2_0;
 
1545
        DEBUGMSGTL(("mibII/interfaces",
 
1546
                    "using linux 2.0 kernel /proc/net/dev\n"));
 
1547
    }
 
1548
 
 
1549
 
 
1550
    while (fgets(line, sizeof(line), devin)) {
 
1551
        struct ifnet   *nnew;
 
1552
        char           *stats, *ifstart = line;
 
1553
 
 
1554
        if (line[strlen(line) - 1] == '\n')
 
1555
            line[strlen(line) - 1] = '\0';
 
1556
 
 
1557
        while (*ifstart && *ifstart == ' ')
 
1558
            ifstart++;
 
1559
 
 
1560
        if (!*ifstart || ((stats = strrchr(ifstart, ':')) == NULL)) {
 
1561
            snmp_log(LOG_ERR,
 
1562
                     "/proc/net/dev data format error, line ==|%s|", line);
 
1563
            continue;
 
1564
        }
 
1565
        if ((scan_line_to_use == scan_line_2_2) && ((stats - line) < 6)) {
 
1566
            snmp_log(LOG_ERR,
 
1567
                     "/proc/net/dev data format error, line ==|%s|", line);
 
1568
        }
 
1569
 
 
1570
        *stats   = 0;
 
1571
        strncpy(ifname_buf, ifstart, sizeof(ifname_buf));
 
1572
        ifname_buf[ sizeof(ifname_buf)-1 ] = 0;
 
1573
        *stats++ = ':';
 
1574
        while (*stats == ' ')
 
1575
            stats++;
 
1576
 
 
1577
        if ((scan_line_to_use == scan_line_2_2 &&
 
1578
             sscanf(stats, scan_line_to_use, &rec_oct, &rec_pkt, &rec_err,
 
1579
                    &rec_drop, &snd_oct, &snd_pkt, &snd_err, &snd_drop,
 
1580
                    &coll) != 9) || (scan_line_to_use == scan_line_2_0
 
1581
                                     && sscanf(stats, scan_line_to_use,
 
1582
                                               &rec_pkt, &rec_err,
 
1583
                                               &snd_pkt, &snd_err,
 
1584
                                               &coll) != 5)) {
 
1585
            if ((scan_line_to_use == scan_line_2_2)
 
1586
                && !strstr(line, "No statistics available"))
 
1587
                snmp_log(LOG_ERR,
 
1588
                         "/proc/net/dev data format error, line ==|%s|",
 
1589
                         line);
 
1590
            continue;
 
1591
        }
 
1592
 
 
1593
        nnew = (struct ifnet *) calloc(1, sizeof(struct ifnet));
 
1594
        if (nnew == NULL)
 
1595
            break;              /* alloc error */
 
1596
 
 
1597
        /*
 
1598
         * chain in: 
 
1599
         */
 
1600
        *ifnetaddr_ptr = nnew;
 
1601
        ifnetaddr_ptr = &nnew->if_next;
 
1602
        i++;
 
1603
 
 
1604
        /*
 
1605
         * linux previous to 1.3.~13 may miss transmitted loopback pkts: 
 
1606
         */
 
1607
        if (!strcmp(ifname_buf, "lo") && rec_pkt > 0 && !snd_pkt)
 
1608
            snd_pkt = rec_pkt;
 
1609
 
 
1610
        nnew->if_ipackets = rec_pkt & 0xffffffff;
 
1611
        nnew->if_ierrors = rec_err;
 
1612
        nnew->if_opackets = snd_pkt & 0xffffffff;
 
1613
        nnew->if_oerrors = snd_err;
 
1614
        nnew->if_collisions = coll;
 
1615
        if (scan_line_to_use == scan_line_2_2) {
 
1616
            nnew->if_ibytes = rec_oct & 0xffffffff;
 
1617
            nnew->if_obytes = snd_oct & 0xffffffff;
 
1618
            nnew->if_iqdrops = rec_drop;
 
1619
            nnew->if_snd.ifq_drops = snd_drop;
 
1620
        } else {
 
1621
            nnew->if_ibytes = (rec_pkt * 308) & 0xffffffff;
 
1622
            nnew->if_obytes = (snd_pkt * 308) & 0xffffffff;
 
1623
        }
 
1624
 
 
1625
        /*
 
1626
         * ifnames are given as ``   eth0'': split in ``eth'' and ``0'': 
 
1627
         */
 
1628
        for (ifname = ifname_buf; *ifname && *ifname == ' '; ifname++);
 
1629
 
 
1630
        /*
 
1631
         * set name and interface# : 
 
1632
         */
 
1633
        nnew->if_name = (char *) strdup(ifname);
 
1634
        for (ptr = nnew->if_name; *ptr && (*ptr < '0' || *ptr > '9');
 
1635
             ptr++);
 
1636
        nnew->if_unit = strdup(*ptr ? ptr : "");
 
1637
        *ptr = 0;
 
1638
 
 
1639
        strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
 
1640
        ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
 
1641
        if (ioctl(fd, SIOCGIFADDR, &ifrq) < 0)
 
1642
            memset((char *) &nnew->if_addr, 0, sizeof(nnew->if_addr));
 
1643
        else
 
1644
            nnew->if_addr = ifrq.ifr_addr;
 
1645
 
 
1646
        strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
 
1647
        ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
 
1648
        if (ioctl(fd, SIOCGIFBRDADDR, &ifrq) < 0)
 
1649
            memset((char *) &nnew->ifu_broadaddr, 0,
 
1650
                   sizeof(nnew->ifu_broadaddr));
 
1651
        else
 
1652
            nnew->ifu_broadaddr = ifrq.ifr_broadaddr;
 
1653
 
 
1654
        strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
 
1655
        ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
 
1656
        if (ioctl(fd, SIOCGIFNETMASK, &ifrq) < 0)
 
1657
            memset((char *) &nnew->ia_subnetmask, 0,
 
1658
                   sizeof(nnew->ia_subnetmask));
 
1659
        else
 
1660
            nnew->ia_subnetmask = ifrq.ifr_netmask;
 
1661
 
 
1662
        strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
 
1663
        ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
 
1664
        nnew->if_flags = ioctl(fd, SIOCGIFFLAGS, &ifrq) < 0
 
1665
            ? 0 : ifrq.ifr_flags;
 
1666
 
 
1667
        nnew->if_type = 0;
 
1668
 
 
1669
        /*
 
1670
         * NOTE: this ioctl does not guarantee 6 bytes of a physaddr.
 
1671
         * In particular, a 'sit0' interface only appears to get back
 
1672
         * 4 bytes of sa_data.
 
1673
         */
 
1674
        memset(ifrq.ifr_hwaddr.sa_data, (0), IFHWADDRLEN);
 
1675
        strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
 
1676
        ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
 
1677
        if (ioctl(fd, SIOCGIFHWADDR, &ifrq) < 0)
 
1678
            memset(nnew->if_hwaddr, (0), IFHWADDRLEN);
 
1679
        else {
 
1680
            memcpy(nnew->if_hwaddr, ifrq.ifr_hwaddr.sa_data, IFHWADDRLEN);
 
1681
 
 
1682
#ifdef ARPHRD_LOOPBACK
 
1683
            switch (ifrq.ifr_hwaddr.sa_family) {
 
1684
            case ARPHRD_ETHER:
 
1685
                nnew->if_type = 6;
 
1686
                break;
 
1687
            case ARPHRD_TUNNEL:
 
1688
            case ARPHRD_TUNNEL6:
 
1689
#ifdef ARPHRD_IPGRE
 
1690
            case ARPHRD_IPGRE:
 
1691
#endif
 
1692
            case ARPHRD_SIT:
 
1693
                nnew->if_type = 131;
 
1694
                break;          /* tunnel */
 
1695
            case ARPHRD_SLIP:
 
1696
            case ARPHRD_CSLIP:
 
1697
            case ARPHRD_SLIP6:
 
1698
            case ARPHRD_CSLIP6:
 
1699
                nnew->if_type = 28;
 
1700
                break;          /* slip */
 
1701
            case ARPHRD_PPP:
 
1702
                nnew->if_type = 23;
 
1703
                break;          /* ppp */
 
1704
            case ARPHRD_LOOPBACK:
 
1705
                nnew->if_type = 24;
 
1706
                break;          /* softwareLoopback */
 
1707
            case ARPHRD_FDDI:
 
1708
                nnew->if_type = 15;
 
1709
                break;
 
1710
            case ARPHRD_ARCNET:
 
1711
                nnew->if_type = 35;
 
1712
                break;
 
1713
            case ARPHRD_LOCALTLK:
 
1714
                nnew->if_type = 42;
 
1715
                break;
 
1716
#ifdef ARPHRD_HIPPI
 
1717
            case ARPHRD_HIPPI:
 
1718
                nnew->if_type = 47;
 
1719
                break;
 
1720
#endif
 
1721
#ifdef ARPHRD_ATM
 
1722
            case ARPHRD_ATM:
 
1723
                nnew->if_type = 37;
 
1724
                break;
 
1725
#endif
 
1726
                /*
 
1727
                 * XXX: more if_arp.h:ARPHDR_xxx to IANAifType mappings... 
 
1728
                 */
 
1729
            }
 
1730
#endif
 
1731
        }
 
1732
 
 
1733
        strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
 
1734
        ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
 
1735
        nnew->if_metric = ioctl(fd, SIOCGIFMETRIC, &ifrq) < 0
 
1736
            ? 0 : ifrq.ifr_metric;
 
1737
 
 
1738
#ifdef SIOCGIFMTU
 
1739
        strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
 
1740
        ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
 
1741
        nnew->if_mtu = (ioctl(fd, SIOCGIFMTU, &ifrq) < 0)
 
1742
            ? 0 : ifrq.ifr_mtu;
 
1743
#else
 
1744
        nnew->if_mtu = 0;
 
1745
#endif
 
1746
 
 
1747
        if_ptr = netsnmp_access_interface_entry_overrides_get(ifname);
 
1748
        if (if_ptr) {
 
1749
            nnew->if_type = if_ptr->type;
 
1750
            nnew->if_speed = if_ptr->speed;
 
1751
        } else {
 
1752
            /*
 
1753
             * do only guess if_type from name, if we could not read
 
1754
             * * it before from SIOCGIFHWADDR 
 
1755
             */
 
1756
            unsigned int defaultspeed = NOMINAL_LINK_SPEED;
 
1757
                if (!(nnew->if_flags & IFF_RUNNING)) {
 
1758
                    /* 
 
1759
                     * use speed 0 if the if speed cannot be determined *and* the
 
1760
                     * interface is down
 
1761
                     */
 
1762
                    defaultspeed = 0;
 
1763
                }
 
1764
 
 
1765
            if (!nnew->if_type)
 
1766
                nnew->if_type = if_type_from_name(nnew->if_name);
 
1767
            switch(nnew->if_type) {
 
1768
            case 6:
 
1769
                nnew->if_speed = getIfSpeed(fd, ifrq, defaultspeed);
 
1770
                break;
 
1771
            case 24:
 
1772
                nnew->if_speed = 10000000;
 
1773
                break;
 
1774
            case 9:
 
1775
                nnew->if_speed = 4000000;
 
1776
                break;
 
1777
            default:
 
1778
                nnew->if_speed = 0;
 
1779
            }
 
1780
            /*Zero speed means link problem*/
 
1781
            if(nnew->if_speed == 0 && nnew->if_flags & IFF_UP){
 
1782
                nnew->if_flags &= ~IFF_RUNNING;
 
1783
            }
 
1784
        }
 
1785
 
 
1786
    }                           /* while (fgets ... */
 
1787
 
 
1788
    ifnetaddr = ifnetaddr_list;
 
1789
 
 
1790
    if (snmp_get_do_debugging()) {
 
1791
        {
 
1792
            struct ifnet   *x = ifnetaddr;
 
1793
            DEBUGMSGTL(("mibII/interfaces", "* see: known interfaces:"));
 
1794
            while (x) {
 
1795
                DEBUGMSG(("mibII/interfaces", " %s", x->if_name));
 
1796
                x = x->if_next;
 
1797
            }
 
1798
            DEBUGMSG(("mibII/interfaces", "\n"));
 
1799
        }                       /* XXX */
 
1800
    }
 
1801
 
 
1802
    fclose(devin);
 
1803
    close(fd);
 
1804
#endif                          /* linux */
 
1805
}
 
1806
 
 
1807
 
 
1808
 
 
1809
#if defined(sunV3) || defined(linux)
 
1810
/*
 
1811
 * **  4.2 BSD doesn't have ifaddr
 
1812
 * **  
 
1813
 */
 
1814
int
 
1815
Interface_Scan_Next(short *Index,
 
1816
                    char *Name,
 
1817
                    struct ifnet *Retifnet, struct in_ifaddr *dummy)
 
1818
{
 
1819
    struct ifnet    ifnet;
 
1820
    register char  *cp;
 
1821
 
 
1822
    while (ifnetaddr) {
 
1823
        /*
 
1824
         *      Get the "ifnet" structure and extract the device name
 
1825
         */
 
1826
#ifndef linux
 
1827
        if (!NETSNMP_KLOOKUP(ifnetaddr, (char *) &ifnet, sizeof ifnet)) {
 
1828
            DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
 
1829
            break;
 
1830
        }
 
1831
 
 
1832
        if (!NETSNMP_KLOOKUP(ifnet.if_name, (char *) saveName, sizeof saveName)) {
 
1833
            DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
 
1834
            break;
 
1835
        }
 
1836
 
 
1837
       /*
 
1838
        * The purpose of this comparison is lost in the mists of time.
 
1839
        * It's been around at least cmu-snmp 2.1.2 for SUNv3 systems and
 
1840
        * was applied to linux systems during the cmu-snmp-linux project.
 
1841
        * No-one now knows what it was intended for, and it breaks IPv6
 
1842
        * tunnel interfaces, so it's been moved out of the Linux code block.
 
1843
        */
 
1844
        if (strcmp(saveName, "ip") == 0) {
 
1845
            ifnetaddr = ifnet.if_next;
 
1846
            continue;
 
1847
        }
 
1848
#else
 
1849
        ifnet = *ifnetaddr;
 
1850
        strncpy(saveName, ifnet.if_name, sizeof(saveName));
 
1851
#endif
 
1852
 
 
1853
        saveName[sizeof(saveName) - 1] = '\0';
 
1854
        cp = (char *) strchr(saveName, '\0');
 
1855
#ifdef linux
 
1856
        strncat(cp, ifnet.if_unit, sizeof(saveName)-strlen(saveName)-1);
 
1857
        saveName[sizeof(saveName) - 1] = '\0';
 
1858
#else
 
1859
        string_append_int(cp, ifnet.if_unit);
 
1860
#endif
 
1861
        if (1 || strcmp(saveName, "lo0") != 0) {        /* XXX */
 
1862
 
 
1863
            if (Index)
 
1864
                *Index = ++saveIndex;
 
1865
            if (Retifnet)
 
1866
                *Retifnet = ifnet;
 
1867
            if (Name)
 
1868
                strcpy(Name, saveName);
 
1869
            saveifnet = ifnet;
 
1870
            saveifnetaddr = ifnetaddr;
 
1871
            ifnetaddr = ifnet.if_next;
 
1872
 
 
1873
            return (1);         /* DONE */
 
1874
        }
 
1875
        ifnetaddr = ifnet.if_next;
 
1876
    }
 
1877
    return (0);                 /* EOF */
 
1878
}
 
1879
 
 
1880
#ifdef linux
 
1881
int
 
1882
Interface_Index_By_Name(char *Name, int Len)
 
1883
{
 
1884
    short           ifIndex = 0;
 
1885
    char            ifName[20];
 
1886
 
 
1887
    Interface_Scan_Init();
 
1888
    while (Interface_Scan_Next(&ifIndex, ifName, NULL, NULL)
 
1889
           && strcmp(Name, ifName));
 
1890
    return ifIndex;
 
1891
}
 
1892
#endif
 
1893
 
 
1894
 
 
1895
#else                           /* sunV3 || linux */
 
1896
 
 
1897
#if defined(netbsd1) || defined(openbsd2)
 
1898
#define ia_next ia_list.tqe_next
 
1899
#define if_next if_list.tqe_next
 
1900
#endif
 
1901
 
 
1902
#if defined(hpux11)
 
1903
 
 
1904
int
 
1905
Interface_Scan_Next(short *Index, char *Name, nmapi_phystat * Retifnet)
 
1906
{
 
1907
    static nmapi_phystat *if_ptr = (nmapi_phystat *) 0;
 
1908
    int             count = Interface_Scan_Get_Count();
 
1909
    unsigned int    ulen;
 
1910
    int             ret;
 
1911
 
 
1912
    if (!if_ptr) {
 
1913
        if (count)
 
1914
            if_ptr =
 
1915
                (nmapi_phystat *) malloc(sizeof(nmapi_phystat) * count);
 
1916
        else
 
1917
            return (0);         /* EOF */
 
1918
    }
 
1919
 
 
1920
    if (saveIndex >= count)
 
1921
        return (0);             /* EOF */
 
1922
 
 
1923
    ulen = (unsigned int) count *sizeof(nmapi_phystat);
 
1924
    if ((ret = get_physical_stat(if_ptr, &ulen)) < 0)
 
1925
        return (0);             /* EOF */
 
1926
 
 
1927
    if (Retifnet)
 
1928
        *Retifnet = if_ptr[saveIndex];
 
1929
    if (Name)
 
1930
        strcpy(Name, if_ptr[saveIndex].nm_device);
 
1931
    saveIndex++;
 
1932
    if (Index)
 
1933
        *Index = saveIndex;
 
1934
    return (1);                 /* DONE */
 
1935
}
 
1936
 
 
1937
#else                           /* hpux11 */
 
1938
 
 
1939
int
 
1940
Interface_Scan_Next(short *Index,
 
1941
                    char *Name,
 
1942
                    struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr)
 
1943
{
 
1944
    struct ifnet    ifnet;
 
1945
    struct in_ifaddr *ia, in_ifaddr;
 
1946
    short           has_ipaddr = 0;
 
1947
#if !STRUCT_IFNET_HAS_IF_XNAME
 
1948
    register char  *cp;
 
1949
#endif
 
1950
 
 
1951
    while (ifnetaddr) {
 
1952
        /*
 
1953
         *      Get the "ifnet" structure and extract the device name
 
1954
         */
 
1955
        if (!NETSNMP_KLOOKUP(ifnetaddr, (char *) &ifnet, sizeof ifnet)) {
 
1956
            DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
 
1957
            break;
 
1958
        }
 
1959
#if STRUCT_IFNET_HAS_IF_XNAME
 
1960
#if defined(netbsd1) || defined(openbsd2)
 
1961
        strncpy(saveName, ifnet.if_xname, sizeof saveName);
 
1962
#else
 
1963
        if (!NETSNMP_KLOOKUP(ifnet.if_xname, (char *) saveName, sizeof saveName)) {
 
1964
            DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
 
1965
            break;
 
1966
        }
 
1967
#endif
 
1968
        saveName[sizeof(saveName) - 1] = '\0';
 
1969
#else
 
1970
        if (!NETSNMP_KLOOKUP(ifnet.if_name, (char *) saveName, sizeof saveName)) {
 
1971
            DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
 
1972
            break;
 
1973
        }
 
1974
 
 
1975
        saveName[sizeof(saveName) - 1] = '\0';
 
1976
        cp = strchr(saveName, '\0');
 
1977
        string_append_int(cp, ifnet.if_unit);
 
1978
#endif
 
1979
        if (1 || strcmp(saveName, "lo0") != 0) {        /* XXX */
 
1980
            /*
 
1981
             *  Try to find an address for this interface
 
1982
             */
 
1983
 
 
1984
#ifdef netbsd1
 
1985
            ia = (struct in_ifaddr *) ifnet.if_addrlist.tqh_first;
 
1986
#elif defined(IFADDR_SYMBOL)
 
1987
            auto_nlist(IFADDR_SYMBOL, (char *) &ia, sizeof(ia));
 
1988
#endif
 
1989
            while (ia) {
 
1990
                if (!NETSNMP_KLOOKUP(ia, (char *) &in_ifaddr, sizeof(in_ifaddr))) {
 
1991
                    DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
 
1992
                    break;
 
1993
                }
 
1994
                {
 
1995
#ifdef netbsd1
 
1996
#define CP(x)   ((char *)(x))
 
1997
                    char           *cp;
 
1998
                    struct sockaddr *sa;
 
1999
                    cp = (CP(in_ifaddr.ia_ifa.ifa_addr) - CP(ia)) +
 
2000
                        CP(&in_ifaddr);
 
2001
                    sa = (struct sockaddr *) cp;
 
2002
 
 
2003
                    if (sa->sa_family == AF_INET)
 
2004
#endif
 
2005
                        if (in_ifaddr.ia_ifp == ifnetaddr) {
 
2006
                            has_ipaddr = 1;     /* this IF has IP-address */
 
2007
                            break;
 
2008
                        }
 
2009
                }
 
2010
#ifdef netbsd1
 
2011
                ia = (struct in_ifaddr *) in_ifaddr.ia_ifa.ifa_list.
 
2012
                    tqe_next;
 
2013
#else
 
2014
                ia = in_ifaddr.ia_next;
 
2015
#endif
 
2016
            }
 
2017
 
 
2018
#if !defined(netbsd1) && !defined(freebsd2) && !defined(openbsd2) && !defined(STRUCT_IFNET_HAS_IF_ADDRLIST)
 
2019
            ifnet.if_addrlist = (struct ifaddr *) ia;   /* WRONG DATA TYPE; ONLY A FLAG */
 
2020
#endif
 
2021
            /*
 
2022
             * ifnet.if_addrlist = (struct ifaddr *)&ia->ia_ifa;   
 
2023
             *
 
2024
             * WRONG DATA TYPE; ONLY A FLAG 
 
2025
             */
 
2026
 
 
2027
            if (Index)
 
2028
                *Index = ++saveIndex;
 
2029
            if (Retifnet)
 
2030
                *Retifnet = ifnet;
 
2031
            if (Retin_ifaddr && has_ipaddr)     /* assign the in_ifaddr only
 
2032
                                                 * if the IF has IP-address */
 
2033
                *Retin_ifaddr = in_ifaddr;
 
2034
            if (Name)
 
2035
                strcpy(Name, saveName);
 
2036
            saveifnet = ifnet;
 
2037
            saveifnetaddr = ifnetaddr;
 
2038
            savein_ifaddr = in_ifaddr;
 
2039
            ifnetaddr = ifnet.if_next;
 
2040
 
 
2041
            return (1);         /* DONE */
 
2042
        }
 
2043
        ifnetaddr = ifnet.if_next;
 
2044
    }
 
2045
    return (0);                 /* EOF */
 
2046
}
 
2047
 
 
2048
#endif                          /* hpux11 */
 
2049
 
 
2050
#endif                          /* sunV3 || linux */
 
2051
 
 
2052
#if defined(hpux11)
 
2053
 
 
2054
static int
 
2055
Interface_Scan_By_Index(int Index, char *Name, nmapi_phystat * Retifnet)
 
2056
{
 
2057
    short           i;
 
2058
 
 
2059
    Interface_Scan_Init();
 
2060
    while (Interface_Scan_Next(&i, Name, Retifnet)) {
 
2061
        if (i == Index)
 
2062
            break;
 
2063
    }
 
2064
    if (i != Index)
 
2065
        return (-1);            /* Error, doesn't exist */
 
2066
    return (0);                 /* DONE */
 
2067
}
 
2068
 
 
2069
#else                           /* hpux11 */
 
2070
 
 
2071
static int
 
2072
Interface_Scan_By_Index(int Index,
 
2073
                        char *Name,
 
2074
                        struct ifnet *Retifnet,
 
2075
                        struct in_ifaddr *Retin_ifaddr)
 
2076
{
 
2077
    short           i;
 
2078
 
 
2079
    Interface_Scan_Init();
 
2080
    while (Interface_Scan_Next(&i, Name, Retifnet, Retin_ifaddr)) {
 
2081
        if (i == Index)
 
2082
            break;
 
2083
    }
 
2084
    if (i != Index)
 
2085
        return (-1);            /* Error, doesn't exist */
 
2086
    return (0);                 /* DONE */
 
2087
}
 
2088
 
 
2089
#endif                          /* hpux11 */
 
2090
 
 
2091
static int      Interface_Count = 0;
 
2092
 
 
2093
#if defined(hpux11)
 
2094
 
 
2095
int
 
2096
Interface_Scan_Get_Count(void)
 
2097
{
 
2098
    if (!Interface_Count) {
 
2099
        int             fd;
 
2100
        struct nmparms  p;
 
2101
        int             val;
 
2102
        unsigned int    ulen;
 
2103
        int             ret;
 
2104
 
 
2105
        if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) {
 
2106
            p.objid = ID_ifNumber;
 
2107
            p.buffer = (void *) &val;
 
2108
            ulen = sizeof(int);
 
2109
            p.len = &ulen;
 
2110
            if ((ret = get_mib_info(fd, &p)) == 0)
 
2111
                Interface_Count = val;
 
2112
            close_mib(fd);
 
2113
        }
 
2114
    }
 
2115
    return (Interface_Count);
 
2116
}
 
2117
 
 
2118
#else                           /* hpux11 */
 
2119
 
 
2120
static time_t   scan_time = 0;
 
2121
 
 
2122
int
 
2123
Interface_Scan_Get_Count(void)
 
2124
{
 
2125
    time_t          time_now = time(NULL);
 
2126
 
 
2127
    if (!Interface_Count || (time_now > scan_time + 60)) {
 
2128
        scan_time = time_now;
 
2129
        Interface_Scan_Init();
 
2130
        Interface_Count = 0;
 
2131
        while (Interface_Scan_Next(NULL, NULL, NULL, NULL) != 0) {
 
2132
            Interface_Count++;
 
2133
        }
 
2134
    }
 
2135
    return (Interface_Count);
 
2136
}
 
2137
 
 
2138
 
 
2139
static int
 
2140
Interface_Get_Ether_By_Index(int Index, u_char * EtherAddr)
 
2141
{
 
2142
    short           i;
 
2143
#if !(defined(linux) || defined(netbsd1) || defined(bsdi2) || defined(openbsd2))
 
2144
    struct arpcom   arpcom;
 
2145
#else                           /* is linux or netbsd1 */
 
2146
    struct arpcom {
 
2147
        char            ac_enaddr[6];
 
2148
    } arpcom;
 
2149
#if defined(netbsd1) || defined(bsdi2) || defined(openbsd2)
 
2150
    struct sockaddr_dl sadl;
 
2151
    struct ifaddr   ifaddr;
 
2152
    u_long          ifaddraddr;
 
2153
#endif
 
2154
#endif
 
2155
 
 
2156
#if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3) || defined(osf5)
 
2157
    memset(arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));
 
2158
#else
 
2159
    memset(&arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));
 
2160
#endif
 
2161
    memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr));
 
2162
 
 
2163
    if (saveIndex != Index) {   /* Optimization! */
 
2164
 
 
2165
        Interface_Scan_Init();
 
2166
 
 
2167
        while (Interface_Scan_Next((short *) &i, NULL, NULL, NULL) != 0) {
 
2168
            if (i == Index)
 
2169
                break;
 
2170
        }
 
2171
        if (i != Index)
 
2172
            return (-1);        /* Error, doesn't exist */
 
2173
    }
 
2174
#ifdef freebsd2
 
2175
    if (saveifnet.if_type != IFT_ETHER) {
 
2176
        return (0);             /* Not an ethernet if */
 
2177
    }
 
2178
#endif
 
2179
    /*
 
2180
     *  the arpcom structure is an extended ifnet structure which
 
2181
     *  contains the ethernet address.
 
2182
     */
 
2183
#ifndef linux
 
2184
#if !(defined(netbsd1) || defined(bsdi2) || defined(openbsd2))
 
2185
    if (!NETSNMP_KLOOKUP(saveifnetaddr, (char *) &arpcom, sizeof arpcom)) {
 
2186
        DEBUGMSGTL(("mibII/interfaces:Interface_Get_Ether_By_Index", "klookup failed\n"));
 
2187
        return 0;
 
2188
    }
 
2189
#else                           /* netbsd1 or bsdi2 or openbsd2 */
 
2190
 
 
2191
#if defined(netbsd1) || defined(openbsd2)
 
2192
#define if_addrlist if_addrlist.tqh_first
 
2193
#define ifa_next    ifa_list.tqe_next
 
2194
#endif
 
2195
 
 
2196
    ifaddraddr = (unsigned long) saveifnet.if_addrlist;
 
2197
    while (ifaddraddr) {
 
2198
        if (!NETSNMP_KLOOKUP(ifaddraddr, (char *) &ifaddr, sizeof ifaddr)) {
 
2199
            DEBUGMSGTL(("mibII/interfaces:Interface_Get_Ether_By_Index", "klookup failed\n"));
 
2200
            break;
 
2201
        }
 
2202
        if (!NETSNMP_KLOOKUP(ifaddr.ifa_addr, (char *) &sadl, sizeof sadl)) {
 
2203
            DEBUGMSGTL(("mibII/interfaces:Interface_Get_Ether_By_Index", "klookup failed\n"));
 
2204
            break;
 
2205
        }
 
2206
        if (sadl.sdl_family == AF_LINK
 
2207
            && (saveifnet.if_type == IFT_ETHER
 
2208
                || saveifnet.if_type == IFT_ISO88025
 
2209
                || saveifnet.if_type == IFT_FDDI)) {
 
2210
            memcpy(arpcom.ac_enaddr, sadl.sdl_data + sadl.sdl_nlen,
 
2211
                   sizeof(arpcom.ac_enaddr));
 
2212
            break;
 
2213
        }
 
2214
        ifaddraddr = (unsigned long) ifaddr.ifa_next;
 
2215
    }
 
2216
#endif                          /* netbsd1 or bsdi2 or openbsd2 */
 
2217
 
 
2218
#else                           /* linux */
 
2219
    memcpy(arpcom.ac_enaddr, saveifnetaddr->if_hwaddr, 6);
 
2220
#endif
 
2221
    if (strncmp("lo", saveName, 2) == 0) {
 
2222
        /*
 
2223
         *  Loopback doesn't have a HW addr, so return 00:00:00:00:00:00
 
2224
         */
 
2225
        memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr));
 
2226
 
 
2227
    } else {
 
2228
 
 
2229
#if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3)
 
2230
        memcpy(EtherAddr, (char *) arpcom.ac_enaddr,
 
2231
               sizeof(arpcom.ac_enaddr));
 
2232
#else
 
2233
        memcpy(EtherAddr, (char *) &arpcom.ac_enaddr,
 
2234
               sizeof(arpcom.ac_enaddr));
 
2235
#endif
 
2236
 
 
2237
 
 
2238
    }
 
2239
    return (0);                 /* DONE */
 
2240
}
 
2241
 
 
2242
#endif                          /* hpux11 */
 
2243
 
 
2244
#else                           /* solaris2 */
 
2245
 
 
2246
int
 
2247
Interface_Scan_Get_Count(void)
 
2248
{
 
2249
    int             i, sd;
 
2250
 
 
2251
    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 
2252
        return (0);
 
2253
    if (ioctl(sd, SIOCGIFNUM, &i) == -1) {
 
2254
        close(sd);
 
2255
        return (0);
 
2256
    } else {
 
2257
        close(sd);
 
2258
        return (i);
 
2259
    }
 
2260
}
 
2261
 
 
2262
int
 
2263
Interface_Index_By_Name(char *Name, int Len)
 
2264
{
 
2265
    return (solaris2_if_nametoindex(Name, Len));
 
2266
}
 
2267
 
 
2268
#endif                          /* solaris2 */
 
2269
 
 
2270
#else                           /* HAVE_NET_IF_MIB_H */
 
2271
 
 
2272
/*
 
2273
 * This code attempts to do the right thing for FreeBSD.  Note that
 
2274
 * the statistics could be gathered through use of of the
 
2275
 * net.route.0.link.iflist.0 sysctl (which we already use to get the
 
2276
 * hardware address of the interfaces), rather than using the ifmib
 
2277
 * code, but eventually I will implement dot3Stats and we will have to
 
2278
 * use the ifmib interface.  ifmib is also a much more natural way of
 
2279
 * mapping the SNMP MIB onto sysctl(3).
 
2280
 */
 
2281
 
 
2282
#include <net/if.h>
 
2283
#include <net/if_dl.h>
 
2284
#include <net/if_mib.h>
 
2285
#include <net/route.h>
 
2286
 
 
2287
static int      header_interfaces(struct variable *, oid *, size_t *, int,
 
2288
                                  size_t *, WriteMethod ** write);
 
2289
static int      header_ifEntry(struct variable *, oid *, size_t *, int,
 
2290
                               size_t *, WriteMethod ** write);
 
2291
u_char         *var_ifEntry(struct variable *, oid *, size_t *, int,
 
2292
                            size_t *, WriteMethod ** write);
 
2293
 
 
2294
static char    *physaddrbuf;
 
2295
static int      nphysaddrs;
 
2296
struct sockaddr_dl **physaddrs;
 
2297
 
 
2298
void
 
2299
init_interfaces_setup(void)
 
2300
{
 
2301
    int             naddrs, ilen, bit;
 
2302
    static int      mib[6]
 
2303
    = { CTL_NET, PF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
 
2304
    char           *cp;
 
2305
    size_t          len;
 
2306
    struct rt_msghdr *rtm;
 
2307
    struct if_msghdr *ifm;
 
2308
    struct ifa_msghdr *ifam;
 
2309
    struct sockaddr *sa;
 
2310
 
 
2311
    DEBUGMSGTL(("mibII:freebsd", "init_interfaces_setup\n"));
 
2312
 
 
2313
    naddrs = 0;
 
2314
    if (physaddrs)
 
2315
        free(physaddrs);
 
2316
    if (physaddrbuf)
 
2317
        free(physaddrbuf);
 
2318
    physaddrbuf = 0;
 
2319
    physaddrs = 0;
 
2320
    nphysaddrs = 0;
 
2321
    len = 0;
 
2322
    if (sysctl(mib, 6, 0, &len, 0, 0) < 0) {
 
2323
        DEBUGMSGTL(("mibII:freebsd", "sysctl 1 < 0\n"));
 
2324
        return;
 
2325
    }
 
2326
 
 
2327
    cp = physaddrbuf = malloc(len);
 
2328
    if (physaddrbuf == 0)
 
2329
        return;
 
2330
    if (sysctl(mib, 6, physaddrbuf, &len, 0, 0) < 0) {
 
2331
        free(physaddrbuf);
 
2332
        physaddrbuf = 0;
 
2333
        DEBUGMSGTL(("mibII:freebsd", "sysctl 2 < 0\n"));
 
2334
        return;
 
2335
    }
 
2336
 
 
2337
  loop:
 
2338
    ilen = len;
 
2339
    cp = physaddrbuf;
 
2340
    while (ilen > 0) {
 
2341
        rtm = (struct rt_msghdr *) cp;
 
2342
        if (rtm->rtm_version != RTM_VERSION || rtm->rtm_type != RTM_IFINFO) {
 
2343
            DEBUGMSGTL(("mibII:freebsd", "version:%d/%d type:%d/%d\n",
 
2344
                        rtm->rtm_version, RTM_VERSION, rtm->rtm_type, RTM_IFINFO));
 
2345
            free(physaddrs);
 
2346
            physaddrs = 0;
 
2347
            free(physaddrbuf);
 
2348
            physaddrbuf = 0;
 
2349
        }
 
2350
        ifm = (struct if_msghdr *) rtm;
 
2351
#if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
 
2352
        if (physaddrs != 0)
 
2353
            physaddrs[naddrs] = (void *) (ifm + 1);
 
2354
        naddrs++;
 
2355
#endif
 
2356
        ilen -= ifm->ifm_msglen;
 
2357
        cp += ifm->ifm_msglen;
 
2358
        rtm = (struct rt_msghdr *) cp;
 
2359
        while (ilen > 0 && rtm->rtm_type == RTM_NEWADDR) {
 
2360
#if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
 
2361
            ilen -= rtm->rtm_msglen;
 
2362
            cp += rtm->rtm_msglen;
 
2363
#else
 
2364
            int             is_alias = 0;
 
2365
            ifam = (struct ifa_msghdr *) rtm;
 
2366
            ilen -= sizeof(*ifam);
 
2367
            cp += sizeof(*ifam);
 
2368
            sa = (struct sockaddr *) cp;
 
2369
#define ROUND(x) (((x) + sizeof(long) - 1) & ~sizeof(long))
 
2370
            for (bit = 1; bit && ilen > 0; bit <<= 1) {
 
2371
                if (!(ifam->ifam_addrs & bit))
 
2372
                    continue;
 
2373
                ilen -= ROUND(sa->sa_len);
 
2374
                cp += ROUND(sa->sa_len);
 
2375
 
 
2376
                if (bit == RTA_IFA) {
 
2377
                    if (physaddrs)
 
2378
#define satosdl(sa) ((struct sockaddr_dl *)(sa))
 
2379
                        physaddrs[naddrs++]
 
2380
                            = satosdl(sa);
 
2381
                    else
 
2382
                        naddrs++;
 
2383
                }
 
2384
                sa = (struct sockaddr *) cp;
 
2385
            }
 
2386
#endif
 
2387
            rtm = (struct rt_msghdr *) cp;
 
2388
        }
 
2389
    }
 
2390
    DEBUGMSGTL(("mibII:freebsd", "found %d addrs\n", naddrs));
 
2391
    if (physaddrs) {
 
2392
        nphysaddrs = naddrs;
 
2393
        return;
 
2394
    }
 
2395
    physaddrs = malloc(naddrs * sizeof(*physaddrs));
 
2396
    if (physaddrs == 0)
 
2397
        return;
 
2398
    naddrs = 0;
 
2399
    goto loop;
 
2400
 
 
2401
}
 
2402
 
 
2403
static int
 
2404
get_phys_address(int iindex, char **ap, int *len)
 
2405
{
 
2406
    int             i;
 
2407
    int             once = 1;
 
2408
 
 
2409
    do {
 
2410
        for (i = 0; i < nphysaddrs; i++) {
 
2411
            if (physaddrs[i]->sdl_index == iindex)
 
2412
                break;
 
2413
        }
 
2414
        if (i < nphysaddrs)
 
2415
            break;
 
2416
        init_interfaces_setup();
 
2417
    } while (once--);
 
2418
 
 
2419
    DEBUGMSGTL(("mibII:freebsd", "get_phys_address %d/%d\n", i, nphysaddrs));
 
2420
    if (i < nphysaddrs) {
 
2421
        *ap = LLADDR(physaddrs[i]);
 
2422
        *len = physaddrs[i]->sdl_alen;
 
2423
        return 0;
 
2424
    }
 
2425
    return -1;
 
2426
}
 
2427
 
 
2428
int
 
2429
Interface_Scan_Get_Count(void)
 
2430
{
 
2431
    static int      count_oid[5] = { CTL_NET, PF_LINK, NETLINK_GENERIC,
 
2432
        IFMIB_SYSTEM, IFMIB_IFCOUNT
 
2433
    };
 
2434
    size_t          len;
 
2435
    int             count;
 
2436
 
 
2437
    len = sizeof count;
 
2438
    if (sysctl(count_oid, 5, &count, &len, (void *) 0, (size_t) 0) < 0) {
 
2439
        DEBUGMSGTL(("mibII:freebsd", "Interface_Scan_Get_Count err\n"));
 
2440
        return -1;
 
2441
    }
 
2442
    DEBUGMSGTL(("mibII:freebsd", "Interface_Scan_Get_Count %d\n", count));
 
2443
    return count;
 
2444
}
 
2445
 
 
2446
 
 
2447
u_char         *
 
2448
var_ifEntry(struct variable * vp,
 
2449
            oid * name,
 
2450
            size_t * length,
 
2451
            int exact, size_t * var_len, WriteMethod ** write_method)
 
2452
{
 
2453
    int             interface;
 
2454
    static int      sname[6] = { CTL_NET, PF_LINK, NETLINK_GENERIC,
 
2455
        IFMIB_IFDATA, 0, IFDATA_GENERAL
 
2456
    };
 
2457
    static struct ifmibdata ifmd;
 
2458
    size_t          len;
 
2459
    char           *cp;
 
2460
    conf_if_list   *if_ptr = NULL;
 
2461
 
 
2462
    interface = header_ifEntry(vp, name, length, exact, var_len,
 
2463
                               write_method);
 
2464
    if (interface == MATCH_FAILED)
 
2465
        return NULL;
 
2466
 
 
2467
    sname[4] = interface;
 
2468
    len = sizeof ifmd;
 
2469
    if (sysctl(sname, 6, &ifmd, &len, 0, 0) < 0) {
 
2470
        DEBUGMSGTL(("mibII:freebsd", "var_ifEntry sysctl err\n"));
 
2471
        return NULL;
 
2472
    }
 
2473
    /*
 
2474
     * hmmm.. where to get the interface name to check overrides?
 
2475
     *
 
2476
     * if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
 
2477
     */
 
2478
 
 
2479
    switch (vp->magic) {
 
2480
    case IFINDEX:
 
2481
        long_return = interface;
 
2482
        return (u_char *) & long_return;
 
2483
    case IFDESCR:
 
2484
        cp = ifmd.ifmd_name;
 
2485
        *var_len = strlen(cp);
 
2486
        return (u_char *) cp;
 
2487
    case NETSNMP_IFTYPE:
 
2488
        if (if_ptr)
 
2489
            long_return = if_ptr->type;
 
2490
        else
 
2491
        long_return = ifmd.ifmd_data.ifi_type;
 
2492
        return (u_char *) & long_return;
 
2493
    case IFMTU:
 
2494
        long_return = (long) ifmd.ifmd_data.ifi_mtu;
 
2495
        return (u_char *) & long_return;
 
2496
    case IFSPEED:
 
2497
        if (if_ptr)
 
2498
            long_return = if_ptr->speed;
 
2499
        else
 
2500
        long_return = ifmd.ifmd_data.ifi_baudrate;
 
2501
        return (u_char *) & long_return;
 
2502
    case IFPHYSADDRESS:
 
2503
        {
 
2504
            char           *cp;
 
2505
            if (get_phys_address(interface, &cp, var_len))
 
2506
                return NULL;
 
2507
            else
 
2508
                return cp;
 
2509
        }
 
2510
    case IFADMINSTATUS:
 
2511
        long_return = ifmd.ifmd_flags & IFF_UP ? 1 : 2;
 
2512
        return (u_char *) & long_return;
 
2513
    case IFOPERSTATUS:
 
2514
        long_return = ifmd.ifmd_flags & IFF_RUNNING ? 1 : 2;
 
2515
        return (u_char *) & long_return;
 
2516
    case IFLASTCHANGE:
 
2517
        if (ifmd.ifmd_data.ifi_lastchange.tv_sec == 0 &&
 
2518
            ifmd.ifmd_data.ifi_lastchange.tv_usec == 0) {
 
2519
            long_return = 0;
 
2520
        } else if (ifmd.ifmd_data.ifi_lastchange.tv_sec < starttime.tv_sec) {
 
2521
            long_return = 0;
 
2522
        } else {
 
2523
            long_return = (u_long)
 
2524
                ((ifmd.ifmd_data.ifi_lastchange.tv_sec -
 
2525
                  starttime.tv_sec) * 100 +
 
2526
                 ((ifmd.ifmd_data.ifi_lastchange.tv_usec -
 
2527
                   starttime.tv_usec) / 10000));
 
2528
        }
 
2529
        return (u_char *) & long_return;
 
2530
    case IFINOCTETS:
 
2531
        long_return = (u_long) ifmd.ifmd_data.ifi_ibytes;
 
2532
        return (u_char *) & long_return;
 
2533
    case IFINUCASTPKTS:
 
2534
        long_return = (u_long) ifmd.ifmd_data.ifi_ipackets;
 
2535
        long_return -= (u_long) ifmd.ifmd_data.ifi_imcasts;
 
2536
        return (u_char *) & long_return;
 
2537
    case IFINNUCASTPKTS:
 
2538
        long_return = (u_long) ifmd.ifmd_data.ifi_imcasts;
 
2539
        return (u_char *) & long_return;
 
2540
    case IFINDISCARDS:
 
2541
        long_return = (u_long) ifmd.ifmd_data.ifi_iqdrops;
 
2542
        return (u_char *) & long_return;
 
2543
    case IFINERRORS:
 
2544
        long_return = ifmd.ifmd_data.ifi_ierrors;
 
2545
        return (u_char *) & long_return;
 
2546
    case IFINUNKNOWNPROTOS:
 
2547
        long_return = (u_long) ifmd.ifmd_data.ifi_noproto;
 
2548
        return (u_char *) & long_return;
 
2549
    case IFOUTOCTETS:
 
2550
        long_return = (u_long) ifmd.ifmd_data.ifi_obytes;
 
2551
        return (u_char *) & long_return;
 
2552
    case IFOUTUCASTPKTS:
 
2553
        long_return = (u_long) ifmd.ifmd_data.ifi_opackets;
 
2554
        long_return -= (u_long) ifmd.ifmd_data.ifi_omcasts;
 
2555
        return (u_char *) & long_return;
 
2556
    case IFOUTNUCASTPKTS:
 
2557
        long_return = (u_long) ifmd.ifmd_data.ifi_omcasts;
 
2558
        return (u_char *) & long_return;
 
2559
    case IFOUTDISCARDS:
 
2560
        long_return = ifmd.ifmd_snd_drops;
 
2561
        return (u_char *) & long_return;
 
2562
    case IFOUTERRORS:
 
2563
        long_return = ifmd.ifmd_data.ifi_oerrors;
 
2564
        return (u_char *) & long_return;
 
2565
    case IFOUTQLEN:
 
2566
        long_return = ifmd.ifmd_snd_len;
 
2567
        return (u_char *) & long_return;
 
2568
    case IFSPECIFIC:
 
2569
        *var_len = nullOidLen;
 
2570
        return (u_char *) nullOid;
 
2571
    default:
 
2572
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
 
2573
                    vp->magic));
 
2574
    }
 
2575
    return NULL;
 
2576
}
 
2577
 
 
2578
#endif                          /* HAVE_NET_IF_MIB_H */
 
2579
#endif                          /* !USE_SYSCTL_IFLIST */
 
2580
 
 
2581
#else                           /* WIN32 cygwin */
 
2582
#include <iphlpapi.h>
 
2583
 
 
2584
WriteMethod     writeIfEntry;
 
2585
long            admin_status = 0;
 
2586
long            oldadmin_status = 0;
 
2587
 
 
2588
static int
 
2589
header_ifEntry(struct variable *vp,
 
2590
               oid * name,
 
2591
               size_t * length,
 
2592
               int exact, size_t * var_len, WriteMethod ** write_method)
 
2593
{
 
2594
#define IFENTRY_NAME_LENGTH     10
 
2595
    oid             newname[MAX_OID_LEN];
 
2596
    register int    ifIndex;
 
2597
    int             result, count;
 
2598
    DWORD           status = NO_ERROR;
 
2599
    DWORD           statusRetry = NO_ERROR;
 
2600
    DWORD           dwActualSize = 0;
 
2601
    PMIB_IFTABLE    pIfTable = NULL;
 
2602
 
 
2603
    DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: "));
 
2604
    DEBUGMSGOID(("mibII/interfaces", name, *length));
 
2605
    DEBUGMSG(("mibII/interfaces", " %d\n", exact));
 
2606
 
 
2607
    memcpy((char *) newname, (char *) vp->name,
 
2608
           (int) vp->namelen * sizeof(oid));
 
2609
    /*
 
2610
     * find "next" ifIndex 
 
2611
     */
 
2612
 
 
2613
 
 
2614
    /*
 
2615
     * query for buffer size needed 
 
2616
     */
 
2617
    status = GetIfTable(pIfTable, &dwActualSize, TRUE);
 
2618
 
 
2619
    if (status == ERROR_INSUFFICIENT_BUFFER) {
 
2620
        /*
 
2621
         * need more space 
 
2622
         */
 
2623
        pIfTable = (PMIB_IFTABLE) malloc(dwActualSize);
 
2624
        if (pIfTable != NULL) {
 
2625
            /*
 
2626
             * Get the sorted IF table 
 
2627
             */
 
2628
            GetIfTable(pIfTable, &dwActualSize, TRUE);
 
2629
        }
 
2630
    }
 
2631
    count = pIfTable->dwNumEntries;
 
2632
    for (ifIndex = 0; ifIndex < count; ifIndex++) {
 
2633
        newname[IFENTRY_NAME_LENGTH] =
 
2634
            (oid) pIfTable->table[ifIndex].dwIndex;
 
2635
        result =
 
2636
            snmp_oid_compare(name, *length, newname,
 
2637
                             (int) vp->namelen + 1);
 
2638
        if ((exact && (result == 0)) || (!exact && (result < 0)))
 
2639
            break;
 
2640
    }
 
2641
    if (ifIndex > count) {
 
2642
        DEBUGMSGTL(("mibII/interfaces", "... index out of range\n"));
 
2643
        return MATCH_FAILED;
 
2644
    }
 
2645
 
 
2646
 
 
2647
    memcpy((char *) name, (char *) newname,
 
2648
           ((int) vp->namelen + 1) * sizeof(oid));
 
2649
    *length = vp->namelen + 1;
 
2650
    *write_method = 0;
 
2651
    *var_len = sizeof(long);    /* default to 'long' results */
 
2652
 
 
2653
    DEBUGMSGTL(("mibII/interfaces", "... get I/F stats "));
 
2654
    DEBUGMSGOID(("mibII/interfaces", name, *length));
 
2655
    DEBUGMSG(("mibII/interfaces", "\n"));
 
2656
 
 
2657
    count = pIfTable->table[ifIndex].dwIndex;
 
2658
    free(pIfTable);
 
2659
    return count;
 
2660
}
 
2661
 
 
2662
 
 
2663
 
 
2664
u_char         *
 
2665
var_interfaces(struct variable * vp,
 
2666
               oid * name,
 
2667
               size_t * length,
 
2668
               int exact, size_t * var_len, WriteMethod ** write_method)
 
2669
{
 
2670
    if (header_generic(vp, name, length, exact, var_len, write_method) ==
 
2671
        MATCH_FAILED)
 
2672
        return NULL;
 
2673
 
 
2674
    switch (vp->magic) {
 
2675
    case IFNUMBER:
 
2676
        GetNumberOfInterfaces(&long_return);
 
2677
        return (u_char *) & long_return;
 
2678
    default:
 
2679
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n",
 
2680
                    vp->magic));
 
2681
    }
 
2682
    return NULL;
 
2683
}
 
2684
 
 
2685
u_char         *
 
2686
var_ifEntry(struct variable * vp,
 
2687
            oid * name,
 
2688
            size_t * length,
 
2689
            int exact, size_t * var_len, WriteMethod ** write_method)
 
2690
{
 
2691
    int             ifIndex;
 
2692
    static MIB_IFROW ifRow;
 
2693
    conf_if_list   *if_ptr = NULL;
 
2694
    
 
2695
    ifIndex =
 
2696
        header_ifEntry(vp, name, length, exact, var_len, write_method);
 
2697
    if (ifIndex == MATCH_FAILED)
 
2698
        return NULL;
 
2699
    /*
 
2700
     * hmmm.. where to get the interface name to check overrides?
 
2701
     *
 
2702
     * if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
 
2703
     */
 
2704
 
 
2705
    /*
 
2706
     * Get the If Table Row by passing index as argument 
 
2707
     */
 
2708
    ifRow.dwIndex = ifIndex;
 
2709
    if (GetIfEntry(&ifRow) != NO_ERROR)
 
2710
        return NULL;
 
2711
    switch (vp->magic) {
 
2712
    case IFINDEX:
 
2713
        long_return = ifIndex;
 
2714
        return (u_char *) & long_return;
 
2715
    case IFDESCR:
 
2716
        *var_len = ifRow.dwDescrLen;
 
2717
        return (u_char *) ifRow.bDescr;
 
2718
    case NETSNMP_IFTYPE:
 
2719
        if (if_ptr)
 
2720
            long_return = if_ptr->type;
 
2721
        else
 
2722
        long_return = ifRow.dwType;
 
2723
        return (u_char *) & long_return;
 
2724
    case IFMTU:
 
2725
        long_return = (long) ifRow.dwMtu;
 
2726
        return (u_char *) & long_return;
 
2727
    case IFSPEED:
 
2728
        if (if_ptr)
 
2729
            long_return = if_ptr->speed;
 
2730
        else
 
2731
        long_return = (long) ifRow.dwSpeed;
 
2732
        return (u_char *) & long_return;
 
2733
    case IFPHYSADDRESS:
 
2734
        *var_len = ifRow.dwPhysAddrLen;
 
2735
        memcpy(return_buf, ifRow.bPhysAddr, *var_len);
 
2736
        return (u_char *) return_buf;
 
2737
    case IFADMINSTATUS:
 
2738
        long_return = ifRow.dwAdminStatus;
 
2739
        admin_status = long_return;
 
2740
        *write_method = writeIfEntry;
 
2741
        return (u_char *) & long_return;
 
2742
    case IFOPERSTATUS:
 
2743
        long_return =
 
2744
           (MIB_IF_OPER_STATUS_OPERATIONAL == ifRow.dwOperStatus) ? 1 : 2;
 
2745
        return (u_char *) & long_return;
 
2746
    case IFLASTCHANGE:
 
2747
        long_return = 0 /* XXX not a UNIX epochal time ifRow.dwLastChange */ ;
 
2748
        return (u_char *) & long_return;
 
2749
    case IFINOCTETS:
 
2750
        long_return = ifRow.dwInOctets;
 
2751
        return (u_char *) & long_return;
 
2752
    case IFINUCASTPKTS:
 
2753
        long_return = ifRow.dwInUcastPkts;
 
2754
        return (u_char *) & long_return;
 
2755
    case IFINNUCASTPKTS:
 
2756
        long_return = ifRow.dwInNUcastPkts;
 
2757
        return (u_char *) & long_return;
 
2758
    case IFINDISCARDS:
 
2759
        long_return = ifRow.dwInDiscards;
 
2760
        return (u_char *) & long_return;
 
2761
    case IFINERRORS:
 
2762
        long_return = ifRow.dwInErrors;
 
2763
        return (u_char *) & long_return;
 
2764
    case IFINUNKNOWNPROTOS:
 
2765
        long_return = ifRow.dwInUnknownProtos;
 
2766
        return (u_char *) & long_return;
 
2767
    case IFOUTOCTETS:
 
2768
        long_return = ifRow.dwOutOctets;
 
2769
        return (u_char *) & long_return;
 
2770
    case IFOUTUCASTPKTS:
 
2771
        long_return = ifRow.dwOutUcastPkts;
 
2772
        return (u_char *) & long_return;
 
2773
    case IFOUTNUCASTPKTS:
 
2774
        long_return = ifRow.dwOutNUcastPkts;
 
2775
        return (u_char *) & long_return;
 
2776
    case IFOUTDISCARDS:
 
2777
        long_return = ifRow.dwOutDiscards;
 
2778
        return (u_char *) & long_return;
 
2779
    case IFOUTERRORS:
 
2780
        long_return = ifRow.dwOutErrors;
 
2781
        return (u_char *) & long_return;
 
2782
    case IFOUTQLEN:
 
2783
        long_return = ifRow.dwOutQLen;
 
2784
        return (u_char *) & long_return;
 
2785
    case IFSPECIFIC:
 
2786
        *var_len = nullOidLen;
 
2787
        return (u_char *) nullOid;
 
2788
    default:
 
2789
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
 
2790
                    vp->magic));
 
2791
    }
 
2792
    return NULL;
 
2793
}
 
2794
 
 
2795
 
 
2796
int
 
2797
writeIfEntry(int action,
 
2798
             u_char * var_val,
 
2799
             u_char var_val_type,
 
2800
             size_t var_val_len,
 
2801
             u_char * statP, oid * name, size_t name_len)
 
2802
{
 
2803
    MIB_IFROW       ifEntryRow;
 
2804
    if ((char) name[9] != IFADMINSTATUS) {
 
2805
        return SNMP_ERR_NOTWRITABLE;
 
2806
    }
 
2807
 
 
2808
    switch (action) {
 
2809
    case RESERVE1:             /* Check values for acceptability */
 
2810
        if (var_val_type != ASN_INTEGER) {
 
2811
            snmp_log(LOG_ERR, "not integer\n");
 
2812
            return SNMP_ERR_WRONGTYPE;
 
2813
        }
 
2814
        if (var_val_len > sizeof(int)) {
 
2815
            snmp_log(LOG_ERR, "bad length\n");
 
2816
            return SNMP_ERR_WRONGLENGTH;
 
2817
        }
 
2818
 
 
2819
        /*
 
2820
         * The dwAdminStatus member can be MIB_IF_ADMIN_STATUS_UP or MIB_IF_ADMIN_STATUS_DOWN 
 
2821
         */
 
2822
        if (!(((int) (*var_val) == MIB_IF_ADMIN_STATUS_UP) ||
 
2823
              ((int) (*var_val) == MIB_IF_ADMIN_STATUS_DOWN))) {
 
2824
            snmp_log(LOG_ERR, "not supported admin state\n");
 
2825
            return SNMP_ERR_WRONGVALUE;
 
2826
        }
 
2827
        break;
 
2828
 
 
2829
    case RESERVE2:             /* Allocate memory and similar resources */
 
2830
        break;
 
2831
 
 
2832
    case ACTION:
 
2833
        /*
 
2834
         * Save the old value, in case of UNDO 
 
2835
         */
 
2836
 
 
2837
        oldadmin_status = admin_status;
 
2838
        admin_status = (int) *var_val;
 
2839
        break;
 
2840
 
 
2841
    case UNDO:                 /* Reverse the SET action and free resources */
 
2842
        admin_status = oldadmin_status;
 
2843
        break;
 
2844
 
 
2845
    case COMMIT:               /* Confirm the SET, performing any irreversible actions,
 
2846
                                 * and free resources */
 
2847
        ifEntryRow.dwIndex = (int) name[10];
 
2848
        ifEntryRow.dwAdminStatus = admin_status;
 
2849
        /*
 
2850
         * Only UP and DOWN status are supported. Thats why done in COMMIT 
 
2851
         */
 
2852
        if (SetIfEntry(&ifEntryRow) != NO_ERROR) {
 
2853
            snmp_log(LOG_ERR,
 
2854
                     "Error in writeIfEntry case COMMIT with index: %d & adminStatus %d\n",
 
2855
                     ifEntryRow.dwIndex, ifEntryRow.dwAdminStatus);
 
2856
            return SNMP_ERR_COMMITFAILED;
 
2857
        }
 
2858
 
 
2859
    case FREE:                 /* Free any resources allocated */
 
2860
        /*
 
2861
         * No resources have been allocated 
 
2862
         */
 
2863
        break;
 
2864
    }
 
2865
    return SNMP_ERR_NOERROR;
 
2866
}                               /* end of writeIfEntry */
 
2867
#endif                          /* WIN32 cygwin */