📄 interfaces.c
字号:
if (getMibstat(MIB_INTERFACES, &ifstat, sizeof(mib2_ifEntry_t), GET_EXACT, &IF_cmp, &interface) != 0) { DEBUGMSGTL(("mibII/interfaces", "... no mib stats\n")); return NULL; } switch (vp->magic){ case IFINDEX: long_return = ifstat.ifIndex; return (u_char *) &long_return; case IFDESCR: *var_len = ifstat.ifDescr.o_length; (void)memcpy(return_buf, ifstat.ifDescr.o_bytes, *var_len); return(u_char *)return_buf; case IFTYPE: long_return = (u_long)ifstat.ifType; return (u_char *) &long_return; case IFMTU: long_return = (u_long)ifstat.ifMtu; return (u_char *) &long_return; case IFSPEED: long_return = (u_long)ifstat.ifSpeed; return (u_char *) &long_return; case IFPHYSADDRESS: *var_len = ifstat.ifPhysAddress.o_length; (void)memcpy(return_buf, ifstat.ifPhysAddress.o_bytes, *var_len); return(u_char *)return_buf; case IFADMINSTATUS: long_return = (u_long)ifstat.ifAdminStatus; return (u_char *) &long_return; case IFOPERSTATUS: long_return = (u_long)ifstat.ifOperStatus; return (u_char *) &long_return; case IFLASTCHANGE: long_return = (u_long)ifstat.ifLastChange; return (u_char *) &long_return; case IFINOCTETS: long_return = (u_long)ifstat.ifInOctets; return (u_char *) &long_return; case IFINUCASTPKTS: long_return = (u_long)ifstat.ifInUcastPkts; return (u_char *) &long_return; case IFINNUCASTPKTS: long_return = (u_long)ifstat.ifInNUcastPkts; return (u_char *) &long_return; case IFINDISCARDS: long_return = (u_long)ifstat.ifInDiscards; return (u_char *) &long_return; case IFINERRORS: long_return = (u_long)ifstat.ifInErrors; return (u_char *) &long_return; case IFINUNKNOWNPROTOS: long_return = (u_long)ifstat.ifInUnknownProtos; return (u_char *) &long_return; case IFOUTOCTETS: long_return = (u_long)ifstat.ifOutOctets; return (u_char *) &long_return; case IFOUTUCASTPKTS: long_return = (u_long)ifstat.ifOutUcastPkts; return (u_char *) &long_return; case IFOUTNUCASTPKTS: long_return = (u_long)ifstat.ifOutNUcastPkts; return (u_char *) &long_return; case IFOUTDISCARDS: long_return = (u_long)ifstat.ifOutDiscards; return (u_char *) &long_return; case IFOUTERRORS: long_return = (u_long)ifstat.ifOutErrors; return (u_char *) &long_return; case IFOUTQLEN: long_return = (u_long)ifstat.ifOutQLen; return (u_char *) &long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n", vp->magic)); } return NULL;}#endif /* solaris2 */ /********************* * * Internal implementation functions * *********************/#ifndef solaris2#if !defined(sunV3) && !defined(linux)static struct in_ifaddr savein_ifaddr;#endifstatic struct ifnet *ifnetaddr, saveifnet, *saveifnetaddr;static int saveIndex=0;static char saveName[16];voidInterface_Scan_Init (void){#ifdef linux char line [256], ifname_buf [64], *ifname, *ptr; struct ifreq ifrq; struct ifnet **ifnetaddr_ptr; FILE *devin; unsigned long rec_pkt, rec_oct, rec_err, snd_pkt, snd_oct, snd_err, coll; int i, fd; conf_if_list *if_ptr; const 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"; const char *scan_line_to_use; #endif auto_nlist(IFNET_SYMBOL, (char *)&ifnetaddr, sizeof(ifnetaddr)); saveIndex=0;#ifdef linux /* free old list: */ while (ifnetaddr_list) { struct ifnet *old = ifnetaddr_list; ifnetaddr_list = ifnetaddr_list->if_next; free (old->if_name); free (old->if_unit); free (old); } ifnetaddr = 0; ifnetaddr_ptr = &ifnetaddr_list; if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { DEBUGMSGTL(("snmpd", "socket open failure in Interface_Scan_Init\n")); return; /** exit (1); **/ } /* * build up ifnetaddr list by hand: */ /* at least linux v1.3.53 says EMFILE without reason... */ if (! (devin = fopen ("/proc/net/dev", "r"))) { close (fd); snmp_log(LOG_ERR,"cannot open /proc/net/dev - continuing...\n"); return; /** exit (1); **/ } i = 0; /* read the second line (a header) and determine the fields we should read from. This should be done in a better way by actually looking for the field names we want. But thats too much work for today. -- Wes */ fgets(line, sizeof(line), devin); fgets(line, sizeof(line), devin); if (strstr(line, "compressed")) { scan_line_to_use = scan_line_2_2; DEBUGMSGTL(("mibII/interfaces", "using linux 2.2 kernel /proc/net/dev\n")); } else { scan_line_to_use = scan_line_2_0; DEBUGMSGTL(("mibII/interfaces", "using linux 2.0 kernel /proc/net/dev\n")); } while (fgets (line, sizeof(line), devin)) { struct ifnet *nnew; char *stats, *ifstart = line; if ( line[strlen(line)-1] == '\n' ) line[strlen(line)-1]='\0'; while (*ifstart == ' ') ifstart++; if ( (stats = strrchr(ifstart, ':')) == NULL ) { snmp_log(LOG_ERR,"/proc/net/dev data format error, line ==|%s|",line); continue; } if ( (scan_line_to_use == scan_line_2_2) && ( (stats-line) < 6 ) ) { snmp_log(LOG_ERR,"/proc/net/dev data format error, line ==|%s|",line); } *stats++ = 0; strcpy(ifname_buf, ifstart); while (*stats == ' ') stats++; if ((scan_line_to_use == scan_line_2_2 && sscanf (stats, scan_line_to_use, &rec_oct, &rec_pkt, &rec_err,&snd_oct, &snd_pkt, &snd_err, &coll) != 7) || (scan_line_to_use == scan_line_2_0 && sscanf (stats, scan_line_to_use, &rec_pkt, &rec_err, &snd_pkt,&snd_err, &coll) != 5)) { if ( (scan_line_to_use == scan_line_2_2) && !strstr(line,"No statistics available") ) snmp_log(LOG_ERR,"/proc/net/dev data format error, line ==|%s|",line); continue; } nnew = (struct ifnet *) calloc (1, sizeof (struct ifnet)); if (nnew == NULL) break; /* alloc error */ /* chain in: */ *ifnetaddr_ptr = nnew; ifnetaddr_ptr = &nnew->if_next; i++; /* linux previous to 1.3.~13 may miss transmitted loopback pkts: */ if (! strcmp (ifname_buf, "lo") && rec_pkt > 0 && ! snd_pkt) snd_pkt = rec_pkt; nnew->if_ipackets = rec_pkt; nnew->if_ierrors = rec_err; nnew->if_opackets = snd_pkt; nnew->if_oerrors = snd_err; nnew->if_collisions = coll; if (scan_line_to_use == scan_line_2_2) { nnew->if_ibytes = rec_oct; nnew->if_obytes = snd_oct; } else { nnew->if_ibytes = rec_pkt*308; nnew->if_obytes = snd_pkt*308; } /* ifnames are given as `` eth0'': split in ``eth'' and ``0'': */ for (ifname = ifname_buf; *ifname && *ifname == ' '; ifname++) ; /* set name and interface# : */ nnew->if_name = (char *) strdup (ifname); for (ptr = nnew->if_name; *ptr && (*ptr < '0' || *ptr > '9'); ptr++) ; nnew->if_unit = strdup(*ptr ? ptr : ""); *ptr = 0; strcpy (ifrq.ifr_name, ifname); if (ioctl (fd, SIOCGIFADDR, &ifrq) < 0) memset ((char *) &nnew->if_addr, 0, sizeof (nnew->if_addr)); else nnew->if_addr = ifrq.ifr_addr; strcpy (ifrq.ifr_name, ifname); if (ioctl (fd, SIOCGIFBRDADDR, &ifrq) < 0) memset ((char *)&nnew->ifu_broadaddr, 0, sizeof(nnew->ifu_broadaddr)); else nnew->ifu_broadaddr = ifrq.ifr_broadaddr; strcpy (ifrq.ifr_name, ifname); if (ioctl (fd, SIOCGIFNETMASK, &ifrq) < 0) memset ((char *)&nnew->ia_subnetmask, 0, sizeof(nnew->ia_subnetmask)); else nnew->ia_subnetmask = ifrq.ifr_netmask; strcpy (ifrq.ifr_name, ifname); nnew->if_flags = ioctl (fd, SIOCGIFFLAGS, &ifrq) < 0 ? 0 : ifrq.ifr_flags; nnew->if_type = 0; strcpy (ifrq.ifr_name, ifname); if (ioctl(fd, SIOCGIFHWADDR, &ifrq) < 0) memset (nnew->if_hwaddr,(0), 6); else { memcpy (nnew->if_hwaddr, ifrq.ifr_hwaddr.sa_data, 6);#ifdef ARPHRD_LOOPBACK switch (ifrq.ifr_hwaddr.sa_family) { case ARPHRD_ETHER: nnew->if_type = 6; break; case ARPHRD_TUNNEL: case ARPHRD_TUNNEL6:#ifdef ARPHRD_IPGRE case ARPHRD_IPGRE:#endif 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 */ case ARPHRD_FDDI: nnew->if_type = 15; break; case ARPHRD_ARCNET: nnew->if_type = 35; break; case ARPHRD_LOCALTLK: nnew->if_type = 42; break;#ifdef ARPHRD_HIPPI case ARPHRD_HIPPI: nnew->if_type = 47; break;#endif /* 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 for (if_ptr = conf_list; if_ptr; if_ptr = if_ptr->next) if (! strcmp (if_ptr->name, ifname)) break; if (if_ptr) { nnew->if_type = if_ptr->type; nnew->if_speed = if_ptr->speed; } else { /* do only guess if_type from name, if we could not read * it before from SIOCGIFHWADDR */ if (!nnew->if_type) nnew->if_type = if_type_from_name(nnew->if_name); nnew->if_speed = nnew->if_type == 6 ? 10000000 : nnew->if_type == 24 ? 10000000 : nnew->if_type == 9 ? 4000000 : 0; } } /* while (fgets ... */ ifnetaddr = ifnetaddr_list; if (snmp_get_do_debugging()) { { struct ifnet *x = ifnetaddr; DEBUGMSGTL(("mibII/interfaces", "* see: known interfaces:")); while (x) { DEBUGMSG(("mibII/interfaces", " %s", x->if_name)); x = x->if_next; } DEBUGMSG(("mibII/interfaces", "\n")); } /* XXX */ } fclose (devin); close (fd);#endif /* linux */}#if defined(sunV3) || defined(linux)/*** 4.2 BSD doesn't have ifaddr** */int Interface_Scan_Next(short *Index, char *Name, struct ifnet *Retifnet, struct in_ifaddr *dummy){ struct ifnet ifnet; register char *cp; while (ifnetaddr) { /* * Get the "ifnet" structure and extract the device name */#ifndef linux klookup((unsigned long)ifnetaddr, (char *)&ifnet, sizeof ifnet); klookup((unsigned long)ifnet.if_name, (char *)saveName, sizeof saveName);#else ifnet = *ifnetaddr; strcpy (saveName, ifnet.if_name);#endif if (strcmp(saveName, "ip") == 0) { ifnetaddr = ifnet.if_next; continue; } saveName[sizeof (saveName)-1] = '\0'; cp = (char *) strchr(saveName, '\0');#ifdef linux strcat (cp, ifnet.if_unit);#else string_append_int (cp, ifnet.if_unit);#endif if (1 || strcmp(saveName,"lo0") != 0) { /* XXX */ if (Index) *Index = ++saveIndex; if (Retifnet) *Retifnet = ifnet; if (Name) strcpy(Name, saveName); saveifnet = ifnet; saveifnetaddr = ifnetaddr; ifnetaddr = ifnet.if_next; return(1); /* DONE */ } ifnetaddr = ifnet.if_next; } return(0); /* EOF */}#ifdef linuxintInterface_Index_By_Name(char *Name, int Len){ short ifIndex = 0; char ifName[20]; Interface_Scan_Init(); while(Interface_Scan_Next(&ifIndex, ifName, NULL, NULL) && strcmp(Name, ifName)) ; return ifIndex;}#endif#else#if defined(netbsd1) || defined(openbsd2)#define ia_next ia_list.tqe_next#define if_next if_list.tqe_next#endifint Interface_Scan_Next(short *Index, char *Name, struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr){ struct ifnet ifnet; struct in_ifaddr *ia, in_ifaddr; short has_ipaddr=0;#if !STRUCT_IFNET_HAS_IF_XNAME register char *cp;#endif 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(saveName, ifnet.if_xname, sizeof saveName);#else klookup((unsigned long)ifnet.if_xname, (char *)saveName, sizeof saveName);#endif saveName[sizeof (saveName)-1] = '\0';#else klookup((unsigned long)ifnet.if_name, (char *)saveName, sizeof saveName); saveName[sizeof (saveName)-1] = '\0'; cp = strchr(saveName, '\0'); string_append_int (cp, ifnet.if_unit);#endif if (1 || strcmp(saveName,"lo0") != 0) { /* XXX */ /* * 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) { has_ipaddr = 1; /* this IF has IP-address */ 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/* ifnet.if_addrlist = (struct ifaddr *)&ia->ia_ifa; */ /* WRONG DATA TYPE; ONLY A FLAG */ if (Index) *Index = ++saveIndex; if (Retifnet) *Retifnet = ifnet; if (Retin_ifaddr && has_ipaddr) /* assign the in_ifaddr only if the IF has IP-address */ *Retin_ifaddr = in_ifaddr; if (Name) strcpy(Name, saveName); saveifnet = ifnet; saveifnetaddr = ifnetaddr; savein_ifaddr = in_ifaddr; ifnetaddr = ifnet.if_next; return(1); /* DONE */ } ifnetaddr = ifnet.if_next; } return(0); /* EOF */}#endif /* sunV3 */static int Interface_Scan_By_Index(int Index, char *Name, struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr){ short i; Interface_Scan_Init(); while (Interface_Scan_Next(&i, Name, Retifnet, Retin_ifaddr)) { if (i == Index) break; } if (i != Index) return(-1); /* Error, doesn't exist */ return(0); /* DONE */}static int Interface_Count=0;static time_t scan_time = 0;static int Interface_Scan_Get_Count (void){ time_t time_now = time(NULL); if (!Interface_Count || (time_now > scan_time + 60)) { scan_time = time_now; Interface_Scan_Init(); while (Interface_Scan_Next(NULL, NULL, NULL, NULL) != 0) { Interface_Count++; } } return(Interface_Count);}static int Interface_Get_Ether_By_Index(int Index, u_char *EtherAddr){ short i;#if !(defined(linux) || defined(netbsd1) || defined(bsdi2) || defined(openbsd2)) struct arpcom arpcom;#else /* is linux or netbsd1 */ struct arpcom { char ac_enaddr[6]; } arpcom;#if defined(netbsd1) || defined(bsdi2) || defined(openbsd2) struct sockaddr_dl sadl; struct ifaddr ifaddr; u_long ifaddraddr;#endif#endif#if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3) memset(arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));#else memset(&arpcom.ac_enaddr, 0, sizeof(arpcom.ac_enaddr));#endif memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr)); if (saveIndex != Index) { /* Optimization! */ Interface_Scan_Init(); while (Interface_Scan_Next((short *)&i, NULL, NULL, NULL) != 0) { if (i == Index) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -