int netsnmp_access_arp_load(netsnmp_arp_access *access) { int err = 0; access->generation++; DEBUGMSGTL(("access:route:container", "route_container_arch_load ipv4\n")); err = _load_arp_table_from_sysctl(access); if (err != 0) { NETSNMP_LOGONCE((LOG_ERR, "netsnmp_access_arp_ipv4 failed %d\n", err)); goto out; } access->gc_hook(access); access->synchronized = (err == 0); #ifdef NETSNMP_ENABLE_IPV6 DEBUGMSGTL(("access:route:container", "route_container_arch_load ipv6\n")); err = _load_ndp_table_from_sysctl(access); if (err != 0) { NETSNMP_LOGONCE((LOG_ERR, "netsnmp_access_arp_ipv6 failed %d\n", err)); goto out; } access->gc_hook(access); access->synchronized = (err == 0); #endif out: return (err == 0 ? 0 : -1); }
/** arch specific load * @internal * * @retval 0 success * @retval -1 no container specified * @retval -2 could not access data source */ int netsnmp_access_route_container_arch_load(netsnmp_container* container, u_int load_flags) { int count, err; err = 0; DEBUGMSGTL(("access:route:container", "route_container_arch_load\n")); if (container == NULL) { snmp_log(LOG_ERR, "no container specified/found for access_route\n"); return -1; } err = _load_ipv4(container, &count); if (err != 0) { NETSNMP_LOGONCE((LOG_ERR, "_load_ipv4 failed %d\n", err)); goto out; } if (err != 0 || load_flags & NETSNMP_ACCESS_ROUTE_LOAD_IPV4_ONLY) return err; err = _load_ipv6(container, &count); if (err != 0) { NETSNMP_LOGONCE((LOG_ERR, "_load_ipv6 failed %d\n", err)); goto out; } out: return (err == 0 ? 0 : -3); }
int tcpTable_load(netsnmp_cache *cache, void *vmagic) { FILE *in; char line[256]; tcpTable_free(cache, NULL); #if HAVE_NETLINK_NETLINK_H if (tcpTable_load_netlink() == 0) { return 0; } #endif if (!(in = fopen("/proc/net/tcp", "r"))) { DEBUGMSGTL(("mibII/tcpTable", "Failed to load TCP Table (linux1)\n")); NETSNMP_LOGONCE((LOG_ERR, "snmpd: cannot open /proc/net/tcp ...\n")); return -1; } /* * scan proc-file and build up a linked list * This will actually be built up in reverse, * but since the entries are unsorted, that doesn't matter. */ while (line == fgets(line, sizeof(line), in)) { struct inpcb pcb, *nnew; unsigned int lp, fp; int state, uid; if (6 != sscanf(line, "%*d: %x:%x %x:%x %x %*X:%*X %*X:%*X %*X %d", &pcb.inp_laddr.s_addr, &lp, &pcb.inp_faddr.s_addr, &fp, &state, &uid)) continue; pcb.inp_lport = htons((unsigned short) lp); pcb.inp_fport = htons((unsigned short) fp); pcb.inp_state = (state & 0xf) < 12 ? linux_states[state & 0xf] : 2; if (pcb.inp_state == 5 /* established */ || pcb.inp_state == 8 /* closeWait */ ) tcp_estab++; pcb.uid = uid; nnew = SNMP_MALLOC_TYPEDEF(struct inpcb); if (nnew == NULL) break; memcpy(nnew, &pcb, sizeof(struct inpcb)); nnew->inp_next = tcp_head; tcp_head = nnew; } fclose(in); DEBUGMSGTL(("mibII/tcpTable", "Loaded TCP Table (linux)\n")); return 0; }
struct hostent * netsnmp_gethostbyname(const char *name) { #if HAVE_GETHOSTBYNAME #ifdef DNSSEC_LOCAL_VALIDATION val_status_t val_status; #endif struct hostent *hp = NULL; if (NULL == name) return NULL; DEBUGMSGTL(("dns:gethostbyname", "looking up %s\n", name)); #ifdef DNSSEC_LOCAL_VALIDATION hp = val_gethostbyname(netsnmp_validator_context(), name, &val_status); DEBUGMSGTL(("dns:sec:val", "val_status %d / %s; trusted: %d\n", val_status, p_val_status(val_status), val_istrusted(val_status))); if (!val_istrusted(val_status)) { snmp_log(LOG_WARNING, "The authenticity of DNS response is not trusted (%s)\n", p_val_status(val_status)); /** continue anyways if DNSSEC_WARN_ONLY is set */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DNSSEC_WARN_ONLY)) hp = NULL; } else if (val_does_not_exist(val_status) && hp) hp = NULL; #else hp = gethostbyname(name); #endif if (hp == NULL) { DEBUGMSGTL(("dns:gethostbyname", "couldn't resolve %s\n", name)); } else if (hp->h_addrtype != AF_INET) { DEBUGMSGTL(("dns:gethostbyname", "warning: response for %s not AF_INET!\n", name)); } else { DEBUGMSGTL(("dns:gethostbyname", "%s resolved okay\n", name)); } return hp; #else NETSNMP_LOGONCE((LOG_ERR, "gethostbyname not available")); return NULL; #endif /* HAVE_GETHOSTBYNAME */ }
static void netsnmp_access_arp_read_netlink(int fd, void *data) { netsnmp_arp_access *access = (netsnmp_arp_access *) data; netsnmp_arp_entry *entry; char buf[16384]; struct nlmsghdr *h; int r, len; do { r = recv(fd, buf, sizeof(buf), MSG_DONTWAIT); if (r < 0) { if (errno == EINTR) continue; if (errno == EAGAIN) return; snmp_log(LOG_WARNING, "netlink buffer overrun\n"); access->synchronized = 0; if (access->cache_expired != NULL) *access->cache_expired = 1; return; } } while (0); len = r; for (h = (struct nlmsghdr *) buf; NLMSG_OK(h, len); h = NLMSG_NEXT(h, len)) { if (h->nlmsg_type == NLMSG_DONE) { access->synchronized = 1; continue; } entry = netsnmp_access_arp_entry_create(); if (NULL == entry) break; DEBUGMSGTL(("access:netlink:arp", "arp netlink notification\n")); entry->generation = access->generation; r = fillup_entry_info (entry, h); if (r > 0) { access->update_hook(access, entry); } else { if (r < 0) { NETSNMP_LOGONCE((LOG_ERR, "filling entry info failed\n")); DEBUGMSGTL(("access:netlink:arp", "filling entry info failed\n")); } netsnmp_access_arp_entry_free(entry); } } }
struct hostent * netsnmp_gethostbyaddr(const void *addr, socklen_t len, int type) { #if HAVE_GETHOSTBYADDR struct hostent *hp = NULL; struct sockaddr_in *saddr_in = NETSNMP_REMOVE_CONST(struct sockaddr_in *,addr); DEBUGMSGTL(("dns:gethostbyaddr", "resolving { AF_INET, %s:%hu }\n", inet_ntoa(saddr_in->sin_addr), ntohs(saddr_in->sin_port))); #ifdef DNSSEC_LOCAL_VALIDATION val_status_t val_status; hp = val_gethostbyaddr(netsnmp_validator_context(), (const void*)&saddr_in->sin_addr, sizeof(struct in_addr), AF_INET, &val_status); DEBUGMSGTL(("dns:sec:val", "val_status %d / %s; trusted: %d\n", val_status, p_val_status(val_status), val_istrusted(val_status))); if (!val_istrusted(val_status)) { snmp_log(LOG_WARNING, "The authenticity of DNS response is not trusted (%s)\n", p_val_status(val_status)); /** continue anyways if DNSSEC_WARN_ONLY is set */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DNSSEC_WARN_ONLY)) hp = NULL; } else if (val_does_not_exist(val_status) && hp) hp = NULL; #else hp = gethostbyaddr((const void*) &saddr_in->sin_addr, sizeof(struct in_addr), AF_INET); #endif if (hp == NULL) { DEBUGMSGTL(("dns:gethostbyaddr", "couldn't resolve addr\n")); } else if (hp->h_addrtype != AF_INET) { DEBUGMSGTL(("dns:gethostbyaddr", "warning: response for addr not AF_INET!\n")); } else { DEBUGMSGTL(("dns:gethostbyaddr", "addr resolved okay\n")); } return hp; #else NETSNMP_LOGONCE((LOG_ERR, "gethostbyaddr not available")); return NULL; #endif }
static void _access_interface_entry_save_name(const char *name, oid index) { int tmp; if(NULL == name) return; tmp = se_find_value_in_slist("interfaces", name); if (tmp == SE_DNE) { se_add_pair_to_slist("interfaces", strdup(name), index); DEBUGMSGTL(("access:interface:ifIndex", "saved ifIndex %" NETSNMP_PRIo "u for %s\n", index, name)); } else if (index != (oid)tmp) { NETSNMP_LOGONCE((LOG_ERR, "IfIndex of an interface changed. Such " \ "interfaces will appear multiple times in IF-MIB.\n")); DEBUGMSGTL(("access:interface:ifIndex", "index %" NETSNMP_PRIo "u != tmp for %s\n", index, name)); } }
/* * Based on load_flags, load ipSystemStatsTable or ipIfStatsTable for ipv4 entries. */ static int _systemstats_v4(netsnmp_container* container, u_int load_flags) { FILE *devin; char line[1024]; netsnmp_systemstats_entry *entry = NULL; int scan_count; char *stats, *start = line; int len; unsigned long long scan_vals[19]; DEBUGMSGTL(("access:systemstats:container:arch", "load v4 (flags %x)\n", load_flags)); netsnmp_assert(container != NULL); /* load function shoulda checked this */ if (load_flags & NETSNMP_ACCESS_SYSTEMSTATS_LOAD_IFTABLE) { /* we do not support ipIfStatsTable for ipv4 */ return 0; } if (!(devin = fopen("/proc/net/snmp", "r"))) { DEBUGMSGTL(("access:systemstats", "Failed to load Systemstats Table (linux1)\n")); NETSNMP_LOGONCE((LOG_ERR, "cannot open /proc/net/snmp ...\n")); return -2; } /* * skip header, but make sure it's the length we expect... */ fgets(line, sizeof(line), devin); len = strlen(line); if (224 != len) { fclose(devin); snmp_log(LOG_ERR, "unexpected header length in /proc/net/snmp." " %d != 224\n", len); return -4; } /* * This file provides the statistics for each systemstats. * Read in each line in turn, isolate the systemstats name * and retrieve (or create) the corresponding data structure. */ start = fgets(line, sizeof(line), devin); fclose(devin); if (start) { len = strlen(line); if (line[len - 1] == '\n') line[len - 1] = '\0'; while (*start && *start == ' ') start++; if ((!*start) || ((stats = strrchr(start, ':')) == NULL)) { snmp_log(LOG_ERR, "systemstats data format error 1, line ==|%s|\n", line); return -4; } DEBUGMSGTL(("access:systemstats", "processing '%s'\n", start)); *stats++ = 0; /* null terminate name */ while (*stats == ' ') /* skip spaces before stats */ stats++; entry = netsnmp_access_systemstats_entry_create(1, 0, "ipSystemStatsTable.ipv4"); if(NULL == entry) { netsnmp_access_systemstats_container_free(container, NETSNMP_ACCESS_SYSTEMSTATS_FREE_NOFLAGS); return -3; } /* * OK - we've now got (or created) the data structure for * this systemstats, including any "static" information. * Now parse the rest of the line (i.e. starting from 'stats') * to extract the relevant statistics, and populate * data structure accordingly. */ memset(scan_vals, 0x0, sizeof(scan_vals)); scan_count = sscanf(stats, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu" "%llu %llu %llu %llu %llu %llu %llu %llu %llu", &scan_vals[0],&scan_vals[1],&scan_vals[2], &scan_vals[3],&scan_vals[4],&scan_vals[5], &scan_vals[6],&scan_vals[7],&scan_vals[8], &scan_vals[9],&scan_vals[10],&scan_vals[11], &scan_vals[12],&scan_vals[13],&scan_vals[14], &scan_vals[15],&scan_vals[16],&scan_vals[17], &scan_vals[18]); DEBUGMSGTL(("access:systemstats", " read %d values\n", scan_count)); if(scan_count != 19) { snmp_log(LOG_ERR, "error scanning systemstats data (expected %d, got %d)\n", 19, scan_count); netsnmp_access_systemstats_entry_free(entry); return -4; } /* entry->stats. = scan_vals[0]; / * Forwarding */ /* entry->stats. = scan_vals[1]; / * DefaultTTL */ entry->stats.HCInReceives.low = scan_vals[2] & 0xffffffff; entry->stats.HCInReceives.high = scan_vals[2] >> 32; entry->stats.InHdrErrors = scan_vals[3]; entry->stats.InAddrErrors = scan_vals[4]; entry->stats.HCOutForwDatagrams.low = scan_vals[5] & 0xffffffff; entry->stats.HCOutForwDatagrams.high = scan_vals[5] >> 32; entry->stats.InUnknownProtos = scan_vals[6]; entry->stats.InDiscards = scan_vals[7]; entry->stats.HCInDelivers.low = scan_vals[8] & 0xffffffff; entry->stats.HCInDelivers.high = scan_vals[8] >> 32; entry->stats.HCOutRequests.low = scan_vals[9] & 0xffffffff; entry->stats.HCOutRequests.high = scan_vals[9] >> 32; entry->stats.HCOutDiscards.low = scan_vals[10] & 0xffffffff;; entry->stats.HCOutDiscards.high = scan_vals[10] >> 32; entry->stats.HCOutNoRoutes.low = scan_vals[11] & 0xffffffff;; entry->stats.HCOutNoRoutes.high = scan_vals[11] >> 32; /* entry->stats. = scan_vals[12]; / * ReasmTimeout */ entry->stats.ReasmReqds = scan_vals[13]; entry->stats.ReasmOKs = scan_vals[14]; entry->stats.ReasmFails = scan_vals[15]; entry->stats.HCOutFragOKs.low = scan_vals[16] & 0xffffffff;; entry->stats.HCOutFragOKs.high = scan_vals[16] >> 32; entry->stats.HCOutFragFails.low = scan_vals[17] & 0xffffffff;; entry->stats.HCOutFragFails.high = scan_vals[17] >> 32; entry->stats.HCOutFragCreates.low = scan_vals[18] & 0xffffffff;; entry->stats.HCOutFragCreates.high = scan_vals[18] >> 32; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINRECEIVES] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INHDRERRORS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INADDRERRORS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFORWDATAGRAMS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INUNKNOWNPROTOS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INDISCARDS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINDELIVERS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTREQUESTS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTDISCARDS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTNOROUTES] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_REASMREQDS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_REASMOKS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_REASMFAILS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGOKS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGFAILS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGCREATES] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_DISCONTINUITYTIME] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_REFRESHRATE] = 1; /* * load addtional statistics defined by RFC 4293 * As these are supported linux 2.6.22 or later, it is no problem * if loading them are failed. */ _additional_systemstats_v4(entry, load_flags); /* * add to container */ if (CONTAINER_INSERT(container, entry) < 0) { DEBUGMSGTL(("access:systemstats:container","error with systemstats_entry: insert into container failed.\n")); netsnmp_access_systemstats_entry_free(entry); } } return 0; }
static int _additional_systemstats_v4(netsnmp_systemstats_entry* entry, u_int load_flags) { FILE *devin; char line[1024]; int scan_count; unsigned long long scan_vals[12]; int retval = 0; DEBUGMSGTL(("access:systemstats:container:arch", "load addtional v4 (flags %u)\n", load_flags)); if (!(devin = fopen("/proc/net/netstat", "r"))) { DEBUGMSGTL(("access:systemstats", "cannot open /proc/net/netstat\n")); NETSNMP_LOGONCE((LOG_ERR,"cannot open /proc/net/netstat\n")); return -2; } /* * Get header and stat lines */ while (fgets(line, sizeof(line), devin)) { if (strncmp(IP_EXT_HEAD, line, sizeof(IP_EXT_HEAD) - 1) == 0) { /* next line should includes IPv4 addtional statistics */ if ((fgets(line, sizeof(line), devin)) == NULL) { retval = -4; break; } if (strncmp(IP_EXT_HEAD, line, sizeof(IP_EXT_HEAD) - 1) != 0) { retval = -4; break; } memset(scan_vals, 0x0, sizeof(scan_vals)); scan_count = sscanf(line, "%*s" /* ignore `IpExt:' */ "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", &scan_vals[0], &scan_vals[1], &scan_vals[2], &scan_vals[3], &scan_vals[4], &scan_vals[5], &scan_vals[6], &scan_vals[7], &scan_vals[8], &scan_vals[9], &scan_vals[10], &scan_vals[11]); if (scan_count < 6) { snmp_log(LOG_ERR, "error scanning addtional systemstats data" "(minimum expected %d, got %d)\n", 6, scan_count); retval = -4; break; } entry->stats.HCInNoRoutes.low = scan_vals[0] & 0xffffffff; entry->stats.HCInNoRoutes.high = scan_vals[0] >> 32; entry->stats.InTruncatedPkts = scan_vals[1]; entry->stats.HCInMcastPkts.low = scan_vals[2] & 0xffffffff; entry->stats.HCInMcastPkts.high = scan_vals[2] >> 32; entry->stats.HCOutMcastPkts.low = scan_vals[3] & 0xffffffff; entry->stats.HCOutMcastPkts.high = scan_vals[3] >> 32; entry->stats.HCInBcastPkts.low = scan_vals[4] & 0xffffffff; entry->stats.HCInBcastPkts.high = scan_vals[4] >> 32; entry->stats.HCOutBcastPkts.low = scan_vals[5] & 0xffffffff; entry->stats.HCOutBcastPkts.high = scan_vals[5] >> 32; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINNOROUTES] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INTRUNCATEDPKTS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINMCASTPKTS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTMCASTPKTS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINBCASTPKTS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTBCASTPKTS] = 1; if (scan_count >= 12) { entry->stats.HCInOctets.low = scan_vals[6] & 0xffffffff; entry->stats.HCInOctets.high = scan_vals[6] >> 32; entry->stats.HCOutOctets.low = scan_vals[7] & 0xffffffff; entry->stats.HCOutOctets.high = scan_vals[7] >> 32; entry->stats.HCInMcastOctets.low = scan_vals[8] & 0xffffffff; entry->stats.HCInMcastOctets.high = scan_vals[8] >> 32; entry->stats.HCOutMcastOctets.low = scan_vals[9] & 0xffffffff; entry->stats.HCOutMcastOctets.high = scan_vals[9] >> 32; /* 10 and 11 are In/OutBcastOctets */ entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINOCTETS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTOCTETS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINMCASTOCTETS] = 1; entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTMCASTOCTETS] = 1; } } }
/* --------------------------------------------------------------------- */ int netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) { rpmts ts; rpmdbMatchIterator mi; Header h; char *n, *v, *r, *g; int32_t *t; time_t install_time; size_t date_len; int i = 1; netsnmp_swinst_entry *entry; ts = rpmtsCreate(); rpmtsSetVSFlags( ts, (_RPMVSF_NOSIGNATURES|_RPMVSF_NODIGESTS)); mi = rpmtsInitIterator( ts, RPMDBI_PACKAGES, NULL, 0); if (mi == NULL) NETSNMP_LOGONCE((LOG_ERR, "rpmdbOpen() failed\n")); while (NULL != (h = rpmdbNextIterator( mi ))) { const u_char *dt; entry = netsnmp_swinst_entry_create( i++ ); if (NULL == entry) continue; /* error already logged by function */ CONTAINER_INSERT(container, entry); h = headerLink( h ); headerGetEntry( h, RPMTAG_NAME, NULL, (void**)&n, NULL); headerGetEntry( h, RPMTAG_VERSION, NULL, (void**)&v, NULL); headerGetEntry( h, RPMTAG_RELEASE, NULL, (void**)&r, NULL); headerGetEntry( h, RPMTAG_GROUP, NULL, (void**)&g, NULL); headerGetEntry( h, RPMTAG_INSTALLTIME, NULL, (void**)&t, NULL); entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), "%s-%s-%s", n, v, r); if (entry->swName_len > sizeof(entry->swName)) entry->swName_len = sizeof(entry->swName); entry->swType = (NULL != strstr( g, "System Environment")) ? 2 /* operatingSystem */ : 4; /* application */ install_time = *t; dt = date_n_time( &install_time, &date_len ); if (date_len != 8 && date_len != 11) { snmp_log(LOG_ERR, "Bogus length from date_n_time for %s", entry->swName); entry->swDate_len = 0; } else { entry->swDate_len = date_len; memcpy(entry->swDate, dt, entry->swDate_len); } headerFree( h ); } rpmdbFreeIterator( mi ); rpmtsFree( ts ); DEBUGMSGTL(("swinst:load:arch", "loaded %d entries\n", (int)CONTAINER_SIZE(container))); return 0; }
static int _load_ipv4(netsnmp_container* container, u_long *index ) { FILE *in; char line[256]; netsnmp_route_entry *entry = NULL; char name[16]; int fd; DEBUGMSGTL(("access:route:container", "route_container_arch_load ipv4\n")); netsnmp_assert(NULL != container); /* * fetch routes from the proc file-system: */ if (!(in = fopen("/proc/net/route", "r"))) { NETSNMP_LOGONCE((LOG_ERR, "cannot open /proc/net/route\n")); return -2; } /* * create socket for ioctls (see NOTE[1], below) */ fd = socket(AF_INET, SOCK_DGRAM, 0); if(fd < 0) { snmp_log(LOG_ERR, "could not create socket\n"); fclose(in); return -2; } fgets(line, sizeof(line), in); /* skip header */ while (fgets(line, sizeof(line), in)) { char rtent_name[32]; int refcnt, rc; uint32_t dest, nexthop, mask; unsigned flags, use; entry = netsnmp_access_route_entry_create(); /* * as with 1.99.14: * Iface Dest GW Flags RefCnt Use Met Mask MTU Win IRTT * BE eth0 00000000 C0A80101 0003 0 0 0 FFFFFFFF 1500 0 0 * LE eth0 00000000 0101A8C0 0003 0 0 0 00FFFFFF 0 0 0 */ rc = sscanf(line, "%s %x %x %x %d %u %d %x %*d %*d %*d\n", rtent_name, &dest, &nexthop, /* * XXX: fix type of the args */ &flags, &refcnt, &use, &entry->rt_metric1, &mask); DEBUGMSGTL(("9:access:route:container", "line |%s|\n", line)); if (8 != rc) { snmp_log(LOG_ERR, "/proc/net/route data format error (%d!=8), line ==|%s|", rc, line); netsnmp_access_route_entry_free(entry); continue; } /* * temporary null terminated name */ strlcpy(name, rtent_name, sizeof(name)); /* * don't bother to try and get the ifindex for routes with * no interface name. * NOTE[1]: normally we'd use netsnmp_access_interface_index_find, * but since that will open/close a socket, and we might * have a lot of routes, call the ioctl routine directly. */ if ('*' != name[0]) entry->if_index = netsnmp_access_interface_ioctl_ifindex_get(fd,name); /* * arbitrary index */ entry->ns_rt_index = ++(*index); #ifdef USING_IP_FORWARD_MIB_IPCIDRROUTETABLE_IPCIDRROUTETABLE_MODULE memcpy(&entry->rt_mask, &mask, 4); /** entry->rt_tos = XXX; */ /** rt info ?? */ #endif /* * copy dest & next hop */ entry->rt_dest_type = INETADDRESSTYPE_IPV4; entry->rt_dest_len = 4; memcpy(entry->rt_dest, &dest, 4); entry->rt_nexthop_type = INETADDRESSTYPE_IPV4; entry->rt_nexthop_len = 4; memcpy(entry->rt_nexthop, &nexthop, 4); /* * count bits in mask */ mask = htonl(mask); entry->rt_pfx_len = netsnmp_ipaddress_ipv4_prefix_len(mask); #ifdef USING_IP_FORWARD_MIB_INETCIDRROUTETABLE_INETCIDRROUTETABLE_MODULE /* inetCidrRoutePolicy OBJECT-TYPE SYNTAX OBJECT IDENTIFIER MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object is an opaque object without any defined semantics. Its purpose is to serve as an additional index which may delineate between multiple entries to the same destination. The value { 0 0 } shall be used as the default value for this object." */ /* * on linux, default routes all look alike, and would have the same * indexed based on dest and next hop. So we use the if index * as the policy, to distinguise between them. Hopefully this is * unique. * xxx-rks: It should really only be for the duplicate case, but that * would be more complicated than I want to get into now. Fix later. */ if (0 == nexthop) { entry->rt_policy = calloc(3, sizeof(oid)); entry->rt_policy[2] = entry->if_index; entry->rt_policy_len = sizeof(oid)*3; } #endif /* * get protocol and type from flags */ entry->rt_type = _type_from_flags(flags); entry->rt_proto = (flags & RTF_DYNAMIC) ? IANAIPROUTEPROTOCOL_ICMP : IANAIPROUTEPROTOCOL_LOCAL; /* * insert into container */ if (CONTAINER_INSERT(container, entry) < 0) { DEBUGMSGTL(("access:route:container", "error with route_entry: insert into container failed.\n")); netsnmp_access_route_entry_free(entry); continue; } } fclose(in); close(fd); return 0; }
static int _load_ipv6(netsnmp_container* container, u_long *index ) { FILE *in; char line[256]; netsnmp_route_entry *entry = NULL; static int log_open_err = 1; DEBUGMSGTL(("access:route:container", "route_container_arch_load ipv6\n")); netsnmp_assert(NULL != container); /* * fetch routes from the proc file-system: */ if (!(in = fopen("/proc/net/ipv6_route", "r"))) { if (1 == log_open_err) { NETSNMP_LOGONCE((LOG_ERR, "cannot open /proc/net/ipv6_route\n")); log_open_err = 0; } return -2; } /* * if we turned off logging of open errors, turn it back on now that * we have been able to open the file. */ if (0 == log_open_err) log_open_err = 1; fgets(line,sizeof(line),in); /* skip header */ while (fgets(line, sizeof(line), in)) { char c_name[IFNAMSIZ+1]; char c_dest[33], c_src[33], c_next[33]; int rc; unsigned int dest_pfx, flags; size_t buf_len, buf_offset; u_char *temp_uchar_ptr; entry = netsnmp_access_route_entry_create(); /* * based on /usr/src/linux/net/ipv6/route.c, kernel 2.6.7: * * [ Dest addr / plen ] * fe80000000000000025056fffec00008 80 \ * * [ (?subtree) : src addr/plen : 0/0] * 00000000000000000000000000000000 00 \ * * [ next hop ][ metric ][ref ctn][ use ] * 00000000000000000000000000000000 00000000 00000000 00000000 \ * * [ flags ][dev name] * 80200001 lo */ rc = sscanf(line, "%32s %2x %32s %*x %32s %x %*x %*x %x %" SNMP_MACRO_VAL_TO_STR(IFNAMSIZ) "s\n", c_dest, &dest_pfx, c_src, /*src_pfx,*/ c_next, &entry->rt_metric1, /** ref,*/ /* use, */ &flags, c_name); DEBUGMSGTL(("9:access:route:container", "line |%s|\n", line)); if (7 != rc) { snmp_log(LOG_ERR, "/proc/net/ipv6_route data format error (%d!=8), " "line ==|%s|", rc, line); continue; } /* * temporary null terminated name */ c_name[ sizeof(c_name)-1 ] = 0; entry->if_index = se_find_value_in_slist("interfaces", c_name); if(SE_DNE == entry->if_index) { snmp_log(LOG_ERR,"unknown interface in /proc/net/ipv6_route " "('%s')\n", c_name); netsnmp_access_route_entry_free(entry); continue; } /* * arbitrary index */ entry->ns_rt_index = ++(*index); #ifdef USING_IP_FORWARD_MIB_IPCIDRROUTETABLE_IPCIDRROUTETABLE_MODULE /** entry->rt_mask = mask; */ /* IPv4 only */ /** entry->rt_tos = XXX; */ /** rt info ?? */ #endif /* * convert hex addresses to binary */ entry->rt_dest_type = INETADDRESSTYPE_IPV6; entry->rt_dest_len = 16; buf_len = sizeof(entry->rt_dest); buf_offset = 0; temp_uchar_ptr = entry->rt_dest; netsnmp_hex_to_binary(&temp_uchar_ptr, &buf_len, &buf_offset, 0, c_dest, NULL); entry->rt_nexthop_type = INETADDRESSTYPE_IPV6; entry->rt_nexthop_len = 16; buf_len = sizeof(entry->rt_nexthop); buf_offset = 0; temp_uchar_ptr = entry->rt_nexthop; netsnmp_hex_to_binary(&temp_uchar_ptr, &buf_len, &buf_offset, 0, c_next, NULL); entry->rt_pfx_len = dest_pfx; #ifdef USING_IP_FORWARD_MIB_INETCIDRROUTETABLE_INETCIDRROUTETABLE_MODULE /* inetCidrRoutePolicy OBJECT-TYPE SYNTAX OBJECT IDENTIFIER MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object is an opaque object without any defined semantics. Its purpose is to serve as an additional index which may delineate between multiple entries to the same destination. The value { 0 0 } shall be used as the default value for this object." */ /* * on linux, default routes all look alike, and would have the same * indexed based on dest and next hop. So we use our arbitrary index * as the policy, to distinguish between them. */ entry->rt_policy = calloc(3, sizeof(oid)); entry->rt_policy[2] = entry->ns_rt_index; entry->rt_policy_len = sizeof(oid)*3; #endif /* * get protocol and type from flags */ entry->rt_type = _type_from_flags(flags); entry->rt_proto = (flags & RTF_DYNAMIC) ? IANAIPROUTEPROTOCOL_ICMP : IANAIPROUTEPROTOCOL_LOCAL; /* * insert into container */ CONTAINER_INSERT(container, entry); } fclose(in); return 0; }
int get_exec_output (struct extensible *ex) { #ifndef USING_UTILITIES_EXECUTE_MODULE ex->result = -1; NETSNMP_LOGONCE ((LOG_WARNING, "support for run_exec_command not available\n")); #else #if HAVE_EXECV char cachefile[STRMAX]; char cache[NETSNMP_MAXCACHESIZE]; int cachebytes; int cfd; #ifdef NETSNMP_EXCACHETIME long curtime; static char lastcmd[STRMAX]; static int lastresult; #endif DEBUGMSGTL (("exec:get_exec_output", "calling %s\n", ex->command)); sprintf (cachefile, "%s/%s", get_persistent_directory (), NETSNMP_CACHEFILE); #ifdef NETSNMP_EXCACHETIME curtime = time (NULL); if (curtime > (cachetime + NETSNMP_EXCACHETIME) || strcmp (ex->command, lastcmd) != 0) { strcpy (lastcmd, ex->command); cachetime = curtime; #endif cachebytes = NETSNMP_MAXCACHESIZE; ex->result = run_exec_command (ex->command, NULL, cache, &cachebytes); unlink (cachefile); /* * XXX Use SNMP_FILEMODE_CLOSED instead of 644? */ if ((cfd = open (cachefile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) { snmp_log (LOG_ERR, "can not create cache file\n"); setPerrorstatus (cachefile); #ifdef NETSNMP_EXCACHETIME cachetime = 0; #endif return -1; } if (cachebytes > 0) write (cfd, (void *) cache, cachebytes); close (cfd); #ifdef NETSNMP_EXCACHETIME lastresult = ex->result; } else { ex->result = lastresult; } #endif DEBUGMSGTL (("exec:get_exec_output", "using cached value\n")); if ((cfd = open (cachefile, O_RDONLY)) < 0) { snmp_log (LOG_ERR, "can not open cache file\n"); setPerrorstatus (cachefile); return -1; } return (cfd); #else /* !HAVE_EXECV */ #if defined(WIN32) && !defined(HAVE_EXECV) /* MSVC and MinGW. Cygwin already works as it has execv and fork */ int fd; /* Reference: MS tech note: 190351 */ HANDLE hOutputReadTmp, hOutputRead, hOutputWrite = NULL; HANDLE hErrorWrite; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; STARTUPINFO si; sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; DEBUGMSGTL (("exec:get_exec_output", "calling %s\n", ex->command)); /* Child temporary output pipe with Inheritance on (sa.bInheritHandle is true) */ if (!CreatePipe (&hOutputReadTmp, &hOutputWrite, &sa, 0)) { DEBUGMSGTL (("util_funcs", "get_exec_pipes CreatePipe ChildOut: %lu\n", GetLastError ())); return -1; } /* Copy the stdout handle to the stderr handle in case the child closes one of * its stdout handles. */ if (!DuplicateHandle (GetCurrentProcess (), hOutputWrite, GetCurrentProcess (), &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS)) { DEBUGMSGTL (("util_funcs", "get_exec_output DuplicateHandle: %lu\n", GetLastError ())); return -1; } /* Create new copies of the input and output handles but set bInheritHandle to * FALSE so the new handle can not be inherited. Otherwise the handles can not * be closed. */ if (!DuplicateHandle (GetCurrentProcess (), hOutputReadTmp, GetCurrentProcess (), &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) { DEBUGMSGTL (("util_funcs", "get_exec_output DupliateHandle ChildOut: %lu\n", GetLastError ())); CloseHandle (hErrorWrite); return -1; } /* Close the temporary output and input handles */ if (!CloseHandle (hOutputReadTmp)) { DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle (hOutputReadTmp): %lu\n", GetLastError ())); CloseHandle (hErrorWrite); CloseHandle (hOutputRead); return -1; } /* Associates a C run-time file descriptor with an existing operating-system file handle. */ fd = _open_osfhandle ((long) hOutputRead, 0); /* Set up STARTUPINFO for CreateProcess with the handles and have it hide the window * for the new process. */ ZeroMemory (&si, sizeof (STARTUPINFO)); si.cb = sizeof (STARTUPINFO); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.hStdOutput = hOutputWrite; si.hStdError = hErrorWrite; si.wShowWindow = SW_HIDE; /* Launch the process that you want to redirect. Example snmpd.conf pass_persist: * pass_persist .1.3.6.1.4.1.2021.255 c:/perl/bin/perl c:/temp/pass_persisttest */ if (!CreateProcess (NULL, ex->command, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { DEBUGMSGTL (("util_funcs", "get_exec_output CreateProcess:'%s' %lu\n", ex->command, GetLastError ())); CloseHandle (hErrorWrite); CloseHandle (hOutputRead); return -1; } /* Set global child process handle */ ex->pid = pi.hProcess; ex->tid = pi.hThread; /* Close pipe handles to make sure that no handles to the write end of the * output pipe are maintained in this process or else the pipe will * not close when the child process exits and any calls to ReadFile * will hang. */ if (!CloseHandle (hOutputWrite)) { DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle hOutputWrite: %lu\n", GetLastError ())); return -1; } if (!CloseHandle (hErrorWrite)) { DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle hErrorWrite: %lu\n", GetLastError ())); return -1; } return fd; #endif /* WIN32 */ #endif #endif /* !defined(USING_UTILITIES_EXECUTE_MODULE) */ return -1; }
/** * update entry stats (checking for counter wrap) * * @retval 0 : success * @retval <0 : error */ int netsnmp_access_systemstats_entry_update_stats(netsnmp_systemstats_entry * prev_vals, netsnmp_systemstats_entry * new_vals) { DEBUGMSGTL(("access:systemstats", "check_wrap\n")); /* * sanity checks */ if ((NULL == prev_vals) || (NULL == new_vals) || (prev_vals->index[0] != new_vals->index[0]) || (prev_vals->index[1] != new_vals->index[1])) return -1; /* * if we've determined that we have 64 bit counters, just copy them. */ if (0 == need_wrap_check) { memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats)); _calculate_entries(prev_vals); return 0; } if (NULL == prev_vals->old_stats) { /* * if we don't have old stats, they can't have wrapped, so just copy */ prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_ipstats); if (NULL == prev_vals->old_stats) { return -2; } } else { /* * update straight 32 bit counters */ memcpy(&prev_vals->stats.columnAvail[0], &new_vals->stats.columnAvail[0], sizeof(new_vals->stats.columnAvail)); prev_vals->stats.InHdrErrors = new_vals->stats.InHdrErrors; prev_vals->stats.InAddrErrors = new_vals->stats.InAddrErrors; prev_vals->stats.InUnknownProtos = new_vals->stats.InUnknownProtos; prev_vals->stats.InTruncatedPkts = new_vals->stats.InTruncatedPkts; prev_vals->stats.ReasmReqds = new_vals->stats.ReasmReqds; prev_vals->stats.ReasmOKs = new_vals->stats.ReasmOKs; prev_vals->stats.ReasmFails = new_vals->stats.ReasmFails; prev_vals->stats.InDiscards = new_vals->stats.InDiscards; /* * update 64bit counters */ if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInNoRoutes, &new_vals->stats.HCInNoRoutes, &prev_vals->old_stats->HCInNoRoutes, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInNoRoutes to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutNoRoutes, &new_vals->stats.HCOutNoRoutes, &prev_vals->old_stats->HCOutNoRoutes, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutNoRoutes to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutDiscards, &new_vals->stats.HCOutDiscards, &prev_vals->old_stats->HCOutDiscards, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutDiscards to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragReqds, &new_vals->stats.HCOutFragReqds, &prev_vals->old_stats->HCOutFragReqds, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutFragReqds to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragOKs, &new_vals->stats.HCOutFragOKs, &prev_vals->old_stats->HCOutFragOKs, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutFragOKs to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragFails, &new_vals->stats.HCOutFragFails, &prev_vals->old_stats->HCOutFragFails, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutFragFails to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragCreates, &new_vals->stats.HCOutFragCreates, &prev_vals->old_stats->HCOutFragCreates, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutFragCreates to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInReceives, &new_vals->stats.HCInReceives, &prev_vals->old_stats->HCInReceives, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInReceives to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInOctets, &new_vals->stats.HCInOctets, &prev_vals->old_stats->HCInOctets, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInOctets to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInForwDatagrams, &new_vals->stats.HCInForwDatagrams, &prev_vals->old_stats->HCInForwDatagrams, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInForwDatagrams to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInDelivers, &new_vals->stats.HCInDelivers, &prev_vals->old_stats->HCInDelivers, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInDelivers to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutRequests, &new_vals->stats.HCOutRequests, &prev_vals->old_stats->HCOutRequests, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutRequests to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutForwDatagrams, &new_vals->stats.HCOutForwDatagrams, &prev_vals->old_stats->HCOutForwDatagrams, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutForwDatagrams to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutTransmits, &new_vals->stats.HCOutTransmits, &prev_vals->old_stats->HCOutTransmits, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutTransmits to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutOctets, &new_vals->stats.HCOutOctets, &prev_vals->old_stats->HCOutOctets, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutOctets to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInMcastPkts, &new_vals->stats.HCInMcastPkts, &prev_vals->old_stats->HCInMcastPkts, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInMcastPkts to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInMcastOctets, &new_vals->stats.HCInMcastOctets, &prev_vals->old_stats->HCInMcastOctets, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInMcastOctets to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutMcastPkts, &new_vals->stats.HCOutMcastPkts, &prev_vals->old_stats->HCOutMcastPkts, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutMcastPkts to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutMcastOctets, &new_vals->stats.HCOutMcastOctets, &prev_vals->old_stats->HCOutMcastOctets, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutMcastOctets to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInBcastPkts, &new_vals->stats.HCInBcastPkts, &prev_vals->old_stats->HCInBcastPkts, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCInBcastPkts to 64bits in %s\n", prev_vals->tableName)); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutBcastPkts, &new_vals->stats.HCOutBcastPkts, &prev_vals->old_stats->HCOutBcastPkts, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding HCOutBcastPkts to 64bits in %s\n", prev_vals->tableName)); } /* * if we've decided we no longer need to check wraps, free old stats */ if (0 == need_wrap_check) { SNMP_FREE(prev_vals->old_stats); } else { /* * update old stats from new stats. * careful - old_stats is a pointer to stats... */ memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats)); } _calculate_entries(prev_vals); return 0; }
/* * try to get load average * Inputs: pointer to array of doubles, number of elements in array * Returns: 0=array has values, -1=error occurred. */ int try_getloadavg(double *r_ave, size_t s_ave) { #ifndef HAVE_GETLOADAVG #ifdef HAVE_SYS_FIXPOINT_H fix favenrun[3]; #endif #if (defined(ultrix) || defined(sun) || defined(__alpha) || defined(dynix)) int i; #if (defined(sun) || defined(__alpha) || defined(dynix)) long favenrun[3]; if (s_ave > 3) /* bounds check */ return (-1); #define FIX_TO_DBL(_IN) (((double) _IN)/((double) FSCALE)) #endif #endif #if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7) perfstat_cpu_total_t cs; #endif #if defined(hpux10) || defined(hpux11) struct pst_dynamic pst_buf; #endif #ifdef irix6 int i, favenrun[3]; sgt_cookie_t cookie; #endif #endif /* !HAVE_GETLOADAVG */ #ifdef HAVE_GETLOADAVG if (getloadavg(r_ave, s_ave) == -1) return (-1); #elif defined(linux) { FILE *in = fopen("/proc/loadavg", "r"); if (!in) { NETSNMP_LOGONCE((LOG_ERR, "snmpd: cannot open /proc/loadavg\n")); return (-1); } fscanf(in, "%lf %lf %lf", r_ave, (r_ave + 1), (r_ave + 2)); fclose(in); } #elif (defined(ultrix) || defined(sun) || defined(__alpha) || defined(dynix)) if (auto_nlist(LOADAVE_SYMBOL, (char *) favenrun, sizeof(favenrun)) == 0) return (-1); for (i = 0; i < s_ave; i++) *(r_ave + i) = FIX_TO_DBL(favenrun[i]); #elif defined(hpux10) || defined(hpux11) if (pstat_getdynamic(&pst_buf, sizeof(struct pst_dynamic), 1, 0) < 0) return(-1); r_ave[0] = pst_buf.psd_avg_1_min; r_ave[1] = pst_buf.psd_avg_5_min; r_ave[2] = pst_buf.psd_avg_15_min; #elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7) if(perfstat_cpu_total((perfstat_id_t *)NULL, &cs, sizeof(perfstat_cpu_total_t), 1) > 0) { r_ave[0] = cs.loadavg[0] / 65536.0; r_ave[1] = cs.loadavg[1] / 65536.0; r_ave[2] = cs.loadavg[2] / 65536.0; } #elif defined(irix6) SGT_COOKIE_INIT(&cookie); SGT_COOKIE_SET_KSYM(&cookie, "avenrun"); sysget(SGT_KSYM, (char*)favenrun, sizeof(favenrun), SGT_READ, &cookie); for (i = 0; i < s_ave; i++) r_ave[i] = favenrun[i] / 1000.0; DEBUGMSGTL(("ucd-snmp/loadave", "irix6: %d %d %d\n", favenrun[0], favenrun[1], favenrun[2])); #elif !defined(cygwin) #if defined(NETSNMP_CAN_USE_NLIST) && defined(LOADAVE_SYMBOL) if (auto_nlist(LOADAVE_SYMBOL, (char *) r_ave, sizeof(double) * s_ave) == 0) #endif return (-1); #endif /* * XXX * To calculate this, we need to compare * successive values of the kernel array * '_cp_times', and calculate the resulting * percentage changes. * This calculation needs to be performed * regularly - perhaps as a background process. * * See the source to 'top' for full details. * * The linux SNMP HostRes implementation * uses 'avenrun[0]*100' as an approximation. * This is less than accurate, but has the * advantage of being simple to implement! * * I'm also assuming a single processor */ return 0; }
/** * update stats * * @retval 0 : success * @retval -1 : error */ int netsnmp_access_interface_entry_update_stats(netsnmp_interface_entry * prev_vals, netsnmp_interface_entry * new_vals) { DEBUGMSGTL(("access:interface", "check_wrap\n")); /* * sanity checks */ if ((NULL == prev_vals) || (NULL == new_vals) || (NULL == prev_vals->name) || (NULL == new_vals->name) || (0 != strncmp(prev_vals->name, new_vals->name, strlen(prev_vals->name)))) return -1; /* * if we've determined that we have 64 bit counters, just copy them. */ if (0 == need_wrap_check) { memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats)); return 0; } if (NULL == prev_vals->old_stats) { /* * if we don't have old stats, copy previous stats */ prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_interface_stats); if (NULL == prev_vals->old_stats) { return -2; } memcpy(prev_vals->old_stats, &prev_vals->stats, sizeof(prev_vals->stats)); } if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.ibytes, &new_vals->stats.ibytes, &prev_vals->old_stats->ibytes, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCInOctets to 64bits\n")); if (new_vals->ns_flags & NETSNMP_INTERFACE_FLAGS_CALCULATE_UCAST) { if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iall, &new_vals->stats.iall, &prev_vals->old_stats->iall, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding packet count to 64bits\n")); } else { if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iucast, &new_vals->stats.iucast, &prev_vals->old_stats->iucast, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCInUcastPkts to 64bits\n")); } if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iucast, &new_vals->stats.iucast, &prev_vals->old_stats->iucast, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCInUcastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.imcast, &new_vals->stats.imcast, &prev_vals->old_stats->imcast, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCInMulticastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.ibcast, &new_vals->stats.ibcast, &prev_vals->old_stats->ibcast, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCInBroadcastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.obytes, &new_vals->stats.obytes, &prev_vals->old_stats->obytes, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCOutOctets to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.oucast, &new_vals->stats.oucast, &prev_vals->old_stats->oucast, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCOutUcastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.omcast, &new_vals->stats.omcast, &prev_vals->old_stats->omcast, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCOutMulticastPkts to 64bits\n")); if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.obcast, &new_vals->stats.obcast, &prev_vals->old_stats->obcast, &need_wrap_check)) NETSNMP_LOGONCE((LOG_ERR, "Error expanding ifHCOutBroadcastPkts to 64bits\n")); /* * Copy 32 bit counters */ prev_vals->stats.ierrors = new_vals->stats.ierrors; prev_vals->stats.idiscards = new_vals->stats.idiscards; prev_vals->stats.iunknown_protos = new_vals->stats.iunknown_protos; prev_vals->stats.inucast = new_vals->stats.inucast; prev_vals->stats.oerrors = new_vals->stats.oerrors; prev_vals->stats.odiscards = new_vals->stats.odiscards; prev_vals->stats.oqlen = new_vals->stats.oqlen; prev_vals->stats.collisions = new_vals->stats.collisions; prev_vals->stats.onucast = new_vals->stats.onucast; /* * if we've decided we no longer need to check wraps, free old stats */ if (0 == need_wrap_check) { SNMP_FREE(prev_vals->old_stats); } else { /* * update old stats from new stats. * careful - old_stats is a pointer to stats... */ memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats)); } return 0; }
/* * Trap handler for invoking a suitable script */ int command_handler( netsnmp_pdu *pdu, netsnmp_transport *transport, netsnmp_trapd_handler *handler) { #ifndef USING_UTILITIES_EXECUTE_MODULE NETSNMP_LOGONCE((LOG_WARNING, "support for run_shell_command not available\n")); return NETSNMPTRAPD_HANDLER_FAIL; #else u_char *rbuf = NULL; size_t r_len = 64, o_len = 0; int oldquick; DEBUGMSGTL(( "snmptrapd", "command_handler\n")); DEBUGMSGTL(( "snmptrapd", "token = '%s'\n", handler->token)); if (handler && handler->token && *handler->token) { netsnmp_pdu *v2_pdu = NULL; if (pdu->command == SNMP_MSG_TRAP) v2_pdu = convert_v1pdu_to_v2(pdu); else v2_pdu = pdu; oldquick = snmp_get_quick_print(); snmp_set_quick_print(1); /* * Format the trap and pass this string to the external command */ if ((rbuf = (u_char *) calloc(r_len, 1)) == NULL) { snmp_log(LOG_ERR, "couldn't display trap -- malloc failed\n"); return NETSNMPTRAPD_HANDLER_FAIL; /* Failed but keep going */ } /* * If there's a format string registered for this trap, then use it. * Otherwise use the standard execution format setting. */ if (handler && handler->format && *handler->format) { DEBUGMSGTL(( "snmptrapd", "format = '%s'\n", handler->format)); realloc_format_trap(&rbuf, &r_len, &o_len, 1, handler->format, v2_pdu, transport); } else { if ( pdu->command == SNMP_MSG_TRAP && exec_format1 ) { DEBUGMSGTL(( "snmptrapd", "exec v1 = '%s'\n", exec_format1)); realloc_format_trap(&rbuf, &r_len, &o_len, 1, exec_format1, pdu, transport); } else if ( pdu->command != SNMP_MSG_TRAP && exec_format2 ) { DEBUGMSGTL(( "snmptrapd", "exec v2/3 = '%s'\n", exec_format2)); realloc_format_trap(&rbuf, &r_len, &o_len, 1, exec_format2, pdu, transport); } else { DEBUGMSGTL(( "snmptrapd", "execute format\n")); realloc_format_trap(&rbuf, &r_len, &o_len, 1, EXECUTE_FORMAT, v2_pdu, transport); } } /* * and pass this formatted string to the command specified */ run_shell_command(handler->token, (char*)rbuf, NULL, NULL); /* Not interested in output */ snmp_set_quick_print(oldquick); if (pdu->command == SNMP_MSG_TRAP) snmp_free_pdu(v2_pdu); free(rbuf); } return NETSNMPTRAPD_HANDLER_OK; #endif /* !def USING_UTILITIES_EXECUTE_MODULE */ }
int netsnmp_getaddrinfo(const char *name, const char *service, const struct addrinfo *hints, struct addrinfo **res) { #if HAVE_GETADDRINFO struct addrinfo *addrs = NULL; struct addrinfo hint; int err; #ifdef DNSSEC_LOCAL_VALIDATION val_status_t val_status; #endif DEBUGMSGTL(("dns:getaddrinfo", "looking up ")); if (name) DEBUGMSG(("dns:getaddrinfo", "\"%s\"", name)); else DEBUGMSG(("dns:getaddrinfo", "<NULL>")); if (service) DEBUGMSG(("dns:getaddrinfo", ":\"%s\"", service)); if (hints) DEBUGMSG(("dns:getaddrinfo", " with hint ({ ... })")); else DEBUGMSG(("dns:getaddrinfo", " with no hint")); DEBUGMSG(("dns:getaddrinfo", "\n")); if (NULL == hints) { memset(&hint, 0, sizeof hint); hint.ai_flags = 0; hint.ai_family = PF_INET; hint.ai_socktype = SOCK_DGRAM; hint.ai_protocol = 0; hints = &hint; } else { memcpy(&hint, hints, sizeof hint); } #ifndef DNSSEC_LOCAL_VALIDATION err = getaddrinfo(name, NULL, &hint, &addrs); #else /* DNSSEC_LOCAL_VALIDATION */ err = val_getaddrinfo(netsnmp_validator_context(), name, NULL, &hint, &addrs, &val_status); DEBUGMSGTL(("dns:sec:val", "err %d, val_status %d / %s; trusted: %d\n", err, val_status, p_val_status(val_status), val_istrusted(val_status))); if (! val_istrusted(val_status)) { int rc; if ((err != 0) && VAL_GETADDRINFO_HAS_STATUS(err)) { snmp_log(LOG_WARNING, "WARNING: UNTRUSTED error in DNS resolution for %s!\n", name); rc = EAI_FAIL; } else { snmp_log(LOG_WARNING, "The authenticity of DNS response is not trusted (%s)\n", p_val_status(val_status)); rc = EAI_NONAME; } /** continue anyways if DNSSEC_WARN_ONLY is set */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DNSSEC_WARN_ONLY)) return rc; } #endif /* DNSSEC_LOCAL_VALIDATION */ *res = addrs; if ((0 == err) && addrs && addrs->ai_addr) { DEBUGMSGTL(("dns:getaddrinfo", "answer { AF_INET, %s:%hu }\n", inet_ntoa(((struct sockaddr_in*)addrs->ai_addr)->sin_addr), ntohs(((struct sockaddr_in*)addrs->ai_addr)->sin_port))); } return err; #else NETSNMP_LOGONCE((LOG_ERR, "getaddrinfo not available")); return EAI_FAIL; #endif /* getaddrinfo */ }
/* * Locate the appropriate transport domain and call the create function for * it. */ netsnmp_transport * netsnmp_tdomain_transport_full(const char *application, const char *str, int local, const char *default_domain, const char *default_target) { netsnmp_tdomain *match = NULL; const char *addr = NULL; const char * const *spec = NULL; int any_found = 0; char buf[SNMP_MAXPATH]; char **lspec = 0; DEBUGMSGTL(("tdomain", "tdomain_transport_full(\"%s\", \"%s\", %d, \"%s\", \"%s\")\n", application, str ? str : "[NIL]", local, default_domain ? default_domain : "[NIL]", default_target ? default_target : "[NIL]")); /* see if we can load a host-name specific set of conf files */ if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_LOAD_HOST_FILES) && netsnmp_is_fqdn(str)) { static int have_added_handler = 0; char *newhost; struct config_line *config_handlers; struct config_files file_names; char *prev_hostname; /* register a "transport" specifier */ if (!have_added_handler) { have_added_handler = 1; netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "transport", NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HOSTNAME); } /* we save on specific setting that we don't allow to change from one transport creation to the next; ie, we don't want the "transport" specifier to be a default. It should be a single invocation use only */ prev_hostname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HOSTNAME); if (prev_hostname) prev_hostname = strdup(prev_hostname); /* read in the hosts/STRING.conf files */ config_handlers = read_config_get_handlers("snmp"); snprintf(buf, sizeof(buf)-1, "hosts/%s", str); file_names.fileHeader = buf; file_names.start = config_handlers; file_names.next = NULL; DEBUGMSGTL(("tdomain", "checking for host specific config %s\n", buf)); read_config_files_of_type(EITHER_CONFIG, &file_names); if (NULL != (newhost = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HOSTNAME))) { strlcpy(buf, newhost, sizeof(buf)); str = buf; } netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_HOSTNAME, prev_hostname); SNMP_FREE(prev_hostname); } /* First try - assume that there is a domain in str (domain:target) */ if (str != NULL) { const char *cp; if ((cp = strchr(str, ':')) != NULL) { char* mystring = (char*)malloc(cp + 1 - str); memcpy(mystring, str, cp - str); mystring[cp - str] = '\0'; addr = cp + 1; match = find_tdomain(mystring); free(mystring); } } /* * Second try, if there is no domain in str (target), then try the * default domain */ if (match == NULL) { addr = str; if (addr && *addr == '/') { DEBUGMSGTL(("tdomain", "Address starts with '/', so assume \"unix\" " "domain\n")); match = find_tdomain("unix"); } else if (default_domain) { DEBUGMSGTL(("tdomain", "Use user specified default domain \"%s\"\n", default_domain)); if (!strchr(default_domain, ',')) match = find_tdomain(default_domain); else { int commas = 0; const char *cp = default_domain; char *dup = strdup(default_domain); while (*++cp) if (*cp == ',') commas++; lspec = (char **) calloc(commas+2, sizeof(char *)); commas = 1; lspec[0] = strtok(dup, ","); while ((lspec[commas++] = strtok(NULL, ","))) ; spec = (const char * const *)lspec; } } else { spec = netsnmp_lookup_default_domains(application); if (spec == NULL) { DEBUGMSGTL(("tdomain", "No default domain found, assume \"udp\"\n")); match = find_tdomain("udp"); } else { const char * const * r = spec; DEBUGMSGTL(("tdomain", "Use application default domains")); while(*r) { DEBUGMSG(("tdomain", " \"%s\"", *r)); ++r; } DEBUGMSG(("tdomain", "\n")); } } } for(;;) { if (match) { netsnmp_transport *t = NULL; const char* addr2; any_found = 1; /* * Ok, we know what domain to try, lets see what default data * should be used with it */ if (default_target != NULL) addr2 = default_target; else addr2 = netsnmp_lookup_default_target(application, match->prefix[0]); DEBUGMSGTL(("tdomain", "trying domain \"%s\" address \"%s\" " "default address \"%s\"\n", match->prefix[0], addr ? addr : "[NIL]", addr2 ? addr2 : "[NIL]")); if (match->f_create_from_tstring) { NETSNMP_LOGONCE((LOG_WARNING, "transport domain %s uses deprecated f_create_from_tstring\n", match->prefix[0])); t = match->f_create_from_tstring(addr, local); } else t = match->f_create_from_tstring_new(addr, local, addr2); if (t) { if (lspec) { free(lspec[0]); free(lspec); } return t; } } addr = str; if (spec && *spec) match = find_tdomain(*spec++); else break; } if (!any_found) snmp_log(LOG_ERR, "No support for any checked transport domain\n"); if (lspec) { free(lspec[0]); free(lspec); } return NULL; }