📄 interfaces.c
字号:
if ( ifTable[i].ifstat ) { free( ifTable[i].ifstat ); ifTable[i].ifstat=NULL; } if ( ifTable[i].ifaddr ) { free( ifTable[i].ifaddr ); ifTable[i].ifaddr=NULL; } }}int Add_IF_Entry( mib_table_t t, struct if_entry *entry ){ int max_idx, i; struct if_entry *ifTable; ifTable = Retrieve_Table_Data( t, &max_idx ); /* Look for an existing entry with this name */ for ( i = 1 ; i <= max_idx ; i++ ) { if ( !strcmp(ifTable[i].name, entry->name )) { if ( ifTable[i].ifstat ) free( ifTable[i].ifstat ); ifTable[i].ifstat = entry->ifstat; entry->ifstat = NULL; if ( ifTable[i].ifaddr ) free( ifTable[i].ifaddr ); ifTable[i].ifaddr = entry->ifaddr; entry->ifaddr = NULL; return 1; } } /* Otherwise, add it to the list */ entry->index = i; return (Add_Entry( t, (void*)entry ));}static int if_scan_idx, if_scan_max_idx;static struct if_entry *if_scan_Table;voidInterface_Scan_Init( void ){ if_scan_idx = 1; if_scan_Table = Retrieve_Table_Data( interface_table, &if_scan_max_idx );}intInterface_Scan_Next(short *Index, char *Name, IFENTRY_TYPE *Retifnet, IFADDR_TYPE *Retifaddr){ while ( if_scan_idx <= if_scan_max_idx ) { if ( if_scan_Table[if_scan_idx].ifstat == NULL ) { if_scan_idx++; continue; } *Index = if_scan_Table[if_scan_idx].index; if ( Name ) strcpy(Name, if_scan_Table[if_scan_idx].name); if ( Retifnet ) memcpy(Retifnet, if_scan_Table[if_scan_idx].ifstat, sizeof( IFENTRY_TYPE )); if ( Retifaddr ) memcpy(Retifaddr, if_scan_Table[if_scan_idx].ifaddr, sizeof( IFADDR_TYPE )); if_scan_idx++; return 0; } return -1;} /********************* * * System-specific functions to read * in the list of interfaces * *********************/#ifdef USE_SYSCTL_IFLIST#define LOAD_INTERFACE_LIST#define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))int Load_Interface_List( mib_table_t t ){ int name[] = {CTL_NET,PF_ROUTE,0,0,NET_RT_IFLIST,0}; u_char *if_list, *if_list_end, *cp; struct if_msghdr *ifm; struct ifa_msghdr *ifam; size_t size; struct if_entry entry; struct sockaddr_dl *sdl; Clear_Interface_Table( t ); /* * Read in the data */ if (sysctl (name, sizeof(name)/sizeof(int), 0, &size, 0, 0) == -1) { snmp_log(LOG_ERR,"sysctl size fail\n"); return -1; } if ( size == 0 ) return -1; /* No interfaces */ if ((if_list = malloc (size)) == NULL) { snmp_log(LOG_ERR,"out of memory allocating interface table\n"); return -1; } if (sysctl (name, sizeof(name)/sizeof(int), if_list, &size, 0, 0) == -1) { snmp_log(LOG_ERR,"sysctl get fail\n"); free(if_list); return -1; } if_list_end = if_list + size; /* * Step through this buffer, * adding entries to the table */ for (cp = if_list; cp < if_list_end; cp += ifm->ifm_msglen) { ifm = (struct if_msghdr *)cp; if (ifm->ifm_type == RTM_IFINFO) { entry.ifstat = malloc(sizeof(*ifm)); if ( entry.ifstat == NULL ) break; sdl = (struct sockaddr_dl *)&ifm[1]; entry.index = ifm->ifm_index; entry.name = strdup( sdl->sdl_data ); entry.name[sdl->sdl_nlen] = 0; memcpy(entry.ifstat, ifm, sizeof(*ifm)); entry.ifaddr = malloc(sizeof(*entry.ifaddr)); entry.ifaddr->sifa_addr.s_addr = 0; /* XXX */ entry.ifaddr->sifa_netmask.s_addr = 0; /* XXX */ entry.ifaddr->sifa_broadcast.s_addr = 0; /* XXX */ ifm = (struct if_msghdr *)(cp + ifm->ifm_msglen); if (ifm->ifm_type == RTM_NEWADDR) { char *cp2, *cp2lim; int i; struct sockaddr_in *sin; cp = (char *)ifm; ifam = (struct ifa_msghdr *) ifm; cp2 = (char *)(ifam + 1); cp2lim = ifam->ifam_msglen + (char *)ifam; for (i = 0; (i < RTAX_MAX) && (cp2 < cp2lim); i++) { if ((ifam->ifam_addrs & (1 << i)) == 0) continue; sin = (struct sockaddr_in *)cp2; if (i == RTAX_IFA) entry.ifaddr->sifa_addr = sin->sin_addr; if (i == RTAX_BRD) entry.ifaddr->sifa_netmask = sin->sin_addr; if (i == RTAX_NETMASK) entry.ifaddr->sifa_broadcast = sin->sin_addr; ADVANCE(cp2, (struct sockaddr *)sin); } } /* * Add this to the table */ if ( Add_IF_Entry( t, &entry ) < 0 ) break; } } free( if_list ); return 0;}#endif#if defined(HAVE_NET_IF_MIB_H) && defined(IS_THIS_DIFFERENT_FROM_ABOVE)#define LOAD_INTERFACE_LISTint Load_Interface_List( mib_table_t t ){ int name[] = {CTL_NET,PF_ROUTE,0,AF_LINK,NET_RT_IFLIST,0}; u_char *if_list, *if_list_end, *cp; size_t size; struct if_entry entry; Clear_Interface_Table( t ); /* * Read in the data */ if (sysctl (name, sizeof(name)/sizeof(int), 0, &size, 0, 0) == -1) { snmp_log(LOG_ERR,"sysctl size fail\n"); return -1; } if ( size == 0 ) return -1; /* No interfaces */ if ((if_list = malloc (size)) == NULL) { snmp_log(LOG_ERR,"out of memory allocating interface table\n"); return -1; } if (sysctl (name, sizeof(name)/sizeof(int), if_list, &size, 0, 0) == -1) { snmp_log(LOG_ERR,"sysctl get fail\n"); free(if_list); return -1; } if_list_end = if_list + size; /* * Step through this buffer, * adding entries to the table */ for (cp = if_list; cp < if_list_end; cp += ifp->ifm_msglen) { /* XXXX - Set up 'entry' */ /* * Add this to the table */ if ( Add_IF_Entry( t, &entry ) < 0 ) break; } free( if_list ); return 0;}#endif#ifdef hpux#define LOAD_INTERFACE_LISTstatic int ifIndexMap[ 100 ]; int Load_Interface_List( mib_table_t t ){ int numIfEntries, numIpAddrEntries, size, i, j; struct if_entry entry; mib_ifEntry *ifEntries; mib_ipAdEnt *ipAddrEntries, ipaddr_p; char *cp; Clear_Interface_Table( t ); /* * Read in interface table */ if (hpux_read_stat((char *)&numIfEntries, sizeof(int), ID_ifNumber) == -1) return -1; size = numIfEntries*sizeof(mib_ifEntry); if ( (ifEntries=(mib_ifEntry *)malloc ( size )) == NULL ) return -1; if (hpux_read_stat((char *)ifEntries, size, ID_ifTable) == -1) { free( ifEntries ); return -1; } /* * Read in ipAdddress table */ if (hpux_read_stat((char *)&numIpAddrEntries, sizeof(int), ID_ipAddrNumEnt) == -1) { free( ifEntries ); return -1; } size = numIpAddrEntries*sizeof(mib_ipAdEnt); if ( (ipAddrEntries=(mib_ipAdEnt *)malloc ( size )) == NULL ) { free( ifEntries ); return -1; } if (hpux_read_stat((char *)ipAddrEntries, size, ID_ipAddrTable) == -1) { free( ifEntries ); free( ipAddrEntries ); return -1; } /* * Merge the two */ for ( i = 0 ; i<numIfEntries ; i++ ) { entry.ifaddr = NULL; entry.ifstat = (mib_ifEntry *)malloc( sizeof( mib_ifEntry )); if ( entry.ifstat == NULL ) break; memcpy( entry.ifstat, &(ifEntries[i]), sizeof( mib_ifEntry )); cp = strchr( ifEntries[i].ifDescr, ' '); if ( cp != NULL ) *cp = '\0'; entry.name = strdup( ifEntries[i].ifDescr ); entry.ifaddr = NULL; for ( j = 0 ; j<numIpAddrEntries ; j++ ) if ( ifEntries[i].ifIndex == ipAddrEntries[j].IfIndex ) { entry.ifaddr = (mib_ipAdEnt *)malloc( sizeof( mib_ipAdEnt )); if ( entry.ifaddr == NULL ) { free( entry.ifstat ); break; } memcpy( entry.ifaddr, &(ipAddrEntries[j]), sizeof(mib_ifEntry)); break; } if ( Add_IF_Entry( t, (void*)&entry) < 0 ) break; /* * Set up a mapping from HP's ifIndex values to UCDs */ ifIndexMap[ entry.ifstat->ifIndex ] = entry.index; } free( ifEntries ); free( ipAddrEntries ); return 0;}#endif#ifdef linux#define LOAD_INTERFACE_LISTconst char *scan_line_2_2="%lu %lu %lu %*lu %*lu %*lu %*lu %*lu %lu %lu %lu %*lu %*lu %lu";const char *scan_line_2_0="%lu %lu %*lu %*lu %*lu %lu %lu %*lu %*lu %lu";int Load_Interface_List( mib_table_t t ){ FILE *in; char line [256], *cp1, *cp2, *ifname; struct if_entry entry; struct ifnet *nnew; struct in_ifaddr *anew; struct ifreq ifrq; int use_2_2_scan_line; int fd; if (! (in = fopen ("/proc/net/dev", "r"))) { snmp_log(LOG_ERR,"cannot open /proc/net/dev ...\n"); return -1; } Clear_Interface_Table( t ); /* * There are two formats for interface statistics output, * corresponding to the 2.0 and 2.2 kernels. * They can be distinguished by the format of the header * (i.e. the first two lines) - the 2.2 format having * a number of additional values reported. * * It might be possible to analyse the fields to determine * precisely which fields are needed, but frankly, it's * not really worth it. This format changes so infrequently * that it's reasonable to hardwire the appropriate scan line * for particular kernels. */ fgets(line, sizeof(line), in); /* skip the first line */ fgets(line, sizeof(line), in); /* this has the field names */ if (strstr(line, "compressed")) { use_2_2_scan_line = TRUE; DEBUGMSGTL(("mibII/interfaces", "using linux 2.2 kernel /proc/net/dev\n")); } else { use_2_2_scan_line = FALSE; DEBUGMSGTL(("mibII/interfaces", "using linux 2.0 kernel /proc/net/dev\n")); } /* * We need a network socket to perform ioctls on, * so let's open it now. */ if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { DEBUGMSGTL(("snmpd", "socket open failure in Interface_Scan_Init\n")); fclose(in); return -1; } /* * Read in the various interface statistics lines, * and create 'IfList' entries for each one, * linking them into a list. */ while (fgets (line, sizeof(line), in)) { nnew = (struct ifnet *) calloc (1, sizeof (struct ifnet)); if ( !nnew ) { break; } anew = (struct in_ifaddr *) calloc (1, sizeof (struct in_ifaddr)); if ( !anew ) { free( nnew ); break; } /* * Extract the interface name * (skipping leading blanks) */ cp1 = line; while (isspace( *cp1 )) cp1++; cp2 = strrchr( cp1, ':' ); *cp2 = '\0'; entry.name = strdup( cp1 ); ifname = entry.name; /* just for ease of use in this routine */ /* * Extract the appropriate statistics * Note that the 2.0 kernel doesn't supply octet counts */ cp2++; if ( use_2_2_scan_line ) { sscanf( cp2, scan_line_2_2, &nnew->if_ibytes, &nnew->if_ipackets, &nnew->if_ierrors, &nnew->if_obytes, &nnew->if_opackets, &nnew->if_oerrors, &nnew->if_collisions); } else { sscanf( cp2, scan_line_2_0, &nnew->if_ipackets, &nnew->if_ierrors, &nnew->if_opackets, &nnew->if_oerrors, &nnew->if_collisions); nnew->if_ibytes = nnew->if_obytes = 0; } /* * Split the name into type and unit number */ nnew->if_name = strdup( cp1 ); cp2 = &(cp1[ strlen( cp1 ) -1 ]); for ( cp2 = cp1 ; cp2 ; cp2++ ) if ( isdigit( *cp2 )) break; if ( cp2 ) while ( isdigit( *cp2 )) { cp2--; if (cp2 == cp1 ) break; } /* XXX - do we actually need this ? */ if ( cp2 ) { nnew->if_unit = strdup( cp2 ); /* or atoi()? */ *cp2 = '\0'; } /* * Fill in the rest of the ifnet & ifaddr structures * using suitable ioctl calls */ strcpy (ifrq.ifr_name, ifname); if (ioctl (fd, SIOCGIFADDR, &ifrq) == 0) anew->ia_addr = ifrq.ifr_addr; strcpy (ifrq.ifr_name, ifname); if (ioctl (fd, SIOCGIFBRDADDR, &ifrq) == 0) anew->ia_broadaddr = ifrq.ifr_broadaddr; strcpy (ifrq.ifr_name, ifname); if (ioctl (fd, SIOCGIFNETMASK, &ifrq) == 0) anew->ia_subnetmask = ifrq.ifr_netmask; strcpy (ifrq.ifr_name, ifname); nnew->if_flags = ioctl (fd, SIOCGIFFLAGS, &ifrq) < 0 ? 0 : ifrq.ifr_flags; strcpy (ifrq.ifr_name, ifname); if (ioctl(fd, SIOCGIFHWADDR, &ifrq) == 0) { memcpy (nnew->if_hwaddr, ifrq.ifr_hwaddr.sa_data, 6);#ifdef ARPHRD_LOOPBACK switch (ifrq.ifr_hwaddr.sa_family) { case ARPHRD_TUNNEL: case ARPHRD_TUNNEL6: case ARPHRD_IPGRE: case ARPHRD_SIT: nnew->if_type = 131; break; /* tunnel */ case ARPHRD_SLIP: case ARPHRD_CSLIP: case ARPHRD_SLIP6: case ARPHRD_CSLIP6: nnew->if_type = 28; break; /* slip */ case ARPHRD_PPP: nnew->if_type = 23; break; /* ppp */ case ARPHRD_LOOPBACK: nnew->if_type = 24; break; /* softwareLoopback */ /* XXX: more if_arp.h:ARPHDR_xxx to IANAifType mappings... */ }#endif } strcpy (ifrq.ifr_name, ifname); nnew->if_metric = ioctl (fd, SIOCGIFMETRIC, &ifrq) < 0 ? 0 : ifrq.ifr_metric; #ifdef SIOCGIFMTU strcpy (ifrq.ifr_name, ifname); nnew->if_mtu = (ioctl (fd, SIOCGIFMTU, &ifrq) < 0) ? 0 : ifrq.ifr_mtu;#else nnew->if_mtu = 0;#endif if (!nnew->if_type) nnew->if_type = Interface_Type_From_Name(nnew->if_name); nnew->if_speed = Interface_Speed_From_Type(nnew->if_type); /* * Add this to the table */ entry.ifstat = nnew; entry.ifaddr = anew; if ( Add_IF_Entry( t, &entry ) < 0 ) break; } /* while fgets() */ fclose( in ); return 0;}#endif#ifndef LOAD_INTERFACE_LISTint Load_Interface_List( mib_table_t t ){ struct ifnet *ifnetaddr, ifnet; struct in_ifaddr *ia, in_ifaddr; struct if_entry entry; char *cp, ifname[32]; Clear_Interface_Table( t ); auto_nlist(IFNET_SYMBOL, (char *)&ifnetaddr, sizeof(ifnetaddr)); while (ifnetaddr) { /* * Get the "ifnet" structure and extract the device name */ klookup((unsigned long)ifnetaddr, (char *)&ifnet, sizeof ifnet);#if STRUCT_IFNET_HAS_IF_XNAME#if defined(netbsd1) || defined(openbsd2) strncpy(ifname, ifnet.if_xname, sizeof ifname);#else klookup((unsigned long)ifnet.if_xname, (char *)ifname, sizeof ifname);#endif ifname[sizeof (ifname)-1] = '\0';#else klookup((unsigned long)ifnet.if_name, (char *)ifname, sizeof ifname); ifname[sizeof (ifname)-1] = '\0'; cp = strchr(ifname, '\0'); string_append_int (cp, ifnet.if_unit);#endif entry.name = strdup( ifname ); /* * Try to find an address for this interface */ auto_nlist(IFADDR_SYMBOL, (char *)&ia, sizeof(ia)); while (ia) { klookup((unsigned long)ia , (char *)&in_ifaddr, sizeof(in_ifaddr)); if (in_ifaddr.ia_ifp == ifnetaddr) break; ia = in_ifaddr.ia_next; }#if !defined(netbsd1) && !defined(freebsd2) && !defined(openbsd2) && !defined(STRUCT_IFNET_HAS_IF_ADDRLIST) ifnet.if_addrlist = (struct ifaddr *)ia; /* WRONG DATA TYPE; ONLY A FLAG */#endif /* * Set up the entry and it to the table */ entry.ifstat = (struct ifnet *)malloc( sizeof( ifnet )); if ( entry.ifstat == NULL ) break; entry.ifaddr = (struct in_ifaddr *)malloc( sizeof( in_ifaddr )); if ( entry.ifaddr == NULL ) { free( entry.ifstat ); break; } memcpy( &entry.ifstat, &ifnet, sizeof( ifnet )); memcpy( &entry.ifaddr, &in_ifaddr, sizeof( in_ifaddr )); if ( Add_IF_Entry( t, &entry ) < 0 ) break; ifnetaddr = ifnet.if_next; } return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -