static int AT_Cmp(void *addr, void *ep) { mib2_ipNetToMediaEntry_t *mp = (mib2_ipNetToMediaEntry_t *) ep; int ret = -1; oid index; #ifdef NETSNMP_INCLUDE_IFTABLE_REWRITES mp->ipNetToMediaIfIndex.o_bytes[mp->ipNetToMediaIfIndex.o_length] = '\0'; index = netsnmp_access_interface_index_find( mp->ipNetToMediaIfIndex.o_bytes); #else index = Interface_Index_By_Name(mp->ipNetToMediaIfIndex.o_bytes, mp->ipNetToMediaIfIndex.o_length); #endif DEBUGMSGTL(("mibII/at", "......... AT_Cmp %lx<>%lx %d<>%d (%.5s)\n", mp->ipNetToMediaNetAddress, ((if_ip_t *) addr)->ipAddr, ((if_ip_t *) addr)->ifIdx, index, mp->ipNetToMediaIfIndex.o_bytes)); if (mp->ipNetToMediaNetAddress != ((if_ip_t *) addr)->ipAddr) ret = 1; else if (((if_ip_t *) addr)->ifIdx != index) ret = 1; else ret = 0; DEBUGMSGTL(("mibII/at", "......... AT_Cmp returns %d\n", ret)); return ret; }
netsnmp_interface_entry * netsnmp_access_interface_entry_create(const char *name, oid if_index) { netsnmp_interface_entry *entry = SNMP_MALLOC_TYPEDEF(netsnmp_interface_entry); DEBUGMSGTL(("access:interface:entry", "create\n")); netsnmp_assert(1 == _access_interface_init); if(NULL == entry) return NULL; if(NULL != name) entry->name = strdup(name); /* * get if index, and save name for reverse lookup */ #ifndef NETSNMP_ACCESS_INTERFACE_NOARCH if (0 == if_index) entry->index = netsnmp_access_interface_index_find(name); else #endif entry->index = if_index; _access_interface_entry_save_name(name, entry->index); if (name) entry->descr = strdup(name); /* * make some assumptions */ entry->connector_present = 1; entry->oid_index.len = 1; entry->oid_index.oids = (oid *) & entry->index; return entry; }
static void ARP_Scan_Init(void) { #ifndef NETSNMP_CAN_USE_SYSCTL #ifndef linux #ifdef hpux11 int fd; struct nmparms p; int val; unsigned int ulen; int ret; if (at) free(at); at = (mib_ipNetToMediaEnt *) 0; arptab_size = 0; if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) { p.objid = ID_ipNetToMediaTableNum; p.buffer = (void *) &val; ulen = sizeof(int); p.len = &ulen; if ((ret = get_mib_info(fd, &p)) == 0) arptab_size = val; if (arptab_size > 0) { ulen = (unsigned) arptab_size *sizeof(mib_ipNetToMediaEnt); at = (mib_ipNetToMediaEnt *) malloc(ulen); p.objid = ID_ipNetToMediaTable; p.buffer = (void *) at; p.len = &ulen; if ((ret = get_mib_info(fd, &p)) < 0) arptab_size = 0; } close_mib(fd); } arptab_current = 0; #else /* hpux11 */ if (!at) { #ifdef ARPTAB_SIZE_SYMBOL auto_nlist(ARPTAB_SIZE_SYMBOL, (char *) &arptab_size, sizeof arptab_size); #ifdef STRUCT_ARPHD_HAS_AT_NEXT at = (struct arphd *) malloc(arptab_size * sizeof(struct arphd)); #else at = (struct arptab *) malloc(arptab_size * sizeof(struct arptab)); #endif #else return; #endif } #ifdef STRUCT_ARPHD_HAS_AT_NEXT auto_nlist(ARPTAB_SYMBOL, (char *) at, arptab_size * sizeof(struct arphd)); at_ptr = at[0].at_next; #else auto_nlist(ARPTAB_SYMBOL, (char *) at, arptab_size * sizeof(struct arptab)); #endif arptab_current = 0; #endif /* hpux11 */ #else /* linux */ static time_t tm = 0; /* Time of last scan */ FILE *in; int i, j; char line[128]; int za, zb, zc, zd; char ifname[21]; char mac[3*MAX_MAC_ADDR_LEN+1]; char *tok; arptab_current = 0; /* Anytime this is called we need to reset 'current' */ if (time(NULL) < tm + 1) { /*Our cool one second cache implementation :-) */ return; } in = fopen("/proc/net/arp", "r"); if (!in) { snmp_log(LOG_ERR, "snmpd: Cannot open /proc/net/arp\n"); arptab_size = 0; return; } /* * Get rid of the header line */ fgets(line, sizeof(line), in); i = 0; while (fgets(line, sizeof(line), in)) { u_long tmp_a; int tmp_flags; if (i >= arptab_curr_max_size) { struct arptab *newtab = (struct arptab *) realloc(at, (sizeof(struct arptab) * (arptab_curr_max_size + ARP_CACHE_INCR))); if (newtab == at) { snmp_log(LOG_ERR, "Error allocating more space for arpcache. " "Cache will continue to be limited to %d entries", arptab_curr_max_size); break; } else { arptab_curr_max_size += ARP_CACHE_INCR; at = newtab; } } if (7 != sscanf(line, "%d.%d.%d.%d 0x%*x 0x%x %s %*[^ ] %20s\n", &za, &zb, &zc, &zd, &tmp_flags, mac, ifname)) { snmp_log(LOG_ERR, "Bad line in /proc/net/arp: %s", line); continue; } /* * Invalidated entries have their flag set to 0. * * We want to ignore them */ if (tmp_flags == 0) { continue; } ifname[sizeof(ifname)-1] = 0; /* make sure name is null terminated */ at[i].at_flags = tmp_flags; tmp_a = ((u_long) za << 24) | ((u_long) zb << 16) | ((u_long) zc << 8) | ((u_long) zd); at[i].at_iaddr.s_addr = htonl(tmp_a); at[i].if_index = netsnmp_access_interface_index_find(ifname); for (j=0,tok=strtok(mac, ":"); tok != NULL; tok=strtok(NULL, ":"),j++) { at[i].at_enaddr[j] = strtol(tok, NULL, 16); } at[i].at_enaddr_len = j; i++; } arptab_size = i; fclose(in); time(&tm); #endif /* linux */ #else /* NETSNMP_CAN_USE_SYSCTL */ int mib[6]; size_t needed; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_FLAGS; mib[5] = RTF_LLINFO; if (at) free(at); rtnext = lim = at = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) snmp_log_perror("route-sysctl-estimate"); else { if ((at = malloc(needed ? needed : 1)) == NULL) snmp_log_perror("malloc"); else { if (sysctl(mib, 6, at, &needed, NULL, 0) < 0) snmp_log_perror("actual retrieval of routing table"); else { lim = at + needed; rtnext = at; } } } #endif /* NETSNMP_CAN_USE_SYSCTL */ }
u_char * var_atEntry(struct variable * vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { /* * object identifier is of form: * 1.3.6.1.2.1.3.1.1.1.interface.1.A.B.C.D, where A.B.C.D is IP address. * Interface is at offset 10, * IPADDR starts at offset 12. */ #define AT_MAX_NAME_LENGTH 16 #define AT_IFINDEX_OFF 10 u_char *cp; oid *op; oid lowest[AT_MAX_NAME_LENGTH]; oid current[AT_MAX_NAME_LENGTH]; if_ip_t NextAddr; mib2_ipNetToMediaEntry_t entry; static mib2_ipNetToMediaEntry_t Lowentry; int Found = 0; req_e req_type; int offset, olength; static in_addr_t addr_ret; /* * fill in object part of name for current (less sizeof instance part) */ DEBUGMSGTL(("mibII/at", "var_atEntry: ")); DEBUGMSGOID(("mibII/at", vp->name, vp->namelen)); DEBUGMSG(("mibII/at", " %d\n", exact)); memset(&Lowentry, 0, sizeof(Lowentry)); memcpy((char *) current, (char *) vp->name, vp->namelen * sizeof(oid)); lowest[0] = 1024; for (NextAddr.ipAddr = (u_long) - 1, NextAddr.ifIdx = 255, req_type = GET_FIRST;; NextAddr.ipAddr = entry.ipNetToMediaNetAddress, NextAddr.ifIdx = current[AT_IFINDEX_OFF], req_type = GET_NEXT) { if (getMibstat (MIB_IP_NET, &entry, sizeof(mib2_ipNetToMediaEntry_t), req_type, &AT_Cmp, &NextAddr) != 0) break; #ifdef NETSNMP_INCLUDE_IFTABLE_REWRITES entry.ipNetToMediaIfIndex.o_bytes[entry.ipNetToMediaIfIndex.o_length] = '\0'; current[AT_IFINDEX_OFF] = netsnmp_access_interface_index_find( entry.ipNetToMediaIfIndex.o_bytes); #else current[AT_IFINDEX_OFF] = Interface_Index_By_Name(entry.ipNetToMediaIfIndex.o_bytes, entry.ipNetToMediaIfIndex.o_length); #endif if (current[6] == 3) { /* AT group oid */ current[AT_IFINDEX_OFF + 1] = 1; offset = AT_IFINDEX_OFF + 2; olength = AT_IFINDEX_OFF + 6; } else { offset = AT_IFINDEX_OFF + 1; olength = AT_IFINDEX_OFF + 5; } COPY_IPADDR(cp, (u_char *) & entry.ipNetToMediaNetAddress, op, current + offset); if (exact) { if (snmp_oid_compare(current, olength, name, *length) == 0) { memcpy((char *) lowest, (char *) current, olength * sizeof(oid)); Lowentry = entry; Found++; break; /* no need to search further */ } } else { if (snmp_oid_compare(current, olength, name, *length) > 0 && snmp_oid_compare(current, olength, lowest, *length) < 0) { /* * if new one is greater than input and closer to input than * previous lowest, and is not equal to it, save this one as the "next" one. */ memcpy((char *) lowest, (char *) current, olength * sizeof(oid)); Lowentry = entry; Found++; } } } DEBUGMSGTL(("mibII/at", "... Found = %d\n", Found)); if (Found == 0) return (NULL); memcpy((char *) name, (char *) lowest, olength * sizeof(oid)); *length = olength; *write_method = 0; switch (vp->magic) { case IPMEDIAIFINDEX: *var_len = sizeof long_return; #ifdef NETSNMP_INCLUDE_IFTABLE_REWRITES Lowentry.ipNetToMediaIfIndex.o_bytes[ Lowentry.ipNetToMediaIfIndex.o_length] = '\0'; long_return = netsnmp_access_interface_index_find( Lowentry.ipNetToMediaIfIndex.o_bytes); #else long_return = Interface_Index_By_Name( Lowentry.ipNetToMediaIfIndex.o_bytes, Lowentry.ipNetToMediaIfIndex.o_length); #endif return (u_char *) & long_return; case IPMEDIAPHYSADDRESS: *var_len = Lowentry.ipNetToMediaPhysAddress.o_length; return Lowentry.ipNetToMediaPhysAddress.o_bytes; case IPMEDIANETADDRESS: *var_len = sizeof(addr_ret); addr_ret = Lowentry.ipNetToMediaNetAddress; return (u_char *) &addr_ret; case IPMEDIATYPE: *var_len = sizeof long_return; long_return = Lowentry.ipNetToMediaType; return (u_char *) & long_return; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n", vp->magic)); } return NULL; }
int _load_v4(netsnmp_container *container, int idx_offset) { FILE *in; char line[128]; int rc = 0; netsnmp_arp_entry *entry; netsnmp_assert(NULL != container); #define PROCFILE "/proc/net/arp" if (!(in = fopen(PROCFILE, "r"))) { snmp_log(LOG_ERR,"could not open " PROCFILE "\n"); return -2; } /* * Get rid of the header line */ fgets(line, sizeof(line), in); /* * IP address | HW | Flag | HW address | Mask | Device * 192.168.1.4 0x1 0x2 00:40:63:CC:1C:8C * eth0 */ while (fgets(line, sizeof(line), in)) { int za, zb, zc, zd, ze, zf, zg, zh, zi, zj; int tmp_flags; char ifname[21]; rc = sscanf(line, "%d.%d.%d.%d 0x%*x 0x%x %x:%x:%x:%x:%x:%x %*[^ ] %20s\n", &za, &zb, &zc, &zd, &tmp_flags, &ze, &zf, &zg, &zh, &zi, &zj, ifname); if (12 != rc) { snmp_log(LOG_ERR, PROCFILE " data format error (%d!=12)\n", rc); snmp_log(LOG_ERR, " line ==|%s|\n", line); continue; } DEBUGMSGTL(("access:arp:container", "ip addr %d.%d.%d.%d, flags 0x%X, hw addr " "%x:%x:%x:%x:%x:%x, name %s\n", za,zb,zc,zd, tmp_flags, ze,zf,zg,zh,zi,zj, ifname )); /* */ entry = netsnmp_access_arp_entry_create(); if(NULL == entry) { rc = -3; break; } /* * look up ifIndex */ entry->if_index = netsnmp_access_interface_index_find(ifname); if(0 == entry->if_index) { snmp_log(LOG_ERR,"couldn't find ifIndex for '%s', skipping\n", ifname); netsnmp_access_arp_entry_free(entry); continue; } /* * now that we've passed all the possible 'continue', assign * index offset. */ entry->ns_arp_index = ++idx_offset; /* * parse ip addr */ entry->arp_ipaddress[0] = za; entry->arp_ipaddress[1] = zb; entry->arp_ipaddress[2] = zc; entry->arp_ipaddress[3] = zd; entry->arp_ipaddress_len = 4; /* * parse hw addr */ entry->arp_physaddress[0] = ze; entry->arp_physaddress[1] = zf; entry->arp_physaddress[2] = zg; entry->arp_physaddress[3] = zh; entry->arp_physaddress[4] = zi; entry->arp_physaddress[5] = zj; entry->arp_physaddress_len = 6; /* * what can we do with hw? from arp manpage: default value of this parameter is ether (i.e. hardware code 0x01 for IEEE 802.3 10Mbps Ethernet). Other values might include network technologies such as ARCnet (arcnet) , PROnet (pronet) , AX.25 (ax25) and NET/ROM (netrom). */ /* * parse mask */ /* xxx-rks: what is mask? how to interpret '*'? */ /* * process type */ if(tmp_flags & ATF_PERM) entry->arp_type = INETNETTOMEDIATYPE_STATIC; else entry->arp_type = INETNETTOMEDIATYPE_DYNAMIC; /* * process status * if flags are 0, we can't tell the difference between * stale or incomplete. */ if(tmp_flags & ATF_COM) entry->arp_state = INETNETTOMEDIASTATE_REACHABLE; else entry->arp_state = INETNETTOMEDIASTATE_UNKNOWN; /* * add entry to container */ CONTAINER_INSERT(container, entry); } fclose(in); if( rc < 0 ) return rc; return idx_offset; }
int _load_v6(netsnmp_container *container, int idx_offset) { FILE *in; char line[80], addr[33], if_name[IFNAMSIZ]; u_char *buf; int if_index, pfx_len, scope, flags, rc = 0; size_t in_len, out_len; netsnmp_ipaddress_entry *entry; _ioctl_extras *extras; static int log_open_err = 1; netsnmp_assert(NULL != container); #define PROCFILE "/proc/net/if_inet6" if (!(in = fopen(PROCFILE, "r"))) { if (1 == log_open_err) { snmp_log(LOG_ERR,"could not open " PROCFILE "\n"); log_open_err = 0; } return -2; } /* * if we hadn't been able to open file and turned of err logging, * turn it back on now that we opened the file. */ if (0 == log_open_err) log_open_err = 1; /* * address index prefix_len scope status if_name */ while (fgets(line, sizeof(line), in)) { /* * fe800000000000000200e8fffe5b5c93 05 40 20 80 eth0 * A D P S F I * A: address * D: device number * P: prefix len * S: scope (see include/net/ipv6.h, net/ipv6/addrconf.c) * F: flags (see include/linux/rtnetlink.h, net/ipv6/addrconf.c) * I: interface */ rc = sscanf(line, "%32s %02x %02x %02x %02x %8s\n", addr, &if_index, &pfx_len, &scope, &flags, if_name); if( 6 != rc ) { snmp_log(LOG_ERR, PROCFILE " data format error (%d!=6), line ==|%s|\n", rc, line); continue; } DEBUGMSGTL(("access:ipaddress:container", "addr %s, index %d, pfx %d, scope %d, flags 0x%X, name %s\n", addr, if_index, pfx_len, scope, flags, if_name)); /* */ entry = netsnmp_access_ipaddress_entry_create(); if(NULL == entry) { rc = -3; break; } in_len = entry->ia_address_len = sizeof(entry->ia_address); netsnmp_assert(16 == in_len); out_len = 0; buf = entry->ia_address; if(1 != snmp_hex_to_binary(&buf, &in_len, &out_len, 0, addr)) { snmp_log(LOG_ERR,"error parsing '%s', skipping\n", entry->ia_address); netsnmp_access_ipaddress_entry_free(entry); continue; } netsnmp_assert(16 == out_len); entry->ia_address_len = out_len; entry->ns_ia_index = ++idx_offset; /* * save if name */ extras = netsnmp_ioctl_ipaddress_extras_get(entry); memcpy(extras->name, if_name, sizeof(extras->name)); extras->flags = flags; /* * yyy-rks: optimization: create a socket outside the loop and use * netsnmp_access_interface_ioctl_ifindex_get() here, since * netsnmp_access_interface_index_find will open/close a socket * every time it is called. */ entry->if_index = netsnmp_access_interface_index_find(if_name); /* #define IPADDRESSSTATUSTC_PREFERRED 1 #define IPADDRESSSTATUSTC_DEPRECATED 2 #define IPADDRESSSTATUSTC_INVALID 3 #define IPADDRESSSTATUSTC_INACCESSIBLE 4 #define IPADDRESSSTATUSTC_UNKNOWN 5 #define IPADDRESSSTATUSTC_TENTATIVE 6 #define IPADDRESSSTATUSTC_DUPLICATE 7 */ if(flags & IFA_F_PERMANENT) entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */ else if(flags & IFA_F_DEPRECATED) entry->ia_status = IPADDRESSSTATUSTC_DEPRECATED; else if(flags & IFA_F_TENTATIVE) entry->ia_status = IPADDRESSSTATUSTC_TENTATIVE; else { entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN; DEBUGMSGTL(("access:ipaddress:ipv6", "unknown flags 0x%x\n", flags)); } /* * if it's not multi, it must be uni. * (an ipv6 address is never broadcast) */ if (IN6_IS_ADDR_MULTICAST(entry->ia_address)) entry->ia_type = IPADDRESSTYPE_ANYCAST; else entry->ia_type = IPADDRESSTYPE_UNICAST; entry->ia_prefix_len = pfx_len; /* * can we figure out if an address is from DHCP? * use manual until then... * *#define IPADDRESSORIGINTC_OTHER 1 *#define IPADDRESSORIGINTC_MANUAL 2 *#define IPADDRESSORIGINTC_DHCP 4 *#define IPADDRESSORIGINTC_LINKLAYER 5 *#define IPADDRESSORIGINTC_RANDOM 6 * * are 'local' address assigned by link layer?? */ if (IN6_IS_ADDR_LINKLOCAL(entry->ia_address) || IN6_IS_ADDR_SITELOCAL(entry->ia_address)) entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER; else entry->ia_origin = IPADDRESSORIGINTC_MANUAL; /* xxx-rks: what can we do with scope? */ /* * add entry to container */ CONTAINER_INSERT(container, entry); } fclose(in); if(rc<0) return rc; return idx_offset; }
static int mib_ipRouteTable_updateTable(void) { FILE *in; s8 line[256]; struct rtentry *rt; s8 name[16]; static u32 Time_Of_Last_Reload = 0; in_addr_t new_ipRouteDest; struct ipRouteTable_entry *new_entry; if(Time_Of_Last_Reload + CACHE_TIME > time(NULL)) { return ERROR_SUCCESS; } else { while(ipRouteTable_head) { mib_ipRouteTable_removeEntry(ipRouteTable_head); } } Time_Of_Last_Reload = time(NULL); if (!rthead) { rthead = (struct rtentry **) calloc(100, sizeof(struct rtentry *)); if (!rthead) { return ERROR_SYSTEM; } rtallocate = 100; } rtsize = 0; if (!(in = fopen(ROUTE_FILE, "r"))) { return ERROR_SYSTEM; } while (fgets(line, sizeof(line), in)) { struct rtentry rtent; s8 rtent_name[32]; s32 refcnt, flags, metric; u32 use; rt = &rtent; memset((s8 *) rt, (0), sizeof(*rt)); rt->rt_dev = rtent_name; if (8 != sscanf(line, "%s %x %x %x %u %d %d %x %*d %*d %*d\n", rt->rt_dev, &(((struct sockaddr_in *) &(rtent.rt_dst))->sin_addr.s_addr), &(((struct sockaddr_in *) &(rtent.rt_gateway))->sin_addr.s_addr), &flags, &refcnt, &use, &metric, &(((struct sockaddr_in *) &(rtent.rt_genmask))->sin_addr.s_addr))) { continue; } new_ipRouteDest= ((struct sockaddr_in *) &(rtent.rt_dst))->sin_addr.s_addr; new_entry = mib_ipRouteTable_createEntry(new_ipRouteDest); if(!new_entry) { return ERROR_SYSTEM; } strncpy(name, rt->rt_dev, sizeof(name)); name[sizeof(name) - 1] = 0; new_entry->ipRouteIfIndex = netsnmp_access_interface_index_find(name); if(flags & RTF_GATEWAY) { new_entry->ipRouteMetric1 = 1; } else { new_entry->ipRouteMetric1 = 0; } new_entry->ipRouteNextHop = ((struct sockaddr_in *) &(rtent.rt_gateway))->sin_addr.s_addr; if (flags & RTF_GATEWAY) { new_entry->ipRouteType = 4; } else { new_entry->ipRouteType = 3; } if (flags & RTF_DYNAMIC) { new_entry->ipRouteProto = 4; } else { new_entry->ipRouteProto = 2; } if (((struct sockaddr_in *) &(rtent.rt_dst))->sin_addr.s_addr == 0) { new_entry->ipRouteMask = 0; } else { new_entry->ipRouteMask = ((struct sockaddr_in *) &(rtent.rt_genmask))->sin_addr.s_addr; } memcpy(new_entry->ipRouteInfo,nullOid,sizeof(new_entry->ipRouteInfo)); new_entry->ipRouteInfo_len = nullOidLen; new_entry->ipRouteAge = 0; new_entry->ipRouteMetric2 = 0; new_entry->ipRouteMetric3 = 0; new_entry->ipRouteMetric4 = 0; new_entry->ipRouteMetric5 = 0; } fclose(in); return ERROR_SUCCESS; }
static int mib_ipAddrTable_getList(void) { s32 num_interfaces = 0; ifc.ifc_len = 0; SNMP_FREE(ifc.ifc_buf); ifr_counter = 0; struct ifnet ifnet_store; s32 fd; in_addr_t new_ipAdEntAddr; static u32 Time_Of_Last_Reload = 0; struct ipAddrTable_entry *new_entry; if(Time_Of_Last_Reload + CACHE_TIME > time(NULL)) { return ERROR_SUCCESS; } else { while(ipAddrTable_head) { mib_ipAddrTable_removeEntry(ipAddrTable_head); } } Time_Of_Last_Reload = time(NULL); do { if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return ERROR_SYSTEM; } num_interfaces += 16; ifc.ifc_len = sizeof(struct ifreq) * num_interfaces; ifc.ifc_buf = (s8*) realloc(ifc.ifc_buf, ifc.ifc_len); if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { ifr = NULL; close(fd); return ERROR_SYSTEM; } close(fd); }while (ifc.ifc_len >= (sizeof(struct ifreq) * num_interfaces)); ifr = ifc.ifc_req; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return(0); } while (ifr) { ifnet_store.if_addr = ifr->ifr_addr; new_ipAdEntAddr=((struct sockaddr_in *)&(ifnet_store.if_addr))->sin_addr.s_addr; new_entry = mib_ipAddrTable_createEntry(new_ipAdEntAddr); if(!new_entry) { return ERROR_SYSTEM; } if (ioctl(fd, SIOCGIFBRDADDR, ifr) < 0) { memset((s8 *) &new_entry->ipAdEntBcastAddr, 0, sizeof(new_entry->ipAdEntBcastAddr)); } else { new_entry->ipAdEntBcastAddr = ((struct sockaddr_in *)&(ifr->ifr_broadaddr))->sin_addr.s_addr; } if (ioctl(fd, SIOCGIFNETMASK, ifr) < 0) { memset((s8 *) &new_entry->ipAdEntNetMask, 0, sizeof(new_entry->ipAdEntBcastAddr)); } else { new_entry->ipAdEntNetMask = ((struct sockaddr_in *)&(ifr->ifr_netmask))->sin_addr.s_addr; } ifr->ifr_addr = ifnet_store.if_addr; new_entry->ipAdEntIfIndex = netsnmp_access_interface_index_find(ifr->ifr_name); new_entry->ipAdEntReasmMaxSize = -1; ifr++; ifr_counter += sizeof(struct ifreq); if (ifr_counter >= ifc.ifc_len) { ifr = NULL; } } close(fd); return (0); }
int _load_v6(netsnmp_container *container, int idx_offset) { #ifndef HAVE_LINUX_RTNETLINK_H DEBUGMSGTL(("access:ipaddress:container", "cannot get ip address information" "as netlink socket is not available\n")); return -1; #else FILE *in; char line[80], addr[40]; char if_name[IFNAMSIZ+1];/* +1 for '\0' because of the ugly sscanf below */ u_char *buf; int if_index, pfx_len, scope, flags, rc = 0; size_t in_len, out_len; netsnmp_ipaddress_entry *entry; _ioctl_extras *extras; struct address_flag_info addr_info; netsnmp_assert(NULL != container); #define PROCFILE "/proc/net/if_inet6" if (!(in = fopen(PROCFILE, "r"))) { DEBUGMSGTL(("access:ipaddress:container","could not open " PROCFILE "\n")); return -2; } /* * address index prefix_len scope status if_name */ while (fgets(line, sizeof(line), in)) { /* * fe800000000000000200e8fffe5b5c93 05 40 20 80 eth0 * A D P S F I * A: address * D: device number * P: prefix len * S: scope (see include/net/ipv6.h, net/ipv6/addrconf.c) * F: flags (see include/linux/rtnetlink.h, net/ipv6/addrconf.c) * I: interface */ rc = sscanf(line, "%39s %08x %08x %04x %02x %" SNMP_MACRO_VAL_TO_STR(IFNAMSIZ) "s\n", addr, &if_index, &pfx_len, &scope, &flags, if_name); if( 6 != rc ) { snmp_log(LOG_ERR, PROCFILE " data format error (%d!=6), line ==|%s|\n", rc, line); continue; } DEBUGMSGTL(("access:ipaddress:container", "addr %s, index %d, pfx %d, scope %d, flags 0x%X, name %s\n", addr, if_index, pfx_len, scope, flags, if_name)); /* */ entry = netsnmp_access_ipaddress_entry_create(); if(NULL == entry) { rc = -3; break; } in_len = entry->ia_address_len = sizeof(entry->ia_address); netsnmp_assert(16 == in_len); out_len = 0; entry->flags = flags; buf = entry->ia_address; if(1 != netsnmp_hex_to_binary(&buf, &in_len, &out_len, 0, addr, ":")) { snmp_log(LOG_ERR,"error parsing '%s', skipping\n", entry->ia_address); netsnmp_access_ipaddress_entry_free(entry); continue; } netsnmp_assert(16 == out_len); entry->ia_address_len = out_len; entry->ns_ia_index = ++idx_offset; /* * save if name */ extras = netsnmp_ioctl_ipaddress_extras_get(entry); memcpy(extras->name, if_name, sizeof(extras->name)); extras->flags = flags; /* * yyy-rks: optimization: create a socket outside the loop and use * netsnmp_access_interface_ioctl_ifindex_get() here, since * netsnmp_access_interface_index_find will open/close a socket * every time it is called. */ entry->if_index = netsnmp_access_interface_index_find(if_name); memset(&addr_info, 0, sizeof(struct address_flag_info)); addr_info = netsnmp_access_other_info_get(entry->if_index, AF_INET6); /* #define IPADDRESSSTATUSTC_PREFERRED 1 #define IPADDRESSSTATUSTC_DEPRECATED 2 #define IPADDRESSSTATUSTC_INVALID 3 #define IPADDRESSSTATUSTC_INACCESSIBLE 4 #define IPADDRESSSTATUSTC_UNKNOWN 5 #define IPADDRESSSTATUSTC_TENTATIVE 6 #define IPADDRESSSTATUSTC_DUPLICATE 7 */ if((flags & IFA_F_PERMANENT) || (!flags)) entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */ #ifdef IFA_F_TEMPORARY else if(flags & IFA_F_TEMPORARY) entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */ #endif else if(flags & IFA_F_DEPRECATED) entry->ia_status = IPADDRESSSTATUSTC_DEPRECATED; else if(flags & IFA_F_TENTATIVE) entry->ia_status = IPADDRESSSTATUSTC_TENTATIVE; else { entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN; DEBUGMSGTL(("access:ipaddress:ipv6", "unknown flags 0x%x\n", flags)); } /* * if it's not multi, it must be uni. * (an ipv6 address is never broadcast) */ if(addr_info.anycastflg) entry->ia_type = IPADDRESSTYPE_ANYCAST; else entry->ia_type = IPADDRESSTYPE_UNICAST; entry->ia_prefix_len = pfx_len; /* * can we figure out if an address is from DHCP? * use manual until then... * *#define IPADDRESSORIGINTC_OTHER 1 *#define IPADDRESSORIGINTC_MANUAL 2 *#define IPADDRESSORIGINTC_DHCP 4 *#define IPADDRESSORIGINTC_LINKLAYER 5 *#define IPADDRESSORIGINTC_RANDOM 6 * * are 'local' address assigned by link layer?? */ if (!flags) entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER; #ifdef IFA_F_TEMPORARY else if (flags & IFA_F_TEMPORARY) entry->ia_origin = IPADDRESSORIGINTC_RANDOM; #endif else if (IN6_IS_ADDR_LINKLOCAL(entry->ia_address)) entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER; else entry->ia_origin = IPADDRESSORIGINTC_MANUAL; if(entry->ia_origin == IPADDRESSORIGINTC_LINKLAYER) entry->ia_storagetype = STORAGETYPE_PERMANENT; /* xxx-rks: what can we do with scope? */ #ifdef HAVE_LINUX_RTNETLINK_H if(netsnmp_access_ipaddress_extra_prefix_info(entry->if_index, &entry->ia_prefered_lifetime ,&entry->ia_valid_lifetime, addr) < 0){ DEBUGMSGTL(("access:ipaddress:container", "unable to fetch extra prefix info\n")); } #else entry->ia_prefered_lifetime = 0; entry->ia_valid_lifetime = 0; #endif #ifdef SUPPORT_PREFIX_FLAGS { prefix_cbx prefix_val; memset(&prefix_val, 0, sizeof(prefix_cbx)); if(net_snmp_find_prefix_info(&prefix_head_list, addr, &prefix_val) < 0) { DEBUGMSGTL(("access:ipaddress:container", "unable to find info\n")); entry->ia_onlink_flag = 1; /*Set by default as true*/ entry->ia_autonomous_flag = 2; /*Set by default as false*/ } else { entry->ia_onlink_flag = prefix_val.ipAddressPrefixOnLinkFlag; entry->ia_autonomous_flag = prefix_val.ipAddressPrefixAutonomousFlag; } } #else entry->ia_onlink_flag = 1; /*Set by default as true*/ entry->ia_autonomous_flag = 2; /*Set by default as false*/ #endif /* * add entry to container */ if (CONTAINER_INSERT(container, entry) < 0) { DEBUGMSGTL(("access:ipaddress:container","error with ipaddress_entry: insert into container failed.\n")); netsnmp_access_ipaddress_entry_free(entry); continue; } } fclose(in); if(rc<0) return rc; return idx_offset; }
static int _load_v6 (netsnmp_container * container, int idx_offset) { mib2_ipv6AddrEntry_t ip6ae; netsnmp_ipaddress_entry *entry; req_e req = GET_FIRST; int rc = 0; DEBUGMSGTL (("access:ipaddress:container", "loading v6... cache %d\n", MIB_IP6_ADDR)); while ((rc = getMibstat (MIB_IP6_ADDR, &ip6ae, sizeof (ip6ae), req, &Get_everything, NULL)) == 0) { req = GET_NEXT; entry = netsnmp_access_ipaddress_entry_create (); if (entry == NULL) return (-1); if (memcmp ((const void *) &ip6ae.ipv6AddrAddress, (const void *) &in6addr_any, sizeof (ip6ae.ipv6AddrAddress)) == 0) continue; ip6ae.ipv6AddrIfIndex.o_bytes[ip6ae.ipv6AddrIfIndex.o_length] = '\0'; DEBUGMSGTL (("access:ipaddress:container", "found if %s\n", ip6ae.ipv6AddrIfIndex.o_bytes)); /* Obtain interface index */ entry->if_index = netsnmp_access_interface_index_find (ip6ae.ipv6AddrIfIndex.o_bytes); if (entry->if_index == 0) { DEBUGMSGTL (("access:ipaddress:container", "cannot find if %s\n", ip6ae.ipv6AddrIfIndex.o_bytes)); netsnmp_access_ipaddress_entry_free (entry); return (-2); } /* Get the address */ entry->ia_address_len = sizeof (ip6ae.ipv6AddrAddress); netsnmp_assert (entry->ia_address_len == 16 && entry->ia_address_len <= sizeof (entry->ia_address)); memcpy (&entry->ia_address, &ip6ae.ipv6AddrAddress, entry->ia_address_len); /* prefix */ entry->ia_prefix_len = ip6ae.ipv6AddrPfxLength; /* type is anycast? (mib2.h: 1 = yes, 2 = no) */ entry->ia_type = (ip6ae.ipv6AddrAnycastFlag == 1) ? IPADDRESSTYPE_ANYCAST : IPADDRESSTYPE_UNICAST; /* origin (mib2.h: 1 = stateless, 2 = stateful, 3 = unknown) */ DEBUGMSGTL (("access:ipaddress:container", "origin %d\n", ip6ae.ipv6AddrType)); if (ip6ae.ipv6AddrType == 1) entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER; else if (ip6ae.ipv6AddrInfo.ae_flags & IFF_DHCPRUNNING) entry->ia_origin = IPADDRESSORIGINTC_DHCP; else entry->ia_origin = IPADDRESSORIGINTC_MANUAL; /* status */ entry->ia_status = ip6ae.ipv6AddrStatus; entry->ns_ia_index = ++idx_offset; DEBUGMSGTL (("access:ipaddress:container", "insert if %" NETSNMP_PRIo "u, addrlen %d\n", entry->if_index, entry->ia_address_len)); if (CONTAINER_INSERT (container, entry) < 0) { DEBUGMSGTL (("access:ipaddress:container", "unable to insert %s\n", ip6ae.ipv6AddrIfIndex.o_bytes)); netsnmp_access_ipaddress_entry_free (entry); return (-3); } } return (idx_offset); }
/* * @retval >=idx_offset ok * @retval -1 memory allocation error * @retval -2 interface lookup error * @retval -3 container error */ static int _load_v4 (netsnmp_container * container, int idx_offset) { mib2_ipAddrEntry_t ipae; netsnmp_ipaddress_entry *entry; req_e req = GET_FIRST; int rc = 0; DEBUGMSGTL (("access:ipaddress:container", "loading v4\n")); while ((rc = getMibstat (MIB_IP_ADDR, &ipae, sizeof (ipae), req, &Get_everything, NULL)) == 0) { req = GET_NEXT; entry = netsnmp_access_ipaddress_entry_create (); if (entry == NULL) return (-1); if (ipae.ipAdEntAddr == INADDR_ANY) continue; ipae.ipAdEntIfIndex.o_bytes[ipae.ipAdEntIfIndex.o_length] = '\0'; DEBUGMSGTL (("access:ipaddress:container", "found if %s\n", ipae.ipAdEntIfIndex.o_bytes)); /* Obtain interface index */ entry->if_index = netsnmp_access_interface_index_find (ipae.ipAdEntIfIndex.o_bytes); if (entry->if_index == 0) { DEBUGMSGTL (("access:ipaddress:container", "cannot find if %s\n", ipae.ipAdEntIfIndex.o_bytes)); netsnmp_access_ipaddress_entry_free (entry); return (-2); } if (strchr ((const char *) &ipae.ipAdEntIfIndex.o_bytes, ':') != 0) entry->flags |= NETSNMP_ACCESS_IPADDRESS_ISALIAS; /* Get the address */ entry->ia_address_len = sizeof (ipae.ipAdEntAddr); netsnmp_assert (entry->ia_address_len == 4 && entry->ia_address_len <= sizeof (entry->ia_address)); memcpy (&entry->ia_address, &ipae.ipAdEntAddr, entry->ia_address_len); /* prefix */ entry->ia_prefix_len = ipae.ipAdEntInfo.ae_subnet_len; /* set the Origin */ if (ipae.ipAdEntInfo.ae_flags & IFF_DHCPRUNNING) entry->ia_origin = IPADDRESSORIGINTC_DHCP; else entry->ia_origin = IPADDRESSORIGINTC_MANUAL; /* set ipv4 constants */ entry->ia_type = IPADDRESSTYPE_UNICAST; entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; entry->ns_ia_index = ++idx_offset; DEBUGMSGTL (("access:ipaddress:container", "insert if %" NETSNMP_PRIo "u, addrlen %d\n", entry->if_index, entry->ia_address_len)); if (CONTAINER_INSERT (container, entry) < 0) { DEBUGMSGTL (("access:ipaddress:container", "unable to insert %s\n", ipae.ipAdEntIfIndex.o_bytes)); netsnmp_access_ipaddress_entry_free (entry); return (-3); } } return (idx_offset); }
static int _load_v4(netsnmp_arp_access *access) { FILE *in; char line[128]; int rc = 0; netsnmp_arp_entry *entry; char arp[3*NETSNMP_ACCESS_ARP_PHYSADDR_BUF_SIZE+1]; char *arp_token; int i; netsnmp_assert(NULL != access); #define PROCFILE "/proc/net/arp" if (!(in = fopen(PROCFILE, "r"))) { snmp_log(LOG_DEBUG,"could not open " PROCFILE "\n"); return -2; } /* * Get rid of the header line */ fgets(line, sizeof(line), in); /* * IP address | HW | Flag | HW address | Mask | Device * 192.168.1.4 0x1 0x2 00:40:63:CC:1C:8C * eth0 */ while (fgets(line, sizeof(line), in)) { int za, zb, zc, zd; unsigned int tmp_flags; char ifname[21]; rc = sscanf(line, "%d.%d.%d.%d 0x%*x 0x%x %96s %*[^ ] %20s\n", &za, &zb, &zc, &zd, &tmp_flags, arp, ifname); if (7 != rc) { snmp_log(LOG_ERR, PROCFILE " data format error (%d!=12)\n", rc); snmp_log(LOG_ERR, " line ==|%s|\n", line); continue; } DEBUGMSGTL(("access:arp:container", "ip addr %d.%d.%d.%d, flags 0x%X, hw addr " "%s, name %s\n", za,zb,zc,zd, tmp_flags, arp, ifname )); /* */ entry = netsnmp_access_arp_entry_create(); if(NULL == entry) { rc = -3; break; } /* * look up ifIndex */ entry->generation = access->generation; entry->if_index = netsnmp_access_interface_index_find(ifname); if(0 == entry->if_index) { snmp_log(LOG_ERR,"couldn't find ifIndex for '%s', skipping\n", ifname); netsnmp_access_arp_entry_free(entry); continue; } /* * now that we've passed all the possible 'continue', assign * index offset. */ /* entry->ns_arp_index = ++idx_offset; */ /* * parse ip addr */ entry->arp_ipaddress[0] = za; entry->arp_ipaddress[1] = zb; entry->arp_ipaddress[2] = zc; entry->arp_ipaddress[3] = zd; entry->arp_ipaddress_len = 4; /* * parse hw addr */ for (arp_token = strtok(arp, ":"), i=0; arp_token != NULL; arp_token = strtok(NULL, ":"), i++) { entry->arp_physaddress[i] = strtol(arp_token, NULL, 16); } entry->arp_physaddress_len = i; /* * what can we do with hw? from arp manpage: default value of this parameter is ether (i.e. hardware code 0x01 for IEEE 802.3 10Mbps Ethernet). Other values might include network technologies such as ARCnet (arcnet) , PROnet (pronet) , AX.25 (ax25) and NET/ROM (netrom). */ /* * parse mask */ /* xxx-rks: what is mask? how to interpret '*'? */ /* * process type */ if(tmp_flags & ATF_PERM) entry->arp_type = INETNETTOMEDIATYPE_STATIC; else entry->arp_type = INETNETTOMEDIATYPE_DYNAMIC; /* * process status * if flags are 0, we can't tell the difference between * stale or incomplete. */ if(tmp_flags & ATF_COM) entry->arp_state = INETNETTOMEDIASTATE_REACHABLE; else entry->arp_state = INETNETTOMEDIASTATE_UNKNOWN; /* * add entry to container */ access->update_hook(access, entry); } fclose(in); return 0; }