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 BUILD_SNMP_SYSOR_MIB
197 #include "sysORTable.h"
200 #include <bcmtypes.h>
201 #include <bcmatmapi.h>
205 #define BRCM_IFLASTCHANGE_SUPPORT
207 extern struct timeval starttime;
209 static void parse_interface_config(const char *, char *);
210 static void free_interface_config(void);
212 struct variable3 interfaces_variables[] = {
213 {IFNUMBER, ASN_INTEGER, RONLY, var_interfaces, 1, {1}},
214 {IFINDEX, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 1}},
215 {IFDESCR, ASN_OCTET_STR, RONLY, var_ifEntry, 3, {2, 1, 2}},
216 {IFTYPE, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 3}},
217 {IFMTU, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 4}},
218 {IFSPEED, ASN_GAUGE, RONLY, var_ifEntry, 3, {2, 1, 5}},
219 {IFPHYSADDRESS, ASN_OCTET_STR, RONLY, var_ifEntry, 3, {2, 1, 6}},
220 #ifdef BUILD_SNMP_SET
221 {IFADMINSTATUS, ASN_INTEGER, RWRITE, var_ifEntry, 3, {2, 1, 7}}, /* brcm, linux can write */
223 {IFADMINSTATUS, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 7}},
224 #endif /* BUILD_SNMP_SET */
225 {IFOPERSTATUS, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 8}},
226 {IFLASTCHANGE, ASN_TIMETICKS, RONLY, var_ifEntry, 3, {2, 1, 9}},
227 {IFINOCTETS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 10}},
228 {IFINUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 11}},
229 {IFINNUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 12}},
230 {IFINDISCARDS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 13}},
231 {IFINERRORS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 14}},
232 {IFINUNKNOWNPROTOS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 15}},
233 {IFOUTOCTETS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 16}},
234 {IFOUTUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 17}},
235 {IFOUTNUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 18}},
236 {IFOUTDISCARDS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 19}},
237 {IFOUTERRORS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 20}},
238 {IFOUTQLEN, ASN_GAUGE, RONLY, var_ifEntry, 3, {2, 1, 21}},
239 {IFSPECIFIC, ASN_OBJECT_ID, RONLY, var_ifEntry, 3, {2, 1, 22}}
243 #define ARPHRD_CPCS 28 /* CPCS */
244 #define ARPHRD_DSL 29 /* ADSL */
247 * Define the OID pointer to the top of the mib tree that we're
248 * registering underneath, and the OID of the MIB module
250 oid interfaces_variables_oid[] = { SNMP_OID_MIB2, 2 };
251 oid interfaces_module_oid[] = { SNMP_OID_MIB2, 31 };
254 init_interfaces(void)
257 * register ourselves with the agent to handle our mib tree
259 REGISTER_MIB("mibII/interfaces", interfaces_variables, variable3,
260 interfaces_variables_oid);
261 #ifdef BUILD_SNMP_SYSOR_MIB
262 REGISTER_SYSOR_ENTRY(interfaces_module_oid,
263 "The MIB module to describe generic objects for network interface sub-layers");
264 #endif /* BUILD_SNMP_SYSOR_MIB */
266 snmpd_register_config_handler("interface", parse_interface_config,
267 free_interface_config,
270 #ifndef USE_SYSCTL_IFLIST
271 #if HAVE_NET_IF_MIB_H
272 init_interfaces_setup();
276 init_kernel_sunos5();
283 * Return interface type using the interface name as a clue.
284 * Returns 1 to imply "other" type if name not recognized.
287 if_type_from_name(const char *pcch)
289 typedef struct _match_if {
292 } *pmatch_if, match_if;
294 static match_if lmatch_if[] = {
300 {0, 0} /* end of list */
304 register pmatch_if pm;
306 for (ii = 0, pm = lmatch_if; pm->mi_name; pm++) {
307 len = strlen(pm->mi_name);
308 if (0 == strncmp(pcch, pm->mi_name, len)) {
309 return (pm->mi_type);
312 return (1); /* in case search fails */
317 typedef struct _conf_if_list {
321 struct _conf_if_list *next;
324 static conf_if_list *conf_list;
326 static struct ifnet *ifnetaddr_list;
330 parse_interface_config(const char *token, char *cptr)
332 conf_if_list *if_ptr, *if_new;
333 char *name, *type, *speed, *ecp;
335 name = strtok(cptr, " \t");
337 config_perror("Missing NAME parameter");
340 type = strtok(NULL, " \t");
342 config_perror("Missing TYPE parameter");
345 speed = strtok(NULL, " \t");
347 config_perror("Missing SPEED parameter");
352 if (strcmp(if_ptr->name, name))
353 if_ptr = if_ptr->next;
357 config_pwarn("Duplicate interface specification");
358 if_new = (conf_if_list *) malloc(sizeof(conf_if_list));
360 config_perror("Out of memory");
363 if_new->speed = strtoul(speed, &ecp, 0);
365 config_perror("Bad SPEED value");
369 if_new->type = strtol(type, &ecp, 0);
370 if (*ecp || if_new->type < 0) {
371 config_perror("Bad TYPE");
375 if_new->name = strdup(name);
377 config_perror("Out of memory");
381 if_new->next = conf_list;
386 free_interface_config(void)
388 conf_if_list *if_ptr = conf_list, *if_next;
390 if_next = if_ptr->next;
403 * vp IN - pointer to variable entry that points here
404 * name IN/OUT - IN/name requested, OUT/name found
405 * length IN/OUT - length of IN/OUT oid's
406 * exact IN - TRUE if an exact match was requested
407 * var_len OUT - length of variable or 0 if function returned
412 WriteMethod writeIfEntry;
414 header_ifEntry(struct variable *vp,
417 int exact, size_t * var_len, WriteMethod ** write_method)
419 #define IFENTRY_NAME_LENGTH 10
420 oid newname[MAX_OID_LEN];
421 register int interface;
424 DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: "));
425 DEBUGMSGOID(("mibII/interfaces", name, *length));
426 DEBUGMSG(("mibII/interfaces", " %d\n", exact));
428 memcpy((char *) newname, (char *) vp->name,
429 (int) vp->namelen * sizeof(oid));
431 * find "next" interface
433 count = Interface_Scan_Get_Count();
434 for (interface = 1; interface <= count; interface++) {
435 newname[IFENTRY_NAME_LENGTH] = (oid) interface;
437 snmp_oid_compare(name, *length, newname,
438 (int) vp->namelen + 1);
439 if ((exact && (result == 0)) || (!exact && (result < 0)))
442 if (interface > count) {
443 DEBUGMSGTL(("mibII/interfaces", "... index out of range\n"));
448 memcpy((char *) name, (char *) newname,
449 ((int) vp->namelen + 1) * sizeof(oid));
450 *length = vp->namelen + 1;
451 #ifdef BUILD_SNMP_SET
452 /* brcm: write is now supported on linux as well */
453 *write_method = writeIfEntry;
455 *write_method = NULL;
456 #endif /* BUILD_SNMP_SET */
457 *var_len = sizeof(long); /* default to 'long' results */
459 DEBUGMSGTL(("mibII/interfaces", "... get I/F stats "));
460 DEBUGMSGOID(("mibII/interfaces", name, *length));
461 DEBUGMSG(("mibII/interfaces", "\n"));
469 var_interfaces(struct variable * vp,
472 int exact, size_t * var_len, WriteMethod ** write_method)
474 if (header_generic(vp, name, length, exact, var_len, write_method) ==
480 long_return = Interface_Scan_Get_Count();
481 return (u_char *) & long_return;
483 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n",
489 #ifdef USE_SYSCTL_IFLIST
491 static u_char *if_list = 0;
492 static const u_char *if_list_end;
493 static size_t if_list_size = 0;
495 struct small_ifaddr {
496 struct in_addr sifa_addr;
497 struct in_addr sifa_netmask;
498 struct in_addr sifa_broadcast;
501 extern const struct sockaddr *get_address(const void *, int, int);
502 extern const struct in_addr *get_in_address(const void *, int, int);
503 static int Interface_Scan_By_Index(int, struct if_msghdr *, char *,
504 struct small_ifaddr *);
505 static int Interface_Get_Ether_By_Index(int, u_char *);
508 Interface_Scan_By_Index(int iindex,
509 struct if_msghdr *if_msg,
510 char *if_name, struct small_ifaddr *sifa)
513 struct if_msghdr *ifp;
514 int have_ifinfo = 0, have_addr = 0;
516 memset(sifa, 0, sizeof(*sifa));
517 for (cp = if_list; cp < if_list_end; cp += ifp->ifm_msglen) {
518 ifp = (struct if_msghdr *) cp;
519 DEBUGMSGTL(("mibII/interfaces", "ifm_type = %d, ifm_index = %d\n",
520 ifp->ifm_type, ifp->ifm_index));
522 switch (ifp->ifm_type) {
525 const struct sockaddr *a;
527 if (ifp->ifm_index == iindex) {
528 a = get_address(ifp + 1, ifp->ifm_addrs, RTA_IFP);
532 ((const struct sockaddr_in *) a)->sin_zero,
533 ((const u_char *) a)[5]);
534 if_name[((const u_char *) a)[5]] = 0;
542 struct ifa_msghdr *ifap = (struct ifa_msghdr *) cp;
544 if (ifap->ifam_index == iindex) {
545 const struct in_addr *ia;
548 * I don't know why the normal get_address() doesn't
549 * work on IRIX 6.2. Maybe this has to do with the
550 * existence of struct sockaddr_new. Hopefully, on
551 * other systems we can simply use get_in_address
552 * three times, with (ifap+1) as the starting
557 *((struct in_addr *) ((char *) (ifap + 1) + 4));
558 ia = get_in_address((char *) (ifap + 1) + 8,
560 ~RTA_NETMASK, RTA_IFA);
564 sifa->sifa_addr = *ia;
565 ia = get_in_address((char *) (ifap + 1) + 8,
566 ifap->ifam_addrs &= ~RTA_NETMASK,
571 sifa->sifa_broadcast = *ia;
577 DEBUGMSGTL(("mibII/interfaces",
578 "routing socket: unknown message type %d\n",
582 if (have_ifinfo && have_addr) {
584 } else if (have_ifinfo && !(if_msg->ifm_flags & IFF_UP))
592 Interface_Scan_Get_Count(void)
595 struct if_msghdr *ifp;
598 Interface_Scan_Init();
601 for (cp = if_list, n = 0; cp < if_list_end; cp += ifp->ifm_msglen) {
602 ifp = (struct if_msghdr *) cp;
604 if (ifp->ifm_type == RTM_IFINFO) {
613 Interface_Scan_Init(void)
615 int name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
618 if (sysctl(name, sizeof(name) / sizeof(int), 0, &size, 0, 0) == -1) {
619 snmp_log(LOG_ERR, "sysctl size fail\n");
621 if (if_list == 0 || if_list_size < size) {
628 if ((if_list = malloc(size)) == NULL) {
630 "out of memory allocating route table (size = %d)\n", size);
637 if (sysctl(name, sizeof(name) / sizeof(int),
638 if_list, &size, 0, 0) == -1) {
639 snmp_log(LOG_ERR, "sysctl get fail\n");
641 if_list_end = if_list + size;
646 var_ifEntry(struct variable *vp,
649 int exact, size_t * var_len, WriteMethod ** write_method)
652 struct if_msghdr if_msg;
653 static char if_name[100];
654 struct small_ifaddr sifa;
658 header_ifEntry(vp, name, length, exact, var_len, write_method);
659 if (interface == MATCH_FAILED)
662 if (Interface_Scan_By_Index(interface, &if_msg, if_name, &sifa) != 0)
667 long_return = interface;
668 return (u_char *) & long_return;
671 *var_len = strlen(if_name);
672 return (u_char *) cp;
674 long_return = (long) if_msg.ifm_data.ifi_type;
675 return (u_char *) & long_return;
677 long_return = (long) if_msg.ifm_data.ifi_mtu;
678 return (u_char *) & long_return;
680 #if STRUCT_IFNET_HAS_IF_BAUDRATE_IFS_VALUE
681 long_return = (u_long) if_msg.ifm_data.ifi_baudrate.ifs_value <<
682 if_msg.ifm_data.ifi_baudrate.ifs_log2;
684 long_return = (u_long) if_msg.ifm_data.ifi_baudrate;
686 return (u_char *) & long_return;
693 long_return = if_msg.ifm_flags & IFF_UP ? 1 : 2;
694 return (u_char *) & long_return;
696 long_return = if_msg.ifm_flags & IFF_RUNNING ? 1 : 2;
697 return (u_char *) & long_return;
702 long_return = (u_long) if_msg.ifm_data.ifi_ibytes;
703 return (u_char *) & long_return;
706 (u_long) if_msg.ifm_data.ifi_ipackets -
707 if_msg.ifm_data.ifi_imcasts;
708 return (u_char *) & long_return;
710 long_return = (u_long) if_msg.ifm_data.ifi_imcasts;
711 return (u_char *) & long_return;
713 long_return = (u_long) if_msg.ifm_data.ifi_iqdrops;
714 return (u_char *) & long_return;
716 long_return = (u_long) if_msg.ifm_data.ifi_ierrors;
717 return (u_char *) & long_return;
718 case IFINUNKNOWNPROTOS:
719 long_return = (u_long) if_msg.ifm_data.ifi_noproto;
720 return (u_char *) & long_return;
722 long_return = (u_long) if_msg.ifm_data.ifi_obytes;
723 return (u_char *) & long_return;
726 (u_long) if_msg.ifm_data.ifi_opackets -
727 if_msg.ifm_data.ifi_omcasts;
728 return (u_char *) & long_return;
729 case IFOUTNUCASTPKTS:
730 long_return = (u_long) if_msg.ifm_data.ifi_omcasts;
731 return (u_char *) & long_return;
734 long_return = (u_long) if_msg.ifm_data.ifi_odrops;
741 return (u_char *) & long_return;
743 long_return = (u_long) if_msg.ifm_data.ifi_oerrors;
744 return (u_char *) & long_return;
749 if (if_msg.ifm_data.ifi_lastchange.tv_sec == 0 &&
750 if_msg.ifm_data.ifi_lastchange.tv_usec == 0)
752 else if (if_msg.ifm_data.ifi_lastchange.tv_sec < starttime.tv_sec)
755 long_return = (u_long)
756 ((if_msg.ifm_data.ifi_lastchange.tv_sec -
757 starttime.tv_sec) * 100 +
758 (if_msg.ifm_data.ifi_lastchange.tv_usec -
759 starttime.tv_usec) / 10000);
762 return (u_char *) & long_return;
769 Interface_Scan_Next(short *Index,
771 struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr)
776 #else /* not USE_SYSCTL_IFLIST */
778 /*********************
780 * Kernel & interface information,
781 * and internal forward declarations
783 *********************/
785 #ifndef HAVE_NET_IF_MIB_H
789 static int Interface_Scan_By_Index(int, char *, struct ifnet *,
791 static int Interface_Get_Ether_By_Index(int, u_char *);
793 static int Interface_Scan_By_Index(int, char *, nmapi_phystat *);
799 /*********************
801 * System specific implementation functions
803 *********************/
810 var_ifEntry(struct variable *vp,
813 int exact, size_t * var_len, WriteMethod ** write_method)
815 static struct ifnet ifnet;
817 static struct in_ifaddr in_ifaddr;
818 static char Name[16];
820 conf_if_list *if_ptr = conf_list;
821 #if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC
826 header_ifEntry(vp, name, length, exact, var_len, write_method);
827 if (interface == MATCH_FAILED)
830 Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddr);
831 while (if_ptr && strcmp(Name, if_ptr->name))
832 if_ptr = if_ptr->next;
836 long_return = interface;
837 return (u_char *) & long_return;
840 *var_len = strlen(cp);
841 return (u_char *) cp;
844 long_return = if_ptr->type;
846 #if STRUCT_IFNET_HAS_IF_TYPE
847 long_return = ifnet.if_type;
849 long_return = 1; /* OTHER */
852 return (u_char *) & long_return;
854 long_return = (long) ifnet.if_mtu;
855 return (u_char *) & long_return;
859 long_return = if_ptr->speed;
861 #if STRUCT_IFNET_HAS_IF_BAUDRATE
862 long_return = ifnet.if_baudrate;
863 #elif STRUCT_IFNET_HAS_IF_SPEED
864 long_return = ifnet.if_speed;
865 #elif STRUCT_IFNET_HAS_IF_TYPE && defined(IFT_ETHER)
866 if (ifnet.if_type == IFT_ETHER)
867 long_return = 10000000;
868 if (ifnet.if_type == IFT_P10)
869 long_return = 10000000;
870 if (ifnet.if_type == IFT_P80)
871 long_return = 80000000;
872 if (ifnet.if_type == IFT_ISDNBASIC)
873 long_return = 64000; /* EDSS1 only */
874 if (ifnet.if_type == IFT_ISDNPRIMARY)
875 long_return = 64000 * 30;
880 long_return = (u_long) 10000000;
883 return (u_char *) & long_return;
885 Interface_Get_Ether_By_Index(interface, return_buf);
887 if ((return_buf[0] == 0) && (return_buf[1] == 0) &&
888 (return_buf[2] == 0) && (return_buf[3] == 0) &&
889 (return_buf[4] == 0) && (return_buf[5] == 0))
891 return (u_char *) return_buf;
893 long_return = ifnet.if_flags & IFF_UP ? 1 : 2;
894 return (u_char *) & long_return;
896 long_return = ifnet.if_flags & IFF_RUNNING ? 1 : 2;
897 return (u_char *) & long_return;
899 #if defined(STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC) && !(defined(freebsd2) && __FreeBSD_version < 199607)
901 * XXX - SNMP's ifLastchange is time when op. status changed
902 * * FreeBSD's if_lastchange is time when packet was input or output
903 * * (at least in 2.1.0-RELEASE. Changed in later versions of the kernel?)
906 * FreeBSD's if_lastchange before the 2.1.5 release is the time when
907 * * a packet was last input or output. In the 2.1.5 and later releases,
908 * * this is fixed, thus the 199607 comparison.
910 if (ifnet.if_lastchange.tv_sec == 0 &&
911 ifnet.if_lastchange.tv_usec == 0)
913 else if (ifnet.if_lastchange.tv_sec < starttime.tv_sec)
916 long_return = (u_long)
917 ((ifnet.if_lastchange.tv_sec - starttime.tv_sec) * 100
918 + (ifnet.if_lastchange.tv_usec -
919 starttime.tv_usec) / 10000);
922 #ifdef BRCM_IFLASTCHANGE_SUPPORT
923 /* brcm - if_lastchange now supported */
924 long_return = ifnet.if_lastchange;
931 return (u_char *) & long_return;
933 #ifdef STRUCT_IFNET_HAS_IF_IBYTES
934 long_return = (u_long) ifnet.if_ibytes;
939 long_return = (u_long) ifnet.if_ipackets * 308; /* XXX */
941 return (u_char *) & long_return;
944 long_return = (u_long) ifnet.if_ipackets;
945 #if STRUCT_IFNET_HAS_IF_IMCASTS
946 long_return -= (u_long) ifnet.if_imcasts;
949 return (u_char *) & long_return;
951 #if STRUCT_IFNET_HAS_IF_IMCASTS
952 long_return = (u_long) ifnet.if_imcasts;
957 long_return = (u_long) 0; /* XXX */
959 return (u_char *) & long_return;
961 #if STRUCT_IFNET_HAS_IF_IQDROPS
962 long_return = (u_long) ifnet.if_iqdrops;
967 long_return = (u_long) 0; /* XXX */
969 return (u_char *) & long_return;
971 long_return = (u_long) ifnet.if_ierrors;
972 return (u_char *) & long_return;
973 case IFINUNKNOWNPROTOS:
974 #if STRUCT_IFNET_HAS_IF_NOPROTO
975 long_return = (u_long) ifnet.if_noproto;
980 long_return = (u_long) 0; /* XXX */
982 return (u_char *) & long_return;
984 #ifdef STRUCT_IFNET_HAS_IF_OBYTES
985 long_return = (u_long) ifnet.if_obytes;
990 long_return = (u_long) ifnet.if_opackets * 308; /* XXX */
992 return (u_char *) & long_return;
995 long_return = (u_long) ifnet.if_opackets;
996 #if STRUCT_IFNET_HAS_IF_OMCASTS
997 long_return -= (u_long) ifnet.if_omcasts;
1000 return (u_char *) & long_return;
1001 case IFOUTNUCASTPKTS:
1002 #if STRUCT_IFNET_HAS_IF_OMCASTS
1003 long_return = (u_long) ifnet.if_omcasts;
1008 long_return = (u_long) 0; /* XXX */
1010 return (u_char *) & long_return;
1012 long_return = ifnet.if_snd.ifq_drops;
1013 return (u_char *) & long_return;
1015 long_return = ifnet.if_oerrors;
1016 return (u_char *) & long_return;
1018 long_return = ifnet.if_snd.ifq_len;
1019 return (u_char *) & long_return;
1021 *var_len = nullOidLen;
1022 return (u_char *) nullOid;
1024 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1033 var_ifEntry(struct variable *vp,
1036 int exact, size_t * var_len, WriteMethod ** write_method)
1039 static nmapi_phystat ifnet;
1041 static struct ifnet ifnet;
1043 register int interface;
1044 #if !defined(hpux11)
1045 static struct in_ifaddr in_ifaddrVar;
1048 static char Name[MAX_PHYSADDR_LEN];
1050 static char Name[16];
1053 #if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC
1056 #if !defined(hpux11)
1057 struct nmparms hp_nmparms;
1058 static mib_ifEntry hp_ifEntry;
1060 int hp_len = sizeof(hp_ifEntry);
1065 header_ifEntry(vp, name, length, exact, var_len, write_method);
1066 if (interface == MATCH_FAILED)
1070 Interface_Scan_By_Index(interface, Name, &ifnet);
1072 Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddrVar);
1075 #if !defined(hpux11)
1077 * Additional information about the interfaces is available under
1078 * HP-UX through the network management interface '/dev/netman'
1080 hp_ifEntry.ifIndex = interface;
1081 hp_nmparms.objid = ID_ifEntry;
1082 hp_nmparms.buffer = (char *) &hp_ifEntry;
1083 hp_nmparms.len = &hp_len;
1084 if ((hp_fd = open("/dev/netman", O_RDONLY)) != -1) {
1085 if (ioctl(hp_fd, NMIOGET, &hp_nmparms) != -1) {
1089 hp_fd = -1; /* failed */
1094 switch (vp->magic) {
1096 long_return = interface;
1097 return (u_char *) & long_return;
1100 cp = ifnet.if_entry.ifDescr;
1103 cp = hp_ifEntry.ifDescr;
1107 *var_len = strlen(cp);
1108 return (u_char *) cp;
1111 long_return = ifnet.if_entry.ifType;
1114 long_return = hp_ifEntry.ifType;
1116 long_return = 1; /* OTHER */
1118 return (u_char *) & long_return;
1121 long_return = (long) ifnet.if_entry.ifMtu;
1123 long_return = (long) ifnet.if_mtu;
1125 return (u_char *) & long_return;
1129 long_return = ifnet.if_entry.ifSpeed;
1132 long_return = hp_ifEntry.ifSpeed;
1134 long_return = (u_long) 1; /* OTHER */
1136 return (u_char *) & long_return;
1139 *var_len = ifnet.if_entry.ifPhysAddress.o_length;
1140 return (u_char *) ifnet.if_entry.ifPhysAddress.o_bytes;
1142 Interface_Get_Ether_By_Index(interface, return_buf);
1144 if ((return_buf[0] == 0) && (return_buf[1] == 0) &&
1145 (return_buf[2] == 0) && (return_buf[3] == 0) &&
1146 (return_buf[4] == 0) && (return_buf[5] == 0))
1148 return (u_char *) return_buf;
1152 long_return = ifnet.if_entry.ifAdmin;
1154 long_return = ifnet.if_flags & IFF_UP ? 1 : 2;
1156 return (u_char *) & long_return;
1159 long_return = ifnet.if_entry.ifOper;
1161 long_return = ifnet.if_flags & IFF_RUNNING ? 1 : 2;
1163 return (u_char *) & long_return;
1166 long_return = ifnet.if_entry.ifLastChange;
1169 long_return = hp_ifEntry.ifLastChange;
1171 long_return = 0; /* XXX */
1173 return (u_char *) & long_return;
1176 long_return = ifnet.if_entry.ifInOctets;
1179 long_return = hp_ifEntry.ifInOctets;
1181 long_return = (u_long) ifnet.if_ipackets * 308; /* XXX */
1183 return (u_char *) & long_return;
1186 long_return = ifnet.if_entry.ifInUcastPkts;
1189 long_return = hp_ifEntry.ifInUcastPkts;
1191 long_return = (u_long) ifnet.if_ipackets;
1193 return (u_char *) & long_return;
1194 case IFINNUCASTPKTS:
1196 long_return = ifnet.if_entry.ifInNUcastPkts;
1199 long_return = hp_ifEntry.ifInNUcastPkts;
1201 long_return = (u_long) 0; /* XXX */
1203 return (u_char *) & long_return;
1206 long_return = ifnet.if_entry.ifInDiscards;
1209 long_return = hp_ifEntry.ifInDiscards;
1211 long_return = (u_long) 0; /* XXX */
1213 return (u_char *) & long_return;
1216 long_return = ifnet.if_entry.ifInErrors;
1218 long_return = ifnet.if_ierrors;
1220 return (u_char *) & long_return;
1221 case IFINUNKNOWNPROTOS:
1223 long_return = ifnet.if_entry.ifInUnknownProtos;
1226 long_return = hp_ifEntry.ifInUnknownProtos;
1228 long_return = (u_long) 0; /* XXX */
1230 return (u_char *) & long_return;
1233 long_return = ifnet.if_entry.ifOutOctets;
1236 long_return = hp_ifEntry.ifOutOctets;
1238 long_return = (u_long) ifnet.if_opackets * 308; /* XXX */
1240 return (u_char *) & long_return;
1241 case IFOUTUCASTPKTS:
1243 long_return = ifnet.if_entry.ifOutUcastPkts;
1246 long_return = hp_ifEntry.ifOutUcastPkts;
1248 long_return = (u_long) ifnet.if_opackets;
1250 return (u_char *) & long_return;
1251 case IFOUTNUCASTPKTS:
1253 long_return = ifnet.if_entry.ifOutNUcastPkts;
1256 long_return = hp_ifEntry.ifOutNUcastPkts;
1258 long_return = (u_long) 0; /* XXX */
1260 return (u_char *) & long_return;
1263 long_return = ifnet.if_entry.ifOutDiscards;
1265 long_return = ifnet.if_snd.ifq_drops;
1267 return (u_char *) & long_return;
1270 long_return = ifnet.if_entry.ifOutErrors;
1272 long_return = ifnet.if_oerrors;
1274 return (u_char *) & long_return;
1277 long_return = ifnet.if_entry.ifOutQlen;
1279 long_return = ifnet.if_snd.ifq_len;
1281 return (u_char *) & long_return;
1283 *var_len = nullOidLen;
1284 return (u_char *) nullOid;
1286 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1293 #else /* solaris2 */
1296 IF_cmp(void *addr, void *ep)
1298 DEBUGMSGTL(("mibII/interfaces", "... IF_cmp %d %d\n",
1299 ((mib2_ifEntry_t *) ep)->ifIndex,
1300 ((mib2_ifEntry_t *) addr)->ifIndex));
1301 if (((mib2_ifEntry_t *) ep)->ifIndex ==
1302 ((mib2_ifEntry_t *) addr)->ifIndex)
1309 var_ifEntry(struct variable * vp,
1312 int exact, size_t * var_len, WriteMethod ** write_method)
1315 mib2_ifEntry_t ifstat;
1319 header_ifEntry(vp, name, length, exact, var_len, write_method);
1320 if (interface == MATCH_FAILED)
1323 if (getMibstat(MIB_INTERFACES, &ifstat, sizeof(mib2_ifEntry_t),
1324 GET_EXACT, &IF_cmp, &interface) != 0) {
1325 DEBUGMSGTL(("mibII/interfaces", "... no mib stats\n"));
1328 switch (vp->magic) {
1330 long_return = ifstat.ifIndex;
1331 return (u_char *) & long_return;
1333 *var_len = ifstat.ifDescr.o_length;
1334 (void) memcpy(return_buf, ifstat.ifDescr.o_bytes, *var_len);
1335 return (u_char *) return_buf;
1337 long_return = (u_long) ifstat.ifType;
1338 return (u_char *) & long_return;
1340 long_return = (u_long) ifstat.ifMtu;
1341 return (u_char *) & long_return;
1343 long_return = (u_long) ifstat.ifSpeed;
1344 return (u_char *) & long_return;
1346 *var_len = ifstat.ifPhysAddress.o_length;
1347 (void) memcpy(return_buf, ifstat.ifPhysAddress.o_bytes, *var_len);
1348 return (u_char *) return_buf;
1350 long_return = (u_long) ifstat.ifAdminStatus;
1351 return (u_char *) & long_return;
1353 long_return = (u_long) ifstat.ifOperStatus;
1354 return (u_char *) & long_return;
1356 long_return = (u_long) ifstat.ifLastChange;
1357 return (u_char *) & long_return;
1359 long_return = (u_long) ifstat.ifInOctets;
1360 return (u_char *) & long_return;
1362 long_return = (u_long) ifstat.ifInUcastPkts;
1363 return (u_char *) & long_return;
1364 case IFINNUCASTPKTS:
1365 long_return = (u_long) ifstat.ifInNUcastPkts;
1366 return (u_char *) & long_return;
1368 long_return = (u_long) ifstat.ifInDiscards;
1369 return (u_char *) & long_return;
1371 long_return = (u_long) ifstat.ifInErrors;
1372 return (u_char *) & long_return;
1373 case IFINUNKNOWNPROTOS:
1374 long_return = (u_long) ifstat.ifInUnknownProtos;
1375 return (u_char *) & long_return;
1377 long_return = (u_long) ifstat.ifOutOctets;
1378 return (u_char *) & long_return;
1379 case IFOUTUCASTPKTS:
1380 long_return = (u_long) ifstat.ifOutUcastPkts;
1381 return (u_char *) & long_return;
1382 case IFOUTNUCASTPKTS:
1383 long_return = (u_long) ifstat.ifOutNUcastPkts;
1384 return (u_char *) & long_return;
1386 long_return = (u_long) ifstat.ifOutDiscards;
1387 return (u_char *) & long_return;
1389 long_return = (u_long) ifstat.ifOutErrors;
1390 return (u_char *) & long_return;
1392 long_return = (u_long) ifstat.ifOutQLen;
1393 return (u_char *) & long_return;
1395 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
1401 #endif /* solaris2 */
1405 /*********************
1407 * Internal implementation functions
1409 *********************/
1414 #if !defined(sunV3) && !defined(linux) && !defined(hpux11)
1415 static struct in_ifaddr savein_ifaddr;
1417 #if !defined(hpux11)
1418 static struct ifnet *ifnetaddr, saveifnet, *saveifnetaddr;
1419 static char saveName[16];
1421 static int saveIndex = 0;
1424 * Determines network interface speed. It is system specific. Only linux
1425 * realization is made.
1427 unsigned int getIfSpeed(int fd, struct ifreq ifr){
1428 unsigned int retspeed = 10000000;
1430 /* the code is based on mii-diag utility by Donald Becker
1431 * see ftp://ftp.scyld.com/pub/diag/mii-diag.c
1433 ushort *data = (ushort *)(&ifr.ifr_data);
1434 /* brcm: not used, remove warning */
1435 /* unsigned int *data32 = (unsigned int *)(&ifr.ifr_data); */
1437 unsigned char new_ioctl_nums = 0;
1440 ushort bmcr, bmsr, nway_advert, lkpar;
1441 const unsigned int media_speeds[] = {10000000, 10000000, 100000000, 100000000, 10000000, 0};
1442 /* It corresponds to "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD", "100baseT4", "Flow-control", 0, */
1447 if (ioctl(fd, 0x8947, &ifr) >= 0) {
1449 } else if (ioctl(fd, SIOCDEVPRIVATE, &ifr) >= 0) {
1452 DEBUGMSGTL(("mibII/interfaces", "SIOCGMIIPHY on %s failed\n", ifr.ifr_name));
1455 /* Begin getting mii register values */
1457 for (mii_reg = 0; mii_reg < 8; mii_reg++){
1460 if(ioctl(fd, new_ioctl_nums ? 0x8948 : SIOCDEVPRIVATE+1, &ifr) <0){
1461 DEBUGMSGTL(("mibII/interfaces", "SIOCGMIIREG on %s failed\n", ifr.ifr_name));
1463 mii_val[mii_reg] = data[3];
1465 /*Parsing of mii values*/
1466 /*Invalid basic mode control register*/
1467 if (mii_val[0] == 0xffff || mii_val[1] == 0x0000) {
1468 DEBUGMSGTL(("mibII/interfaces", "No MII transceiver present!.\n"));
1471 /* Descriptive rename. */
1472 bmcr = mii_val[0]; /*basic mode control register*/
1473 bmsr = mii_val[1]; /* basic mode status register*/
1474 nway_advert = mii_val[4]; /* autonegotiation advertisement*/
1475 lkpar = mii_val[5]; /*link partner ability*/
1477 /*Check for link existence, returns 0 if link is absent*/
1478 if ((bmsr & 0x0016) != 0x0004){
1479 DEBUGMSGTL(("mibII/interfaces", "No link...\n"));
1484 if(!(bmcr & 0x1000) ){
1485 DEBUGMSGTL(("mibII/interfaces", "Auto-negotiation disabled.\n"));
1486 retspeed = bmcr & 0x2000 ? 100000000 : 10000000;
1489 /* Link partner got our advertised abilities */
1490 if (lkpar & 0x4000) {
1491 int negotiated = nway_advert & lkpar & 0x3e0;
1492 int max_capability = 0;
1493 /* Scan for the highest negotiated capability, highest priority
1494 (100baseTx-FDX) to lowest (10baseT-HDX). */
1495 int media_priority[] = {8, 9, 7, 6, 5}; /* media_names[i-5] */
1496 for (i = 0; media_priority[i]; i++){
1497 if (negotiated & (1 << media_priority[i])) {
1498 max_capability = media_priority[i];
1503 retspeed = media_speeds[max_capability - 5];
1505 DEBUGMSGTL(("mibII/interfaces", "No common media type was autonegotiated!\n"));
1515 Interface_Scan_Init(void)
1518 char line[256], ifname_buf[64], *ifname, *ptr;
1520 struct ifnet **ifnetaddr_ptr;
1522 unsigned long rec_pkt, rec_oct, rec_err, rec_drop;
1523 unsigned long snd_pkt, snd_oct, snd_err, snd_drop, coll;
1525 conf_if_list *if_ptr;
1526 const char *scan_line_2_2 =
1527 "%lu %lu %lu %lu %*lu %*lu %*lu %*lu %lu %lu %lu %lu %*lu %lu";
1528 const char *scan_line_2_0 =
1529 "%lu %lu %*lu %*lu %*lu %lu %lu %*lu %*lu %lu";
1530 const char *scan_line_to_use;
1532 PIOCTL_MIB_INFO pNetDevMibInfo;
1533 IOCTL_MIB_INFO netDevMibInfo;
1536 #if !defined(hpux11)
1537 auto_nlist(IFNET_SYMBOL, (char *) &ifnetaddr, sizeof(ifnetaddr));
1545 while (ifnetaddr_list) {
1546 struct ifnet *old = ifnetaddr_list;
1547 ifnetaddr_list = ifnetaddr_list->if_next;
1554 ifnetaddr_ptr = &ifnetaddr_list;
1556 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1557 DEBUGMSGTL(("snmpd",
1558 "socket open failure in Interface_Scan_Init\n"));
1559 return; /** exit (1); **/
1563 * build up ifnetaddr list by hand:
1567 * at least linux v1.3.53 says EMFILE without reason...
1569 if (!(devin = fopen("/proc/net/dev", "r"))) {
1571 snmp_log(LOG_ERR, "cannot open /proc/net/dev - continuing...\n");
1572 return; /** exit (1); **/
1578 * read the second line (a header) and determine the fields we
1579 * should read from. This should be done in a better way by
1580 * actually looking for the field names we want. But thats too
1581 * much work for today. -- Wes
1583 fgets(line, sizeof(line), devin);
1584 fgets(line, sizeof(line), devin);
1585 if (strstr(line, "compressed")) {
1586 scan_line_to_use = scan_line_2_2;
1587 DEBUGMSGTL(("mibII/interfaces",
1588 "using linux 2.2 kernel /proc/net/dev\n"));
1590 scan_line_to_use = scan_line_2_0;
1591 DEBUGMSGTL(("mibII/interfaces",
1592 "using linux 2.0 kernel /proc/net/dev\n"));
1596 while (fgets(line, sizeof(line), devin)) {
1598 char *stats, *ifstart = line;
1600 if (line[strlen(line) - 1] == '\n')
1601 line[strlen(line) - 1] = '\0';
1603 while (*ifstart && *ifstart == ' ')
1606 if (!*ifstart || ((stats = strrchr(ifstart, ':')) == NULL)) {
1608 "/proc/net/dev data format error, line ==|%s|", line);
1611 if ((scan_line_to_use == scan_line_2_2) && ((stats - line) < 6)) {
1613 "/proc/net/dev data format error, line ==|%s|", line);
1617 strncpy(ifname_buf, ifstart, sizeof(ifname_buf));
1618 ifname_buf[ sizeof(ifname_buf)-1 ] = 0;
1620 while (*stats == ' ')
1623 if ((scan_line_to_use == scan_line_2_2 &&
1624 sscanf(stats, scan_line_to_use, &rec_oct, &rec_pkt, &rec_err,
1625 &rec_drop, &snd_oct, &snd_pkt, &snd_err, &snd_drop,
1626 &coll) != 9) || (scan_line_to_use == scan_line_2_0
1627 && sscanf(stats, scan_line_to_use,
1631 if ((scan_line_to_use == scan_line_2_2)
1632 && !strstr(line, "No statistics available"))
1634 "/proc/net/dev data format error, line ==|%s|",
1639 nnew = (struct ifnet *) calloc(1, sizeof(struct ifnet));
1641 break; /* alloc error */
1646 *ifnetaddr_ptr = nnew;
1647 ifnetaddr_ptr = &nnew->if_next;
1651 * linux previous to 1.3.~13 may miss transmitted loopback pkts:
1653 if (!strcmp(ifname_buf, "lo") && rec_pkt > 0 && !snd_pkt)
1656 nnew->if_ipackets = rec_pkt;
1657 nnew->if_ierrors = rec_err;
1658 nnew->if_opackets = snd_pkt;
1659 nnew->if_oerrors = snd_err;
1660 nnew->if_collisions = coll;
1661 if (scan_line_to_use == scan_line_2_2) {
1662 nnew->if_ibytes = rec_oct;
1663 nnew->if_obytes = snd_oct;
1664 nnew->if_iqdrops = rec_drop;
1665 nnew->if_snd.ifq_drops = snd_drop;
1667 nnew->if_ibytes = rec_pkt * 308;
1668 nnew->if_obytes = snd_pkt * 308;
1672 * ifnames are given as `` eth0'': split in ``eth'' and ``0'':
1674 for (ifname = ifname_buf; *ifname && *ifname == ' '; ifname++);
1677 * set name and interface# :
1679 nnew->if_name = (char *) strdup(ifname);
1680 for (ptr = nnew->if_name; *ptr && (*ptr < '0' || *ptr > '9');
1682 nnew->if_unit = strdup(*ptr ? ptr : "");
1685 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1686 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1687 if (ioctl(fd, SIOCGIFADDR, &ifrq) < 0)
1688 memset((char *) &nnew->if_addr, 0, sizeof(nnew->if_addr));
1690 nnew->if_addr = ifrq.ifr_addr;
1692 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1693 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1694 if (ioctl(fd, SIOCGIFBRDADDR, &ifrq) < 0)
1695 memset((char *) &nnew->ifu_broadaddr, 0,
1696 sizeof(nnew->ifu_broadaddr));
1698 nnew->ifu_broadaddr = ifrq.ifr_broadaddr;
1700 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1701 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1702 if (ioctl(fd, SIOCGIFNETMASK, &ifrq) < 0)
1703 memset((char *) &nnew->ia_subnetmask, 0,
1704 sizeof(nnew->ia_subnetmask));
1706 nnew->ia_subnetmask = ifrq.ifr_netmask;
1708 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1709 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1710 nnew->if_flags = ioctl(fd, SIOCGIFFLAGS, &ifrq) < 0
1711 ? 0 : ifrq.ifr_flags;
1715 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1716 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1717 if (ioctl(fd, SIOCGIFHWADDR, &ifrq) < 0)
1718 memset(nnew->if_hwaddr, (0), 6);
1720 memcpy(nnew->if_hwaddr, ifrq.ifr_hwaddr.sa_data, 6);
1722 #ifdef ARPHRD_LOOPBACK
1723 switch (ifrq.ifr_hwaddr.sa_family) {
1725 nnew->if_type = IF_IANAIFTYPE_ETHERNETCSMACD;
1728 case ARPHRD_TUNNEL6:
1733 nnew->if_type = IF_IANAIFTYPE_TUNNEL;
1739 nnew->if_type = IF_IANAIFTYPE_SLIP;
1742 nnew->if_type = IF_IANAIFTYPE_PPP;
1744 case ARPHRD_LOOPBACK:
1745 nnew->if_type = IF_IANAIFTYPE_SOFTWARELOOPBACK;
1746 break; /* softwareLoopback */
1748 nnew->if_type = IF_IANAIFTYPE_FDDI;
1751 nnew->if_type = IF_IANAIFTYPE_ARCNETPLUS;
1753 case ARPHRD_LOCALTLK:
1754 nnew->if_type = IF_IANAIFTYPE_LOCALTALK;
1758 nnew->if_type = IF_IANAIFTYPE_HIPPI;
1763 nnew->if_type = IF_IANAIFTYPE_ATM;
1768 nnew->if_type = IF_IANAIFTYPE_AAL5;
1771 nnew->if_type = IF_IANAIFTYPE_ADSL;
1775 * XXX: more if_arp.h:ARPHDR_xxx to IANAifType mappings...
1781 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1782 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1783 nnew->if_metric = ioctl(fd, SIOCGIFMETRIC, &ifrq) < 0
1784 ? 0 : ifrq.ifr_metric;
1787 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1788 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1789 nnew->if_mtu = (ioctl(fd, SIOCGIFMTU, &ifrq) < 0)
1795 #ifdef BRCM_IFLASTCHANGE_SUPPORT
1796 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1797 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1798 nnew->if_lastchange = (ioctl(fd, SIOCGIFTRANSSTART, &ifrq) < 0)
1799 ? 0 : ifrq.ifr_ifru.ifru_ivalue;
1801 nnew->if_lastchange = 0;
1803 for (if_ptr = conf_list; if_ptr; if_ptr = if_ptr->next)
1804 if (!strcmp(if_ptr->name, ifname))
1808 nnew->if_type = if_ptr->type;
1809 nnew->if_speed = if_ptr->speed;
1812 * do only guess if_type from name, if we could not read
1813 * * it before from SIOCGIFHWADDR
1816 nnew->if_type = if_type_from_name(nnew->if_name);
1817 switch (nnew->if_type)
1819 case IF_IANAIFTYPE_ETHERNETCSMACD:
1820 case IF_IANAIFTYPE_SOFTWARELOOPBACK:
1821 strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
1822 ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
1823 ifrq.ifr_data = (char*)&netDevMibInfo;
1825 if (ioctl(fd, SIOCMIBINFO, &ifrq) < 0) {
1829 pNetDevMibInfo = (IOCTL_MIB_INFO *)(ifrq.ifr_data);
1830 nnew->if_speed = pNetDevMibInfo->ulIfSpeed;
1833 case IF_IANAIFTYPE_TOKENRING:
1834 nnew->if_speed = 4000000;
1836 case IF_IANAIFTYPE_ADSL:
1837 nnew->if_speed = getAdslIfSpeed();
1838 if (getAdslOperStatus() == IF_OPER_STATUS_UP)
1839 nnew->if_flags |= IFF_RUNNING;
1841 nnew->if_flags &= ~IFF_RUNNING;
1842 if (getAdslAdminStatus() == IF_ADMIN_STATUS_UP)
1843 nnew->if_flags |= IFF_UP;
1845 nnew->if_flags &= ~IFF_UP;
1847 case IF_IANAIFTYPE_ATM:
1848 case IF_IANAIFTYPE_AAL5:
1849 nnew->if_speed = getAdslIfSpeed();
1850 if (getAtmIntfOperStatus() == IF_OPER_STATUS_UP)
1851 nnew->if_flags |= IFF_RUNNING;
1853 nnew->if_flags &= ~IFF_RUNNING;
1854 if (getAtmIntfAdminStatus() == IF_ADMIN_STATUS_UP)
1855 nnew->if_flags |= IFF_UP;
1857 nnew->if_flags &= ~IFF_UP;
1864 } /* while (fgets ... */
1866 ifnetaddr = ifnetaddr_list;
1868 if (snmp_get_do_debugging()) {
1870 struct ifnet *x = ifnetaddr;
1871 DEBUGMSGTL(("mibII/interfaces", "* see: known interfaces:"));
1873 DEBUGMSG(("mibII/interfaces", " %s", x->if_name));
1876 DEBUGMSG(("mibII/interfaces", "\n"));
1887 #if defined(sunV3) || defined(linux)
1889 * ** 4.2 BSD doesn't have ifaddr
1893 Interface_Scan_Next(short *Index,
1895 struct ifnet *Retifnet, struct in_ifaddr *dummy)
1902 * Get the "ifnet" structure and extract the device name
1905 klookup((unsigned long) ifnetaddr, (char *) &ifnet, sizeof ifnet);
1906 klookup((unsigned long) ifnet.if_name, (char *) saveName,
1910 strncpy(saveName, ifnet.if_name, sizeof(saveName));
1912 if (strcmp(saveName, "ip") == 0) {
1913 ifnetaddr = ifnet.if_next;
1919 saveName[sizeof(saveName) - 1] = '\0';
1920 cp = (char *) strchr(saveName, '\0');
1922 strncat(cp, ifnet.if_unit, sizeof(saveName)-strlen(saveName)-1);
1923 saveName[sizeof(saveName) - 1] = '\0';
1925 string_append_int(cp, ifnet.if_unit);
1927 if (1 || strcmp(saveName, "lo0") != 0) { /* XXX */
1930 *Index = ++saveIndex;
1934 strcpy(Name, saveName);
1936 saveifnetaddr = ifnetaddr;
1937 ifnetaddr = ifnet.if_next;
1939 return (1); /* DONE */
1941 ifnetaddr = ifnet.if_next;
1943 return (0); /* EOF */
1948 Interface_Index_By_Name(char *Name, int Len)
1953 Interface_Scan_Init();
1955 while (Interface_Scan_Next(&ifIndex, ifName, NULL, NULL)
1956 && strcmp(Name, ifName));
1959 /*brcm: if an interface is not found, we should return 0 rather than the
1960 last index in the interface list */
1961 while ((Interface_Scan_Next(&ifIndex, ifName, NULL, NULL)) != 0)
1963 if (strcmp(Name, ifName) == 0)
1967 #endif /* brcm bug fix */
1972 #else /* sunV3 || linux */
1974 #if defined(netbsd1) || defined(openbsd2)
1975 #define ia_next ia_list.tqe_next
1976 #define if_next if_list.tqe_next
1982 Interface_Scan_Next(short *Index, char *Name, nmapi_phystat * Retifnet)
1984 static nmapi_phystat *if_ptr = (nmapi_phystat *) 0;
1985 int count = Interface_Scan_Get_Count();
1992 (nmapi_phystat *) malloc(sizeof(nmapi_phystat) * count);
1994 return (0); /* EOF */
1997 if (saveIndex >= count)
1998 return (0); /* EOF */
2000 ulen = (unsigned int) count *sizeof(nmapi_phystat);
2001 if ((ret = get_physical_stat(if_ptr, &ulen)) < 0)
2002 return (0); /* EOF */
2005 *Retifnet = if_ptr[saveIndex];
2007 strcpy(Name, if_ptr[saveIndex].nm_device);
2011 return (1); /* DONE */
2017 Interface_Scan_Next(short *Index,
2019 struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr)
2022 struct in_ifaddr *ia, in_ifaddr;
2023 short has_ipaddr = 0;
2024 #if !STRUCT_IFNET_HAS_IF_XNAME
2030 * Get the "ifnet" structure and extract the device name
2032 klookup((unsigned long) ifnetaddr, (char *) &ifnet, sizeof ifnet);
2033 #if STRUCT_IFNET_HAS_IF_XNAME
2034 #if defined(netbsd1) || defined(openbsd2)
2035 strncpy(saveName, ifnet.if_xname, sizeof saveName);
2037 klookup((unsigned long) ifnet.if_xname, (char *) saveName,
2040 saveName[sizeof(saveName) - 1] = '\0';
2042 klookup((unsigned long) ifnet.if_name, (char *) saveName,
2045 saveName[sizeof(saveName) - 1] = '\0';
2046 cp = strchr(saveName, '\0');
2047 string_append_int(cp, ifnet.if_unit);
2049 if (1 || strcmp(saveName, "lo0") != 0) { /* XXX */
2051 * Try to find an address for this interface
2054 auto_nlist(IFADDR_SYMBOL, (char *) &ia, sizeof(ia));
2056 ia = (struct in_ifaddr *) ifnet.if_addrlist.tqh_first;
2059 klookup((unsigned long) ia, (char *) &in_ifaddr,
2063 #define CP(x) ((char *)(x))
2065 struct sockaddr *sa;
2066 cp = (CP(in_ifaddr.ia_ifa.ifa_addr) - CP(ia)) +
2068 sa = (struct sockaddr *) cp;
2070 if (sa->sa_family == AF_INET)
2072 if (in_ifaddr.ia_ifp == ifnetaddr) {
2073 has_ipaddr = 1; /* this IF has IP-address */
2078 ia = (struct in_ifaddr *) in_ifaddr.ia_ifa.ifa_list.
2081 ia = in_ifaddr.ia_next;
2085 #if !defined(netbsd1) && !defined(freebsd2) && !defined(openbsd2) && !defined(STRUCT_IFNET_HAS_IF_ADDRLIST)
2086 ifnet.if_addrlist = (struct ifaddr *) ia; /* WRONG DATA TYPE; ONLY A FLAG */
2089 * ifnet.if_addrlist = (struct ifaddr *)&ia->ia_ifa;
2091 * WRONG DATA TYPE; ONLY A FLAG
2095 *Index = ++saveIndex;
2098 if (Retin_ifaddr && has_ipaddr) /* assign the in_ifaddr only
2099 * if the IF has IP-address */
2100 *Retin_ifaddr = in_ifaddr;
2102 strcpy(Name, saveName);
2104 saveifnetaddr = ifnetaddr;
2105 savein_ifaddr = in_ifaddr;
2106 ifnetaddr = ifnet.if_next;
2108 return (1); /* DONE */
2110 ifnetaddr = ifnet.if_next;
2112 return (0); /* EOF */
2117 #endif /* sunV3 || linux */
2122 Interface_Scan_By_Index(int Index, char *Name, nmapi_phystat * Retifnet)
2126 Interface_Scan_Init();
2127 while (Interface_Scan_Next(&i, Name, Retifnet)) {
2132 return (-1); /* Error, doesn't exist */
2133 return (0); /* DONE */
2139 Interface_Scan_By_Index(int Index,
2141 struct ifnet *Retifnet,
2142 struct in_ifaddr *Retin_ifaddr)
2146 Interface_Scan_Init();
2147 while (Interface_Scan_Next(&i, Name, Retifnet, Retin_ifaddr)) {
2152 return (-1); /* Error, doesn't exist */
2153 return (0); /* DONE */
2158 static int Interface_Count = 0;
2163 Interface_Scan_Get_Count(void)
2165 if (!Interface_Count) {
2172 if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) {
2173 p.objid = ID_ifNumber;
2174 p.buffer = (void *) &val;
2177 if ((ret = get_mib_info(fd, &p)) == 0)
2178 Interface_Count = val;
2182 return (Interface_Count);
2187 static time_t scan_time = 0;
2190 Interface_Scan_Get_Count(void)
2192 time_t time_now = time(NULL);
2194 if (!Interface_Count || (time_now > scan_time + 60)) {
2195 scan_time = time_now;
2196 Interface_Scan_Init();
2197 Interface_Count = 0;
2198 while (Interface_Scan_Next(NULL, NULL, NULL, NULL) != 0) {
2202 return (Interface_Count);
2207 Interface_Get_Ether_By_Index(int Index, u_char * EtherAddr)
2210 #if !(defined(linux) || defined(netbsd1) || defined(bsdi2) || defined(openbsd2))
2211 struct arpcom arpcom;
2212 #else /* is linux or netbsd1 */
2216 #if defined(netbsd1) || defined(bsdi2) || defined(openbsd2)
2217 struct sockaddr_dl sadl;
2218 struct ifaddr ifaddr;
2223 #if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3)
2224 memset(arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));
2226 memset(&arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));
2228 memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr));
2230 if (saveIndex != Index) { /* Optimization! */
2232 Interface_Scan_Init();
2234 while (Interface_Scan_Next((short *) &i, NULL, NULL, NULL) != 0) {
2239 return (-1); /* Error, doesn't exist */
2242 if (saveifnet.if_type != IFT_ETHER) {
2243 return (0); /* Not an ethernet if */
2247 * the arpcom structure is an extended ifnet structure which
2248 * contains the ethernet address.
2251 #if !(defined(netbsd1) || defined(bsdi2) || defined(openbsd2))
2252 klookup((unsigned long) saveifnetaddr, (char *) &arpcom,
2254 #else /* netbsd1 or bsdi2 or openbsd2 */
2256 #if defined(netbsd1) || defined(openbsd2)
2257 #define if_addrlist if_addrlist.tqh_first
2258 #define ifa_next ifa_list.tqe_next
2261 ifaddraddr = (unsigned long) saveifnet.if_addrlist;
2262 while (ifaddraddr) {
2263 klookup(ifaddraddr, (char *) &ifaddr, sizeof ifaddr);
2264 klookup((unsigned long) ifaddr.ifa_addr, (char *) &sadl,
2266 if (sadl.sdl_family == AF_LINK
2267 && (saveifnet.if_type == IFT_ETHER
2268 || saveifnet.if_type == IFT_ISO88025
2269 || saveifnet.if_type == IFT_FDDI)) {
2270 memcpy(arpcom.ac_enaddr, sadl.sdl_data + sadl.sdl_nlen,
2271 sizeof(arpcom.ac_enaddr));
2274 ifaddraddr = (unsigned long) ifaddr.ifa_next;
2276 #endif /* netbsd1 or bsdi2 or openbsd2 */
2279 memcpy(arpcom.ac_enaddr, saveifnetaddr->if_hwaddr, 6);
2281 if (strncmp("lo", saveName, 2) == 0) {
2283 * Loopback doesn't have a HW addr, so return 00:00:00:00:00:00
2285 memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr));
2289 #if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3)
2290 memcpy(EtherAddr, (char *) arpcom.ac_enaddr,
2291 sizeof(arpcom.ac_enaddr));
2293 memcpy(EtherAddr, (char *) &arpcom.ac_enaddr,
2294 sizeof(arpcom.ac_enaddr));
2299 return (0); /* DONE */
2304 #else /* solaris2 */
2307 Interface_Scan_Get_Count(void)
2311 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
2313 if (ioctl(sd, SIOCGIFNUM, &i) == -1) {
2323 Interface_Index_By_Name(char *Name, int Len)
2325 int i, sd, lastlen = 0, interfaces = 0;
2327 struct ifreq *ifrp = NULL;
2333 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2338 * Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF
2339 * on some platforms; see W. R. Stevens, ``Unix Network Programming
2340 * Volume I'', p.435.
2343 for (i = 8;; i += 8) {
2344 buf = calloc(i, sizeof(struct ifreq));
2349 ifc.ifc_len = i * sizeof(struct ifreq);
2350 ifc.ifc_buf = (caddr_t) buf;
2352 if (ioctl(sd, SIOCGIFCONF, (char *) &ifc) < 0) {
2353 if (errno != EINVAL || lastlen != 0) {
2355 * Something has gone genuinely wrong.
2362 * Otherwise, it could just be that the buffer is too small.
2365 if (ifc.ifc_len == lastlen) {
2367 * The length is the same as the last time; we're done.
2371 lastlen = ifc.ifc_len;
2377 interfaces = (ifc.ifc_len / sizeof(struct ifreq)) + 1;
2379 for (i = 1; i < interfaces; i++, ifrp++) {
2380 if (strncmp(ifrp->ifr_name, Name, Len) == 0) {
2392 #endif /* solaris2 */
2394 #else /* HAVE_NET_IF_MIB_H */
2397 * This code attempts to do the right thing for FreeBSD. Note that
2398 * the statistics could be gathered through use of of the
2399 * net.route.0.link.iflist.0 sysctl (which we already use to get the
2400 * hardware address of the interfaces), rather than using the ifmib
2401 * code, but eventually I will implement dot3Stats and we will have to
2402 * use the ifmib interface. ifmib is also a much more natural way of
2403 * mapping the SNMP MIB onto sysctl(3).
2407 #include <net/if_dl.h>
2408 #include <net/if_mib.h>
2409 #include <net/route.h>
2411 static int header_interfaces(struct variable *, oid *, size_t *, int,
2412 size_t *, WriteMethod ** write);
2413 static int header_ifEntry(struct variable *, oid *, size_t *, int,
2414 size_t *, WriteMethod ** write);
2415 u_char *var_ifEntry(struct variable *, oid *, size_t *, int,
2416 size_t *, WriteMethod ** write);
2418 static char *physaddrbuf;
2419 static int nphysaddrs;
2420 struct sockaddr_dl **physaddrs;
2423 init_interfaces_setup(void)
2425 int naddrs, ilen, bit;
2427 = { CTL_NET, PF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
2430 struct rt_msghdr *rtm;
2431 struct if_msghdr *ifm;
2432 struct ifa_msghdr *ifam;
2433 struct sockaddr *sa;
2444 if (sysctl(mib, 6, 0, &len, 0, 0) < 0)
2447 cp = physaddrbuf = malloc(len);
2448 if (physaddrbuf == 0)
2450 if (sysctl(mib, 6, physaddrbuf, &len, 0, 0) < 0) {
2460 rtm = (struct rt_msghdr *) cp;
2461 if (rtm->rtm_version != RTM_VERSION || rtm->rtm_type != RTM_IFINFO) {
2467 ifm = (struct if_msghdr *) rtm;
2468 #if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
2470 physaddrs[naddrs] = (void *) (ifm + 1);
2473 ilen -= ifm->ifm_msglen;
2474 cp += ifm->ifm_msglen;
2475 rtm = (struct rt_msghdr *) cp;
2476 while (ilen > 0 && rtm->rtm_type == RTM_NEWADDR) {
2477 #if defined(freebsd3) || defined(freebsd4) || defined(freebsd5)
2478 ilen -= rtm->rtm_msglen;
2479 cp += rtm->rtm_msglen;
2482 ifam = (struct ifa_msghdr *) rtm;
2483 ilen -= sizeof(*ifam);
2484 cp += sizeof(*ifam);
2485 sa = (struct sockaddr *) cp;
2486 #define ROUND(x) (((x) + sizeof(long) - 1) & ~sizeof(long))
2487 for (bit = 1; bit && ilen > 0; bit <<= 1) {
2488 if (!(ifam->ifam_addrs & bit))
2490 ilen -= ROUND(sa->sa_len);
2491 cp += ROUND(sa->sa_len);
2493 if (bit == RTA_IFA) {
2495 #define satosdl(sa) ((struct sockaddr_dl *)(sa))
2501 sa = (struct sockaddr *) cp;
2504 rtm = (struct rt_msghdr *) cp;
2508 nphysaddrs = naddrs;
2511 physaddrs = malloc(naddrs * sizeof(*physaddrs));
2520 get_phys_address(int iindex, char **ap, int *len)
2526 for (i = 0; i < nphysaddrs; i++) {
2527 if (physaddrs[i]->sdl_index == iindex)
2532 init_interfaces_setup();
2535 if (i < nphysaddrs) {
2536 *ap = LLADDR(physaddrs[i]);
2537 *len = physaddrs[i]->sdl_alen;
2544 Interface_Scan_Get_Count(void)
2546 static int count_oid[5] = { CTL_NET, PF_LINK, NETLINK_GENERIC,
2547 IFMIB_SYSTEM, IFMIB_IFCOUNT
2553 if (sysctl(count_oid, 5, &count, &len, (void *) 0, (size_t) 0) < 0)
2560 var_ifEntry(struct variable * vp,
2563 int exact, size_t * var_len, WriteMethod ** write_method)
2566 static int sname[6] = { CTL_NET, PF_LINK, NETLINK_GENERIC,
2567 IFMIB_IFDATA, 0, IFDATA_GENERAL
2569 static struct ifmibdata ifmd;
2573 interface = header_ifEntry(vp, name, length, exact, var_len,
2575 if (interface == MATCH_FAILED)
2578 sname[4] = interface;
2580 if (sysctl(sname, 6, &ifmd, &len, 0, 0) < 0)
2583 switch (vp->magic) {
2585 long_return = interface;
2586 return (u_char *) & long_return;
2588 cp = ifmd.ifmd_name;
2589 *var_len = strlen(cp);
2590 return (u_char *) cp;
2592 long_return = ifmd.ifmd_data.ifi_type;
2593 return (u_char *) & long_return;
2595 long_return = (long) ifmd.ifmd_data.ifi_mtu;
2596 return (u_char *) & long_return;
2598 long_return = ifmd.ifmd_data.ifi_baudrate;
2599 return (u_char *) & long_return;
2603 if (get_phys_address(interface, &cp, var_len))
2609 long_return = ifmd.ifmd_flags & IFF_UP ? 1 : 2;
2610 return (u_char *) & long_return;
2612 long_return = ifmd.ifmd_flags & IFF_RUNNING ? 1 : 2;
2613 return (u_char *) & long_return;
2615 if (ifmd.ifmd_data.ifi_lastchange.tv_sec == 0 &&
2616 ifmd.ifmd_data.ifi_lastchange.tv_usec == 0) {
2618 } else if (ifmd.ifmd_data.ifi_lastchange.tv_sec < starttime.tv_sec) {
2621 long_return = (u_long)
2622 ((ifmd.ifmd_data.ifi_lastchange.tv_sec -
2623 starttime.tv_sec) * 100 +
2624 ((ifmd.ifmd_data.ifi_lastchange.tv_usec -
2625 starttime.tv_usec) / 10000));
2627 return (u_char *) & long_return;
2629 long_return = (u_long) ifmd.ifmd_data.ifi_ibytes;
2630 return (u_char *) & long_return;
2632 long_return = (u_long) ifmd.ifmd_data.ifi_ipackets;
2633 long_return -= (u_long) ifmd.ifmd_data.ifi_imcasts;
2634 return (u_char *) & long_return;
2635 case IFINNUCASTPKTS:
2636 long_return = (u_long) ifmd.ifmd_data.ifi_imcasts;
2637 return (u_char *) & long_return;
2639 long_return = (u_long) ifmd.ifmd_data.ifi_iqdrops;
2640 return (u_char *) & long_return;
2642 long_return = ifmd.ifmd_data.ifi_ierrors;
2643 return (u_char *) & long_return;
2644 case IFINUNKNOWNPROTOS:
2645 long_return = (u_long) ifmd.ifmd_data.ifi_noproto;
2646 return (u_char *) & long_return;
2648 long_return = (u_long) ifmd.ifmd_data.ifi_obytes;
2649 return (u_char *) & long_return;
2650 case IFOUTUCASTPKTS:
2651 long_return = (u_long) ifmd.ifmd_data.ifi_opackets;
2652 long_return -= (u_long) ifmd.ifmd_data.ifi_omcasts;
2653 return (u_char *) & long_return;
2654 case IFOUTNUCASTPKTS:
2655 long_return = (u_long) ifmd.ifmd_data.ifi_omcasts;
2656 return (u_char *) & long_return;
2658 long_return = ifmd.ifmd_snd_drops;
2659 return (u_char *) & long_return;
2661 long_return = ifmd.ifmd_data.ifi_oerrors;
2662 return (u_char *) & long_return;
2664 long_return = ifmd.ifmd_snd_len;
2665 return (u_char *) & long_return;
2667 *var_len = nullOidLen;
2668 return (u_char *) nullOid;
2670 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
2676 #endif /* HAVE_NET_IF_MIB_H */
2677 #endif /* !USE_SYSCTL_IFLIST */
2680 #include <iphlpapi.h>
2682 WriteMethod writeIfEntry;
2683 long admin_status = 0;
2684 long oldadmin_status = 0;
2687 header_ifEntry(struct variable *vp,
2690 int exact, size_t * var_len, WriteMethod ** write_method)
2692 #define IFENTRY_NAME_LENGTH 10
2693 oid newname[MAX_OID_LEN];
2694 register int ifIndex;
2696 DWORD status = NO_ERROR;
2697 DWORD statusRetry = NO_ERROR;
2698 DWORD dwActualSize = 0;
2699 PMIB_IFTABLE pIfTable = NULL;
2701 DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: "));
2702 DEBUGMSGOID(("mibII/interfaces", name, *length));
2703 DEBUGMSG(("mibII/interfaces", " %d\n", exact));
2705 memcpy((char *) newname, (char *) vp->name,
2706 (int) vp->namelen * sizeof(oid));
2708 * find "next" ifIndex
2713 * query for buffer size needed
2715 status = GetIfTable(pIfTable, &dwActualSize, TRUE);
2717 if (status == ERROR_INSUFFICIENT_BUFFER) {
2721 pIfTable = (PMIB_IFTABLE) malloc(dwActualSize);
2722 if (pIfTable != NULL) {
2724 * Get the sorted IF table
2726 GetIfTable(pIfTable, &dwActualSize, TRUE);
2729 count = pIfTable->dwNumEntries;
2730 for (ifIndex = 0; ifIndex < count; ifIndex++) {
2731 newname[IFENTRY_NAME_LENGTH] =
2732 (oid) pIfTable->table[ifIndex].dwIndex;
2734 snmp_oid_compare(name, *length, newname,
2735 (int) vp->namelen + 1);
2736 if ((exact && (result == 0)) || (!exact && (result < 0)))
2739 if (ifIndex > count) {
2740 DEBUGMSGTL(("mibII/interfaces", "... index out of range\n"));
2741 return MATCH_FAILED;
2745 memcpy((char *) name, (char *) newname,
2746 ((int) vp->namelen + 1) * sizeof(oid));
2747 *length = vp->namelen + 1;
2749 *var_len = sizeof(long); /* default to 'long' results */
2751 DEBUGMSGTL(("mibII/interfaces", "... get I/F stats "));
2752 DEBUGMSGOID(("mibII/interfaces", name, *length));
2753 DEBUGMSG(("mibII/interfaces", "\n"));
2755 count = pIfTable->table[ifIndex].dwIndex;
2763 var_interfaces(struct variable * vp,
2766 int exact, size_t * var_len, WriteMethod ** write_method)
2768 if (header_generic(vp, name, length, exact, var_len, write_method) ==
2772 switch (vp->magic) {
2774 GetNumberOfInterfaces(&long_return);
2775 return (u_char *) & long_return;
2777 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n",
2784 var_ifEntry(struct variable * vp,
2787 int exact, size_t * var_len, WriteMethod ** write_method)
2790 static char Name[16];
2791 conf_if_list *if_ptr = conf_list;
2792 static MIB_IFROW ifRow;
2795 header_ifEntry(vp, name, length, exact, var_len, write_method);
2796 if (ifIndex == MATCH_FAILED)
2800 * Get the If Table Row by passing index as argument
2802 ifRow.dwIndex = ifIndex;
2803 if (GetIfEntry(&ifRow) != NO_ERROR)
2805 switch (vp->magic) {
2807 long_return = ifIndex;
2808 return (u_char *) & long_return;
2810 *var_len = ifRow.dwDescrLen;
2811 return (u_char *) ifRow.bDescr;
2813 long_return = ifRow.dwType;
2814 return (u_char *) & long_return;
2816 long_return = (long) ifRow.dwMtu;
2817 return (u_char *) & long_return;
2819 long_return = (long) ifRow.dwSpeed;
2820 return (u_char *) & long_return;
2822 *var_len = ifRow.dwPhysAddrLen;
2823 memcpy(return_buf, ifRow.bPhysAddr, *var_len);
2824 return (u_char *) return_buf;
2826 long_return = ifRow.dwAdminStatus;
2827 admin_status = long_return;
2828 *write_method = writeIfEntry;
2829 return (u_char *) & long_return;
2831 long_return = ifRow.dwOperStatus;
2832 return (u_char *) & long_return;
2834 long_return = ifRow.dwLastChange;
2835 return (u_char *) & long_return;
2837 long_return = ifRow.dwInOctets;
2838 return (u_char *) & long_return;
2840 long_return = ifRow.dwInUcastPkts;
2841 return (u_char *) & long_return;
2842 case IFINNUCASTPKTS:
2843 long_return = ifRow.dwInNUcastPkts;
2844 return (u_char *) & long_return;
2846 long_return = ifRow.dwInDiscards;
2847 return (u_char *) & long_return;
2849 long_return = ifRow.dwInErrors;
2850 return (u_char *) & long_return;
2851 case IFINUNKNOWNPROTOS:
2852 long_return = ifRow.dwInUnknownProtos;
2853 return (u_char *) & long_return;
2855 long_return = ifRow.dwOutOctets;
2856 return (u_char *) & long_return;
2857 case IFOUTUCASTPKTS:
2858 long_return = ifRow.dwOutUcastPkts;
2859 return (u_char *) & long_return;
2860 case IFOUTNUCASTPKTS:
2861 long_return = ifRow.dwOutNUcastPkts;
2862 return (u_char *) & long_return;
2864 long_return = ifRow.dwOutDiscards;
2865 return (u_char *) & long_return;
2867 long_return = ifRow.dwOutErrors;
2868 return (u_char *) & long_return;
2870 long_return = ifRow.dwOutQLen;
2871 return (u_char *) & long_return;
2873 *var_len = nullOidLen;
2874 return (u_char *) nullOid;
2876 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n",
2884 writeIfEntry(int action,
2886 u_char var_val_type,
2888 u_char * statP, oid * name, size_t name_len)
2890 MIB_IFROW ifEntryRow;
2891 if ((char) name[9] != IFADMINSTATUS) {
2892 return SNMP_ERR_NOTWRITABLE;
2896 case RESERVE1: /* Check values for acceptability */
2897 if (var_val_type != ASN_INTEGER) {
2898 snmp_log(LOG_ERR, "not integer\n");
2899 return SNMP_ERR_WRONGTYPE;
2901 if (var_val_len > sizeof(int)) {
2902 snmp_log(LOG_ERR, "bad length\n");
2903 return SNMP_ERR_WRONGLENGTH;
2907 * The dwAdminStatus member can be MIB_IF_ADMIN_STATUS_UP or MIB_IF_ADMIN_STATUS_DOWN
2909 if (!(((int) (*var_val) == MIB_IF_ADMIN_STATUS_UP) ||
2910 ((int) (*var_val) == MIB_IF_ADMIN_STATUS_DOWN))) {
2911 snmp_log(LOG_ERR, "not supported admin state\n");
2912 return SNMP_ERR_WRONGVALUE;
2916 case RESERVE2: /* Allocate memory and similar resources */
2921 * Save the old value, in case of UNDO
2924 oldadmin_status = admin_status;
2925 admin_status = (int) *var_val;
2928 case UNDO: /* Reverse the SET action and free resources */
2929 admin_status = oldadmin_status;
2932 case COMMIT: /* Confirm the SET, performing any irreversible actions,
2933 * and free resources */
2934 ifEntryRow.dwIndex = (int) name[10];
2935 ifEntryRow.dwAdminStatus = admin_status;
2937 * Only UP and DOWN status are supported. Thats why done in COMMIT
2939 if (SetIfEntry(&ifEntryRow) != NO_ERROR) {
2941 "Error in writeIfEntry case COMMIT with index: %d & adminStatus %d\n",
2942 ifEntryRow.dwIndex, ifEntryRow.dwAdminStatus);
2943 return SNMP_ERR_COMMITFAILED;
2946 case FREE: /* Free any resources allocated */
2948 * No resources have been allocated
2952 return SNMP_ERR_NOERROR;
2953 } /* end of writeIfEntry */
2957 #ifdef BUILD_SNMP_SET
2958 static int setPppConnAdminDown(char *devName);
2960 writeIfEntry(int action,
2962 u_char var_val_type,
2964 u_char * statP, oid * name, size_t name_len)
2970 if ((char) name[9] != IFADMINSTATUS)
2971 return SNMP_ERR_NOTWRITABLE;
2974 case RESERVE1: /* Check values for acceptability */
2975 if (var_val_type != ASN_INTEGER) {
2976 snmp_log(LOG_ERR, "not integer\n");
2977 return SNMP_ERR_WRONGTYPE;
2979 if (var_val_len > sizeof(int)) {
2980 snmp_log(LOG_ERR, "bad length\n");
2981 return SNMP_ERR_WRONGLENGTH;
2984 value = *((int*)var_val);
2986 if ((value != IF_ADMIN_STATUS_UP) &&
2987 (value != IF_ADMIN_STATUS_DOWN)) {
2988 snmp_log(LOG_ERR, "not supported admin state %d\n",value);
2989 return SNMP_ERR_WRONGVALUE;
2993 case RESERVE2: /* Allocate memory and similar resources */
2998 * Save the old value, in case of UNDO
3002 case UNDO: /* Reverse the SET action and free resources */
3005 case COMMIT: /* Confirm the SET, performing any irreversible actions,
3006 * and free resources */
3007 index = *((int*)&name[10]);
3008 value = *((int*)var_val);
3009 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
3010 snmp_log(LOG_ERR, "socket open failure in WriteIfEntry\n");
3011 return SNMP_ERR_COMMITFAILED;
3014 /* get ifName first */
3015 ifrq.ifr_ifindex = index;
3016 if (ioctl(fd, SIOCGIFNAME, &ifrq) < 0) {
3017 snmp_log(LOG_ERR, "WriteIfEntry unable to locate device name for ifIndex %d\n",index);
3018 return SNMP_ERR_COMMITFAILED;
3021 if (strcmp(ifrq.ifr_name,IF_BRCM_DSL_DEV_NAME) == 0) {
3022 if (setAdslAdminStatus(value) < 0)
3023 return SNMP_ERR_COMMITFAILED;
3025 else if ((strcmp(ifrq.ifr_name,"atm0") == 0) ||
3026 (strcmp(ifrq.ifr_name,"cpcs0") == 0)) {
3027 if (setAtmIntfAdminStatus(value) < 0)
3028 return SNMP_ERR_COMMITFAILED;
3030 else if ((strncmp(ifrq.ifr_name,"ppp",strlen("ppp"))) == 0) {
3031 /* value is always down since after ppp is admin down the first time, dev is gone */
3032 if (setPppConnAdminDown(ifrq.ifr_name) < 0)
3033 return SNMP_ERR_COMMITFAILED;
3035 if (value == IF_ADMIN_STATUS_UP)
3036 ifrq.ifr_flags |= IFF_UP;
3038 ifrq.ifr_flags &= ~IFF_UP;
3039 if (ioctl(fd, SIOCSIFFLAGS, &ifrq) < 0) {
3041 return SNMP_ERR_COMMITFAILED;
3045 case FREE: /* Free any resources allocated */
3047 * No resources have been allocated
3051 return SNMP_ERR_NOERROR;
3052 } /* end of ifWriteEntry */
3054 int setPppConnAdminDown(char *devName)
3061 sprintf(path,"/proc/var/fyi/wan/%s/wanup",devName);
3063 fs = fopen(path, "w");
3072 if( (fd = open( "/dev/brcmboard", O_RDWR )) != -1 ) {
3073 ioctl( fd, BOARD_IOCTL_WAKEUP_MONITOR_TASK, NULL);
3079 #endif /* BUILD_SNMP_SET */