📄 interfaces.c
字号:
/* * Interfaces MIB group implementation - interfaces.c * */#include <config.h>#include "mibincl.h"#if HAVE_STRING_H#include <string.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif#include <sys/types.h>#if defined(IFNET_NEEDS_KERNEL) && !defined(_KERNEL) && defined(IFNET_NEEDS_KERNEL_LATE)#define _KERNEL 1#define _I_DEFINED_KERNEL#endif#include <sys/socket.h>#if HAVE_SYS_SOCKIO_H#include <sys/sockio.h>#endif#if HAVE_FCNTL_H#include <fcntl.h>#endif#if HAVE_SYS_IOCTL_H#include <sys/ioctl.h>#endif#include <net/if.h>#if HAVE_NET_IF_VAR_H#include <net/if_var.h>#endif#ifdef _I_DEFINED_KERNEL#undef _KERNEL#endif#if HAVE_SYS_STREAM_H#include <sys/stream.h>#endif#if HAVE_NET_ROUTE_H#include <net/route.h>#endif#if HAVE_NETINET_IN_SYSTM_H#include <netinet/in_systm.h>#endif#if HAVE_SYS_HASHING_H#include <sys/hashing.h>#endif#if HAVE_NETINET_IN_VAR_H#include <netinet/in_var.h>#endif#include <netinet/ip.h>#ifdef INET6#if HAVE_NETINET_IP6_H#include <netinet/ip6.h>#endif#endif#if HAVE_SYS_QUEUE_H#include <sys/queue.h>#endif#if HAVE_NETINET_IP_VAR_H#include <netinet/ip_var.h>#endif#ifdef INET6#if HAVE_NETINET6_IP6_VAR_H#include <netinet6/ip6_var.h>#endif#endif#if HAVE_NETINET_IN_PCB_H#include <netinet/in_pcb.h>#endif#if HAVE_NETINET_IF_ETHER_H#include <netinet/if_ether.h>#endif#if HAVE_NET_IF_TYPES_H#include <net/if_types.h>#endif#if HAVE_NET_IF_DL_H#include <net/if_dl.h>#endif#if HAVE_INET_MIB2_H#include <inet/mib2.h>#endif#if HAVE_IOCTLS_H#include <ioctls.h>#endif#include <ctype.h>#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#ifdef solaris2#include "kernel_sunos5.h"#else#include "kernel.h"#endif#ifdef hpux#include <sys/mib.h>#include "kernel_hpux.h"#endif /* hpux */#if HAVE_SYS_SYSCTL_H#include <sys/sysctl.h>#ifdef freebsd3# define USE_SYSCTL_IFLIST#else# if defined(CTL_NET) && !defined(freebsd2)# ifdef PF_ROUTE# ifdef NET_RT_IFLIST# ifndef netbsd1# define USE_SYSCTL_IFLIST# endif# endif# endif# endif#endif /* defined(freebsd3) */#endif /* HAVE_SYS_SYSCTL_H */#include "system.h"#include "snmp_logging.h"#if HAVE_OSRELDATE_H#include <osreldate.h>#endif#ifdef CAN_USE_SYSCTL#include <sys/sysctl.h>#endif#include "interfaces.h"#include "struct.h"#include "util_funcs.h"#include "auto_nlist.h"#include "sysORTable.h"#ifndef INTERFACE_CACHE_TIMEOUT#define INTERFACE_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT#endifmib_table_t interface_table; /********************* * * Kernel & interface information, * and internal forward declarations * *********************/#include "if_fields.h"int Interface_Scan_Get_Count( void );int Load_Interface_List( mib_table_t );void Init_Interface_Speeds( void );int Interface_Speed_From_Type( int type );int Interface_Speed_From_Name( const char *name );int Interface_Type_From_Name( const char *name ); /********************* * * Initialisation * *********************/struct variable4 interfaces_variables[] = { {IFNUMBER, ASN_INTEGER, RONLY, var_interfaces, 1, {1}}, {IFINDEX, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 1}}, {IFDESCR, ASN_OCTET_STR, RONLY, var_ifEntry, 3, {2, 1, 2}}, {IFTYPE, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 3}}, {IFMTU, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 4}}, {IFSPEED, ASN_GAUGE, RONLY, var_ifEntry, 3, {2, 1, 5}}, {IFPHYSADDRESS, ASN_OCTET_STR, RONLY, var_ifEntry, 3, {2, 1, 6}}, {IFADMINSTATUS, ASN_INTEGER, RWRITE, var_ifEntry, 3, {2, 1, 7}}, {IFOPERSTATUS, ASN_INTEGER, RONLY, var_ifEntry, 3, {2, 1, 8}}, {IFLASTCHANGE, ASN_TIMETICKS, RONLY, var_ifEntry, 3, {2, 1, 9}}, {IFINOCTETS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 10}}, {IFINUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 11}}, {IFINNUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 12}}, {IFINDISCARDS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 13}}, {IFINERRORS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 14}}, {IFINUNKNOWNPROTOS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 15}}, {IFOUTOCTETS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 16}}, {IFOUTUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 17}}, {IFOUTNUCASTPKTS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 18}}, {IFOUTDISCARDS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 19}}, {IFOUTERRORS, ASN_COUNTER, RONLY, var_ifEntry, 3, {2, 1, 20}}, {IFOUTQLEN, ASN_GAUGE, RONLY, var_ifEntry, 3, {2, 1, 21}}, {IFSPECIFIC, ASN_OBJECT_ID, RONLY, var_ifEntry, 3, {2, 1, 22}}};/* Define the OID pointer to the top of the mib tree that we're registering underneath, and the OID of the MIB module */oid interfaces_variables_oid[] = { SNMP_OID_MIB2,2 };oid interfaces_module_oid[] = { SNMP_OID_MIB2,31 };void init_interfaces(void){ /* register ourselves with the agent to handle our mib tree */ REGISTER_MIB("mibII/interfaces", interfaces_variables, variable4, \ interfaces_variables_oid); REGISTER_SYSOR_ENTRY(interfaces_module_oid, "The MIB module to describe generic objects for network interface sub-layers"); interface_table = Initialise_Table( sizeof(struct if_entry), INTERFACE_CACHE_TIMEOUT, Load_Interface_List, NULL ); Init_Interface_Speeds();} /********************* * * Main variable handling routines * *********************/u_char *var_interfaces(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ if (header_generic(vp, name, length, exact, var_len, write_method) == MATCH_FAILED ) return NULL; switch (vp->magic) { case IFNUMBER: long_return = Interface_Scan_Get_Count (); return (u_char *)&long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_interfaces\n", vp->magic)); } return NULL;}u_char *var_ifEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ int max_idx, idx; struct if_entry *ifTable; IFENTRY_TYPE *ifstat; /* * We can treat this as a 'simple' table, * once we know the maximimum index. * * Note that this is *not* necessarily * the same as 'Interface_Scan_Get_Count()' * as the interface table can potentially * be "sparse". */ ifTable = Retrieve_Table_Data( interface_table, &max_idx ); if ( ifTable == NULL ) return NULL; if (header_simple_table(vp, name, length, exact, var_len, write_method, max_idx) == MATCH_FAILED ) return NULL; /* * If the suggested index is not currently being used, * amend it (if appropriate) */ idx = name[ vp->namelen ]; if ( ifTable[idx].ifstat == NULL ) { if ( exact ) return NULL; while ( idx++ < max_idx ) { if ( ifTable[idx].ifstat != NULL ) break; /* found one */ } if ( idx == max_idx ) return NULL; name[ vp->namelen ] = idx; } ifstat = ifTable[ idx ].ifstat; switch (vp->magic){ case IFINDEX: long_return = idx; return (u_char *) &long_return; case IFDESCR: *var_len = strlen( ifTable[ idx ].name ); return (u_char *) ifTable[ idx ].name; case IFTYPE:#ifdef IFENTRY_FIELD_TYPE long_return = (u_long)ifstat->IFENTRY_FIELD_TYPE;#else long_return = Interface_Type_From_Name( ifTable[ idx ].name );#endif return (u_char *) &long_return; case IFMTU: long_return = (u_long)ifstat->IFENTRY_FIELD_MTU; return (u_char *) &long_return; case IFSPEED:#ifdef IFENTRY_FIELD_SPEED long_return = (u_long)ifstat->IFENTRY_FIELD_SPEED;#else#ifdef IFENTRY_FIELD_TYPE long_return = Interface_Speed_From_Type(ifstat->IFENTRY_FIELD_TYPE);#else long_return = Interface_Speed_From_Name( ifTable[ idx ].name );#endif#endif return (u_char *) &long_return; case IFPHYSADDRESS:#ifdef IFENTRY_FIELD_PHYSADDR *var_len = IFENTRY_STRING_SIZE(ifstat->IFENTRY_FIELD_PHYSADDR); (void)memcpy(return_buf, IFENTRY_STRING_VALUE(ifstat->IFENTRY_FIELD_PHYSADDR), *var_len); return (u_char *)return_buf;#else#ifdef IFENTRY_CALCULATE_PHYSADDR if (Interface_Get_Ether_By_Index (idx, return_buf, var_len)) { return (u_char *)return_buf; }#endif return NULL;#endif case IFADMINSTATUS:#ifdef IFENTRY_FIELD_ADMIN long_return = (u_long)ifstat->IFENTRY_FIELD_ADMIN; return (u_char *) &long_return;#else#ifdef IFENTRY_CALCULATE_STATUS long_return = ifstat->IFENTRY_FIELD_FLAGS & IFF_RUNNING ? 1 : 2; return (u_char *) &long_return;#endif#endif return NULL; case IFOPERSTATUS:#ifdef IFENTRY_FIELD_OPER long_return = (u_long)ifstat->IFENTRY_FIELD_OPER; return (u_char *) &long_return;#else#ifdef IFENTRY_CALCULATE_STATUS long_return = ifstat->IFENTRY_FIELD_FLAGS & IFF_UP ? 1 : 2; return (u_char *) &long_return;#endif#endif return NULL; case IFLASTCHANGE:#ifdef IFENTRY_FIELD_LASTCH#ifndef IFENTRY_CALCULATE_LASTCH long_return = (u_long)ifstat->IFENTRY_FIELD_LASTCH; return (u_char *) &long_return;#else long_return = marker_ttime( &ifstat->IFENTRY_FIELD_LASTCH ) return (u_char *) &long_return;#endif#else return NULL;#endif case IFINOCTETS:#ifdef IFENTRY_FIELD_INOCTETS if ( ifstat->IFENTRY_FIELD_INOCTETS == 0 ) return NULL; long_return = (u_long)ifstat->IFENTRY_FIELD_INOCTETS; return (u_char *) &long_return;#else return NULL;#endif case IFINUCASTPKTS: long_return = (u_long)ifstat->IFENTRY_FIELD_INPKTS;#ifdef IFENTRY_FIX_UNICAST long_return -= (u_long)ifstat->IFENTRY_FIELD_INMCASTS;#endif return (u_char *) &long_return; case IFINNUCASTPKTS:#ifdef IFENTRY_FIELD_INMCASTS long_return = (u_long)ifstat->IFENTRY_FIELD_INMCASTS; return (u_char *) &long_return;#else return NULL;#endif case IFINDISCARDS:#ifdef IFENTRY_FIELD_INDISCARDS long_return = (u_long)ifstat->IFENTRY_FIELD_INDISCARDS; return (u_char *) &long_return;#else return NULL;#endif case IFINERRORS: long_return = (u_long)ifstat->IFENTRY_FIELD_INERRORS; return (u_char *) &long_return; case IFINUNKNOWNPROTOS:#ifdef IFENTRY_FIELD_UNKNOWN long_return = (u_long)ifstat->IFENTRY_FIELD_UNKNOWN; return (u_char *) &long_return;#else return NULL;#endif case IFOUTOCTETS:#ifdef IFENTRY_FIELD_OUTOCTETS if ( ifstat->IFENTRY_FIELD_OUTOCTETS == 0 ) return NULL; long_return = (u_long)ifstat->IFENTRY_FIELD_OUTOCTETS; return (u_char *) &long_return;#else return NULL;#endif case IFOUTUCASTPKTS: long_return = (u_long)ifstat->IFENTRY_FIELD_OUTPKTS;#ifdef IFENTRY_FIX_UNICAST long_return -= (u_long)ifstat->IFENTRY_FIELD_OUTMCASTS;#endif return (u_char *) &long_return; case IFOUTNUCASTPKTS:#ifdef IFENTRY_FIELD_OUTMCASTS long_return = (u_long)ifstat->IFENTRY_FIELD_OUTMCASTS; return (u_char *) &long_return;#else return NULL;#endif case IFOUTDISCARDS:#ifdef IFENTRY_FIELD_OUTDISCARDS long_return = (u_long)ifstat->IFENTRY_FIELD_OUTDISCARDS; return (u_char *) &long_return;#else return NULL;#endif case IFOUTERRORS: long_return = (u_long)ifstat->IFENTRY_FIELD_OUTERRORS; return (u_char *) &long_return; case IFOUTQLEN:#ifdef IFENTRY_FIELD_QLEN long_return = (u_long)ifstat->IFENTRY_FIELD_QLEN; return (u_char *) &long_return;#else return NULL;#endif case IFSPECIFIC: return NULL; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n", vp->magic)); } return NULL;} /********************* * * System-independent internal implementation functions * *********************/typedef struct _match_if { int mi_type; const char *mi_name;} match_if;static match_if lmatch_if[] = { { 24, "lo" }, /* loopback */ { 6, "eth" }, /* ethernet */ { 6, "le" }, /* Lance ethernet */ { 6, "qe" }, /* Quad ethernet */ { 6, "hme" }, { 9, "tr" }, /* Token Ring */ { 23, "ppp" }, /* Point-to-Point */ { 28, "sl" }, { 37, "lane" }, /* LAN Emulation (ATM) */ { 37, "fa" }, /* Fore ATM */ { 37, "qa" }, /* Fore? ATM */ { 62, "qfe" }, /* Quad Fast ethernet */ { 0, 0 } /* end of list */};#define MAX_IF_TYPES 161 /* From IANAifType-MIB */static int if_speeds[ MAX_IF_TYPES ];void Init_Interface_Speeds( void ){ int i; for ( i = 0 ; i < MAX_IF_TYPES ; i++ ) if_speeds[i] = 0;#define MBIT 1000000 if_speeds[ 6 ] = 10 * MBIT; /* traditional ethernet */ if_speeds[ 9 ] = 4 * MBIT; /* Token Ring */ if_speeds[ 37 ] = 155 * MBIT; /* ATM */ if_speeds[ 62 ] = 100 * MBIT; /* fast ethernet */ /* XXXX - Fill in the rest */}int Interface_Type_From_Name( const char *name ){ int len; match_if *pm; for ( pm = lmatch_if ; pm->mi_name!= NULL ; pm++ ) { len = strlen( pm->mi_name ); if ( !strncmp( name, pm->mi_name, len )) return (pm->mi_type); } return( 1 ); /* 'other' */}int Interface_Speed_From_Type( int type ){ if (( type < MAX_IF_TYPES ) && ( type >= 0 )) return if_speeds[ type ]; else return 0;}int Interface_Speed_From_Name( const char *name ){ return ( Interface_Speed_From_Type( Interface_Type_From_Name( name )));}int Interface_Get_Ether_By_Index (int idx, char* buf, int *len) { int max_idx; struct if_entry *ifTable; ifTable = Retrieve_Table_Data( interface_table, &max_idx ); if ( idx > max_idx ) return -1; /* How do we do this ? */ return -1;}int Interface_Scan_Get_Count (void) { int max_idx, i, count; struct if_entry *ifTable; ifTable = Retrieve_Table_Data( interface_table, &max_idx ); count = 0; for ( i = 1 ; i <= max_idx ; i++ ) if ( ifTable[i].ifstat ) count++; return count;}int Interface_Index_By_Name ( char *name) { int max_idx, i; struct if_entry *ifTable; ifTable = Retrieve_Table_Data( interface_table, &max_idx ); for ( i = 1 ; i <= max_idx ; i++ ) if ( !strcmp(ifTable[i].name, name )) return ( ifTable[i].index ); return -1;}void Clear_Interface_Table( mib_table_t t){ int max_idx, i; struct if_entry *ifTable; ifTable = Retrieve_Table_Data( t, &max_idx ); for ( i = 1 ; i <= max_idx ; i++ ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -