📄 interface_sysctl.c
字号:
m_speed = t_speed; } } *speed = m_speed; *speed_high = m_speed_high; } free(media_list); } close(s); DEBUGMSGTL(("access:interface:container:sysctl", "%s: speed: %u, speed_high: %u\n", name, *speed, *speed_high)); return *speed;}/* * * @retval 0 success * @retval -1 no container specified * @retval -2 could not get interface info * @retval -3 could not create entry (probably malloc) */intnetsnmp_arch_interface_container_load(netsnmp_container* container, u_int load_flags){ netsnmp_interface_entry *entry = NULL; u_char *if_list = NULL, *cp; size_t if_list_size = 0; struct if_msghdr *ifp; int sysctl_oid[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; struct ifa_msghdr *ifa; struct sockaddr *a; struct sockaddr_dl *adl; int amask; char *if_name; int flags; DEBUGMSGTL(("access:interface:container:sysctl", "load (flags %p)\n", load_flags)); if (NULL == container) { snmp_log(LOG_ERR, "no container specified/found for interface\n"); return -1; } if (sysctl(sysctl_oid, sizeof(sysctl_oid)/sizeof(int), 0, &if_list_size, 0, 0) == -1) { snmp_log(LOG_ERR, "could not get interface info (size)\n"); return -2; } if_list = malloc(if_list_size); if (if_list == NULL) { snmp_log(LOG_ERR, "could not allocate memory for interface info " "(%lu bytes)\n", if_list_size); return -3; } else { DEBUGMSGTL(("access:interface:container:sysctl", "allocated %lu bytes for if_list\n", if_list_size)); } if (sysctl(sysctl_oid, sizeof(sysctl_oid)/sizeof(int), if_list, &if_list_size, 0, 0) == -1) { snmp_log(LOG_ERR, "could not get interface info\n"); free(if_list); return -2; } /* 1st pass: create interface entries */ for (cp = if_list; cp < if_list + if_list_size; cp += ifp->ifm_msglen) { ifp = (struct if_msghdr *) cp; if_name = NULL; flags = 0; adl = NULL; if (ifp->ifm_type != RTM_IFINFO) continue; if (ifp->ifm_addrs & RTA_IFP) { a = (struct sockaddr *) (ifp + 1); /* * if_msghdr is followed by one or more sockaddrs, of which we * need only RTA_IFP. most of the time RTA_IFP is the first * address we get, hence the shortcut. */ if ((ifp->ifm_addrs & (~RTA_IFP - 1)) != 0) { /* skip all addresses up to RTA_IFP. */ for (amask = (RTA_IFP >> 1); amask != 0; amask >>= 1) { if (ifp->ifm_addrs & amask) a = (struct sockaddr *) ( ((char *) a) + ROUNDUP(a->sa_len) ); } } adl = (struct sockaddr_dl *) a; if_name = (char *) adl->sdl_data; if_name[adl->sdl_nlen] = '\0'; } if (!(ifp->ifm_addrs & RTA_IFP) || if_name == NULL) { snmp_log(LOG_ERR, "ifm_index %u: no interface name in message, " "skipping\n", ifp->ifm_index); continue; } entry = netsnmp_access_interface_entry_create(if_name, ifp->ifm_index); if(NULL == entry) { netsnmp_access_interface_container_free(container, NETSNMP_ACCESS_INTERFACE_FREE_NOFLAGS); free(if_list); return -3; } /* get physical address */ if (adl != NULL && adl->sdl_alen > 0) { entry->paddr_len = adl->sdl_alen; entry->paddr = malloc(entry->paddr_len); memcpy(entry->paddr, adl->sdl_data + adl->sdl_nlen, adl->sdl_alen); DEBUGMSGTL(("access:interface:container:sysctl", "%s: paddr_len=%d, entry->paddr=%x:%x:%x:%x:%x:%x\n", if_name, entry->paddr_len, entry->paddr[0], entry->paddr[1], entry->paddr[2], entry->paddr[3], entry->paddr[4], entry->paddr[5])); } else { entry->paddr = malloc(6); entry->paddr_len = 6; memset(entry->paddr, 0, 6); } entry->mtu = ifp->ifm_data.ifi_mtu; entry->type = ifp->ifm_data.ifi_type; entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS; entry->os_flags = ifp->ifm_flags; if (ifp->ifm_flags & IFF_UP) { entry->admin_status = IFADMINSTATUS_UP;#if defined( LINK_STATE_UP ) && defined( LINK_STATE_DOWN ) if (ifp->ifm_data.ifi_link_state == LINK_STATE_UP) { entry->oper_status = IFOPERSTATUS_UP; } else if (ifp->ifm_data.ifi_link_state == LINK_STATE_DOWN) { entry->oper_status = IFOPERSTATUS_DOWN; } else#endif { /* * link state is unknown, which is not very useful to report. * use running state instead. */ entry->oper_status = ifp->ifm_flags & IFF_RUNNING ? 1 : 2; } } else { entry->admin_status = IFADMINSTATUS_DOWN; /* * IF-MIB specifically says that ifOperStatus should be down in * this case */ entry->oper_status = IFOPERSTATUS_DOWN; } entry->reasm_max_v4 = entry->reasm_max_v6 = IP_MAXPACKET; entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_V4_REASMMAX | NETSNMP_INTERFACE_FLAGS_HAS_V6_REASMMAX; /* get counters */ entry->stats.ibytes.low = ifp->ifm_data.ifi_ibytes; entry->stats.ibytes.high = 0; entry->stats.iucast.low = ifp->ifm_data.ifi_ipackets; entry->stats.iucast.high = 0; entry->stats.imcast.low = ifp->ifm_data.ifi_imcasts; entry->stats.imcast.high = 0; entry->stats.ierrors = ifp->ifm_data.ifi_ierrors; entry->stats.idiscards = ifp->ifm_data.ifi_iqdrops; entry->stats.iunknown_protos = ifp->ifm_data.ifi_noproto; entry->stats.obytes.low = ifp->ifm_data.ifi_obytes; entry->stats.obytes.high = 0; entry->stats.oucast.low = ifp->ifm_data.ifi_opackets; entry->stats.oucast.high = 0; entry->stats.omcast.low = ifp->ifm_data.ifi_omcasts; entry->stats.omcast.high = 0; entry->stats.oerrors = ifp->ifm_data.ifi_oerrors; entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_BYTES | NETSNMP_INTERFACE_FLAGS_HAS_DROPS | NETSNMP_INTERFACE_FLAGS_HAS_MCAST_PKTS; if (timercmp(&ifp->ifm_data.ifi_lastchange, &starttime, >)) { entry->lastchange = (ifp->ifm_data.ifi_lastchange.tv_sec - starttime.tv_sec) * 100; entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_LASTCHANGE; } else { entry->lastchange = 0; } if (ifp->ifm_flags & ARCH_PROMISC_FLAG) entry->promiscuous = 1; /* try to guess the speed from media type */ netsnmp_sysctl_get_if_speed(entry->name, &entry->speed, &entry->speed_high); if (entry->speed_high != 0) { entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_HIGH_SPEED; } else { /* or resort to ifi_baudrate */ entry->speed = ifp->ifm_data.ifi_baudrate; } netsnmp_access_interface_entry_overrides(entry); CONTAINER_INSERT(container, entry); DEBUGMSGTL(("access:interface:container:sysctl", "created entry %u for %s\n", entry->index, entry->name)); } /* for (each interface entry) */ /* pass 2: walk addresses */ for (cp = if_list; cp < if_list + if_list_size; cp += ifa->ifam_msglen) { ifa = (struct ifa_msghdr *) cp; if (ifa->ifam_type != RTM_NEWADDR) continue; DEBUGMSGTL(("access:interface:container:sysctl", "received 0x%x in RTM_NEWADDR for ifindex %u\n", ifa->ifam_addrs, ifa->ifam_index)); entry = netsnmp_access_interface_entry_get_by_index(container, ifa->ifam_index); if (entry == NULL) { snmp_log(LOG_ERR, "address for a nonexistent interface? index=%d", ifa->ifam_index); continue; } /* * walk the list of addresses received. we do not use actual * addresses, the sole purpose of this is to set flags */ a = (struct sockaddr *) (ifa + 1); for (amask = ifa->ifam_addrs; amask != 0; amask >>= 1) { if ((amask & 1) != 0) { DEBUGMSGTL(("access:interface:container:sysctl", "%s: a=%p, sa_len=%d, sa_family=0x%x\n", entry->name, a, a->sa_len, a->sa_family)); if (a->sa_family == AF_INET) entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_IPV4; else if (a->sa_family == AF_INET6) entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_IPV6; a = (struct sockaddr *) ( ((char *) a) + ROUNDUP(a->sa_len) ); } } DEBUGMSGTL(("access:interface:container:sysctl", "%s: flags=0x%x\n", entry->name, entry->ns_flags)); } if (if_list != NULL) free(if_list); return 0;}intnetsnmp_arch_set_admin_status(netsnmp_interface_entry * entry, int ifAdminStatus_val){ DEBUGMSGTL(("access:interface:arch", "set_admin_status\n")); /* TODO: implement this call */ /* not implemented */ snmp_log(LOG_ERR, "netsnmp_arch_set_admin_status not (yet) implemented " "for BSD sysctl.\n"); return -4;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -