2 * Interfaces MIB group implementation - interfaces.c
6 #include <net-snmp/net-snmp-config.h>
8 #if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL) && !defined(IFNET_NEEDS_KERNEL_LATE)
10 #define _I_DEFINED_KERNEL
26 #include <sys/param.h>
28 #include <sys/types.h>
32 #if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL) && defined(IFNET_NEEDS_KERNEL_LATE)
34 #define _I_DEFINED_KERNEL
37 #include <sys/socket.h>
39 #ifndef STREAM_NEEDS_KERNEL_ISLANDS
41 #include <sys/stream.h>
44 #if HAVE_SYS_SOCKETVAR_H
45 #include <sys/socketvar.h>
48 #if TIME_WITH_SYS_TIME
50 # include <sys/timeb.h>
52 # include <sys/time.h>
57 # include <sys/time.h>
63 #include <sys/sockio.h>
69 #include <sys/ioctl.h>
72 #include <netinet/in.h>
78 #include <net/if_var.h>
80 #ifdef _I_DEFINED_KERNEL
83 #ifdef STREAM_NEEDS_KERNEL_ISLANDS
85 #include <sys/stream.h>
89 #include <net/route.h>
91 #if HAVE_NETINET_IN_SYSTM_H
92 #include <netinet/in_systm.h>
94 #if HAVE_SYS_HASHING_H
95 #include <sys/hashing.h>
97 #if HAVE_NETINET_IN_VAR_H
98 #include <netinet/in_var.h>
100 #if HAVE_NETINET_IP_H
101 #include <netinet/ip.h>
104 #if HAVE_NETINET_IP6_H
105 #include <netinet/ip6.h>
109 #include <sys/queue.h>
111 #if HAVE_NETINET_IP_VAR_H
112 #include <netinet/ip_var.h>
115 #if HAVE_NETINET6_IP6_VAR_H
116 #include <netinet6/ip6_var.h>
119 #if HAVE_NETINET_IN_PCB_H
120 #include <netinet/in_pcb.h>
122 #if HAVE_NETINET_IF_ETHER_H
123 #include <netinet/if_ether.h>
125 #if HAVE_NET_IF_TYPES_H
126 #include <net/if_types.h>
130 #include <net/if_dl.h>
132 #include <sys/net/if_dl.h>
136 #include <inet/mib2.h>
148 #include "kernel_sunos5.h"
155 #include <netinet/mib_kern.h>
163 #if HAVE_SYS_SYSCTL_H
164 #include <sys/sysctl.h>
166 #if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
167 # define USE_SYSCTL_IFLIST
169 # if defined(CTL_NET) && !defined(freebsd2) && !defined(netbsd1)
171 # ifdef NET_RT_IFLIST
173 # define USE_SYSCTL_IFLIST
178 #endif /* defined(freebsd3) */
179 #endif /* HAVE_SYS_SYSCTL_H */
182 #include <osreldate.h>
184 #ifdef CAN_USE_SYSCTL
185 #include <sys/sysctl.h>
188 #include <net-snmp/net-snmp-includes.h>
189 #include <net-snmp/agent/net-snmp-agent-includes.h>
190 #include <net-snmp/agent/auto_nlist.h>
192 #include "interfaces.h"
194 #include "util_funcs.h"
196 #ifdef SNMP_SYSOR_MIB
197 #include "sysORTable.h"
200 #include "../../../../../kernel/linux/include/linux/sockios.h" // BRCM global socket ioctl
201 #include <bcmtypes.h>
202 #include <bcmatmapi.h>
206 #define BRCM_IFLASTCHANGE_SUPPORT
208 extern struct timeval starttime;
210 static void parse_interface_config(const char *, char *);
211 static void free_interface_config(void);
213 struct variable3 interfaces_variables[] = {
214 {IFNUMBER, ASN_INTEGER, RONLY, var_interfaces, 1, {1}},
215 {IFINDEX, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 1}},
216 {IFDESCR, ASN_OCTET_STR, RONLY, var_ifEntry, 3, {2, 1, 2}},
217 {IFTYPE, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 3}},
218 {IFMTU, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 4}},
219 {IFSPEED, ASN_GAUGE, RONLY, var_ifEntry, 3, {2, 1, 5}},
220 {IFPHYSADDRESS, ASN_OCTET_STR, RONLY, var_ifEntry, 3, {2, 1, 6}},
222 {IFADMINSTATUS, ASN_INTEGER, RWRITE, var_ifEntry, 3, {2, 1, 7}}, /* brcm, linux can write */
224 {IFADMINSTATUS, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 7}},
225 #endif /* SNMP_SET */
226 {IFOPERSTATUS, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 8}},
227 {IFLASTCHANGE, ASN_TIMETICKS, RONLY, var_ifEntry, 3, {2, 1, 9}},
228 {IFINOCTETS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 10}},
229 {IFINUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 11}},
230 {IFINNUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 12}},
231 {IFINDISCARDS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 13}},
232 {IFINERRORS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 14}},
233 {IFINUNKNOWNPROTOS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 15}},
234 {IFOUTOCTETS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 16}},
235 {IFOUTUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 17}},
236 {IFOUTNUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 18}},
237 {IFOUTDISCARDS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 19}},
238 {IFOUTERRORS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 20}},
239 {IFOUTQLEN, ASN_GAUGE, RONLY, var_ifEntry, 3, {2, 1, 21}},
240 {IFSPECIFIC, ASN_OBJECT_ID, RONLY, var_ifEntry, 3, {2, 1, 22}}
244 #define ARPHRD_CPCS 28 /* CPCS */
245 #define ARPHRD_DSL 29 /* ADSL */
248 * Define the OID pointer to the top of the mib tree that we're
249 * registering underneath, and the OID of the MIB module
251 oid interfaces_variables_oid[] = { SNMP_OID_MIB2, 2 };
252 oid interfaces_module_oid[] = { SNMP_OID_MIB2, 31 };
255 init_interfaces(void)
258 * register ourselves with the agent to handle our mib tree
260 REGISTER_MIB("mibII/interfaces", interfaces_variables, variable3,
261 interfaces_variables_oid);
262 #ifdef SNMP_SYSOR_MIB
263 REGISTER_SYSOR_ENTRY(interfaces_module_oid,
264 "The MIB module to describe generic objects for network interface sub-layers");
265 #endif /* SNMP_SYSOR_MIB */
267 snmpd_register_config_handler("interface", parse_interface_config,
268 free_interface_config,
271 #ifndef USE_SYSCTL_IFLIST
272 #if HAVE_NET_IF_MIB_H
273 init_interfaces_setup();
277 init_kernel_sunos5();
284 * Return interface type using the interface name as a clue.
285 * Returns 1 to imply "other" type if name not recognized.
288 if_type_from_name(const char *pcch)
290 typedef struct _match_if {
293 } *pmatch_if, match_if;
295 static match_if lmatch_if[] = {
301 {0, 0} /* end of list */
305 register pmatch_if pm;
307 for (ii = 0, pm = lmatch_if; pm->mi_name; pm++) {
308 len = strlen(pm->mi_name);
309 if (0 == strncmp(pcch, pm->mi_name, len)) {
310 return (pm->mi_type);
313 return (1); /* in case search fails */
318 typedef struct _conf_if_list {
322 struct _conf_if_list *next;
325 static conf_if_list *conf_list;
327 static struct ifnet *ifnetaddr_list;
331 parse_interface_config(const char *token, char *cptr)
333 conf_if_list *if_ptr, *if_new;
334 char *name, *type, *speed, *ecp;
336 name = strtok(cptr, " \t");
338 config_perror("Missing NAME parameter");
341 type = strtok(NULL, " \t");
343 config_perror("Missing TYPE parameter");
346 speed = strtok(NULL, " \t");
348 config_perror("Missing SPEED parameter");
353 if (strcmp(if_ptr->name, name))
354 if_ptr = if_ptr->next;
358 config_pwarn("Duplicate interface specification");
359 if_new = (conf_if_list *) malloc(sizeof(conf_if_list));
361 config_perror("Out of memory");
364 if_new->speed = strtoul(speed, &ecp, 0);
366 config_perror("Bad SPEED value");
370 if_new->type = strtol(type, &ecp, 0);
371 if (*ecp || if_new->type < 0) {
372 config_perror("Bad TYPE");
376 if_new->name = strdup(name);
378 config_perror("Out of memory");
382 if_new->next = conf_list;
387 free_interface_config(void)
389 conf_if_list *if_ptr = conf_list, *if_next;
391 if_next = if_ptr->next;
404 * vp IN - pointer to variable entry that points here
405 * name IN/OUT - IN/name requested, OUT/name found
406 * length IN/OUT - length of IN/OUT oid's
407 * exact IN - TRUE if an exact match was requested
408 * var_len OUT - length of variable or 0 if function returned
413 WriteMethod writeIfEntry;
415 header_ifEntry(struct variable *vp,
418 int exact, size_t * var_len, WriteMethod ** write_method)
420 #define IFENTRY_NAME_LENGTH 10
421 oid newname[MAX_OID_LEN];
422 register int interface;
425 DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: "));
426 DEBUGMSGOID(("mibII/interfaces", name, *length));
427 DEBUGMSG(("mibII/interfaces", " %d\n", exact));
429 memcpy((char *) newname, (char *) vp->name,
430 (int) vp->namelen * sizeof(oid));
432 * find "next" interface
434 count = Interface_Scan_Get_Count();
435 for (interface = 1; interface <= count; interface++) {
436 newname[IFENTRY_NAME_LENGTH] = (oid) interface;
438 snmp_oid_compare(name, *length, newname,
439 (int) vp->namelen + 1);
440 if ((exact && (result == 0)) || (!exact && (result < 0)))
443 if (interface > count) {
444 DEBUGMSGTL(("mibII/interfaces", "... index out of range\n"));
449 memcpy((char *) name, (char *) newname,
450 ((int) vp->namelen + 1) * sizeof(oid));
451 *length = vp->namelen + 1;
453 /* brcm: write is now supported on linux as well */
454 *write_method = writeIfEntry;
456 *write_method = NULL;
457 #endif /* SNMP_SET */
458 *var_len = sizeof(long); /* default to 'long' results */
460 DEBUGMSGTL(("mibII/interfaces", "... get I/F stats "));
461 DEBUGMSGOID(("mibII/interfaces", name, *length));
462 DEBUGMSG(("mibII/interfaces", "\n"));
470 var_interfaces(struct variable * vp,
473 int exact, size_t * var_len, WriteMethod ** write_method)
475 if (header_generic(vp, name, length, exact, var_len, write_method) ==
481 long_return = Interface_Scan_Get_Count();
482 return (u_char *) & long_return;
484 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n",
490 #ifdef USE_SYSCTL_IFLIST
492 static u_char *if_list = 0;
493 static const u_char *if_list_end;
494 static size_t if_list_size = 0;
496 struct small_ifaddr {
497 struct in_addr sifa_addr;
498 struct in_addr sifa_netmask;
499 struct in_addr sifa_broadcast;
502 extern const struct sockaddr *get_address(const void *, int, int);
503 extern const struct in_addr *get_in_address(const void *, int, int);
504 static int Interface_Scan_By_Index(int, struct if_msghdr *, char *,
505 struct small_ifaddr *);
506 static int Interface_Get_Ether_By_Index(int, u_char *);
509 Interface_Scan_By_Index(int iindex,
510 struct if_msghdr *if_msg,
511 char *if_name, struct small_ifaddr *sifa)
514 struct if_msghdr *ifp;
515 int have_ifinfo = 0, have_addr = 0;
517 memset(sifa, 0, sizeof(*sifa));
518 for (cp = if_list; cp < if_list_end; cp += ifp->ifm_msglen) {
519 ifp = (struct if_msghdr *) cp;
520 DEBUGMSGTL(("mibII/interfaces", "ifm_type = %d, ifm_index = %d\n",
521 ifp->ifm_type, ifp->ifm_index));
523 switch (ifp->ifm_type) {
526 const struct sockaddr *a;
528 if (ifp->ifm_index == iindex) {
529 a = get_address(ifp + 1, ifp->ifm_addrs, RTA_IFP);
533 ((const struct sockaddr_in *) a)->sin_zero,
534 ((const u_char *) a)[5]);
535 if_name[((const u_char *) a)[5]] = 0;
543 struct ifa_msghdr *ifap = (struct ifa_msghdr *) cp;
545 if (ifap->ifam_index == iindex) {
546 const struct in_addr *ia;
549 * I don't know why the normal get_address() doesn't
550 * work on IRIX 6.2. Maybe this has to do with the
551 * existence of struct sockaddr_new. Hopefully, on
552 * other systems we can simply use get_in_address
553 * three times, with (ifap+1) as the starting
558 *((struct in_addr *) ((char *) (ifap + 1) + 4));
559 ia = get_in_address((char *) (ifap + 1) + 8,
561 ~RTA_NETMASK, RTA_IFA);
565 sifa->sifa_addr = *ia;
566 ia = get_in_address((char *) (ifap + 1) + 8,
567 ifap->ifam_addrs &= ~RTA_NETMASK,
572 sifa->sifa_broadcast = *ia;
578 DEBUGMSGTL(("mibII/interfaces",
579 "routing socket: unknown message type %d\n",
583 if (have_ifinfo && have_addr) {
585 } else if (have_ifinfo && !(if_msg->ifm_flags & IFF_UP))
593 Interface_Scan_Get_Count(void)
596 struct if_msghdr *ifp;
599 Interface_Scan_Init();
602 for (cp = if_list, n = 0; cp < if_list_end; cp += ifp->ifm_msglen) {
603 ifp = (struct if_msghdr *) cp;
605 if (ifp->ifm_type == RTM_IFINFO) {
614 Interface_Scan_Init(void)
616 int name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
619 if (sysctl(name, sizeof(name) / sizeof(int), 0, &size, 0, 0) == -1) {
620 snmp_log(LOG_ERR, "sysctl size fail\n");
622 if (if_list == 0 || if_list_size < size) {
629 if ((if_list = malloc(size)) == NULL) {
631 "out of memory allocating route table (size = %d)\n", size);
638 if (sysctl(name, sizeof(name) / sizeof(int),
639 if_list, &size, 0, 0) == -1) {
640 snmp_log(LOG_ERR, "sysctl get fail\n");
642 if_list_end = if_list + size;
647 var_ifEntry(struct variable *vp,
650 int exact, size_t * var_len, WriteMethod ** write_method)
653 struct if_msghdr if_msg;
654 static char if_name[100];
655 struct small_ifaddr sifa;
659 header_ifEntry(vp, name, length, exact, var_len, write_method);
660 if (interface == MATCH_FAILED)
663 if (Interface_Scan_By_Index(interface, &if_msg, if_name, &sifa) != 0)
668 long_return = interface;
669 return (u_char *) & long_return;
672 *var_len = strlen(if_name);
673 return (u_char *) cp;
675 long_return = (long) if_msg.ifm_data.ifi_type;
676 return (u_char *) & long_return;
678 long_return = (long) if_msg.ifm_data.ifi_mtu;
679 return (u_char *) & long_return;
681 #if STRUCT_IFNET_HAS_IF_BAUDRATE_IFS_VALUE
682 long_return = (u_long) if_msg.ifm_data.ifi_baudrate.ifs_value <<
683 if_msg.ifm_data.ifi_baudrate.ifs_log2;
685 long_return = (u_long) if_msg.ifm_data.ifi_baudrate;
687 return (u_char *) & long_return;
694 long_return = if_msg.ifm_flags & IFF_UP ? 1 : 2;
695 return (u_char *) & long_return;
697 long_return = if_msg.ifm_flags & IFF_RUNNING ? 1 : 2;
698 return (u_char *) & long_return;
703 long_return = (u_long) if_msg.ifm_data.ifi_ibytes;
704 return (u_char *) & long_return;
707 (u_long) if_msg.ifm_data.ifi_ipackets -
708 if_msg.ifm_data.ifi_imcasts;
709 return (u_char *) & long_return;
711 long_return = (u_long) if_msg.ifm_data.ifi_imcasts;
712 return (u_char *) & long_return;
714 long_return = (u_long) if_msg.ifm_data.ifi_iqdrops;
715 return (u_char *) & long_return;
717 long_return = (u_long) if_msg.ifm_data.ifi_ierrors;
718 return (u_char *) & long_return;
719 case IFINUNKNOWNPROTOS:
720 long_return = (u_long) if_msg.ifm_data.ifi_noproto;
721 return (u_char *) & long_return;
723 long_return = (u_long) if_msg.ifm_data.ifi_obytes;
724 return (u_char *) & long_return;
727 (u_long) if_msg.ifm_data.ifi_opackets -
728 if_msg.ifm_data.ifi_omcasts;
729 return (u_char *) & long_return;
730 case IFOUTNUCASTPKTS:
731 long_return = (u_long) if_msg.ifm_data.ifi_omcasts;
732 return (u_char *) & long_return;
735 long_return = (u_long) if_msg.ifm_data.ifi_odrops;
742 return (u_char *) & long_return;
744 long_return = (u_long) if_msg.ifm_data.ifi_oerrors;
745 return (u_char *) & long_return;
750 if (if_msg.ifm_data.ifi_lastchange.tv_sec == 0 &&
751 if_msg.ifm_data.ifi_lastchange.tv_usec == 0)
753 else if (if_msg.ifm_data.ifi_lastchange.tv_sec < starttime.tv_sec)
756 long_return = (u_long)
757 ((if_msg.ifm_data.ifi_lastchange.tv_sec -
758 starttime.tv_sec) * 100 +
759 (if_msg.ifm_data.ifi_lastchange.tv_usec -
760 starttime.tv_usec) / 10000);
763 return (u_char *) & long_return;
770 Interface_Scan_Next(short *Index,
772 struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr)
777 #else /* not USE_SYSCTL_IFLIST */
779 /*********************
781 * Kernel & interface information,
782 * and internal forward declarations
784 *********************/
786 #ifndef HAVE_NET_IF_MIB_H
790 static int Interface_Scan_By_Index(int, char *, struct ifnet *,
792 static int Interface_Get_Ether_By_Index(int, u_char *);
794 static int Interface_Scan_By_Index(int, char *, nmapi_phystat *);
800 /*********************
802 * System specific implementation functions
804 *********************/
811 var_ifEntry(struct variable *vp,
814 int exact, size_t * var_len, WriteMethod ** write_method)
816 static struct ifnet ifnet;
818 static struct in_ifaddr in_ifaddr;
819 static char Name[16];
821 conf_if_list *if_ptr = conf_list;
822 #if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC
827 header_ifEntry(vp, name, length, exact, var_len, write_method);
828 if (interface == MATCH_FAILED)
831 Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddr);
832 while (if_ptr && strcmp(Name, if_ptr->name))
833 if_ptr = if_ptr->next;
837 long_return = interface;
838 return (u_char *) & long_return;
841 *var_len = strlen(cp);
842 return (u_char *) cp;
845 long_return = if_ptr->type;
847 #if STRUCT_IFNET_HAS_IF_TYPE
848 long_return = ifnet.if_type;
850 long_return = 1; /* OTHER */
853 return (u_char *) & long_return;
855 long_return = (long) ifnet.if_mtu;
856 return (u_char *) & long_return;
860 long_return = if_ptr->speed;
862 #if STRUCT_IFNET_HAS_IF_BAUDRATE
863 long_return = ifnet.if_baudrate;
864 #elif STRUCT_IFNET_HAS_IF_SPEED
865 long_return = ifnet.if_speed;
866 #elif STRUCT_IFNET_HAS_IF_TYPE && defined(IFT_ETHER)
867 if (ifnet.if_type == IFT_ETHER)
868 long_return = 10000000;
869 if (ifnet.if_type == IFT_P10)
870 long_return = 10000000;
871 if (ifnet.if_type == IFT_P80)
872 long_return = 80000000;
873 if (ifnet.if_type == IFT_ISDNBASIC)
874 long_return = 64000; /* EDSS1 only */
875 if (ifnet.if_type == IFT_ISDNPRIMARY)
876 long_return = 64000 * 30;
881 long_return = (u_long) 10000000;
884 return (u_char *) & long_return;
886 Interface_Get_Ether_By_Index(interface, return_buf);
888 if ((return_buf[0] == 0) && (return_buf[1] == 0) &&
889 (return_buf[2] == 0) && (return_buf[3] == 0) &&
890 (return_buf[4] == 0) && (return_buf[5] == 0))
892 return (u_char *) return_buf;
894 long_return = ifnet.if_flags & IFF_UP ? 1 : 2;
895 return (u_char *) & long_return;
897 long_return = ifnet.if_flags & IFF_RUNNING ? 1 : 2;
898 return (u_char *) & long_return;
900 #if defined(STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC) && !(defined(freebsd2) && __FreeBSD_version < 199607)
902 * XXX - SNMP's ifLastchange is time when op. status changed
903 * * FreeBSD's if_lastchange is time when packet was input or output
904 * * (at least in 2.1.0-RELEASE. Changed in later versions of the kernel?)
907 * FreeBSD's if_lastchange before the 2.1.5 release is the time when
908 * * a packet was last input or output. In the 2.1.5 and later releases,
909 * * this is fixed, thus the 199607 comparison.
911 if (ifnet.if_lastchange.tv_sec == 0 &&
912 ifnet.if_lastchange.tv_usec == 0)
914 else if (ifnet.if_lastchange.tv_sec < starttime.tv_sec)
917 long_return = (u_long)
918 ((ifnet.if_lastchange.tv_sec - starttime.tv_sec) * 100
919 + (ifnet.if_lastchange.tv_usec -
920 starttime.tv_usec) / 10000);
923 #ifdef BRCM_IFLASTCHANGE_SUPPORT
924 /* brcm - if_lastchange now supported */
925 long_return = ifnet.if_lastchange;
932 return (u_char *) & long_return;
934 #ifdef STRUCT_IFNET_HAS_IF_IBYTES
935 long_return = (u_long) ifnet.if_ibytes;
940 long_return = (u_long) ifnet.if_ipackets * 308; /* XXX */
942 return (u_char *) & long_return;
945 long_return = (u_long) ifnet.if_ipackets;
946 #if STRUCT_IFNET_HAS_IF_IMCASTS
947 long_return -= (u_long) ifnet.if_imcasts;
950 return (u_char *) & long_return;
952 #if STRUCT_IFNET_HAS_IF_IMCASTS
953 long_return = (u_long) ifnet.if_imcasts;
958 long_return = (u_long) 0; /* XXX */
960 return (u_char *) & long_return;
962 #if STRUCT_IFNET_HAS_IF_IQDROPS
963 long_return = (u_long) ifnet.if_iqdrops;
968 long_return = (u_long) 0; /* XXX */
970 return (u_char *) & long_return;
972 long_return = (u_long) ifnet.if_ierrors;
973 return (u_char *) & long_return;
974 case IFINUNKNOWNPROTOS:
975 #if STRUCT_IFNET_HAS_IF_NOPROTO
976 long_return = (u_long) ifnet.if_noproto;
981 long_return = (u_long) 0; /* XXX */
983 return (u_char *) & long_return;
985 #ifdef STRUCT_IFNET_HAS_IF_OBYTES
986 long_return = (u_long) ifnet.if_obytes;
991 long_return = (u_long) ifnet.if_opackets * 308; /* XXX */
993 return (u_char *) & long_return;
996 long_return = (u_long) ifnet.if_opackets;
997 #if STRUCT_IFNET_HAS_IF_OMCASTS
998 long_return -= (u_long) ifnet.if_omcasts;
1001 return (u_char *) & long_return;
1002 case IFOUTNUCASTPKTS:
1003 #if STRUCT_IFNET_HAS_IF_OMCASTS
1004 long_return = (u_long) ifnet.if_omcasts;
1009 long_return = (u_long) 0; /* XXX */
1011 return (u_char *) & long_return;
1013 long_return = ifnet.if_snd.ifq_drops;
1014 return (u_char *) & long_return;
1016 long_return = ifnet.if_oerrors;
1017 return (u_char *) & long_return;
1019 long_return = ifnet.if_snd.ifq_len;
1020 return (u_char *) & long_return;
1022 *var_len = nullOidLen;
1023 return (u_char *) nullOid;
1025 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1034 var_ifEntry(struct variable *vp,
1037 int exact, size_t * var_len, WriteMethod ** write_method)
1040 static nmapi_phystat ifnet;
1042 static struct ifnet ifnet;
1044 register int interface;
1045 #if !defined(hpux11)
1046 static struct in_ifaddr in_ifaddrVar;
1049 static char Name[MAX_PHYSADDR_LEN];
1051 static char Name[16];
1054 #if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC
1057 #if !defined(hpux11)
1058 struct nmparms hp_nmparms;
1059 static mib_ifEntry hp_ifEntry;
1061 int hp_len = sizeof(hp_ifEntry);
1066 header_ifEntry(vp, name, length, exact, var_len, write_method);
1067 if (interface == MATCH_FAILED)
1071 Interface_Scan_By_Index(interface, Name, &ifnet);
1073 Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddrVar);
1076 #if !defined(hpux11)
1078 * Additional information about the interfaces is available under
1079 * HP-UX through the network management interface '/dev/netman'
1081 hp_ifEntry.ifIndex = interface;
1082 hp_nmparms.objid = ID_ifEntry;
1083 hp_nmparms.buffer = (char *) &hp_ifEntry;
1084 hp_nmparms.len = &hp_len;
1085 if ((hp_fd = open("/dev/netman", O_RDONLY)) != -1) {
1086 if (ioctl(hp_fd, NMIOGET, &hp_nmparms) != -1) {
1090 hp_fd = -1; /* failed */
1095 switch (vp->magic) {
1097 long_return = interface;
1098 return (u_char *) & long_return;
1101 cp = ifnet.if_entry.ifDescr;
1104 cp = hp_ifEntry.ifDescr;
1108 *var_len = strlen(cp);
1109 return (u_char *) cp;
1112 long_return = ifnet.if_entry.ifType;
1115 long_return = hp_ifEntry.ifType;
1117 long_return = 1; /* OTHER */
1119 return (u_char *) & long_return;
1122 long_return = (long) ifnet.if_entry.ifMtu;
1124 long_return = (long) ifnet.if_mtu;
1126 return (u_char *) & long_return;
1130 long_return = ifnet.if_entry.ifSpeed;
1133 long_return = hp_ifEntry.ifSpeed;
1135 long_return = (u_long) 1; /* OTHER */
1137 return (u_char *) & long_return;
1140 *var_len = ifnet.if_entry.ifPhysAddress.o_length;
1141 return (u_char *) ifnet.if_entry.ifPhysAddress.o_bytes;
1143 Interface_Get_Ether_By_Index(interface, return_buf);
1145 if ((return_buf[0] == 0) && (return_buf[1] == 0) &&
1146 (return_buf[2] == 0) && (return_buf[3] == 0) &&
1147 (return_buf[4] == 0) && (return_buf[5] == 0))
1149 return (u_char *) return_buf;
1153 long_return = ifnet.if_entry.ifAdmin;
1155 long_return = ifnet.if_flags & IFF_UP ? 1 : 2;
1157 return (u_char *) & long_return;
1160 long_return = ifnet.if_entry.ifOper;
1162 long_return = ifnet.if_flags & IFF_RUNNING ? 1 : 2;
1164 return (u_char *) & long_return;
1167 long_return = ifnet.if_entry.ifLastChange;
1170 long_return = hp_ifEntry.ifLastChange;
1172 long_return = 0; /* XXX */
1174 return (u_char *) & long_return;
1177 long_return = ifnet.if_entry.ifInOctets;
1180 long_return = hp_ifEntry.ifInOctets;
1182 long_return = (u_long) ifnet.if_ipackets * 308; /* XXX */
1184 return (u_char *) & long_return;
1187 long_return = ifnet.if_entry.ifInUcastPkts;
1190 long_return = hp_ifEntry.ifInUcastPkts;
1192 long_return = (u_long) ifnet.if_ipackets;
1194 return (u_char *) & long_return;
1195 case IFINNUCASTPKTS:
1197 long_return = ifnet.if_entry.ifInNUcastPkts;
1200 long_return = hp_ifEntry.ifInNUcastPkts;
1202 long_return = (u_long) 0; /* XXX */
1204 return (u_char *) & long_return;
1207 long_return = ifnet.if_entry.ifInDiscards;
1210 long_return = hp_ifEntry.ifInDiscards;
1212 long_return = (u_long) 0; /* XXX */
1214 return (u_char *) & long_return;
1217 long_return = ifnet.if_entry.ifInErrors;
1219 long_return = ifnet.if_ierrors;
1221 return (u_char *) & long_return;
1222 case IFINUNKNOWNPROTOS:
1224 long_return = ifnet.if_entry.ifInUnknownProtos;
1227 long_return = hp_ifEntry.ifInUnknownProtos;
1229 long_return = (u_long) 0; /* XXX */
1231 return (u_char *) & long_return;
1234 long_return = ifnet.if_entry.ifOutOctets;
1237 long_return = hp_ifEntry.ifOutOctets;
1239 long_return = (u_long) ifnet.if_opackets * 308; /* XXX */
1241 return (u_char *) & long_return;
1242 case IFOUTUCASTPKTS:
1244 long_return = ifnet.if_entry.ifOutUcastPkts;
1247 long_return = hp_ifEntry.ifOutUcastPkts;
1249 long_return = (u_long) ifnet.if_opackets;
1251 return (u_char *) & long_return;
1252 case IFOUTNUCASTPKTS:
1254 long_return = ifnet.if_entry.ifOutNUcastPkts;
1257 long_return = hp_ifEntry.ifOutNUcastPkts;
1259 long_return = (u_long) 0; /* XXX */
1261 return (u_char *) & long_return;
1264 long_return = ifnet.if_entry.ifOutDiscards;
1266 long_return = ifnet.if_snd.ifq_drops;
1268 return (u_char *) & long_return;
1271 long_return = ifnet.if_entry.ifOutErrors;
1273 long_return = ifnet.if_oerrors;
1275 return (u_char *) & long_return;
1278 long_return = ifnet.if_entry.ifOutQlen;
1280 long_return = ifnet.if_snd.ifq_len;
1282 return (u_char *) & long_return;
1284 *var_len = nullOidLen;
1285 return (u_char *) nullOid;
1287 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1294 #else /* solaris2 */
1297 IF_cmp(void *addr, void *ep)
1299 DEBUGMSGTL(("mibII/interfaces", "... IF_cmp %d %d\n",
1300 ((mib2_ifEntry_t *) ep)->ifIndex,
1301 ((mib2_ifEntry_t *) addr)->ifIndex));
1302 if (((mib2_ifEntry_t *) ep)->ifIndex ==
1303 ((mib2_ifEntry_t *) addr)->ifIndex)
1310 var_ifEntry(struct variable * vp,
1313 int exact, size_t * var_len, WriteMethod ** write_method)
1316 mib2_ifEntry_t ifstat;
1320 header_ifEntry(vp, name, length, exact, var_len, write_method);
1321 if (interface == MATCH_FAILED)
1324 if (getMibstat(MIB_INTERFACES, &ifstat, sizeof(mib2_ifEntry_t),
1325 GET_EXACT, &IF_cmp, &interface) != 0) {
1326 DEBUGMSGTL(("mibII/interfaces", "... no mib stats\n"));
1329 switch (vp->magic) {
1331 long_return = ifstat.ifIndex;
1332 return (u_char *) & long_return;
1334 *var_len = ifstat.ifDescr.o_length;
1335 (void) memcpy(return_buf, ifstat.ifDescr.o_bytes, *var_len);
1336 return (u_char *) return_buf;
1338 long_return = (u_long) ifstat.ifType;
1339 return (u_char *) & long_return;
1341 long_return = (u_long) ifstat.ifMtu;
1342 return (u_char *) & long_return;
1344 long_return = (u_long) ifstat.ifSpeed;
1345 return (u_char *) & long_return;
1347 *var_len = ifstat.ifPhysAddress.o_length;
1348 (void) memcpy(return_buf, ifstat.ifPhysAddress.o_bytes, *var_len);
1349 return (u_char *) return_buf;
1351 long_return = (u_long) ifstat.ifAdminStatus;
1352 return (u_char *) & long_return;
1354 long_return = (u_long) ifstat.ifOperStatus;
1355 return (u_char *) & long_return;
1357 long_return = (u_long) ifstat.ifLastChange;
1358 return (u_char *) & long_return;
1360 long_return = (u_long) ifstat.ifInOctets;
1361 return (u_char *) & long_return;
1363 long_return = (u_long) ifstat.ifInUcastPkts;
1364 return (u_char *) & long_return;
1365 case IFINNUCASTPKTS:
1366 long_return = (u_long) ifstat.ifInNUcastPkts;
1367 return (u_char *) & long_return;
1369 long_return = (u_long) ifstat.ifInDiscards;
1370 return (u_char *) & long_return;
1372 long_return = (u_long) ifstat.ifInErrors;
1373 return (u_char *) & long_return;
1374 case IFINUNKNOWNPROTOS:
1375 long_return = (u_long) ifstat.ifInUnknownProtos;
1376 return (u_char *) & long_return;
1378 long_return = (u_long) ifstat.ifOutOctets;
1379 return (u_char *) & long_return;
1380 case IFOUTUCASTPKTS:
1381 long_return = (u_long) ifstat.ifOutUcastPkts;
1382 return (u_char *) & long_return;
1383 case IFOUTNUCASTPKTS:
1384 long_return = (u_long) ifstat.ifOutNUcastPkts;
1385 return (u_char *) & long_return;
1387 long_return = (u_long) ifstat.ifOutDiscards;
1388 return (u_char *) & long_return;
1390 long_return = (u_long) ifstat.ifOutErrors;
1391 return (u_char *) & long_return;
1393 long_return = (u_long) ifstat.ifOutQLen;
1394 return (u_char *) & long_return;
1396 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1402 #endif /* solaris2 */
1406 /*********************
1408 * Internal implementation functions
1410 *********************/
1415 #if !defined(sunV3) && !defined(linux) && !defined(hpux11)
1416 static struct in_ifaddr savein_ifaddr;
1418 #if !defined(hpux11)
1419 static struct ifnet *ifnetaddr, saveifnet, *saveifnetaddr;
1420 static char saveName[16];
1422 static int saveIndex = 0;
1425 * Determines network interface speed. It is system specific. Only linux
1426 * realization is made.
1428 unsigned int getIfSpeed(int fd, struct ifreq ifr){
1429 unsigned int retspeed = 10000000;
1431 /* the code is based on mii-diag utility by Donald Becker
1432 * see ftp://ftp.scyld.com/pub/diag/mii-diag.c
1434 ushort *data = (ushort *)(&ifr.ifr_data);
1435 /* brcm: not used, remove warning */
1436 /* unsigned int *data32 = (unsigned int *)(&ifr.ifr_data); */
1438 unsigned char new_ioctl_nums = 0;
1441 ushort bmcr, bmsr, nway_advert, lkpar;
1442 const unsigned int media_speeds[] = {10000000, 10000000, 100000000, 100000000, 10000000, 0};
1443 /* It corresponds to "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD", "100baseT4", "Flow-control", 0, */
1448 if (ioctl(fd, 0x8947, &ifr) >= 0) {
1450 } else if (ioctl(fd, SIOCDEVPRIVATE, &ifr) >= 0) {
1453 DEBUGMSGTL(("mibII/interfaces", "SIOCGMIIPHY on %s failed\n", ifr.ifr_name));
1456 /* Begin getting mii register values */
1458 for (mii_reg = 0; mii_reg < 8; mii_reg++){
1461 if(ioctl(fd, new_ioctl_nums ? 0x8948 : SIOCDEVPRIVATE+1, &ifr) <0){
1462 DEBUGMSGTL(("mibII/interfaces", "SIOCGMIIREG on %s failed\n", ifr.ifr_name));
1464 mii_val[mii_reg] = data[3];
1466 /*Parsing of mii values*/
1467 /*Invalid basic mode control register*/
1468 if (mii_val[0] == 0xffff || mii_val[1] == 0x0000) {
1469 DEBUGMSGTL(("mibII/interfaces", "No MII transceiver present!.\n"));
1472 /* Descriptive rename. */
1473 bmcr = mii_val[0]; /*basic mode control register*/
1474 bmsr = mii_val[1]; /* basic mode status register*/
1475 nway_advert = mii_val[4]; /* autonegotiation advertisement*/
1476 lkpar = mii_val[5]; /*link partner ability*/
1478 /*Check for link existence, returns 0 if link is absent*/
1479 if ((bmsr & 0x0016) != 0x0004){
1480 DEBUGMSGTL(("mibII/interfaces", "No link...\n"));
1485 if(!(bmcr & 0x1000) ){
1486 DEBUGMSGTL(("mibII/interfaces", "Auto-negotiation disabled.\n"));
1487 retspeed = bmcr & 0x2000 ? 100000000 : 10000000;
1490 /* Link partner got our advertised abilities */
1491 if (lkpar & 0x4000) {
1492 int negotiated = nway_advert & lkpar & 0x3e0;
1493 int max_capability = 0;
1494 /* Scan for the highest negotiated capability, highest priority
1495 (100baseTx-FDX) to lowest (10baseT-HDX). */
1496 int media_priority[] = {8, 9, 7, 6, 5}; /* media_names[i-5] */
1497 for (i = 0; media_priority[i]; i++){
1498 if (negotiated & (1 << media_priority[i])) {
1499 max_capability = media_priority[i];
1504 retspeed = media_speeds[max_capability - 5];
1506 DEBUGMSGTL(("mibII/interfaces", "No common media type was autonegotiated!\n"));
1516 Interface_Scan_Init(void)
1519 char line[256], ifname_buf[64], *ifname, *ptr;
1521 struct ifnet **ifnetaddr_ptr;
1523 unsigned long rec_pkt, rec_oct, rec_err, rec_drop;
1524 unsigned long snd_pkt, snd_oct, snd_err, snd_drop, coll;
1526 conf_if_list *if_ptr;
1527 const char *scan_line_2_2 =
1528 "%lu %lu %lu %lu %*lu %*lu %*lu %*lu %lu %lu %lu %lu %*lu %lu";
1529 const char *scan_line_2_0 =
1530 "%lu %lu %*lu %*lu %*lu %lu %lu %*lu %*lu %lu";
1531 const char *scan_line_to_use;
1533 PIOCTL_MIB_INFO pNetDevMibInfo;
1534 IOCTL_MIB_INFO netDevMibInfo;
1537 #if !defined(hpux11)
1538 auto_nlist(IFNET_SYMBOL, (char *) &ifnetaddr, sizeof(ifnetaddr));
1546 while (ifnetaddr_list) {
1547 struct ifnet *old = ifnetaddr_list;
1548 ifnetaddr_list = ifnetaddr_list->if_next;
1555 ifnetaddr_ptr = &ifnetaddr_list;
1557 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1558 DEBUGMSGTL(("snmpd",
1559 "socket open failure in Interface_Scan_Init\n"));
1560 return; /** exit (1); **/
1564 * build up ifnetaddr list by hand:
1568 * at least linux v1.3.53 says EMFILE without reason...
1570 if (!(devin = fopen("/proc/net/dev", "r"))) {
1572 snmp_log(LOG_ERR, "cannot open /proc/net/dev - continuing...\n");
1573 return; /** exit (1); **/
1579 * read the second line (a header) and determine the fields we
1580 * should read from. This should be done in a better way by
1581 * actually looking for the field names we want. But thats too
1582 * much work for today. -- Wes
1584 fgets(line, sizeof(line), devin);
1585 fgets(line, sizeof(line), devin);
1586 if (strstr(line, "compressed")) {
1587 scan_line_to_use = scan_line_2_2;
1588 DEBUGMSGTL(("mibII/interfaces",
1589 "using linux 2.2 kernel /proc/net/dev\n"));
1591 scan_line_to_use = scan_line_2_0;
1592 DEBUGMSGTL(("mibII/interfaces",
1593 "using linux 2.0 kernel /proc/net/dev\n"));
1597 while (fgets(line, sizeof(line), devin)) {
1599 char *stats, *ifstart = line;
1601 if (line[strlen(line) - 1] == '\n')
1602 line[strlen(line) - 1] = '\0';
1604 while (*ifstart && *ifstart == ' ')
1607 if (!*ifstart || ((stats = strrchr(ifstart, ':')) == NULL)) {
1609 "/proc/net/dev data format error, line ==|%s|", line);
1612 if ((scan_line_to_use == scan_line_2_2) && ((stats - line) < 6)) {
1614 "/proc/net/dev data format error, line ==|%s|", line);
1618 strncpy(ifname_buf, ifstart, sizeof(ifname_buf));
1619 ifname_buf[ sizeof(ifname_buf)-1 ] = 0;
1621 while (*stats == ' ')
1624 if ((scan_line_to_use == scan_line_2_2 &&
1625 sscanf(stats, scan_line_to_use, &rec_oct, &rec_pkt, &rec_err,
1626 &rec_drop, &snd_oct, &snd_pkt, &snd_err, &snd_drop,
1627 &coll) != 9) || (scan_line_to_use == scan_line_2_0
1628 && sscanf(stats, scan_line_to_use,
1632 if ((scan_line_to_use == scan_line_2_2)
1633 && !strstr(line, "No statistics available"))
1635 "/proc/net/dev data format error, line ==|%s|",
1640 nnew = (struct ifnet *) calloc(1, sizeof(struct ifnet));
1642 break; /* alloc error */
1647 *ifnetaddr_ptr = nnew;
1648 ifnetaddr_ptr = &nnew->if_next;
1652 * linux previous to 1.3.~13 may miss transmitted loopback pkts:
1654 if (!strcmp(ifname_buf, "lo") && rec_pkt > 0 && !snd_pkt)
1657 nnew->if_ipackets = rec_pkt;
1658 nnew->if_ierrors = rec_err;
1659 nnew->if_opackets = snd_pkt;
1660 nnew->if_oerrors = snd_err;
1661 nnew->if_collisions = coll;
1662 if (scan_line_to_use == scan_line_2_2) {
1663 nnew->if_ibytes = rec_oct;
1664 nnew->if_obytes = snd_oct;
1665 nnew->if_iqdrops = rec_drop;
1666 nnew->if_snd.ifq_drops = snd_drop;
1668 nnew->if_ibytes = rec_pkt * 308;
1669 nnew->if_obytes = snd_pkt * 308;
1673 * ifnames are given as `` eth0'': split in ``eth'' and ``0'':
1675 for (ifname = ifname_buf; *ifname && *ifname == ' '; ifname++);
1678 * set name and interface# :
1680 nnew->if_name = (char *) strdup(ifname);
1681 for (ptr = nnew->if_name; *ptr && (*ptr < '0' || *ptr > '9');
1683 nnew->if_unit = strdup(*ptr ? ptr : "");
1686 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1687 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1688 if (ioctl(fd, SIOCGIFADDR, &ifrq) < 0)
1689 memset((char *) &nnew->if_addr, 0, sizeof(nnew->if_addr));
1691 nnew->if_addr = ifrq.ifr_addr;
1693 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1694 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1695 if (ioctl(fd, SIOCGIFBRDADDR, &ifrq) < 0)
1696 memset((char *) &nnew->ifu_broadaddr, 0,
1697 sizeof(nnew->ifu_broadaddr));
1699 nnew->ifu_broadaddr = ifrq.ifr_broadaddr;
1701 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1702 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1703 if (ioctl(fd, SIOCGIFNETMASK, &ifrq) < 0)
1704 memset((char *) &nnew->ia_subnetmask, 0,
1705 sizeof(nnew->ia_subnetmask));
1707 nnew->ia_subnetmask = ifrq.ifr_netmask;
1709 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1710 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1711 nnew->if_flags = ioctl(fd, SIOCGIFFLAGS, &ifrq) < 0
1712 ? 0 : ifrq.ifr_flags;
1716 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1717 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1718 if (ioctl(fd, SIOCGIFHWADDR, &ifrq) < 0)
1719 memset(nnew->if_hwaddr, (0), 6);
1721 memcpy(nnew->if_hwaddr, ifrq.ifr_hwaddr.sa_data, 6);
1723 #ifdef ARPHRD_LOOPBACK
1724 switch (ifrq.ifr_hwaddr.sa_family) {
1726 nnew->if_type = IF_IANAIFTYPE_ETHERNETCSMACD;
1729 case ARPHRD_TUNNEL6:
1734 nnew->if_type = IF_IANAIFTYPE_TUNNEL;
1740 nnew->if_type = IF_IANAIFTYPE_SLIP;
1743 nnew->if_type = IF_IANAIFTYPE_PPP;
1745 case ARPHRD_LOOPBACK:
1746 nnew->if_type = IF_IANAIFTYPE_SOFTWARELOOPBACK;
1747 break; /* softwareLoopback */
1749 nnew->if_type = IF_IANAIFTYPE_FDDI;
1752 nnew->if_type = IF_IANAIFTYPE_ARCNETPLUS;
1754 case ARPHRD_LOCALTLK:
1755 nnew->if_type = IF_IANAIFTYPE_LOCALTALK;
1759 nnew->if_type = IF_IANAIFTYPE_HIPPI;
1764 nnew->if_type = IF_IANAIFTYPE_ATM;
1769 nnew->if_type = IF_IANAIFTYPE_AAL5;
1772 nnew->if_type = IF_IANAIFTYPE_ADSL;
1776 * XXX: more if_arp.h:ARPHDR_xxx to IANAifType mappings...
1782 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1783 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1784 nnew->if_metric = ioctl(fd, SIOCGIFMETRIC, &ifrq) < 0
1785 ? 0 : ifrq.ifr_metric;
1788 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1789 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1790 nnew->if_mtu = (ioctl(fd, SIOCGIFMTU, &ifrq) < 0)
1796 #ifdef BRCM_IFLASTCHANGE_SUPPORT
1797 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1798 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1799 nnew->if_lastchange = (ioctl(fd, SIOCGIFTRANSSTART, &ifrq) < 0)
1800 ? 0 : ifrq.ifr_ifru.ifru_ivalue;
1802 nnew->if_lastchange = 0;
1804 for (if_ptr = conf_list; if_ptr; if_ptr = if_ptr->next)
1805 if (!strcmp(if_ptr->name, ifname))
1809 nnew->if_type = if_ptr->type;
1810 nnew->if_speed = if_ptr->speed;
1813 * do only guess if_type from name, if we could not read
1814 * * it before from SIOCGIFHWADDR
1817 nnew->if_type = if_type_from_name(nnew->if_name);
1818 switch (nnew->if_type)
1820 case IF_IANAIFTYPE_ETHERNETCSMACD:
1821 case IF_IANAIFTYPE_SOFTWARELOOPBACK:
1822 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1823 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1824 ifrq.ifr_data = (char*)&netDevMibInfo;
1826 if (ioctl(fd, SIOCMIBINFO, &ifrq) < 0) {
1830 pNetDevMibInfo = (IOCTL_MIB_INFO *)(ifrq.ifr_data);
1831 nnew->if_speed = pNetDevMibInfo->ulIfSpeed;
1834 case IF_IANAIFTYPE_TOKENRING:
1835 nnew->if_speed = 4000000;
1837 case IF_IANAIFTYPE_ADSL:
1838 nnew->if_speed = getAdslIfSpeed();
1839 if (getAdslOperStatus() == IF_OPER_STATUS_UP)
1840 nnew->if_flags |= IFF_RUNNING;
1842 nnew->if_flags &= ~IFF_RUNNING;
1843 if (getAdslAdminStatus() == IF_ADMIN_STATUS_UP)
1844 nnew->if_flags |= IFF_UP;
1846 nnew->if_flags &= ~IFF_UP;
1848 case IF_IANAIFTYPE_ATM:
1849 case IF_IANAIFTYPE_AAL5:
1850 nnew->if_speed = getAdslIfSpeed();
1851 if (getAtmIntfOperStatus() == IF_OPER_STATUS_UP)
1852 nnew->if_flags |= IFF_RUNNING;
1854 nnew->if_flags &= ~IFF_RUNNING;
1855 if (getAtmIntfAdminStatus() == IF_ADMIN_STATUS_UP)
1856 nnew->if_flags |= IFF_UP;
1858 nnew->if_flags &= ~IFF_UP;
1865 } /* while (fgets ... */
1867 ifnetaddr = ifnetaddr_list;
1869 if (snmp_get_do_debugging()) {
1871 struct ifnet *x = ifnetaddr;
1872 DEBUGMSGTL(("mibII/interfaces", "* see: known interfaces:"));
1874 DEBUGMSG(("mibII/interfaces", " %s", x->if_name));
1877 DEBUGMSG(("mibII/interfaces", "\n"));
1888 #if defined(sunV3) || defined(linux)
1890 * ** 4.2 BSD doesn't have ifaddr
1894 Interface_Scan_Next(short *Index,
1896 struct ifnet *Retifnet, struct in_ifaddr *dummy)
1903 * Get the "ifnet" structure and extract the device name
1906 klookup((unsigned long) ifnetaddr, (char *) &ifnet, sizeof ifnet);
1907 klookup((unsigned long) ifnet.if_name, (char *) saveName,
1911 strncpy(saveName, ifnet.if_name, sizeof(saveName));
1913 if (strcmp(saveName, "ip") == 0) {
1914 ifnetaddr = ifnet.if_next;
1920 saveName[sizeof(saveName) - 1] = '\0';
1921 cp = (char *) strchr(saveName, '\0');
1923 strncat(cp, ifnet.if_unit, sizeof(saveName)-strlen(saveName)-1);
1924 saveName[sizeof(saveName) - 1] = '\0';
1926 string_append_int(cp, ifnet.if_unit);
1928 if (1 || strcmp(saveName, "lo0") != 0) { /* XXX */
1931 *Index = ++saveIndex;
1935 strcpy(Name, saveName);
1937 saveifnetaddr = ifnetaddr;
1938 ifnetaddr = ifnet.if_next;
1940 return (1); /* DONE */
1942 ifnetaddr = ifnet.if_next;
1944 return (0); /* EOF */
1949 Interface_Index_By_Name(char *Name, int Len)
1954 Interface_Scan_Init();
1956 while (Interface_Scan_Next(&ifIndex, ifName, NULL, NULL)
1957 && strcmp(Name, ifName));
1960 /*brcm: if an interface is not found, we should return 0 rather than the
1961 last index in the interface list */
1962 while ((Interface_Scan_Next(&ifIndex, ifName, NULL, NULL)) != 0)
1964 if (strcmp(Name, ifName) == 0)
1968 #endif /* brcm bug fix */
1973 #else /* sunV3 || linux */
1975 #if defined(netbsd1) || defined(openbsd2)
1976 #define ia_next ia_list.tqe_next
1977 #define if_next if_list.tqe_next
1983 Interface_Scan_Next(short *Index, char *Name, nmapi_phystat * Retifnet)
1985 static nmapi_phystat *if_ptr = (nmapi_phystat *) 0;
1986 int count = Interface_Scan_Get_Count();
1993 (nmapi_phystat *) malloc(sizeof(nmapi_phystat) * count);
1995 return (0); /* EOF */
1998 if (saveIndex >= count)
1999 return (0); /* EOF */
2001 ulen = (unsigned int) count *sizeof(nmapi_phystat);
2002 if ((ret = get_physical_stat(if_ptr, &ulen)) < 0)
2003 return (0); /* EOF */
2006 *Retifnet = if_ptr[saveIndex];
2008 strcpy(Name, if_ptr[saveIndex].nm_device);
2012 return (1); /* DONE */
2018 Interface_Scan_Next(short *Index,
2020 struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr)
2023 struct in_ifaddr *ia, in_ifaddr;
2024 short has_ipaddr = 0;
2025 #if !STRUCT_IFNET_HAS_IF_XNAME
2031 * Get the "ifnet" structure and extract the device name
2033 klookup((unsigned long) ifnetaddr, (char *) &ifnet, sizeof ifnet);
2034 #if STRUCT_IFNET_HAS_IF_XNAME
2035 #if defined(netbsd1) || defined(openbsd2)
2036 strncpy(saveName, ifnet.if_xname, sizeof saveName);
2038 klookup((unsigned long) ifnet.if_xname, (char *) saveName,
2041 saveName[sizeof(saveName) - 1] = '\0';
2043 klookup((unsigned long) ifnet.if_name, (char *) saveName,
2046 saveName[sizeof(saveName) - 1] = '\0';
2047 cp = strchr(saveName, '\0');
2048 string_append_int(cp, ifnet.if_unit);
2050 if (1 || strcmp(saveName, "lo0") != 0) { /* XXX */
2052 * Try to find an address for this interface
2055 auto_nlist(IFADDR_SYMBOL, (char *) &ia, sizeof(ia));
2057 ia = (struct in_ifaddr *) ifnet.if_addrlist.tqh_first;
2060 klookup((unsigned long) ia, (char *) &in_ifaddr,
2064 #define CP(x) ((char *)(x))
2066 struct sockaddr *sa;
2067 cp = (CP(in_ifaddr.ia_ifa.ifa_addr) - CP(ia)) +
2069 sa = (struct sockaddr *) cp;
2071 if (sa->sa_family == AF_INET)
2073 if (in_ifaddr.ia_ifp == ifnetaddr) {
2074 has_ipaddr = 1; /* this IF has IP-address */
2079 ia = (struct in_ifaddr *) in_ifaddr.ia_ifa.ifa_list.
2082 ia = in_ifaddr.ia_next;
2086 #if !defined(netbsd1) && !defined(freebsd2) && !defined(openbsd2) && !defined(STRUCT_IFNET_HAS_IF_ADDRLIST)
2087 ifnet.if_addrlist = (struct ifaddr *) ia; /* WRONG DATA TYPE; ONLY A FLAG */
2090 * ifnet.if_addrlist = (struct ifaddr *)&ia->ia_ifa;
2092 * WRONG DATA TYPE; ONLY A FLAG
2096 *Index = ++saveIndex;
2099 if (Retin_ifaddr && has_ipaddr) /* assign the in_ifaddr only
2100 * if the IF has IP-address */
2101 *Retin_ifaddr = in_ifaddr;
2103 strcpy(Name, saveName);
2105 saveifnetaddr = ifnetaddr;
2106 savein_ifaddr = in_ifaddr;
2107 ifnetaddr = ifnet.if_next;
2109 return (1); /* DONE */
2111 ifnetaddr = ifnet.if_next;
2113 return (0); /* EOF */
2118 #endif /* sunV3 || linux */
2123 Interface_Scan_By_Index(int Index, char *Name, nmapi_phystat * Retifnet)
2127 Interface_Scan_Init();
2128 while (Interface_Scan_Next(&i, Name, Retifnet)) {
2133 return (-1); /* Error, doesn't exist */
2134 return (0); /* DONE */
2140 Interface_Scan_By_Index(int Index,
2142 struct ifnet *Retifnet,
2143 struct in_ifaddr *Retin_ifaddr)
2147 Interface_Scan_Init();
2148 while (Interface_Scan_Next(&i, Name, Retifnet, Retin_ifaddr)) {
2153 return (-1); /* Error, doesn't exist */
2154 return (0); /* DONE */
2159 static int Interface_Count = 0;
2164 Interface_Scan_Get_Count(void)
2166 if (!Interface_Count) {
2173 if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) {
2174 p.objid = ID_ifNumber;
2175 p.buffer = (void *) &val;
2178 if ((ret = get_mib_info(fd, &p)) == 0)
2179 Interface_Count = val;
2183 return (Interface_Count);
2188 static time_t scan_time = 0;
2191 Interface_Scan_Get_Count(void)
2193 time_t time_now = time(NULL);
2195 if (!Interface_Count || (time_now > scan_time + 60)) {
2196 scan_time = time_now;
2197 Interface_Scan_Init();
2198 Interface_Count = 0;
2199 while (Interface_Scan_Next(NULL, NULL, NULL, NULL) != 0) {
2203 return (Interface_Count);
2208 Interface_Get_Ether_By_Index(int Index, u_char * EtherAddr)
2211 #if !(defined(linux) || defined(netbsd1) || defined(bsdi2) || defined(openbsd2))
2212 struct arpcom arpcom;
2213 #else /* is linux or netbsd1 */
2217 #if defined(netbsd1) || defined(bsdi2) || defined(openbsd2)
2218 struct sockaddr_dl sadl;
2219 struct ifaddr ifaddr;
2224 #if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3)
2225 memset(arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));
2227 memset(&arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));
2229 memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr));
2231 if (saveIndex != Index) { /* Optimization! */
2233 Interface_Scan_Init();
2235 while (Interface_Scan_Next((short *) &i, NULL, NULL, NULL) != 0) {
2240 return (-1); /* Error, doesn't exist */
2243 if (saveifnet.if_type != IFT_ETHER) {
2244 return (0); /* Not an ethernet if */
2248 * the arpcom structure is an extended ifnet structure which
2249 * contains the ethernet address.
2252 #if !(defined(netbsd1) || defined(bsdi2) || defined(openbsd2))
2253 klookup((unsigned long) saveifnetaddr, (char *) &arpcom,
2255 #else /* netbsd1 or bsdi2 or openbsd2 */
2257 #if defined(netbsd1) || defined(openbsd2)
2258 #define if_addrlist if_addrlist.tqh_first
2259 #define ifa_next ifa_list.tqe_next
2262 ifaddraddr = (unsigned long) saveifnet.if_addrlist;
2263 while (ifaddraddr) {
2264 klookup(ifaddraddr, (char *) &ifaddr, sizeof ifaddr);
2265 klookup((unsigned long) ifaddr.ifa_addr, (char *) &sadl,
2267 if (sadl.sdl_family == AF_LINK
2268 && (saveifnet.if_type == IFT_ETHER
2269 || saveifnet.if_type == IFT_ISO88025
2270 || saveifnet.if_type == IFT_FDDI)) {
2271 memcpy(arpcom.ac_enaddr, sadl.sdl_data + sadl.sdl_nlen,
2272 sizeof(arpcom.ac_enaddr));
2275 ifaddraddr = (unsigned long) ifaddr.ifa_next;
2277 #endif /* netbsd1 or bsdi2 or openbsd2 */
2280 memcpy(arpcom.ac_enaddr, saveifnetaddr->if_hwaddr, 6);
2282 if (strncmp("lo", saveName, 2) == 0) {
2284 * Loopback doesn't have a HW addr, so return 00:00:00:00:00:00
2286 memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr));
2290 #if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3)
2291 memcpy(EtherAddr, (char *) arpcom.ac_enaddr,
2292 sizeof(arpcom.ac_enaddr));
2294 memcpy(EtherAddr, (char *) &arpcom.ac_enaddr,
2295 sizeof(arpcom.ac_enaddr));
2300 return (0); /* DONE */
2305 #else /* solaris2 */
2308 Interface_Scan_Get_Count(void)
2312 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
2314 if (ioctl(sd, SIOCGIFNUM, &i) == -1) {
2324 Interface_Index_By_Name(char *Name, int Len)
2326 int i, sd, lastlen = 0, interfaces = 0;
2328 struct ifreq *ifrp = NULL;
2334 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2339 * Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF
2340 * on some platforms; see W. R. Stevens, ``Unix Network Programming
2341 * Volume I'', p.435.
2344 for (i = 8;; i += 8) {
2345 buf = calloc(i, sizeof(struct ifreq));
2350 ifc.ifc_len = i * sizeof(struct ifreq);
2351 ifc.ifc_buf = (caddr_t) buf;
2353 if (ioctl(sd, SIOCGIFCONF, (char *) &ifc) < 0) {
2354 if (errno != EINVAL || lastlen != 0) {
2356 * Something has gone genuinely wrong.
2363 * Otherwise, it could just be that the buffer is too small.
2366 if (ifc.ifc_len == lastlen) {
2368 * The length is the same as the last time; we're done.
2372 lastlen = ifc.ifc_len;
2378 interfaces = (ifc.ifc_len / sizeof(struct ifreq)) + 1;
2380 for (i = 1; i < interfaces; i++, ifrp++) {
2381 if (strncmp(ifrp->ifr_name, Name, Len) == 0) {
2393 #endif /* solaris2 */
2395 #else /* HAVE_NET_IF_MIB_H */
2398 * This code attempts to do the right thing for FreeBSD. Note that
2399 * the statistics could be gathered through use of of the
2400 * net.route.0.link.iflist.0 sysctl (which we already use to get the
2401 * hardware address of the interfaces), rather than using the ifmib
2402 * code, but eventually I will implement dot3Stats and we will have to
2403 * use the ifmib interface. ifmib is also a much more natural way of
2404 * mapping the SNMP MIB onto sysctl(3).
2408 #include <net/if_dl.h>
2409 #include <net/if_mib.h>
2410 #include <net/route.h>
2412 static int header_interfaces(struct variable *, oid *, size_t *, int,
2413 size_t *, WriteMethod ** write);
2414 static int header_ifEntry(struct variable *, oid *, size_t *, int,
2415 size_t *, WriteMethod ** write);
2416 u_char *var_ifEntry(struct variable *, oid *, size_t *, int,
2417 size_t *, WriteMethod ** write);
2419 static char *physaddrbuf;
2420 static int nphysaddrs;
2421 struct sockaddr_dl **physaddrs;
2424 init_interfaces_setup(void)
2426 int naddrs, ilen, bit;
2428 = { CTL_NET, PF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
2431 struct rt_msghdr *rtm;
2432 struct if_msghdr *ifm;
2433 struct ifa_msghdr *ifam;
2434 struct sockaddr *sa;
2445 if (sysctl(mib, 6, 0, &len, 0, 0) < 0)
2448 cp = physaddrbuf = malloc(len);
2449 if (physaddrbuf == 0)
2451 if (sysctl(mib, 6, physaddrbuf, &len, 0, 0) < 0) {
2461 rtm = (struct rt_msghdr *) cp;
2462 if (rtm->rtm_version != RTM_VERSION || rtm->rtm_type != RTM_IFINFO) {
2468 ifm = (struct if_msghdr *) rtm;
2469 #if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
2471 physaddrs[naddrs] = (void *) (ifm + 1);
2474 ilen -= ifm->ifm_msglen;
2475 cp += ifm->ifm_msglen;
2476 rtm = (struct rt_msghdr *) cp;
2477 while (ilen > 0 && rtm->rtm_type == RTM_NEWADDR) {
2478 #if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
2479 ilen -= rtm->rtm_msglen;
2480 cp += rtm->rtm_msglen;
2483 ifam = (struct ifa_msghdr *) rtm;
2484 ilen -= sizeof(*ifam);
2485 cp += sizeof(*ifam);
2486 sa = (struct sockaddr *) cp;
2487 #define ROUND(x) (((x) + sizeof(long) - 1) & ~sizeof(long))
2488 for (bit = 1; bit && ilen > 0; bit <<= 1) {
2489 if (!(ifam->ifam_addrs & bit))
2491 ilen -= ROUND(sa->sa_len);
2492 cp += ROUND(sa->sa_len);
2494 if (bit == RTA_IFA) {
2496 #define satosdl(sa) ((struct sockaddr_dl *)(sa))
2502 sa = (struct sockaddr *) cp;
2505 rtm = (struct rt_msghdr *) cp;
2509 nphysaddrs = naddrs;
2512 physaddrs = malloc(naddrs * sizeof(*physaddrs));
2521 get_phys_address(int iindex, char **ap, int *len)
2527 for (i = 0; i < nphysaddrs; i++) {
2528 if (physaddrs[i]->sdl_index == iindex)
2533 init_interfaces_setup();
2536 if (i < nphysaddrs) {
2537 *ap = LLADDR(physaddrs[i]);
2538 *len = physaddrs[i]->sdl_alen;
2545 Interface_Scan_Get_Count(void)
2547 static int count_oid[5] = { CTL_NET, PF_LINK, NETLINK_GENERIC,
2548 IFMIB_SYSTEM, IFMIB_IFCOUNT
2554 if (sysctl(count_oid, 5, &count, &len, (void *) 0, (size_t) 0) < 0)
2561 var_ifEntry(struct variable * vp,
2564 int exact, size_t * var_len, WriteMethod ** write_method)
2567 static int sname[6] = { CTL_NET, PF_LINK, NETLINK_GENERIC,
2568 IFMIB_IFDATA, 0, IFDATA_GENERAL
2570 static struct ifmibdata ifmd;
2574 interface = header_ifEntry(vp, name, length, exact, var_len,
2576 if (interface == MATCH_FAILED)
2579 sname[4] = interface;
2581 if (sysctl(sname, 6, &ifmd, &len, 0, 0) < 0)
2584 switch (vp->magic) {
2586 long_return = interface;
2587 return (u_char *) & long_return;
2589 cp = ifmd.ifmd_name;
2590 *var_len = strlen(cp);
2591 return (u_char *) cp;
2593 long_return = ifmd.ifmd_data.ifi_type;
2594 return (u_char *) & long_return;
2596 long_return = (long) ifmd.ifmd_data.ifi_mtu;
2597 return (u_char *) & long_return;
2599 long_return = ifmd.ifmd_data.ifi_baudrate;
2600 return (u_char *) & long_return;
2604 if (get_phys_address(interface, &cp, var_len))
2610 long_return = ifmd.ifmd_flags & IFF_UP ? 1 : 2;
2611 return (u_char *) & long_return;
2613 long_return = ifmd.ifmd_flags & IFF_RUNNING ? 1 : 2;
2614 return (u_char *) & long_return;
2616 if (ifmd.ifmd_data.ifi_lastchange.tv_sec == 0 &&
2617 ifmd.ifmd_data.ifi_lastchange.tv_usec == 0) {
2619 } else if (ifmd.ifmd_data.ifi_lastchange.tv_sec < starttime.tv_sec) {
2622 long_return = (u_long)
2623 ((ifmd.ifmd_data.ifi_lastchange.tv_sec -
2624 starttime.tv_sec) * 100 +
2625 ((ifmd.ifmd_data.ifi_lastchange.tv_usec -
2626 starttime.tv_usec) / 10000));
2628 return (u_char *) & long_return;
2630 long_return = (u_long) ifmd.ifmd_data.ifi_ibytes;
2631 return (u_char *) & long_return;
2633 long_return = (u_long) ifmd.ifmd_data.ifi_ipackets;
2634 long_return -= (u_long) ifmd.ifmd_data.ifi_imcasts;
2635 return (u_char *) & long_return;
2636 case IFINNUCASTPKTS:
2637 long_return = (u_long) ifmd.ifmd_data.ifi_imcasts;
2638 return (u_char *) & long_return;
2640 long_return = (u_long) ifmd.ifmd_data.ifi_iqdrops;
2641 return (u_char *) & long_return;
2643 long_return = ifmd.ifmd_data.ifi_ierrors;
2644 return (u_char *) & long_return;
2645 case IFINUNKNOWNPROTOS:
2646 long_return = (u_long) ifmd.ifmd_data.ifi_noproto;
2647 return (u_char *) & long_return;
2649 long_return = (u_long) ifmd.ifmd_data.ifi_obytes;
2650 return (u_char *) & long_return;
2651 case IFOUTUCASTPKTS:
2652 long_return = (u_long) ifmd.ifmd_data.ifi_opackets;
2653 long_return -= (u_long) ifmd.ifmd_data.ifi_omcasts;
2654 return (u_char *) & long_return;
2655 case IFOUTNUCASTPKTS:
2656 long_return = (u_long) ifmd.ifmd_data.ifi_omcasts;
2657 return (u_char *) & long_return;
2659 long_return = ifmd.ifmd_snd_drops;
2660 return (u_char *) & long_return;
2662 long_return = ifmd.ifmd_data.ifi_oerrors;
2663 return (u_char *) & long_return;
2665 long_return = ifmd.ifmd_snd_len;
2666 return (u_char *) & long_return;
2668 *var_len = nullOidLen;
2669 return (u_char *) nullOid;
2671 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
2677 #endif /* HAVE_NET_IF_MIB_H */
2678 #endif /* !USE_SYSCTL_IFLIST */
2681 #include <iphlpapi.h>
2683 WriteMethod writeIfEntry;
2684 long admin_status = 0;
2685 long oldadmin_status = 0;
2688 header_ifEntry(struct variable *vp,
2691 int exact, size_t * var_len, WriteMethod ** write_method)
2693 #define IFENTRY_NAME_LENGTH 10
2694 oid newname[MAX_OID_LEN];
2695 register int ifIndex;
2697 DWORD status = NO_ERROR;
2698 DWORD statusRetry = NO_ERROR;
2699 DWORD dwActualSize = 0;
2700 PMIB_IFTABLE pIfTable = NULL;
2702 DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: "));
2703 DEBUGMSGOID(("mibII/interfaces", name, *length));
2704 DEBUGMSG(("mibII/interfaces", " %d\n", exact));
2706 memcpy((char *) newname, (char *) vp->name,
2707 (int) vp->namelen * sizeof(oid));
2709 * find "next" ifIndex
2714 * query for buffer size needed
2716 status = GetIfTable(pIfTable, &dwActualSize, TRUE);
2718 if (status == ERROR_INSUFFICIENT_BUFFER) {
2722 pIfTable = (PMIB_IFTABLE) malloc(dwActualSize);
2723 if (pIfTable != NULL) {
2725 * Get the sorted IF table
2727 GetIfTable(pIfTable, &dwActualSize, TRUE);
2730 count = pIfTable->dwNumEntries;
2731 for (ifIndex = 0; ifIndex < count; ifIndex++) {
2732 newname[IFENTRY_NAME_LENGTH] =
2733 (oid) pIfTable->table[ifIndex].dwIndex;
2735 snmp_oid_compare(name, *length, newname,
2736 (int) vp->namelen + 1);
2737 if ((exact && (result == 0)) || (!exact && (result < 0)))
2740 if (ifIndex > count) {
2741 DEBUGMSGTL(("mibII/interfaces", "... index out of range\n"));
2742 return MATCH_FAILED;
2746 memcpy((char *) name, (char *) newname,
2747 ((int) vp->namelen + 1) * sizeof(oid));
2748 *length = vp->namelen + 1;
2750 *var_len = sizeof(long); /* default to 'long' results */
2752 DEBUGMSGTL(("mibII/interfaces", "... get I/F stats "));
2753 DEBUGMSGOID(("mibII/interfaces", name, *length));
2754 DEBUGMSG(("mibII/interfaces", "\n"));
2756 count = pIfTable->table[ifIndex].dwIndex;
2764 var_interfaces(struct variable * vp,
2767 int exact, size_t * var_len, WriteMethod ** write_method)
2769 if (header_generic(vp, name, length, exact, var_len, write_method) ==
2773 switch (vp->magic) {
2775 GetNumberOfInterfaces(&long_return);
2776 return (u_char *) & long_return;
2778 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n",
2785 var_ifEntry(struct variable * vp,
2788 int exact, size_t * var_len, WriteMethod ** write_method)
2791 static char Name[16];
2792 conf_if_list *if_ptr = conf_list;
2793 static MIB_IFROW ifRow;
2796 header_ifEntry(vp, name, length, exact, var_len, write_method);
2797 if (ifIndex == MATCH_FAILED)
2801 * Get the If Table Row by passing index as argument
2803 ifRow.dwIndex = ifIndex;
2804 if (GetIfEntry(&ifRow) != NO_ERROR)
2806 switch (vp->magic) {
2808 long_return = ifIndex;
2809 return (u_char *) & long_return;
2811 *var_len = ifRow.dwDescrLen;
2812 return (u_char *) ifRow.bDescr;
2814 long_return = ifRow.dwType;
2815 return (u_char *) & long_return;
2817 long_return = (long) ifRow.dwMtu;
2818 return (u_char *) & long_return;
2820 long_return = (long) ifRow.dwSpeed;
2821 return (u_char *) & long_return;
2823 *var_len = ifRow.dwPhysAddrLen;
2824 memcpy(return_buf, ifRow.bPhysAddr, *var_len);
2825 return (u_char *) return_buf;
2827 long_return = ifRow.dwAdminStatus;
2828 admin_status = long_return;
2829 *write_method = writeIfEntry;
2830 return (u_char *) & long_return;
2832 long_return = ifRow.dwOperStatus;
2833 return (u_char *) & long_return;
2835 long_return = ifRow.dwLastChange;
2836 return (u_char *) & long_return;
2838 long_return = ifRow.dwInOctets;
2839 return (u_char *) & long_return;
2841 long_return = ifRow.dwInUcastPkts;
2842 return (u_char *) & long_return;
2843 case IFINNUCASTPKTS:
2844 long_return = ifRow.dwInNUcastPkts;
2845 return (u_char *) & long_return;
2847 long_return = ifRow.dwInDiscards;
2848 return (u_char *) & long_return;
2850 long_return = ifRow.dwInErrors;
2851 return (u_char *) & long_return;
2852 case IFINUNKNOWNPROTOS:
2853 long_return = ifRow.dwInUnknownProtos;
2854 return (u_char *) & long_return;
2856 long_return = ifRow.dwOutOctets;
2857 return (u_char *) & long_return;
2858 case IFOUTUCASTPKTS:
2859 long_return = ifRow.dwOutUcastPkts;
2860 return (u_char *) & long_return;
2861 case IFOUTNUCASTPKTS:
2862 long_return = ifRow.dwOutNUcastPkts;
2863 return (u_char *) & long_return;
2865 long_return = ifRow.dwOutDiscards;
2866 return (u_char *) & long_return;
2868 long_return = ifRow.dwOutErrors;
2869 return (u_char *) & long_return;
2871 long_return = ifRow.dwOutQLen;
2872 return (u_char *) & long_return;
2874 *var_len = nullOidLen;
2875 return (u_char *) nullOid;
2877 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
2885 writeIfEntry(int action,
2887 u_char var_val_type,
2889 u_char * statP, oid * name, size_t name_len)
2891 MIB_IFROW ifEntryRow;
2892 if ((char) name[9] != IFADMINSTATUS) {
2893 return SNMP_ERR_NOTWRITABLE;
2897 case RESERVE1: /* Check values for acceptability */
2898 if (var_val_type != ASN_INTEGER) {
2899 snmp_log(LOG_ERR, "not integer\n");
2900 return SNMP_ERR_WRONGTYPE;
2902 if (var_val_len > sizeof(int)) {
2903 snmp_log(LOG_ERR, "bad length\n");
2904 return SNMP_ERR_WRONGLENGTH;
2908 * The dwAdminStatus member can be MIB_IF_ADMIN_STATUS_UP or MIB_IF_ADMIN_STATUS_DOWN
2910 if (!(((int) (*var_val) == MIB_IF_ADMIN_STATUS_UP) ||
2911 ((int) (*var_val) == MIB_IF_ADMIN_STATUS_DOWN))) {
2912 snmp_log(LOG_ERR, "not supported admin state\n");
2913 return SNMP_ERR_WRONGVALUE;
2917 case RESERVE2: /* Allocate memory and similar resources */
2922 * Save the old value, in case of UNDO
2925 oldadmin_status = admin_status;
2926 admin_status = (int) *var_val;
2929 case UNDO: /* Reverse the SET action and free resources */
2930 admin_status = oldadmin_status;
2933 case COMMIT: /* Confirm the SET, performing any irreversible actions,
2934 * and free resources */
2935 ifEntryRow.dwIndex = (int) name[10];
2936 ifEntryRow.dwAdminStatus = admin_status;
2938 * Only UP and DOWN status are supported. Thats why done in COMMIT
2940 if (SetIfEntry(&ifEntryRow) != NO_ERROR) {
2942 "Error in writeIfEntry case COMMIT with index: %d & adminStatus %d\n",
2943 ifEntryRow.dwIndex, ifEntryRow.dwAdminStatus);
2944 return SNMP_ERR_COMMITFAILED;
2947 case FREE: /* Free any resources allocated */
2949 * No resources have been allocated
2953 return SNMP_ERR_NOERROR;
2954 } /* end of writeIfEntry */
2959 static int setPppConnAdminDown(char *devName);
2961 writeIfEntry(int action,
2963 u_char var_val_type,
2965 u_char * statP, oid * name, size_t name_len)
2971 if ((char) name[9] != IFADMINSTATUS)
2972 return SNMP_ERR_NOTWRITABLE;
2975 case RESERVE1: /* Check values for acceptability */
2976 if (var_val_type != ASN_INTEGER) {
2977 snmp_log(LOG_ERR, "not integer\n");
2978 return SNMP_ERR_WRONGTYPE;
2980 if (var_val_len > sizeof(int)) {
2981 snmp_log(LOG_ERR, "bad length\n");
2982 return SNMP_ERR_WRONGLENGTH;
2985 value = *((int*)var_val);
2987 if ((value != IF_ADMIN_STATUS_UP) &&
2988 (value != IF_ADMIN_STATUS_DOWN)) {
2989 snmp_log(LOG_ERR, "not supported admin state %d\n",value);
2990 return SNMP_ERR_WRONGVALUE;
2994 case RESERVE2: /* Allocate memory and similar resources */
2999 * Save the old value, in case of UNDO
3003 case UNDO: /* Reverse the SET action and free resources */
3006 case COMMIT: /* Confirm the SET, performing any irreversible actions,
3007 * and free resources */
3008 index = *((int*)&name[10]);
3009 value = *((int*)var_val);
3010 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
3011 snmp_log(LOG_ERR, "socket open failure in WriteIfEntry\n");
3012 return SNMP_ERR_COMMITFAILED;
3015 /* get ifName first */
3016 ifrq.ifr_ifindex = index;
3017 if (ioctl(fd, SIOCGIFNAME, &ifrq) < 0) {
3018 snmp_log(LOG_ERR, "WriteIfEntry unable to locate device name for ifIndex %d\n",index);
3019 return SNMP_ERR_COMMITFAILED;
3022 if (strcmp(ifrq.ifr_name,IF_BRCM_DSL_DEV_NAME) == 0) {
3023 if (setAdslAdminStatus(value) < 0)
3024 return SNMP_ERR_COMMITFAILED;
3026 else if ((strcmp(ifrq.ifr_name,"atm0") == 0) ||
3027 (strcmp(ifrq.ifr_name,"cpcs0") == 0)) {
3028 if (setAtmIntfAdminStatus(value) < 0)
3029 return SNMP_ERR_COMMITFAILED;
3031 else if ((strncmp(ifrq.ifr_name,"ppp",strlen("ppp"))) == 0) {
3032 /* value is always down since after ppp is admin down the first time, dev is gone */
3033 if (setPppConnAdminDown(ifrq.ifr_name) < 0)
3034 return SNMP_ERR_COMMITFAILED;
3036 if (value == IF_ADMIN_STATUS_UP)
3037 ifrq.ifr_flags |= IFF_UP;
3039 ifrq.ifr_flags &= ~IFF_UP;
3040 if (ioctl(fd, SIOCSIFFLAGS, &ifrq) < 0) {
3042 return SNMP_ERR_COMMITFAILED;
3046 case FREE: /* Free any resources allocated */
3048 * No resources have been allocated
3052 return SNMP_ERR_NOERROR;
3053 } /* end of ifWriteEntry */
3055 int setPppConnAdminDown(char *devName)
3062 sprintf(path,"/proc/var/fyi/wan/%s/wanup",devName);
3064 fs = fopen(path, "w");
3073 if( (fd = open( "/dev/brcmboard", O_RDWR )) != -1 ) {
3074 ioctl( fd, BOARD_IOCTL_WAKEUP_MONITOR_TASK, NULL);
3080 #endif /* SNMP_SET */