int check_and_reload_table(struct internal_mib_table *table) { /* * If the saved data is fairly recent, * we don't need to reload it */ if (table->cache_marker && !(atime_ready(table->cache_marker, table->cache_timeout * 1000))) return 1; /* * Call the routine provided to read in the data * * N.B: Update the cache marker *before* calling * this routine, to avoid problems with recursion */ if (!table->cache_marker) table->cache_marker = atime_newMarker(); else atime_setMarker(table->cache_marker); table->next_index = 1; if (table->reload((mib_table_t) table) < 0) { free(table->cache_marker); table->cache_marker = NULL; return 0; } table->current_index = 1; if (table->compare != NULL) /* Sort the table */ qsort(TABLE_START(table), table->next_index-1, table->data_size, table->compare); return 1; }
/** * Return the number of timeTicks since the given marker */ int marker_tticks(const_marker_t pm) { int res; marker_t now = atime_newMarker(); res = atime_diff(pm, now); free(now); return res / 10; /* atime_diff works in msec, not csec */ }
int uatime_ready(const_marker_t pm, unsigned int deltaT) { marker_t now; u_long diff; if (!pm) return 0; now = atime_newMarker(); diff = uatime_diff(pm, now); free(now); if (diff < deltaT) return 0; return 1; }
/** * Test: Has (marked time plus delta) exceeded current time (in msec) ? * Returns 0 if test fails or cannot be tested (no marker). */ int atime_ready(marker_t pm, int deltaT) { marker_t now; long diff; if (!pm) return 0; now = atime_newMarker(); diff = atime_diff(pm, now); free(now); if (diff < deltaT) return 0; return 1; }
long read_udp_stat(UDP_STAT_STRUCTURE * udpstat, int magic) { long ret_value = -1; #if (defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS)) static int sname[4] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS }; size_t len = sizeof(*udpstat); #endif #ifdef solaris2 static mib2_ip_t ipstat; #endif #ifdef hpux11 int fd; struct nmparms p; unsigned int ulen; if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) return (-1); /* error */ switch (magic) { case UDPINDATAGRAMS: p.objid = ID_udpInDatagrams; break; case UDPNOPORTS: p.objid = ID_udpNoPorts; break; case UDPOUTDATAGRAMS: p.objid = ID_udpOutDatagrams; break; case UDPINERRORS: p.objid = ID_udpInErrors; break; default: *udpstat = 0; close_mib(fd); return (0); } p.buffer = (void *) udpstat; ulen = sizeof(UDP_STAT_STRUCTURE); p.len = &ulen; ret_value = get_mib_info(fd, &p); close_mib(fd); return (ret_value); /* 0: ok, < 0: error */ #else /* hpux11 */ if (udp_stats_cache_marker && (!atime_ready (udp_stats_cache_marker, UDP_STATS_CACHE_TIMEOUT * 1000))) #ifdef solaris2 return (magic == UDPNOPORTS ? ipstat.udpNoPorts : 0); #else return 0; #endif if (udp_stats_cache_marker) atime_setMarker(udp_stats_cache_marker); else udp_stats_cache_marker = atime_newMarker(); #ifdef linux ret_value = linux_read_udp_stat(udpstat); #endif #ifdef WIN32 ret_value = GetUdpStatistics(udpstat); #endif #ifdef solaris2 if (magic == UDPNOPORTS) { if (getMibstat (MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST, &Get_everything, NULL) < 0) ret_value = -1; else ret_value = ipstat.udpNoPorts; } else ret_value = getMibstat(MIB_UDP, udpstat, sizeof(mib2_udp_t), GET_FIRST, &Get_everything, NULL); #endif #ifdef HAVE_SYS_TCPIPSTATS_H ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, udpstat, sizeof *udpstat); #endif #if defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS) ret_value = sysctl(sname, 4, udpstat, &len, 0, 0); #endif #ifdef UDPSTAT_SYMBOL if (auto_nlist(UDPSTAT_SYMBOL, (char *) udpstat, sizeof(*udpstat))) ret_value = 0; #endif if (ret_value == -1) { free(udp_stats_cache_marker); udp_stats_cache_marker = NULL; } return ret_value; #endif /* hpux11 */ }
int linux_read_mibII_stats(void) { FILE *in = fopen("/proc/net/snmp", "r"); char line[1024]; if (!in) { free(linux_mibII_stats_cache_marker); linux_mibII_stats_cache_marker = NULL; return -1; } if (linux_mibII_stats_cache_marker && (!atime_ready (linux_mibII_stats_cache_marker, LINUX_STATS_CACHE_TIMEOUT * 1000))) { fclose(in); return 0; } if (linux_mibII_stats_cache_marker) atime_setMarker(linux_mibII_stats_cache_marker); else linux_mibII_stats_cache_marker = atime_newMarker(); while (line == fgets(line, sizeof(line), in)) { if (!strncmp(line, IP_STATS_LINE, IP_STATS_PREFIX_LEN)) { sscanf(line, IP_STATS_LINE, &cached_ip_mib.ipForwarding, &cached_ip_mib.ipDefaultTTL, &cached_ip_mib.ipInReceives, &cached_ip_mib.ipInHdrErrors, &cached_ip_mib.ipInAddrErrors, &cached_ip_mib.ipForwDatagrams, &cached_ip_mib.ipInUnknownProtos, &cached_ip_mib.ipInDiscards, &cached_ip_mib.ipInDelivers, &cached_ip_mib.ipOutRequests, &cached_ip_mib.ipOutDiscards, &cached_ip_mib.ipOutNoRoutes, &cached_ip_mib.ipReasmTimeout, &cached_ip_mib.ipReasmReqds, &cached_ip_mib.ipReasmOKs, &cached_ip_mib.ipReasmFails, &cached_ip_mib.ipFragOKs, &cached_ip_mib.ipFragFails, &cached_ip_mib.ipFragCreates); cached_ip_mib.ipRoutingDiscards = 0; /* XXX */ } else if (!strncmp(line, ICMP_STATS_LINE, ICMP_STATS_PREFIX_LEN)) { sscanf(line, ICMP_STATS_LINE, &cached_icmp_mib.icmpInMsgs, &cached_icmp_mib.icmpInErrors, &cached_icmp_mib.icmpInDestUnreachs, &cached_icmp_mib.icmpInTimeExcds, &cached_icmp_mib.icmpInParmProbs, &cached_icmp_mib.icmpInSrcQuenchs, &cached_icmp_mib.icmpInRedirects, &cached_icmp_mib.icmpInEchos, &cached_icmp_mib.icmpInEchoReps, &cached_icmp_mib.icmpInTimestamps, &cached_icmp_mib.icmpInTimestampReps, &cached_icmp_mib.icmpInAddrMasks, &cached_icmp_mib.icmpInAddrMaskReps, &cached_icmp_mib.icmpOutMsgs, &cached_icmp_mib.icmpOutErrors, &cached_icmp_mib.icmpOutDestUnreachs, &cached_icmp_mib.icmpOutTimeExcds, &cached_icmp_mib.icmpOutParmProbs, &cached_icmp_mib.icmpOutSrcQuenchs, &cached_icmp_mib.icmpOutRedirects, &cached_icmp_mib.icmpOutEchos, &cached_icmp_mib.icmpOutEchoReps, &cached_icmp_mib.icmpOutTimestamps, &cached_icmp_mib.icmpOutTimestampReps, &cached_icmp_mib.icmpOutAddrMasks, &cached_icmp_mib.icmpOutAddrMaskReps); } else if (!strncmp(line, TCP_STATS_LINE, TCP_STATS_PREFIX_LEN)) { int ret = sscanf(line, TCP_STATS_LINE, &cached_tcp_mib.tcpRtoAlgorithm, &cached_tcp_mib.tcpRtoMin, &cached_tcp_mib.tcpRtoMax, &cached_tcp_mib.tcpMaxConn, &cached_tcp_mib.tcpActiveOpens, &cached_tcp_mib.tcpPassiveOpens, &cached_tcp_mib.tcpAttemptFails, &cached_tcp_mib.tcpEstabResets, &cached_tcp_mib.tcpCurrEstab, &cached_tcp_mib.tcpInSegs, &cached_tcp_mib.tcpOutSegs, &cached_tcp_mib.tcpRetransSegs, &cached_tcp_mib.tcpInErrs, &cached_tcp_mib.tcpOutRsts); cached_tcp_mib.tcpInErrsValid = (ret > 12) ? 1 : 0; cached_tcp_mib.tcpOutRstsValid = (ret > 13) ? 1 : 0; } else if (!strncmp(line, UDP_STATS_LINE, UDP_STATS_PREFIX_LEN)) { sscanf(line, UDP_STATS_LINE, &cached_udp_mib.udpInDatagrams, &cached_udp_mib.udpNoPorts, &cached_udp_mib.udpInErrors, &cached_udp_mib.udpOutDatagrams); } } fclose(in); /* * Tweak illegal values: * * valid values for ipForwarding are 1 == yup, 2 == nope * a 0 is forbidden, so patch: */ if (!cached_ip_mib.ipForwarding) cached_ip_mib.ipForwarding = 2; /* * 0 is illegal for tcpRtoAlgorithm * so assume `other' algorithm: */ if (!cached_tcp_mib.tcpRtoAlgorithm) cached_tcp_mib.tcpRtoAlgorithm = 1; return 0; }
long read_ip_stat(IP_STAT_STRUCTURE * ipstat, int magic) { long ret_value = 0; #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) int i; #endif #if !(defined (linux) || defined(solaris2)) static int ttl, forward; #endif #ifdef hpux11 int fd; struct nmparms p; unsigned int ulen; #endif #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) static int sname[4] = { CTL_NET, PF_INET, IPPROTO_IP, 0 }; size_t len; #endif #ifdef hpux11 if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) return (-1); /* error */ switch (magic) { case IPFORWARDING: p.objid = ID_ipForwarding; break; case IPDEFAULTTTL: p.objid = ID_ipDefaultTTL; break; case IPINRECEIVES: p.objid = ID_ipInReceives; break; case IPINHDRERRORS: p.objid = ID_ipInHdrErrors; break; case IPINADDRERRORS: p.objid = ID_ipInAddrErrors; break; case IPFORWDATAGRAMS: p.objid = ID_ipForwDatagrams; break; case IPINUNKNOWNPROTOS: p.objid = ID_ipInUnknownProtos; break; case IPINDISCARDS: p.objid = ID_ipInDiscards; break; case IPINDELIVERS: p.objid = ID_ipInDelivers; break; case IPOUTREQUESTS: p.objid = ID_ipOutRequests; break; case IPOUTDISCARDS: p.objid = ID_ipOutDiscards; break; case IPOUTNOROUTES: p.objid = ID_ipOutNoRoutes; break; case IPREASMTIMEOUT: p.objid = ID_ipReasmTimeout; break; case IPREASMREQDS: p.objid = ID_ipReasmReqds; break; case IPREASMOKS: p.objid = ID_ipReasmOKs; break; case IPREASMFAILS: p.objid = ID_ipReasmFails; break; case IPFRAGOKS: p.objid = ID_ipFragOKs; break; case IPFRAGFAILS: p.objid = ID_ipFragFails; break; case IPFRAGCREATES: p.objid = ID_ipFragCreates; break; case IPROUTEDISCARDS: p.objid = ID_ipRoutingDiscards; break; default: *ipstat = 0; close_mib(fd); return (0); } p.buffer = (void *) ipstat; ulen = sizeof(IP_STAT_STRUCTURE); p.len = &ulen; ret_value = get_mib_info(fd, &p); close_mib(fd); return (ret_value); /* 0: ok, < 0: error */ #else /* hpux11 */ if (ip_stats_cache_marker && (!atime_ready (ip_stats_cache_marker, IP_STATS_CACHE_TIMEOUT * 1000))) #if !(defined(linux) || defined(solaris2)) return ((magic == IPFORWARDING ? forward : (magic == IPDEFAULTTTL ? ttl : 0))); #else return 0; #endif if (ip_stats_cache_marker) atime_setMarker(ip_stats_cache_marker); else ip_stats_cache_marker = atime_newMarker(); #ifdef linux ret_value = linux_read_ip_stat(ipstat); #endif #ifdef solaris2 ret_value = getMibstat(MIB_IP, ipstat, sizeof(mib2_ip_t), GET_FIRST, &Get_everything, NULL); #endif #ifdef WIN32 ret_value = GetIpStatistics(ipstat); #endif #if !(defined(linux) || defined(solaris2) || defined(WIN32)) if (magic == IPFORWARDING) { #if defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS) len = sizeof i; sname[3] = IPCTL_FORWARDING; if (sysctl(sname, 4, &i, &len, 0, 0) < 0) forward = -1; else forward = (i ? 1 /* GATEWAY */ : 2 /* HOST */ ); #else if (!auto_nlist (IP_FORWARDING_SYMBOL, (char *) &ret_value, sizeof(ret_value))) forward = -1; else forward = (ret_value ? 1 /* GATEWAY */ : 2 /* HOST */ ); #endif if (forward == -1) { free(ip_stats_cache_marker); ip_stats_cache_marker = NULL; } return forward; } if (magic == IPDEFAULTTTL) { #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) len = sizeof i; sname[3] = IPCTL_DEFTTL; if (sysctl(sname, 4, &i, &len, 0, 0) < 0) ttl = -1; else ttl = i; #else if (!auto_nlist (TCP_TTL_SYMBOL, (char *) &ret_value, sizeof(ret_value))) ttl = -1; else ttl = ret_value; #endif if (ttl == -1) { free(ip_stats_cache_marker); ip_stats_cache_marker = NULL; } return ttl; } #ifdef HAVE_SYS_TCPIPSTATS_H ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, ipstat, sizeof *ipstat); #endif #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) len = sizeof *ipstat; sname[3] = IPCTL_STATS; ret_value = sysctl(sname, 4, ipstat, &len, 0, 0); #endif #ifdef IPSTAT_SYMBOL if (auto_nlist(IPSTAT_SYMBOL, (char *) ipstat, sizeof(*ipstat))) ret_value = 0; #endif #endif /* !(defined(linux) || defined(solaris2)) */ if (ret_value == -1) { free(ip_stats_cache_marker); ip_stats_cache_marker = NULL; } return ret_value; #endif /* hpux11 */ }