📄 interfaces.c
字号:
vp->magic)); } return NULL;}#ifdef USE_SYSCTL_IFLISTstatic u_char *if_list = 0;static const u_char *if_list_end;static size_t if_list_size = 0;struct small_ifaddr { struct in_addr sifa_addr; struct in_addr sifa_netmask; struct in_addr sifa_broadcast;};extern const struct sockaddr *get_address(const void *, int, int);extern const struct in_addr *get_in_address(const void *, int, int);static int Interface_Scan_By_Index(int, struct if_msghdr *, char *, struct small_ifaddr *);static int Interface_Get_Ether_By_Index(int, u_char *);static intInterface_Scan_By_Index(int iindex, struct if_msghdr *if_msg, char *if_name, struct small_ifaddr *sifa){ u_char *cp; struct if_msghdr *ifp; int have_ifinfo = 0, have_addr = 0; memset(sifa, 0, sizeof(*sifa)); for (cp = if_list; cp < if_list_end; cp += ifp->ifm_msglen) { ifp = (struct if_msghdr *) cp; DEBUGMSGTL(("mibII/interfaces", "ifm_type = %d, ifm_index = %d\n", ifp->ifm_type, ifp->ifm_index)); switch (ifp->ifm_type) { case RTM_IFINFO: { const struct sockaddr *a; if (ifp->ifm_index == iindex) { a = get_address(ifp + 1, ifp->ifm_addrs, RTA_IFP); if (a == NULL) return 0; strncpy(if_name, ((const struct sockaddr_in *) a)->sin_zero, ((const u_char *) a)[5]); if_name[((const u_char *) a)[5]] = 0; *if_msg = *ifp; ++have_ifinfo; } } break; case RTM_NEWADDR: { struct ifa_msghdr *ifap = (struct ifa_msghdr *) cp; if (ifap->ifam_index == iindex) { const struct in_addr *ia; /* * I don't know why the normal get_address() doesn't * work on IRIX 6.2. Maybe this has to do with the * existence of struct sockaddr_new. Hopefully, on * other systems we can simply use get_in_address * three times, with (ifap+1) as the starting * address. */ sifa->sifa_netmask = *((struct in_addr *) ((char *) (ifap + 1) + 4)); ia = get_in_address((char *) (ifap + 1) + 8, ifap->ifam_addrs &= ~RTA_NETMASK, RTA_IFA); if (ia == NULL) return 0; sifa->sifa_addr = *ia; ia = get_in_address((char *) (ifap + 1) + 8, ifap->ifam_addrs &= ~RTA_NETMASK, RTA_BRD); if (ia == NULL) return 0; sifa->sifa_broadcast = *ia; ++have_addr; } } break; default: DEBUGMSGTL(("mibII/interfaces", "routing socket: unknown message type %d\n", ifp->ifm_type)); } } if (have_ifinfo && have_addr) { return 0; } else if (have_ifinfo && !(if_msg->ifm_flags & IFF_UP)) return 0; else { return -1; }}intInterface_Scan_Get_Count(void){ u_char *cp; struct if_msghdr *ifp; long n; Interface_Scan_Init(); for (cp = if_list, n = 0; cp < if_list_end; cp += ifp->ifm_msglen) { ifp = (struct if_msghdr *) cp; if (ifp->ifm_type == RTM_IFINFO) { ++n; } } return n;}voidInterface_Scan_Init(void){ int name[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; size_t size; if (sysctl(name, sizeof(name) / sizeof(int), 0, &size, 0, 0) == -1) { snmp_log(LOG_ERR, "sysctl size fail\n"); } else { if (if_list == 0 || if_list_size < size) { if (if_list != 0) { free(if_list); if_list = 0; } if ((if_list = malloc(size)) == 0) { snmp_log(LOG_ERR, "out of memory allocating route table\n"); return; } if_list_size = size; } else { size = if_list_size; } if (sysctl(name, sizeof(name) / sizeof(int), if_list, &size, 0, 0) == -1) { snmp_log(LOG_ERR, "sysctl get fail\n"); } if_list_end = if_list + size; }}WriteMethod writeIfEntry;u_char *var_ifEntry(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method){ int interface; struct if_msghdr if_msg; static char if_name[100]; struct small_ifaddr sifa; char *cp; DEBUGMSGTL(("blah", "var_ifEntry....\n")); interface = header_ifEntry(vp, name, length, exact, var_len, write_method); if (interface == MATCH_FAILED) return NULL; if (Interface_Scan_By_Index(interface, &if_msg, if_name, &sifa) != 0) return NULL; switch (vp->magic) { case IFINDEX: long_return = interface; return (u_char *) & long_return; case IFDESCR: cp = if_name; *var_len = strlen(if_name); return (u_char *) cp; case IFTYPE: long_return = (long) if_msg.ifm_data.ifi_type; return (u_char *) & long_return; case IFMTU: long_return = (long) if_msg.ifm_data.ifi_mtu; return (u_char *) & long_return; case IFSPEED:#if STRUCT_IFNET_HAS_IF_BAUDRATE_IFS_VALUE long_return = (u_long) if_msg.ifm_data.ifi_baudrate.ifs_value << if_msg.ifm_data.ifi_baudrate.ifs_log2;#else long_return = (u_long) if_msg.ifm_data.ifi_baudrate;#endif return (u_char *) & long_return; case IFPHYSADDRESS: /* * XXX */ return NULL; case IFADMINSTATUS: long_return = if_msg.ifm_flags & IFF_UP ? 1 : 2; *write_method = writeIfEntry; return (u_char *) & long_return; case IFOPERSTATUS: long_return = if_msg.ifm_flags & IFF_RUNNING ? 1 : 2; return (u_char *) & long_return; /* * ifLastChange */ case IFINOCTETS: long_return = (u_long) if_msg.ifm_data.ifi_ibytes; return (u_char *) & long_return; case IFINUCASTPKTS: long_return = (u_long) if_msg.ifm_data.ifi_ipackets - if_msg.ifm_data.ifi_imcasts; return (u_char *) & long_return; case IFINNUCASTPKTS: long_return = (u_long) if_msg.ifm_data.ifi_imcasts; return (u_char *) & long_return; case IFINDISCARDS: long_return = (u_long) if_msg.ifm_data.ifi_iqdrops; return (u_char *) & long_return; case IFINERRORS: long_return = (u_long) if_msg.ifm_data.ifi_ierrors; return (u_char *) & long_return; case IFINUNKNOWNPROTOS: long_return = (u_long) if_msg.ifm_data.ifi_noproto; return (u_char *) & long_return; case IFOUTOCTETS: long_return = (u_long) if_msg.ifm_data.ifi_obytes; return (u_char *) & long_return; case IFOUTUCASTPKTS: long_return = (u_long) if_msg.ifm_data.ifi_opackets - if_msg.ifm_data.ifi_omcasts; return (u_char *) & long_return; case IFOUTNUCASTPKTS: long_return = (u_long) if_msg.ifm_data.ifi_omcasts; return (u_char *) & long_return; case IFOUTDISCARDS:#ifdef if_odrops long_return = (u_long) if_msg.ifm_data.ifi_odrops;#else#if NO_DUMMY_VALUES return NULL;#endif long_return = 0;#endif return (u_char *) & long_return; case IFOUTERRORS: long_return = (u_long) if_msg.ifm_data.ifi_oerrors; return (u_char *) & long_return; case IFLASTCHANGE:#ifdef irix6 long_return = 0;#else if (if_msg.ifm_data.ifi_lastchange.tv_sec == 0 && if_msg.ifm_data.ifi_lastchange.tv_usec == 0) long_return = 0; else if (if_msg.ifm_data.ifi_lastchange.tv_sec < starttime.tv_sec) long_return = 0; else { long_return = (u_long) ((if_msg.ifm_data.ifi_lastchange.tv_sec - starttime.tv_sec) * 100 + (if_msg.ifm_data.ifi_lastchange.tv_usec - starttime.tv_usec) / 10000); }#endif return (u_char *) & long_return; default: return 0; }}intInterface_Scan_Next(short *Index, char *Name, struct ifnet *Retifnet, struct in_ifaddr *Retin_ifaddr){ return 0;}intwriteIfEntry(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len){ char buf[10]; DEBUGMSGTL(("blah", "writeifentry....\n")); if ((char) name[9] != IFADMINSTATUS) { return SNMP_ERR_NOTWRITABLE; } switch (action) { case RESERVE1: /* Check values for acceptability */ if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "not integer\n"); return SNMP_ERR_WRONGTYPE; } if (var_val_len > sizeof(int)) { snmp_log(LOG_ERR, "bad length\n"); return SNMP_ERR_WRONGLENGTH; } /* * The dwAdminStatus member can be MIB_IF_ADMIN_STATUS_UP or MIB_IF_ADMIN_STATUS_DOWN */ if (!(((int) (*var_val) == 1) || ((int) (*var_val) == 2))) { snmp_log(LOG_ERR, "not supported admin state\n"); return SNMP_ERR_WRONGVALUE; } break; case RESERVE2: /* Allocate memory and similar resources */ break; case ACTION: break; case UNDO: /* Reverse the SET action and free resources */ break; case COMMIT: /* Confirm the SET, performing any irreversible actions, * and free resources */ /* * Only UP and DOWN status are supported. Thats why done in COMMIT */ if ((int) (*var_val) == 1) setIfUp(getIfName((int) name[10], buf)); else setIfDown(getIfName((int) name[10], buf)); case FREE: /* Free any resources allocated */ /* * No resources have been allocated */ break; } return SNMP_ERR_NOERROR;}#else /* not USE_SYSCTL_IFLIST */ /********************* * * Kernel & interface information, * and internal forward declarations * *********************/#ifndef HAVE_NET_IF_MIB_H#ifndef solaris2#ifndef hpux11static int Interface_Scan_By_Index(int, char *, struct ifnet *, struct in_ifaddr *);static int Interface_Get_Ether_By_Index(int, u_char *);#elsestatic int Interface_Scan_By_Index(int, char *, nmapi_phystat *);#endif#endif /********************* * * System specific implementation functions * *********************/#ifndef solaris2#ifndef hpuxu_char *var_ifEntry(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method){ static struct ifnet ifnet; int interface; static struct in_ifaddr in_ifaddr; static char Name[16]; char *cp; conf_if_list *if_ptr = conf_list;#if STRUCT_IFNET_HAS_IF_LASTCHANGE_TV_SEC struct timeval now;#endif interface = header_ifEntry(vp, name, length, exact, var_len, write_method); if (interface == MATCH_FAILED) return NULL; Interface_Scan_By_Index(interface, Name, &ifnet, &in_ifaddr); while (if_ptr && strcmp(Name, if_ptr->name)) if_ptr = if_ptr->next; switch (vp->magic) { case IFINDEX: long_return = interface; return (u_char *) & long_return; case IFDESCR: cp = Name; *var_len = strlen(cp); return (u_char *) cp; case IFTYPE: if (if_ptr) long_return = if_ptr->type; else {#if STRUCT_IFNET_HAS_IF_TYPE long_return = ifnet.if_type;#else long_return = 1; /* OTHER */#endif } return (u_char *) & long_return; case IFMTU:{ long_return = (long) ifnet.if_mtu; return (u_char *) & long_return; } case IFSPEED: if (if_ptr) long_return = if_ptr->speed; else {#if STRUCT_IFNET_HAS_IF_BAUDRATE long_return = ifnet.if_baudrate;#elif STRUCT_IFNET_HAS_IF_SPEED long_return = ifnet.if_speed;#elif STRUCT_IFNET_HAS_IF_TYPE && defined(IFT_ETHER) if (ifnet.if_type == IFT_ETHER) long_return = 10000000; if (ifnet.if_type == IFT_P10) long_return = 10000000; if (ifnet.if_type == IFT_P80) long_return = 80000000; if (ifnet.if_type == IFT_ISDNBASIC) long_return = 64000; /* EDSS1 only */ if (ifnet.if_type == IFT_ISDNPRIMARY)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -