2
* Interfaces MIB group implementation - interfaces.c
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
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.
17
#include <net-snmp/net-snmp-config.h>
19
#if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL) && !defined(IFNET_NEEDS_KERNEL_LATE)
21
#define _I_DEFINED_KERNEL
37
#include <sys/param.h>
39
#include <sys/types.h>
43
#if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL) && defined(IFNET_NEEDS_KERNEL_LATE)
45
#define _I_DEFINED_KERNEL
48
#include <sys/socket.h>
50
#ifndef STREAM_NEEDS_KERNEL_ISLANDS
52
#include <sys/stream.h>
55
#if HAVE_SYS_SOCKETVAR_H
56
#include <sys/socketvar.h>
59
#if TIME_WITH_SYS_TIME
60
# if defined (WIN32) || defined (cygwin)
61
# include <sys/timeb.h>
63
# include <sys/time.h>
68
# include <sys/time.h>
74
#include <sys/sockio.h>
80
#include <sys/ioctl.h>
83
#include <netinet/in.h>
88
#if HAVE_NETINET_IN_VAR_H
89
#include <netinet/in_var.h>
92
#include <net/if_var.h>
94
#ifdef _I_DEFINED_KERNEL
97
#ifdef STREAM_NEEDS_KERNEL_ISLANDS
99
#include <sys/stream.h>
103
#include <net/route.h>
105
#if HAVE_NETINET_IN_SYSTM_H
106
#include <netinet/in_systm.h>
108
#if HAVE_SYS_HASHING_H
109
#include <sys/hashing.h>
111
#if HAVE_NETINET_IN_VAR_H
112
#include <netinet/in_var.h>
114
#if HAVE_NETINET_IP_H
115
#include <netinet/ip.h>
117
#ifdef NETSNMP_ENABLE_IPV6
118
#if HAVE_NETINET_IP6_H
119
#include <netinet/ip6.h>
123
#include <sys/queue.h>
125
#if HAVE_NETINET_IP_VAR_H
126
#include <netinet/ip_var.h>
128
#ifdef NETSNMP_ENABLE_IPV6
129
#if HAVE_NETNETSNMP_ENABLE_IPV6_IP6_VAR_H
130
#include <netinet6/ip6_var.h>
133
#if HAVE_NETINET_IN_PCB_H
134
#include <netinet/in_pcb.h>
136
#if HAVE_NETINET_IF_ETHER_H
137
#include <netinet/if_ether.h>
139
#if HAVE_NET_IF_TYPES_H
140
#include <net/if_types.h>
144
#include <net/if_dl.h>
146
#include <sys/net/if_dl.h>
150
#include <inet/mib2.h>
158
#include "kernel_sunos5.h"
165
#include <netinet/mib_kern.h>
172
#if HAVE_SYS_SYSCTL_H
173
#include <sys/sysctl.h>
175
#if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
176
# define USE_SYSCTL_IFLIST
178
# if defined(CTL_NET) && !defined(freebsd2) && !defined(netbsd1)
180
# ifdef NET_RT_IFLIST
182
# define USE_SYSCTL_IFLIST
187
#endif /* defined(freebsd3) */
188
#endif /* HAVE_SYS_SYSCTL_H */
191
#include <osreldate.h>
193
#ifdef NETSNMP_CAN_USE_SYSCTL
194
#include <sys/sysctl.h>
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>
202
#include "interfaces.h"
204
#include "util_funcs.h"
205
#include "sysORTable.h"
207
/* if you want caching enabled for speed retrival purposes, set this to 5?*/
208
#define MINLOADFREQ 0 /* min reload frequency in seconds */
210
static unsigned long LastLoad = 0; /* ET in secs at last table load */
213
extern struct timeval starttime;
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}},
226
{IFADMINSTATUS, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 7}},
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}}
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
249
oid interfaces_variables_oid[] = { SNMP_OID_MIB2, 2 };
250
oid interfaces_module_oid[] = { SNMP_OID_MIB2, 31 };
253
init_interfaces(void)
256
* register ourselves with the agent to handle our mib tree
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");
263
#ifndef USE_SYSCTL_IFLIST
264
#if HAVE_NET_IF_MIB_H
265
init_interfaces_setup();
269
init_kernel_sunos5();
276
* Return interface type using the interface name as a clue.
277
* Returns 1 to imply "other" type if name not recognized.
280
if_type_from_name(const char *pcch)
282
typedef struct _match_if {
285
} *pmatch_if, match_if;
287
static match_if lmatch_if[] = {
293
{0, 0} /* end of list */
297
register pmatch_if pm;
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);
305
return (1); /* in case search fails */
311
static struct ifnet *ifnetaddr_list;
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
326
#if !defined (WIN32) && !defined (cygwin)
328
header_ifEntry(struct variable *vp,
331
int exact, size_t * var_len, WriteMethod ** write_method)
333
#define IFENTRY_NAME_LENGTH 10
334
oid newname[MAX_OID_LEN];
335
register int interface;
338
DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: "));
339
DEBUGMSGOID(("mibII/interfaces", name, *length));
340
DEBUGMSG(("mibII/interfaces", " %d\n", exact));
342
memcpy((char *) newname, (char *) vp->name,
343
(int) vp->namelen * sizeof(oid));
345
* find "next" interface
347
count = Interface_Scan_Get_Count();
348
for (interface = 1; interface <= count; interface++) {
349
newname[IFENTRY_NAME_LENGTH] = (oid) interface;
351
snmp_oid_compare(name, *length, newname,
352
(int) vp->namelen + 1);
353
if ((exact && (result == 0)) || (!exact && (result < 0)))
356
if (interface > count) {
357
DEBUGMSGTL(("mibII/interfaces", "... index out of range\n"));
362
memcpy((char *) name, (char *) newname,
363
((int) vp->namelen + 1) * sizeof(oid));
364
*length = vp->namelen + 1;
366
*var_len = sizeof(long); /* default to 'long' results */
368
DEBUGMSGTL(("mibII/interfaces", "... get I/F stats "));
369
DEBUGMSGOID(("mibII/interfaces", name, *length));
370
DEBUGMSG(("mibII/interfaces", "\n"));
378
var_interfaces(struct variable * vp,
381
int exact, size_t * var_len, WriteMethod ** write_method)
383
if (header_generic(vp, name, length, exact, var_len, write_method) ==
389
long_return = Interface_Scan_Get_Count();
390
return (u_char *) & long_return;
392
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n",
398
#ifdef USE_SYSCTL_IFLIST
400
static u_char *if_list = 0;
401
static const u_char *if_list_end;
402
static size_t if_list_size = 0;
404
struct small_ifaddr {
405
struct in_addr sifa_addr;
406
struct in_addr sifa_netmask;
407
struct in_addr sifa_broadcast;
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 *);
417
Interface_Scan_By_Index(int iindex,
418
struct if_msghdr *if_msg,
419
char *if_name, struct small_ifaddr *sifa)
422
struct if_msghdr *ifp;
423
int have_ifinfo = 0, have_addr = 0;
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));
432
switch (ifp->ifm_type) {
435
const struct sockaddr *a;
437
if (ifp->ifm_index == iindex) {
438
a = get_address(ifp + 1, ifp->ifm_addrs, RTA_IFP);
442
((const struct sockaddr_in *) a)->sin_zero,
443
((const u_char *) a)[5]);
444
if_name[((const u_char *) a)[5]] = 0;
452
struct ifa_msghdr *ifap = (struct ifa_msghdr *) cp;
454
if ((NULL != sifa) && (ifap->ifam_index == iindex)) {
455
const struct in_addr *ia;
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
467
*((struct in_addr *) ((char *) (ifap + 1) + 4));
468
ia = get_in_address((char *) (ifap + 1) + 8,
470
~RTA_NETMASK, RTA_IFA);
474
sifa->sifa_addr = *ia;
475
ia = get_in_address((char *) (ifap + 1) + 8,
476
ifap->ifam_addrs &= ~RTA_NETMASK,
481
sifa->sifa_broadcast = *ia;
487
DEBUGMSGTL(("mibII/interfaces",
488
"routing socket: unknown message type %d\n",
492
if (have_ifinfo && (NULL == sifa) || (have_addr)) {
494
} else if (have_ifinfo && !(if_msg->ifm_flags & IFF_UP))
502
Interface_Scan_Get_Count(void)
505
struct if_msghdr *ifp;
508
Interface_Scan_Init();
511
for (cp = if_list, n = 0; cp < if_list_end; cp += ifp->ifm_msglen) {
512
ifp = (struct if_msghdr *) cp;
514
if (ifp->ifm_type == RTM_IFINFO) {
523
Interface_Scan_Init(void)
525
int name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
528
if (sysctl(name, sizeof(name) / sizeof(int), 0, &size, 0, 0) == -1) {
529
snmp_log(LOG_ERR, "sysctl size fail\n");
531
if (if_list == 0 || if_list_size < size) {
538
if ((if_list = malloc(size)) == NULL) {
540
"out of memory allocating route table (size = %d)\n", size);
547
if (sysctl(name, sizeof(name) / sizeof(int),
548
if_list, &size, 0, 0) == -1) {
549
snmp_log(LOG_ERR, "sysctl get fail\n");
551
if_list_end = if_list + size;
556
var_ifEntry(struct variable *vp,
559
int exact, size_t * var_len, WriteMethod ** write_method)
562
struct if_msghdr if_msg;
563
static char if_name[100];
564
conf_if_list *if_ptr;
568
header_ifEntry(vp, name, length, exact, var_len, write_method);
569
if (interface == MATCH_FAILED)
572
if (Interface_Scan_By_Index(interface, &if_msg, if_name, NULL) != 0)
574
if_ptr = netsnmp_access_interface_entry_overrides_get(if_name);
578
long_return = interface;
579
return (u_char *) & long_return;
582
*var_len = strlen(if_name);
583
return (u_char *) cp;
586
long_return = if_ptr->type;
588
long_return = (long) if_msg.ifm_data.ifi_type;
589
return (u_char *) & long_return;
591
long_return = (long) if_msg.ifm_data.ifi_mtu;
592
return (u_char *) & long_return;
595
long_return = if_ptr->speed;
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;
601
long_return = (u_long) if_msg.ifm_data.ifi_baudrate;
604
return (u_char *) & long_return;
611
long_return = if_msg.ifm_flags & IFF_UP ? 1 : 2;
612
return (u_char *) & long_return;
614
long_return = if_msg.ifm_flags & IFF_RUNNING ? 1 : 2;
615
return (u_char *) & long_return;
620
long_return = (u_long) if_msg.ifm_data.ifi_ibytes;
621
return (u_char *) & long_return;
624
(u_long) if_msg.ifm_data.ifi_ipackets -
625
if_msg.ifm_data.ifi_imcasts;
626
return (u_char *) & long_return;
628
long_return = (u_long) if_msg.ifm_data.ifi_imcasts;
629
return (u_char *) & long_return;
631
long_return = (u_long) if_msg.ifm_data.ifi_iqdrops;
632
return (u_char *) & long_return;
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;
640
long_return = (u_long) if_msg.ifm_data.ifi_obytes;
641
return (u_char *) & 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;
652
long_return = (u_long) if_msg.ifm_data.ifi_odrops;
654
#if NETSNMP_NO_DUMMY_VALUES
659
return (u_char *) & long_return;
661
long_return = (u_long) if_msg.ifm_data.ifi_oerrors;
662
return (u_char *) & long_return;
667
if (if_msg.ifm_data.ifi_lastchange.tv_sec == 0 &&
668
if_msg.ifm_data.ifi_lastchange.tv_usec == 0)
670
else if (if_msg.ifm_data.ifi_lastchange.tv_sec < starttime.tv_sec)
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);
680
return (u_char *) & long_return;
687
Interface_Scan_Next(short *Index,
689
struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr)
694
#else /* not USE_SYSCTL_IFLIST */
696
/*********************
698
* Kernel & interface information,
699
* and internal forward declarations
701
*********************/
703
#ifndef HAVE_NET_IF_MIB_H
707
static int Interface_Scan_By_Index(int, char *, struct ifnet *,
709
static int Interface_Get_Ether_By_Index(int, u_char *);
711
static int Interface_Scan_By_Index(int, char *, nmapi_phystat *);
717
/*********************
719
* System specific implementation functions
721
*********************/
728
var_ifEntry(struct variable *vp,
731
int exact, size_t * var_len, WriteMethod ** write_method)
733
static struct ifnet ifnet;
735
static struct in_ifaddr in_ifaddr;
736
static char Name[16];
738
conf_if_list *if_ptr;
739
#if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC
744
header_ifEntry(vp, name, length, exact, var_len, write_method);
745
if (interface == MATCH_FAILED)
748
Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddr);
749
if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
753
long_return = interface;
754
return (u_char *) & long_return;
757
*var_len = strlen(cp);
758
return (u_char *) cp;
761
long_return = if_ptr->type;
763
#if STRUCT_IFNET_HAS_IF_TYPE
764
long_return = ifnet.if_type;
766
long_return = 1; /* OTHER */
769
return (u_char *) & long_return;
771
long_return = (long) ifnet.if_mtu;
772
return (u_char *) & long_return;
776
long_return = if_ptr->speed;
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;
794
#if NETSNMP_NO_DUMMY_VALUES
797
long_return = (u_long) 10000000;
800
return (u_char *) & long_return;
802
Interface_Get_Ether_By_Index(interface, return_buf);
803
#if defined(aix4) || defined(aix5) || defined(aix6)
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))
813
return (u_char *) return_buf;
815
long_return = ifnet.if_flags & IFF_UP ? 1 : 2;
816
return (u_char *) & long_return;
818
long_return = ifnet.if_flags & IFF_RUNNING ? 1 : 2;
819
return (u_char *) & long_return;
821
#if defined(STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC) && !(defined(freebsd2) && __FreeBSD_version < 199607)
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?)
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.
832
if (ifnet.if_lastchange.tv_sec == 0 &&
833
ifnet.if_lastchange.tv_usec == 0)
835
else if (ifnet.if_lastchange.tv_sec < starttime.tv_sec)
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);
844
#if NETSNMP_NO_DUMMY_VALUES
847
long_return = 0; /* XXX */
849
return (u_char *) & long_return;
851
#ifdef STRUCT_IFNET_HAS_IF_IBYTES
852
#if defined(aix4) || defined(aix5) || defined(aix6)
853
long_return = (u_long) ifnet.if_ibytes & 0xffffffff;
855
long_return = (u_long) ifnet.if_ibytes;
858
#if NETSNMP_NO_DUMMY_VALUES
861
long_return = (u_long) ifnet.if_ipackets * 308; /* XXX */
863
return (u_char *) & long_return;
866
#if defined(aix4) || defined(aix5) || defined(aix6)
867
long_return = (u_long) ifnet.if_ipackets & 0xffffffff;
869
long_return = (u_long) ifnet.if_ipackets;
871
#if STRUCT_IFNET_HAS_IF_IMCASTS
872
#if defined(aix4) || defined(aix5) || defined(aix6)
873
long_return -= (u_long) ifnet.if_imcasts & 0xffffffff;
875
long_return -= (u_long) ifnet.if_imcasts;
879
return (u_char *) & long_return;
881
#if STRUCT_IFNET_HAS_IF_IMCASTS
882
#if defined(aix4) || defined(aix5) || defined(aix6)
883
long_return = (u_long) ifnet.if_imcasts & 0xffffffff;
885
long_return = (u_long) ifnet.if_imcasts;
888
#if NETSNMP_NO_DUMMY_VALUES
891
long_return = (u_long) 0; /* XXX */
893
return (u_char *) & long_return;
895
#if STRUCT_IFNET_HAS_IF_IQDROPS
896
#if defined(aix4) || defined(aix5) || defined(aix6)
897
long_return = (u_long) ifnet.if_iqdrops & 0xffffffff;
899
long_return = (u_long) ifnet.if_iqdrops;
902
#if NETSNMP_NO_DUMMY_VALUES
905
long_return = (u_long) 0; /* XXX */
907
return (u_char *) & long_return;
909
#if defined(aix4) || defined(aix5) || defined(aix6)
910
long_return = (u_long) ifnet.if_ierrors & 0xffffffff;
912
long_return = (u_long) ifnet.if_ierrors;
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;
920
long_return = (u_long) ifnet.if_noproto;
923
#if NETSNMP_NO_DUMMY_VALUES
926
long_return = (u_long) 0; /* XXX */
928
return (u_char *) & long_return;
930
#ifdef STRUCT_IFNET_HAS_IF_OBYTES
931
#if defined(aix4) || defined(aix5) || defined(aix6)
932
long_return = (u_long) ifnet.if_obytes & 0xffffffff;
934
long_return = (u_long) ifnet.if_obytes;
937
#if NETSNMP_NO_DUMMY_VALUES
940
long_return = (u_long) ifnet.if_opackets * 308; /* XXX */
942
return (u_char *) & long_return;
945
#if defined(aix4) || defined(aix5) || defined(aix6)
946
long_return = (u_long) ifnet.if_opackets & 0xffffffff;
948
long_return = (u_long) ifnet.if_opackets;
950
#if STRUCT_IFNET_HAS_IF_OMCASTS
951
#if defined(aix4) || defined(aix5) || defined(aix6)
952
long_return -= (u_long) ifnet.if_omcasts & 0xffffffff;
954
long_return -= (u_long) ifnet.if_omcasts;
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;
964
long_return = (u_long) ifnet.if_omcasts;
967
#if NETSNMP_NO_DUMMY_VALUES
970
long_return = (u_long) 0; /* XXX */
972
return (u_char *) & long_return;
974
#if defined(aix4) || defined(aix5) || defined(aix6)
975
long_return = ifnet.if_snd.ifq_drops & 0xffffffff;
977
long_return = ifnet.if_snd.ifq_drops;
979
return (u_char *) & long_return;
981
#if defined(aix4) || defined(aix5) || defined(aix6)
982
long_return = ifnet.if_oerrors & 0xffffffff;
984
long_return = ifnet.if_oerrors;
986
return (u_char *) & long_return;
988
#if defined(aix4) || defined(aix5) || defined(aix6)
989
long_return = ifnet.if_snd.ifq_len & 0xffffffff;
991
long_return = ifnet.if_snd.ifq_len;
993
return (u_char *) & long_return;
995
*var_len = nullOidLen;
996
return (u_char *) nullOid;
998
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1007
var_ifEntry(struct variable *vp,
1010
int exact, size_t * var_len, WriteMethod ** write_method)
1013
static nmapi_phystat ifnet;
1015
static struct ifnet ifnet;
1017
register int interface;
1018
#if !defined(hpux11)
1019
static struct in_ifaddr in_ifaddrVar;
1022
static char Name[MAX_PHYSADDR_LEN];
1024
static char Name[16];
1027
#if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC
1030
#if !defined(hpux11)
1031
struct nmparms hp_nmparms;
1032
static mib_ifEntry hp_ifEntry;
1034
int hp_len = sizeof(hp_ifEntry);
1036
conf_if_list *if_ptr;
1039
header_ifEntry(vp, name, length, exact, var_len, write_method);
1040
if (interface == MATCH_FAILED)
1044
Interface_Scan_By_Index(interface, Name, &ifnet);
1046
Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddrVar);
1049
#if !defined(hpux11)
1051
* Additional information about the interfaces is available under
1052
* HP-UX through the network management interface '/dev/netman'
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) {
1063
hp_fd = -1; /* failed */
1067
if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
1069
switch (vp->magic) {
1071
long_return = interface;
1072
return (u_char *) & long_return;
1075
cp = ifnet.if_entry.ifDescr;
1078
cp = hp_ifEntry.ifDescr;
1082
*var_len = strlen(cp);
1083
return (u_char *) cp;
1084
case NETSNMP_IFTYPE:
1086
long_return = if_ptr->type;
1089
long_return = ifnet.if_entry.ifType;
1092
long_return = hp_ifEntry.ifType;
1094
long_return = 1; /* OTHER */
1097
return (u_char *) & long_return;
1100
long_return = (long) ifnet.if_entry.ifMtu;
1102
long_return = (long) ifnet.if_mtu;
1104
return (u_char *) & long_return;
1108
long_return = if_ptr->speed;
1111
long_return = ifnet.if_entry.ifSpeed;
1114
long_return = hp_ifEntry.ifSpeed;
1116
long_return = (u_long) 1; /* OTHER */
1119
return (u_char *) & long_return;
1122
*var_len = ifnet.if_entry.ifPhysAddress.o_length;
1123
return (u_char *) ifnet.if_entry.ifPhysAddress.o_bytes;
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))
1132
return (u_char *) return_buf;
1136
long_return = ifnet.if_entry.ifAdmin;
1138
long_return = ifnet.if_flags & IFF_UP ? 1 : 2;
1140
return (u_char *) & long_return;
1143
long_return = ifnet.if_entry.ifOper;
1145
long_return = ifnet.if_flags & IFF_RUNNING ? 1 : 2;
1147
return (u_char *) & long_return;
1150
long_return = ifnet.if_entry.ifLastChange;
1153
long_return = hp_ifEntry.ifLastChange;
1155
long_return = 0; /* XXX */
1157
return (u_char *) & long_return;
1160
long_return = ifnet.if_entry.ifInOctets;
1163
long_return = hp_ifEntry.ifInOctets;
1165
long_return = (u_long) ifnet.if_ipackets * 308; /* XXX */
1167
return (u_char *) & long_return;
1170
long_return = ifnet.if_entry.ifInUcastPkts;
1173
long_return = hp_ifEntry.ifInUcastPkts;
1175
long_return = (u_long) ifnet.if_ipackets;
1177
return (u_char *) & long_return;
1178
case IFINNUCASTPKTS:
1180
long_return = ifnet.if_entry.ifInNUcastPkts;
1183
long_return = hp_ifEntry.ifInNUcastPkts;
1185
long_return = (u_long) 0; /* XXX */
1187
return (u_char *) & long_return;
1190
long_return = ifnet.if_entry.ifInDiscards;
1193
long_return = hp_ifEntry.ifInDiscards;
1195
long_return = (u_long) 0; /* XXX */
1197
return (u_char *) & long_return;
1200
long_return = ifnet.if_entry.ifInErrors;
1202
long_return = ifnet.if_ierrors;
1204
return (u_char *) & long_return;
1205
case IFINUNKNOWNPROTOS:
1207
long_return = ifnet.if_entry.ifInUnknownProtos;
1210
long_return = hp_ifEntry.ifInUnknownProtos;
1212
long_return = (u_long) 0; /* XXX */
1214
return (u_char *) & long_return;
1217
long_return = ifnet.if_entry.ifOutOctets;
1220
long_return = hp_ifEntry.ifOutOctets;
1222
long_return = (u_long) ifnet.if_opackets * 308; /* XXX */
1224
return (u_char *) & long_return;
1225
case IFOUTUCASTPKTS:
1227
long_return = ifnet.if_entry.ifOutUcastPkts;
1230
long_return = hp_ifEntry.ifOutUcastPkts;
1232
long_return = (u_long) ifnet.if_opackets;
1234
return (u_char *) & long_return;
1235
case IFOUTNUCASTPKTS:
1237
long_return = ifnet.if_entry.ifOutNUcastPkts;
1240
long_return = hp_ifEntry.ifOutNUcastPkts;
1242
long_return = (u_long) 0; /* XXX */
1244
return (u_char *) & long_return;
1247
long_return = ifnet.if_entry.ifOutDiscards;
1249
long_return = ifnet.if_snd.ifq_drops;
1251
return (u_char *) & long_return;
1254
long_return = ifnet.if_entry.ifOutErrors;
1256
long_return = ifnet.if_oerrors;
1258
return (u_char *) & long_return;
1261
long_return = ifnet.if_entry.ifOutQlen;
1263
long_return = ifnet.if_snd.ifq_len;
1265
return (u_char *) & long_return;
1267
*var_len = nullOidLen;
1268
return (u_char *) nullOid;
1270
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1277
#else /* solaris2 */
1280
IF_cmp(void *addr, void *ep)
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)
1293
var_ifEntry(struct variable * vp,
1296
int exact, size_t * var_len, WriteMethod ** write_method)
1299
mib2_ifEntry_t ifstat;
1300
conf_if_list *if_ptr = NULL;
1303
header_ifEntry(vp, name, length, exact, var_len, write_method);
1304
if (interface == MATCH_FAILED)
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"));
1313
* hmmm.. where to get the interface name to check overrides?
1315
* if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
1317
switch (vp->magic) {
1319
long_return = ifstat.ifIndex;
1320
return (u_char *) & long_return;
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:
1327
long_return = if_ptr->type;
1329
long_return = (u_long) ifstat.ifType;
1330
return (u_char *) & long_return;
1332
long_return = (u_long) ifstat.ifMtu;
1333
return (u_char *) & long_return;
1336
long_return = if_ptr->speed;
1338
long_return = (u_long) ifstat.ifSpeed;
1339
return (u_char *) & long_return;
1341
*var_len = ifstat.ifPhysAddress.o_length;
1342
(void) memcpy(return_buf, ifstat.ifPhysAddress.o_bytes, *var_len);
1343
return (u_char *) return_buf;
1345
long_return = (u_long) ifstat.ifAdminStatus;
1346
return (u_char *) & long_return;
1348
long_return = (u_long) ifstat.ifOperStatus;
1349
return (u_char *) & long_return;
1351
long_return = (u_long) ifstat.ifLastChange;
1352
return (u_char *) & long_return;
1354
long_return = (u_long) ifstat.ifInOctets;
1355
return (u_char *) & long_return;
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;
1363
long_return = (u_long) ifstat.ifInDiscards;
1364
return (u_char *) & long_return;
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;
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;
1381
long_return = (u_long) ifstat.ifOutDiscards;
1382
return (u_char *) & long_return;
1384
long_return = (u_long) ifstat.ifOutErrors;
1385
return (u_char *) & long_return;
1387
long_return = (u_long) ifstat.ifOutQLen;
1388
return (u_char *) & long_return;
1390
long_return = (u_long) ifstat.ifSpecific;
1391
return (u_char *) & long_return;
1393
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1399
#endif /* solaris2 */
1403
/*********************
1405
* Internal implementation functions
1407
*********************/
1412
#if !defined(sunV3) && !defined(linux) && !defined(hpux11)
1413
static struct in_ifaddr savein_ifaddr;
1415
#if !defined(hpux11)
1416
static struct ifnet *ifnetaddr, saveifnet, *saveifnetaddr;
1417
static char saveName[16];
1419
static int saveIndex = 0;
1422
* Determines network interface speed. It is system specific. Only linux
1423
* realization is made.
1425
unsigned int getIfSpeed(int fd, struct ifreq ifr, unsigned int defaultspeed)
1428
/** temporary expose internal until this module can be re-written */
1430
netsnmp_linux_interface_get_if_speed(int fd, const char *name,
1431
unsigned long long defaultspeed);
1433
return netsnmp_linux_interface_get_if_speed(fd, ifr.ifr_name, defaultspeed);
1435
return defaultspeed;
1440
Interface_Scan_Init(void)
1443
char line[256], ifname_buf[64], *ifname, *ptr;
1445
struct ifnet **ifnetaddr_ptr;
1448
conf_if_list *if_ptr;
1452
* byte pkts errs drop fifo frame cmprs mcst |
1454
* byte pkts errs drop fifo colls carrier compressed
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;
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";
1476
const char *scan_line_to_use;
1477
struct timeval et; /* elapsed time */
1481
#if !defined(hpux11) && defined(IFNET_SYMBOL)
1482
auto_nlist(IFNET_SYMBOL, (char *) &ifnetaddr, sizeof(ifnetaddr));
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 */
1494
LastLoad = et.tv_sec;
1499
while (ifnetaddr_list) {
1500
struct ifnet *old = ifnetaddr_list;
1501
ifnetaddr_list = ifnetaddr_list->if_next;
1508
ifnetaddr_ptr = &ifnetaddr_list;
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); **/
1517
* build up ifnetaddr list by hand:
1521
* at least linux v1.3.53 says EMFILE without reason...
1523
if (!(devin = fopen("/proc/net/dev", "r"))) {
1525
snmp_log(LOG_ERR, "cannot open /proc/net/dev - continuing...\n");
1526
return; /** exit (1); **/
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
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"));
1544
scan_line_to_use = scan_line_2_0;
1545
DEBUGMSGTL(("mibII/interfaces",
1546
"using linux 2.0 kernel /proc/net/dev\n"));
1550
while (fgets(line, sizeof(line), devin)) {
1552
char *stats, *ifstart = line;
1554
if (line[strlen(line) - 1] == '\n')
1555
line[strlen(line) - 1] = '\0';
1557
while (*ifstart && *ifstart == ' ')
1560
if (!*ifstart || ((stats = strrchr(ifstart, ':')) == NULL)) {
1562
"/proc/net/dev data format error, line ==|%s|", line);
1565
if ((scan_line_to_use == scan_line_2_2) && ((stats - line) < 6)) {
1567
"/proc/net/dev data format error, line ==|%s|", line);
1571
strncpy(ifname_buf, ifstart, sizeof(ifname_buf));
1572
ifname_buf[ sizeof(ifname_buf)-1 ] = 0;
1574
while (*stats == ' ')
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,
1585
if ((scan_line_to_use == scan_line_2_2)
1586
&& !strstr(line, "No statistics available"))
1588
"/proc/net/dev data format error, line ==|%s|",
1593
nnew = (struct ifnet *) calloc(1, sizeof(struct ifnet));
1595
break; /* alloc error */
1600
*ifnetaddr_ptr = nnew;
1601
ifnetaddr_ptr = &nnew->if_next;
1605
* linux previous to 1.3.~13 may miss transmitted loopback pkts:
1607
if (!strcmp(ifname_buf, "lo") && rec_pkt > 0 && !snd_pkt)
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;
1621
nnew->if_ibytes = (rec_pkt * 308) & 0xffffffff;
1622
nnew->if_obytes = (snd_pkt * 308) & 0xffffffff;
1626
* ifnames are given as `` eth0'': split in ``eth'' and ``0'':
1628
for (ifname = ifname_buf; *ifname && *ifname == ' '; ifname++);
1631
* set name and interface# :
1633
nnew->if_name = (char *) strdup(ifname);
1634
for (ptr = nnew->if_name; *ptr && (*ptr < '0' || *ptr > '9');
1636
nnew->if_unit = strdup(*ptr ? ptr : "");
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));
1644
nnew->if_addr = ifrq.ifr_addr;
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));
1652
nnew->ifu_broadaddr = ifrq.ifr_broadaddr;
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));
1660
nnew->ia_subnetmask = ifrq.ifr_netmask;
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;
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.
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);
1680
memcpy(nnew->if_hwaddr, ifrq.ifr_hwaddr.sa_data, IFHWADDRLEN);
1682
#ifdef ARPHRD_LOOPBACK
1683
switch (ifrq.ifr_hwaddr.sa_family) {
1688
case ARPHRD_TUNNEL6:
1693
nnew->if_type = 131;
1704
case ARPHRD_LOOPBACK:
1706
break; /* softwareLoopback */
1713
case ARPHRD_LOCALTLK:
1727
* XXX: more if_arp.h:ARPHDR_xxx to IANAifType mappings...
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;
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)
1747
if_ptr = netsnmp_access_interface_entry_overrides_get(ifname);
1749
nnew->if_type = if_ptr->type;
1750
nnew->if_speed = if_ptr->speed;
1753
* do only guess if_type from name, if we could not read
1754
* * it before from SIOCGIFHWADDR
1756
unsigned int defaultspeed = NOMINAL_LINK_SPEED;
1757
if (!(nnew->if_flags & IFF_RUNNING)) {
1759
* use speed 0 if the if speed cannot be determined *and* the
1766
nnew->if_type = if_type_from_name(nnew->if_name);
1767
switch(nnew->if_type) {
1769
nnew->if_speed = getIfSpeed(fd, ifrq, defaultspeed);
1772
nnew->if_speed = 10000000;
1775
nnew->if_speed = 4000000;
1780
/*Zero speed means link problem*/
1781
if(nnew->if_speed == 0 && nnew->if_flags & IFF_UP){
1782
nnew->if_flags &= ~IFF_RUNNING;
1786
} /* while (fgets ... */
1788
ifnetaddr = ifnetaddr_list;
1790
if (snmp_get_do_debugging()) {
1792
struct ifnet *x = ifnetaddr;
1793
DEBUGMSGTL(("mibII/interfaces", "* see: known interfaces:"));
1795
DEBUGMSG(("mibII/interfaces", " %s", x->if_name));
1798
DEBUGMSG(("mibII/interfaces", "\n"));
1809
#if defined(sunV3) || defined(linux)
1811
* ** 4.2 BSD doesn't have ifaddr
1815
Interface_Scan_Next(short *Index,
1817
struct ifnet *Retifnet, struct in_ifaddr *dummy)
1824
* Get the "ifnet" structure and extract the device name
1827
if (!NETSNMP_KLOOKUP(ifnetaddr, (char *) &ifnet, sizeof ifnet)) {
1828
DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
1832
if (!NETSNMP_KLOOKUP(ifnet.if_name, (char *) saveName, sizeof saveName)) {
1833
DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
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.
1844
if (strcmp(saveName, "ip") == 0) {
1845
ifnetaddr = ifnet.if_next;
1850
strncpy(saveName, ifnet.if_name, sizeof(saveName));
1853
saveName[sizeof(saveName) - 1] = '\0';
1854
cp = (char *) strchr(saveName, '\0');
1856
strncat(cp, ifnet.if_unit, sizeof(saveName)-strlen(saveName)-1);
1857
saveName[sizeof(saveName) - 1] = '\0';
1859
string_append_int(cp, ifnet.if_unit);
1861
if (1 || strcmp(saveName, "lo0") != 0) { /* XXX */
1864
*Index = ++saveIndex;
1868
strcpy(Name, saveName);
1870
saveifnetaddr = ifnetaddr;
1871
ifnetaddr = ifnet.if_next;
1873
return (1); /* DONE */
1875
ifnetaddr = ifnet.if_next;
1877
return (0); /* EOF */
1882
Interface_Index_By_Name(char *Name, int Len)
1887
Interface_Scan_Init();
1888
while (Interface_Scan_Next(&ifIndex, ifName, NULL, NULL)
1889
&& strcmp(Name, ifName));
1895
#else /* sunV3 || linux */
1897
#if defined(netbsd1) || defined(openbsd2)
1898
#define ia_next ia_list.tqe_next
1899
#define if_next if_list.tqe_next
1905
Interface_Scan_Next(short *Index, char *Name, nmapi_phystat * Retifnet)
1907
static nmapi_phystat *if_ptr = (nmapi_phystat *) 0;
1908
int count = Interface_Scan_Get_Count();
1915
(nmapi_phystat *) malloc(sizeof(nmapi_phystat) * count);
1917
return (0); /* EOF */
1920
if (saveIndex >= count)
1921
return (0); /* EOF */
1923
ulen = (unsigned int) count *sizeof(nmapi_phystat);
1924
if ((ret = get_physical_stat(if_ptr, &ulen)) < 0)
1925
return (0); /* EOF */
1928
*Retifnet = if_ptr[saveIndex];
1930
strcpy(Name, if_ptr[saveIndex].nm_device);
1934
return (1); /* DONE */
1940
Interface_Scan_Next(short *Index,
1942
struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr)
1945
struct in_ifaddr *ia, in_ifaddr;
1946
short has_ipaddr = 0;
1947
#if !STRUCT_IFNET_HAS_IF_XNAME
1953
* Get the "ifnet" structure and extract the device name
1955
if (!NETSNMP_KLOOKUP(ifnetaddr, (char *) &ifnet, sizeof ifnet)) {
1956
DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
1959
#if STRUCT_IFNET_HAS_IF_XNAME
1960
#if defined(netbsd1) || defined(openbsd2)
1961
strncpy(saveName, ifnet.if_xname, sizeof saveName);
1963
if (!NETSNMP_KLOOKUP(ifnet.if_xname, (char *) saveName, sizeof saveName)) {
1964
DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
1968
saveName[sizeof(saveName) - 1] = '\0';
1970
if (!NETSNMP_KLOOKUP(ifnet.if_name, (char *) saveName, sizeof saveName)) {
1971
DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
1975
saveName[sizeof(saveName) - 1] = '\0';
1976
cp = strchr(saveName, '\0');
1977
string_append_int(cp, ifnet.if_unit);
1979
if (1 || strcmp(saveName, "lo0") != 0) { /* XXX */
1981
* Try to find an address for this interface
1985
ia = (struct in_ifaddr *) ifnet.if_addrlist.tqh_first;
1986
#elif defined(IFADDR_SYMBOL)
1987
auto_nlist(IFADDR_SYMBOL, (char *) &ia, sizeof(ia));
1990
if (!NETSNMP_KLOOKUP(ia, (char *) &in_ifaddr, sizeof(in_ifaddr))) {
1991
DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
1996
#define CP(x) ((char *)(x))
1998
struct sockaddr *sa;
1999
cp = (CP(in_ifaddr.ia_ifa.ifa_addr) - CP(ia)) +
2001
sa = (struct sockaddr *) cp;
2003
if (sa->sa_family == AF_INET)
2005
if (in_ifaddr.ia_ifp == ifnetaddr) {
2006
has_ipaddr = 1; /* this IF has IP-address */
2011
ia = (struct in_ifaddr *) in_ifaddr.ia_ifa.ifa_list.
2014
ia = in_ifaddr.ia_next;
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 */
2022
* ifnet.if_addrlist = (struct ifaddr *)&ia->ia_ifa;
2024
* WRONG DATA TYPE; ONLY A FLAG
2028
*Index = ++saveIndex;
2031
if (Retin_ifaddr && has_ipaddr) /* assign the in_ifaddr only
2032
* if the IF has IP-address */
2033
*Retin_ifaddr = in_ifaddr;
2035
strcpy(Name, saveName);
2037
saveifnetaddr = ifnetaddr;
2038
savein_ifaddr = in_ifaddr;
2039
ifnetaddr = ifnet.if_next;
2041
return (1); /* DONE */
2043
ifnetaddr = ifnet.if_next;
2045
return (0); /* EOF */
2050
#endif /* sunV3 || linux */
2055
Interface_Scan_By_Index(int Index, char *Name, nmapi_phystat * Retifnet)
2059
Interface_Scan_Init();
2060
while (Interface_Scan_Next(&i, Name, Retifnet)) {
2065
return (-1); /* Error, doesn't exist */
2066
return (0); /* DONE */
2072
Interface_Scan_By_Index(int Index,
2074
struct ifnet *Retifnet,
2075
struct in_ifaddr *Retin_ifaddr)
2079
Interface_Scan_Init();
2080
while (Interface_Scan_Next(&i, Name, Retifnet, Retin_ifaddr)) {
2085
return (-1); /* Error, doesn't exist */
2086
return (0); /* DONE */
2091
static int Interface_Count = 0;
2096
Interface_Scan_Get_Count(void)
2098
if (!Interface_Count) {
2105
if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) {
2106
p.objid = ID_ifNumber;
2107
p.buffer = (void *) &val;
2110
if ((ret = get_mib_info(fd, &p)) == 0)
2111
Interface_Count = val;
2115
return (Interface_Count);
2120
static time_t scan_time = 0;
2123
Interface_Scan_Get_Count(void)
2125
time_t time_now = time(NULL);
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) {
2135
return (Interface_Count);
2140
Interface_Get_Ether_By_Index(int Index, u_char * EtherAddr)
2143
#if !(defined(linux) || defined(netbsd1) || defined(bsdi2) || defined(openbsd2))
2144
struct arpcom arpcom;
2145
#else /* is linux or netbsd1 */
2149
#if defined(netbsd1) || defined(bsdi2) || defined(openbsd2)
2150
struct sockaddr_dl sadl;
2151
struct ifaddr ifaddr;
2156
#if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3) || defined(osf5)
2157
memset(arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));
2159
memset(&arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));
2161
memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr));
2163
if (saveIndex != Index) { /* Optimization! */
2165
Interface_Scan_Init();
2167
while (Interface_Scan_Next((short *) &i, NULL, NULL, NULL) != 0) {
2172
return (-1); /* Error, doesn't exist */
2175
if (saveifnet.if_type != IFT_ETHER) {
2176
return (0); /* Not an ethernet if */
2180
* the arpcom structure is an extended ifnet structure which
2181
* contains the ethernet address.
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"));
2189
#else /* netbsd1 or bsdi2 or openbsd2 */
2191
#if defined(netbsd1) || defined(openbsd2)
2192
#define if_addrlist if_addrlist.tqh_first
2193
#define ifa_next ifa_list.tqe_next
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"));
2202
if (!NETSNMP_KLOOKUP(ifaddr.ifa_addr, (char *) &sadl, sizeof sadl)) {
2203
DEBUGMSGTL(("mibII/interfaces:Interface_Get_Ether_By_Index", "klookup failed\n"));
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));
2214
ifaddraddr = (unsigned long) ifaddr.ifa_next;
2216
#endif /* netbsd1 or bsdi2 or openbsd2 */
2219
memcpy(arpcom.ac_enaddr, saveifnetaddr->if_hwaddr, 6);
2221
if (strncmp("lo", saveName, 2) == 0) {
2223
* Loopback doesn't have a HW addr, so return 00:00:00:00:00:00
2225
memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr));
2229
#if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3)
2230
memcpy(EtherAddr, (char *) arpcom.ac_enaddr,
2231
sizeof(arpcom.ac_enaddr));
2233
memcpy(EtherAddr, (char *) &arpcom.ac_enaddr,
2234
sizeof(arpcom.ac_enaddr));
2239
return (0); /* DONE */
2244
#else /* solaris2 */
2247
Interface_Scan_Get_Count(void)
2251
if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
2253
if (ioctl(sd, SIOCGIFNUM, &i) == -1) {
2263
Interface_Index_By_Name(char *Name, int Len)
2265
return (solaris2_if_nametoindex(Name, Len));
2268
#endif /* solaris2 */
2270
#else /* HAVE_NET_IF_MIB_H */
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).
2283
#include <net/if_dl.h>
2284
#include <net/if_mib.h>
2285
#include <net/route.h>
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);
2294
static char *physaddrbuf;
2295
static int nphysaddrs;
2296
struct sockaddr_dl **physaddrs;
2299
init_interfaces_setup(void)
2301
int naddrs, ilen, bit;
2303
= { CTL_NET, PF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
2306
struct rt_msghdr *rtm;
2307
struct if_msghdr *ifm;
2308
struct ifa_msghdr *ifam;
2309
struct sockaddr *sa;
2311
DEBUGMSGTL(("mibII:freebsd", "init_interfaces_setup\n"));
2322
if (sysctl(mib, 6, 0, &len, 0, 0) < 0) {
2323
DEBUGMSGTL(("mibII:freebsd", "sysctl 1 < 0\n"));
2327
cp = physaddrbuf = malloc(len);
2328
if (physaddrbuf == 0)
2330
if (sysctl(mib, 6, physaddrbuf, &len, 0, 0) < 0) {
2333
DEBUGMSGTL(("mibII:freebsd", "sysctl 2 < 0\n"));
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));
2350
ifm = (struct if_msghdr *) rtm;
2351
#if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
2353
physaddrs[naddrs] = (void *) (ifm + 1);
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;
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))
2373
ilen -= ROUND(sa->sa_len);
2374
cp += ROUND(sa->sa_len);
2376
if (bit == RTA_IFA) {
2378
#define satosdl(sa) ((struct sockaddr_dl *)(sa))
2384
sa = (struct sockaddr *) cp;
2387
rtm = (struct rt_msghdr *) cp;
2390
DEBUGMSGTL(("mibII:freebsd", "found %d addrs\n", naddrs));
2392
nphysaddrs = naddrs;
2395
physaddrs = malloc(naddrs * sizeof(*physaddrs));
2404
get_phys_address(int iindex, char **ap, int *len)
2410
for (i = 0; i < nphysaddrs; i++) {
2411
if (physaddrs[i]->sdl_index == iindex)
2416
init_interfaces_setup();
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;
2429
Interface_Scan_Get_Count(void)
2431
static int count_oid[5] = { CTL_NET, PF_LINK, NETLINK_GENERIC,
2432
IFMIB_SYSTEM, IFMIB_IFCOUNT
2438
if (sysctl(count_oid, 5, &count, &len, (void *) 0, (size_t) 0) < 0) {
2439
DEBUGMSGTL(("mibII:freebsd", "Interface_Scan_Get_Count err\n"));
2442
DEBUGMSGTL(("mibII:freebsd", "Interface_Scan_Get_Count %d\n", count));
2448
var_ifEntry(struct variable * vp,
2451
int exact, size_t * var_len, WriteMethod ** write_method)
2454
static int sname[6] = { CTL_NET, PF_LINK, NETLINK_GENERIC,
2455
IFMIB_IFDATA, 0, IFDATA_GENERAL
2457
static struct ifmibdata ifmd;
2460
conf_if_list *if_ptr = NULL;
2462
interface = header_ifEntry(vp, name, length, exact, var_len,
2464
if (interface == MATCH_FAILED)
2467
sname[4] = interface;
2469
if (sysctl(sname, 6, &ifmd, &len, 0, 0) < 0) {
2470
DEBUGMSGTL(("mibII:freebsd", "var_ifEntry sysctl err\n"));
2474
* hmmm.. where to get the interface name to check overrides?
2476
* if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
2479
switch (vp->magic) {
2481
long_return = interface;
2482
return (u_char *) & long_return;
2484
cp = ifmd.ifmd_name;
2485
*var_len = strlen(cp);
2486
return (u_char *) cp;
2487
case NETSNMP_IFTYPE:
2489
long_return = if_ptr->type;
2491
long_return = ifmd.ifmd_data.ifi_type;
2492
return (u_char *) & long_return;
2494
long_return = (long) ifmd.ifmd_data.ifi_mtu;
2495
return (u_char *) & long_return;
2498
long_return = if_ptr->speed;
2500
long_return = ifmd.ifmd_data.ifi_baudrate;
2501
return (u_char *) & long_return;
2505
if (get_phys_address(interface, &cp, var_len))
2511
long_return = ifmd.ifmd_flags & IFF_UP ? 1 : 2;
2512
return (u_char *) & long_return;
2514
long_return = ifmd.ifmd_flags & IFF_RUNNING ? 1 : 2;
2515
return (u_char *) & long_return;
2517
if (ifmd.ifmd_data.ifi_lastchange.tv_sec == 0 &&
2518
ifmd.ifmd_data.ifi_lastchange.tv_usec == 0) {
2520
} else if (ifmd.ifmd_data.ifi_lastchange.tv_sec < starttime.tv_sec) {
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));
2529
return (u_char *) & long_return;
2531
long_return = (u_long) ifmd.ifmd_data.ifi_ibytes;
2532
return (u_char *) & long_return;
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;
2541
long_return = (u_long) ifmd.ifmd_data.ifi_iqdrops;
2542
return (u_char *) & long_return;
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;
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;
2560
long_return = ifmd.ifmd_snd_drops;
2561
return (u_char *) & long_return;
2563
long_return = ifmd.ifmd_data.ifi_oerrors;
2564
return (u_char *) & long_return;
2566
long_return = ifmd.ifmd_snd_len;
2567
return (u_char *) & long_return;
2569
*var_len = nullOidLen;
2570
return (u_char *) nullOid;
2572
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
2578
#endif /* HAVE_NET_IF_MIB_H */
2579
#endif /* !USE_SYSCTL_IFLIST */
2581
#else /* WIN32 cygwin */
2582
#include <iphlpapi.h>
2584
WriteMethod writeIfEntry;
2585
long admin_status = 0;
2586
long oldadmin_status = 0;
2589
header_ifEntry(struct variable *vp,
2592
int exact, size_t * var_len, WriteMethod ** write_method)
2594
#define IFENTRY_NAME_LENGTH 10
2595
oid newname[MAX_OID_LEN];
2596
register int ifIndex;
2598
DWORD status = NO_ERROR;
2599
DWORD statusRetry = NO_ERROR;
2600
DWORD dwActualSize = 0;
2601
PMIB_IFTABLE pIfTable = NULL;
2603
DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: "));
2604
DEBUGMSGOID(("mibII/interfaces", name, *length));
2605
DEBUGMSG(("mibII/interfaces", " %d\n", exact));
2607
memcpy((char *) newname, (char *) vp->name,
2608
(int) vp->namelen * sizeof(oid));
2610
* find "next" ifIndex
2615
* query for buffer size needed
2617
status = GetIfTable(pIfTable, &dwActualSize, TRUE);
2619
if (status == ERROR_INSUFFICIENT_BUFFER) {
2623
pIfTable = (PMIB_IFTABLE) malloc(dwActualSize);
2624
if (pIfTable != NULL) {
2626
* Get the sorted IF table
2628
GetIfTable(pIfTable, &dwActualSize, TRUE);
2631
count = pIfTable->dwNumEntries;
2632
for (ifIndex = 0; ifIndex < count; ifIndex++) {
2633
newname[IFENTRY_NAME_LENGTH] =
2634
(oid) pIfTable->table[ifIndex].dwIndex;
2636
snmp_oid_compare(name, *length, newname,
2637
(int) vp->namelen + 1);
2638
if ((exact && (result == 0)) || (!exact && (result < 0)))
2641
if (ifIndex > count) {
2642
DEBUGMSGTL(("mibII/interfaces", "... index out of range\n"));
2643
return MATCH_FAILED;
2647
memcpy((char *) name, (char *) newname,
2648
((int) vp->namelen + 1) * sizeof(oid));
2649
*length = vp->namelen + 1;
2651
*var_len = sizeof(long); /* default to 'long' results */
2653
DEBUGMSGTL(("mibII/interfaces", "... get I/F stats "));
2654
DEBUGMSGOID(("mibII/interfaces", name, *length));
2655
DEBUGMSG(("mibII/interfaces", "\n"));
2657
count = pIfTable->table[ifIndex].dwIndex;
2665
var_interfaces(struct variable * vp,
2668
int exact, size_t * var_len, WriteMethod ** write_method)
2670
if (header_generic(vp, name, length, exact, var_len, write_method) ==
2674
switch (vp->magic) {
2676
GetNumberOfInterfaces(&long_return);
2677
return (u_char *) & long_return;
2679
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n",
2686
var_ifEntry(struct variable * vp,
2689
int exact, size_t * var_len, WriteMethod ** write_method)
2692
static MIB_IFROW ifRow;
2693
conf_if_list *if_ptr = NULL;
2696
header_ifEntry(vp, name, length, exact, var_len, write_method);
2697
if (ifIndex == MATCH_FAILED)
2700
* hmmm.. where to get the interface name to check overrides?
2702
* if_ptr = netsnmp_access_interface_entry_overrides_get(Name);
2706
* Get the If Table Row by passing index as argument
2708
ifRow.dwIndex = ifIndex;
2709
if (GetIfEntry(&ifRow) != NO_ERROR)
2711
switch (vp->magic) {
2713
long_return = ifIndex;
2714
return (u_char *) & long_return;
2716
*var_len = ifRow.dwDescrLen;
2717
return (u_char *) ifRow.bDescr;
2718
case NETSNMP_IFTYPE:
2720
long_return = if_ptr->type;
2722
long_return = ifRow.dwType;
2723
return (u_char *) & long_return;
2725
long_return = (long) ifRow.dwMtu;
2726
return (u_char *) & long_return;
2729
long_return = if_ptr->speed;
2731
long_return = (long) ifRow.dwSpeed;
2732
return (u_char *) & long_return;
2734
*var_len = ifRow.dwPhysAddrLen;
2735
memcpy(return_buf, ifRow.bPhysAddr, *var_len);
2736
return (u_char *) return_buf;
2738
long_return = ifRow.dwAdminStatus;
2739
admin_status = long_return;
2740
*write_method = writeIfEntry;
2741
return (u_char *) & long_return;
2744
(MIB_IF_OPER_STATUS_OPERATIONAL == ifRow.dwOperStatus) ? 1 : 2;
2745
return (u_char *) & long_return;
2747
long_return = 0 /* XXX not a UNIX epochal time ifRow.dwLastChange */ ;
2748
return (u_char *) & long_return;
2750
long_return = ifRow.dwInOctets;
2751
return (u_char *) & long_return;
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;
2759
long_return = ifRow.dwInDiscards;
2760
return (u_char *) & long_return;
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;
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;
2777
long_return = ifRow.dwOutDiscards;
2778
return (u_char *) & long_return;
2780
long_return = ifRow.dwOutErrors;
2781
return (u_char *) & long_return;
2783
long_return = ifRow.dwOutQLen;
2784
return (u_char *) & long_return;
2786
*var_len = nullOidLen;
2787
return (u_char *) nullOid;
2789
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
2797
writeIfEntry(int action,
2799
u_char var_val_type,
2801
u_char * statP, oid * name, size_t name_len)
2803
MIB_IFROW ifEntryRow;
2804
if ((char) name[9] != IFADMINSTATUS) {
2805
return SNMP_ERR_NOTWRITABLE;
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;
2814
if (var_val_len > sizeof(int)) {
2815
snmp_log(LOG_ERR, "bad length\n");
2816
return SNMP_ERR_WRONGLENGTH;
2820
* The dwAdminStatus member can be MIB_IF_ADMIN_STATUS_UP or MIB_IF_ADMIN_STATUS_DOWN
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;
2829
case RESERVE2: /* Allocate memory and similar resources */
2834
* Save the old value, in case of UNDO
2837
oldadmin_status = admin_status;
2838
admin_status = (int) *var_val;
2841
case UNDO: /* Reverse the SET action and free resources */
2842
admin_status = oldadmin_status;
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;
2850
* Only UP and DOWN status are supported. Thats why done in COMMIT
2852
if (SetIfEntry(&ifEntryRow) != NO_ERROR) {
2854
"Error in writeIfEntry case COMMIT with index: %d & adminStatus %d\n",
2855
ifEntryRow.dwIndex, ifEntryRow.dwAdminStatus);
2856
return SNMP_ERR_COMMITFAILED;
2859
case FREE: /* Free any resources allocated */
2861
* No resources have been allocated
2865
return SNMP_ERR_NOERROR;
2866
} /* end of writeIfEntry */
2867
#endif /* WIN32 cygwin */