📄 interfaces.c
字号:
static int Interface_Count=0;static int Interface_Scan_Get_Count (void){ if (!Interface_Count) { 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; } if (i != Index) return(-1); /* Error, doesn't exist */ }#ifdef freebsd2 if (saveifnet.if_type != IFT_ETHER) { return(0); /* Not an ethernet if */ }#endif /* * the arpcom structure is an extended ifnet structure which * contains the ethernet address. */#ifndef linux#if !(defined(netbsd1) || defined(bsdi2) || defined(openbsd2)) klookup((unsigned long)saveifnetaddr, (char *)&arpcom, sizeof arpcom);#else /* netbsd1 or bsdi2 or openbsd2 */#if defined(netbsd1) || defined(openbsd2)#define if_addrlist if_addrlist.tqh_first#define ifa_next ifa_list.tqe_next#endif ifaddraddr = (unsigned long)saveifnet.if_addrlist; while (ifaddraddr) { klookup(ifaddraddr, (char *)&ifaddr, sizeof ifaddr); klookup((unsigned long)ifaddr.ifa_addr, (char *)&sadl, sizeof sadl); if (sadl.sdl_family == AF_LINK && (saveifnet.if_type == IFT_ETHER || saveifnet.if_type == IFT_ISO88025 || saveifnet.if_type == IFT_FDDI)) { memcpy(arpcom.ac_enaddr, sadl.sdl_data + sadl.sdl_nlen, sizeof(arpcom.ac_enaddr)); break; } ifaddraddr = (unsigned long)ifaddr.ifa_next; }#endif /* netbsd1 or bsdi2 or openbsd2 */#else /* linux */ memcpy(arpcom.ac_enaddr, saveifnetaddr->if_hwaddr, 6);#endif if (strncmp("lo", saveName, 2) == 0) { /* * Loopback doesn't have a HW addr, so return 00:00:00:00:00:00 */ memset(EtherAddr, 0, sizeof(arpcom.ac_enaddr)); } else {#if defined(mips) || defined(hpux) || defined(osf4) || defined(osf3) memcpy( EtherAddr,(char *) arpcom.ac_enaddr, sizeof (arpcom.ac_enaddr));#else memcpy( EtherAddr,(char *) &arpcom.ac_enaddr, sizeof (arpcom.ac_enaddr));#endif } return(0); /* DONE */}#else /* solaris2 */static int Interface_Scan_Get_Count (void){ int i, sd; if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return (0); if (ioctl(sd, SIOCGIFNUM, &i) == -1) { close(sd); return (0); } else { close(sd); return (i); }}intInterface_Index_By_Name(char *Name, int Len){ int i, sd, ret; char buf[1024]; struct ifconf ifconf; struct ifreq *ifrp; if (Name == 0) return (0); if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return (0); ifconf.ifc_buf = buf; ifconf.ifc_len = sizeof(buf); if (ioctl(sd, SIOCGIFCONF, &ifconf) == -1) { ret = 0; goto Return; } for (i = 1, ifrp = ifconf.ifc_req, ret = 0; (char *)ifrp < (char *)ifconf.ifc_buf + ifconf.ifc_len; i++, ifrp++) if (strncmp(Name, ifrp->ifr_name, Len) == 0) { ret = i; break; } else ret = 0; Return: close(sd); return (ret); /* DONE */}#endif /* solaris2 */#else /* HAVE_NET_IF_MIB_H *//* * This code attempts to do the right thing for FreeBSD. Note that * the statistics could be gathered through use of of the * net.route.0.link.iflist.0 sysctl (which we already use to get the * hardware address of the interfaces), rather than using the ifmib * code, but eventually I will implement dot3Stats and we will have to * use the ifmib interface. ifmib is also a much more natural way of * mapping the SNMP MIB onto sysctl(3). */#include <net/if.h>#include <net/if_dl.h>#include <net/if_mib.h>#include <net/route.h>static int header_interfaces(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **write);static int header_ifEntry(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **write);u_char *var_ifEntry(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **write);static char *physaddrbuf;static int nphysaddrs;struct sockaddr_dl **physaddrs;void init_interfaces_setup(void){ int naddrs, ilen, bit; static int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 }; char *cp; size_t len; struct rt_msghdr *rtm; struct if_msghdr *ifm; struct ifa_msghdr *ifam; struct sockaddr *sa; naddrs = 0; if (physaddrs) free(physaddrs); if (physaddrbuf) free(physaddrbuf); physaddrbuf = 0; physaddrs = 0; nphysaddrs = 0; len = 0; if (sysctl(mib, 6, 0, &len, 0, 0) < 0) return; cp = physaddrbuf = malloc(len); if (physaddrbuf == 0) return; if (sysctl(mib, 6, physaddrbuf, &len, 0, 0) < 0) { free(physaddrbuf); physaddrbuf = 0; return; }loop: ilen = len; cp = physaddrbuf; while (ilen > 0) { rtm = (struct rt_msghdr *)cp; if (rtm->rtm_version != RTM_VERSION || rtm->rtm_type != RTM_IFINFO) { free(physaddrs); physaddrs = 0; free(physaddrbuf); physaddrbuf = 0; } ifm = (struct if_msghdr *)rtm; ilen -= ifm->ifm_msglen; cp += ifm->ifm_msglen; rtm = (struct rt_msghdr *)cp; while (ilen > 0 && rtm->rtm_type == RTM_NEWADDR) { int is_alias = 0; ifam = (struct ifa_msghdr *)rtm; ilen -= sizeof(*ifam); cp += sizeof(*ifam); sa = (struct sockaddr *)cp;#define ROUND(x) (((x) + sizeof(long) - 1) & ~sizeof(long)) for (bit = 1; bit && ilen > 0; bit <<= 1) { if (!(ifam->ifam_addrs & bit)) continue; ilen -= ROUND(sa->sa_len); cp += ROUND(sa->sa_len); if (bit == RTA_IFA) { if (physaddrs)#define satosdl(sa) ((struct sockaddr_dl *)(sa)) physaddrs[naddrs++] = satosdl(sa); else naddrs++; } sa = (struct sockaddr *)cp; } rtm = (struct rt_msghdr *)cp; } } if (physaddrs) { nphysaddrs = naddrs; return; } physaddrs = malloc(naddrs * sizeof(*physaddrs)); if (physaddrs == 0) return; naddrs = 0; goto loop; }static intget_phys_address(int iindex, char **ap, int *len){ int i; int once = 1; do { for (i = 0; i < nphysaddrs; i++) { if (physaddrs[i]->sdl_index == iindex) break; } if (i < nphysaddrs) break; init_interfaces_setup(); } while (once--); if (i < nphysaddrs) { *ap = LLADDR(physaddrs[i]); *len = physaddrs[i]->sdl_alen; return 0; } return -1;}static intheader_interfaces(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){#define INTERFACES_NAME_LENGTH 8 oid newname[MAX_OID_LEN]; int result; DEBUGMSGTL(("mibII/interfaces", "var_interfaces: ")); DEBUGMSGOID(("mibII/interfaces", name, *length)); DEBUGMSG(("mibII/interfaces", " %d\n", exact)); memcpy(newname, vp->name, (int)vp->namelen * sizeof(oid)); newname[INTERFACES_NAME_LENGTH] = 0; result = snmp_oid_compare(name, *length, newname, (int)vp->namelen + 1); if ((exact && (result != 0)) || (!exact && (result >= 0))) return MATCH_FAILED; memcpy(name, newname, ((int)vp->namelen + 1) * sizeof(oid)); *length = vp->namelen + 1; *write_method = 0; *var_len = sizeof(long); /* default to 'long' results */ return MATCH_SUCCEEDED;}static int count_oid[5] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };static intheader_ifEntry(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){#define IFENTRY_NAME_LENGTH 10 oid newname[MAX_OID_LEN]; register int interface; int result, count; static int count_oid[5] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT }; size_t len;#ifdef DODEBUG DEBUGMSGTL(("mibII/interfaces", "var_ifEntry: ")); DEBUGMSGOID(("mibII/interfaces", name, *length)); DEBUGMSG(("mibII/interfaces"," %d\n", exact));#endif memcpy(newname, vp->name, (int)vp->namelen * sizeof(oid)); /* find "next" interface */ len = sizeof count; if (sysctl(count_oid, 5, &count, &len, (void *)0, (size_t)0) < 0) return MATCH_FAILED; for(interface = 1; interface <= count; interface++){ newname[IFENTRY_NAME_LENGTH] = (oid)interface; result = snmp_oid_compare(name, *length, newname, (int)vp->namelen + 1); if ((exact && (result == 0)) || (!exact && (result < 0))) break; } if (interface > count) {#ifdef DODEBUG DEBUGMSGTL(("interfaces", "... index out of range\n"));#endif return MATCH_FAILED; } memcpy(name, newname, ((int)vp->namelen + 1) * sizeof(oid)); *length = vp->namelen + 1; *write_method = 0; *var_len = sizeof(long); /* default to 'long' results */#ifdef DODEBUG DEBUGMSGTL(("interfaces", "... get I/F stats ")); DEBUGMSGOID(("interfaces", name, *length)); DEBUGMSG(("interfaces","\n"));#endif return interface;}u_char *var_interfaces(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ size_t len; int count; if (header_interfaces(vp, name, length, exact, var_len, write_method) == MATCH_FAILED) return NULL; switch (vp->magic){ case IFNUMBER: len = sizeof count; if (sysctl(count_oid, 5, &count, &len, 0, 0) < 0) return NULL; long_return = 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 interface; static int sname[6] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, 0, IFDATA_GENERAL }; static struct ifmibdata ifmd; size_t len; char *cp; interface = header_ifEntry(vp, name, length, exact, var_len, write_method); if (interface == MATCH_FAILED) return NULL; sname[4] = interface; len = sizeof ifmd; if (sysctl(sname, 6, &ifmd, &len, 0, 0) < 0) return NULL; switch (vp->magic) { case IFINDEX: long_return = interface; return (u_char *) &long_return; case IFDESCR: cp = ifmd.ifmd_name; *var_len = strlen(cp); return (u_char *)cp; case IFTYPE: long_return = ifmd.ifmd_data.ifi_type; return (u_char *) &long_return; case IFMTU: long_return = (long) ifmd.ifmd_data.ifi_mtu; return (u_char *) &long_return; case IFSPEED: long_return = ifmd.ifmd_data.ifi_baudrate; return (u_char *) &long_return; case IFPHYSADDRESS: { char *cp; if (get_phys_address(interface, &cp, var_len)) return NULL; else return cp; } case IFADMINSTATUS: long_return = ifmd.ifmd_flags & IFF_RUNNING ? 1 : 2; return (u_char *) &long_return; case IFOPERSTATUS: long_return = ifmd.ifmd_flags & IFF_UP ? 1 : 2; return (u_char *) &long_return; case IFLASTCHANGE: if ((ifmd.ifmd_data.ifi_lastchange.tv_sec == 0 ) && (ifmd.ifmd_data.ifi_lastchange.tv_usec == 0)) { long_return = 0; } else { struct timeval now; gettimeofday(&now, (struct timezone *)0); long_return = (u_long) ((now.tv_sec - ifmd.ifmd_data.ifi_lastchange.tv_sec) * 100 + ((now.tv_usec - ifmd.ifmd_data.ifi_lastchange.tv_usec) / 10000)); } return (u_char *) &long_return; case IFINOCTETS: long_return = (u_long) ifmd.ifmd_data.ifi_ibytes; return (u_char *) &long_return; case IFINUCASTPKTS: long_return = (u_long) ifmd.ifmd_data.ifi_ipackets; long_return -= (u_long) ifmd.ifmd_data.ifi_imcasts; return (u_char *) &long_return; case IFINNUCASTPKTS: long_return = (u_long) ifmd.ifmd_data.ifi_imcasts; return (u_char *) &long_return; case IFINDISCARDS: long_return = (u_long) ifmd.ifmd_data.ifi_iqdrops; return (u_char *) &long_return; case IFINERRORS: long_return = ifmd.ifmd_data.ifi_ierrors; return (u_char *) &long_return; case IFINUNKNOWNPROTOS: long_return = (u_long) ifmd.ifmd_data.ifi_noproto; return (u_char *) &long_return; case IFOUTOCTETS: long_return = (u_long) ifmd.ifmd_data.ifi_obytes; return (u_char *) &long_return; case IFOUTUCASTPKTS: long_return = (u_long) ifmd.ifmd_data.ifi_opackets; long_return -= (u_long) ifmd.ifmd_data.ifi_omcasts; return (u_char *) &long_return; case IFOUTNUCASTPKTS: long_return = (u_long) ifmd.ifmd_data.ifi_omcasts; return (u_char *) &long_return; case IFOUTDISCARDS: long_return = ifmd.ifmd_snd_drops; return (u_char *) &long_return; case IFOUTERRORS: long_return = ifmd.ifmd_data.ifi_oerrors; return (u_char *) &long_return; case IFOUTQLEN: long_return = ifmd.ifmd_snd_len; return (u_char *) &long_return; case IFSPECIFIC: *var_len = nullOidLen; return (u_char *) nullOid; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_ifEntry\n", vp->magic)); } return NULL;}#endif /* HAVE_NET_IF_MIB_H */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -