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; }
static int AT_Cmp(void *addr, void *ep) { mib2_ipNetToMediaEntry_t *mp = (mib2_ipNetToMediaEntry_t *) ep; int ret = -1; DEBUGMSGTL(("mibII/at", "......... AT_Cmp %lx<>%lx %d<>%d (%.5s)\n", mp->ipNetToMediaNetAddress, ((if_ip_t *) addr)->ipAddr, ((if_ip_t *) addr)->ifIdx, Interface_Index_By_Name(mp->ipNetToMediaIfIndex.o_bytes, mp->ipNetToMediaIfIndex.o_length), mp->ipNetToMediaIfIndex.o_bytes)); if (mp->ipNetToMediaNetAddress != ((if_ip_t *) addr)->ipAddr) ret = 1; else if (((if_ip_t *) addr)->ifIdx != Interface_Index_By_Name(mp->ipNetToMediaIfIndex.o_bytes, mp->ipNetToMediaIfIndex.o_length)) ret = 1; else ret = 0; DEBUGMSGTL(("mibII/at", "......... AT_Cmp returns %d\n", ret)); return ret; }
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; }
static void ARP_Scan_Init(void) { #ifndef 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) { 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 } #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; char line[128]; int za, zb, zc, zd, ze, zf, zg, zh, zi, zj; char ifname[21]; 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 (12 != 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)) { 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; } at[i].at_flags = tmp_flags; at[i].at_enaddr[0] = ze; at[i].at_enaddr[1] = zf; at[i].at_enaddr[2] = zg; at[i].at_enaddr[3] = zh; at[i].at_enaddr[4] = zi; at[i].at_enaddr[5] = zj; 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 = Interface_Index_By_Name(ifname, strlen(ifname)); i++; } arptab_size = i; fclose(in); time(&tm); #endif /* linux */ #else /* 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 /* CAN_USE_SYSCTL */ }