| /* |
| * Linux kernel interface |
| * |
| */ |
| |
| #include <config.h> |
| #include "mibincl.h" |
| #include "util_funcs.h" |
| #include "tools.h" |
| |
| #if HAVE_STRING_H |
| #include <string.h> |
| #endif |
| #include <sys/types.h> |
| #if HAVE_SYS_PARAM_H |
| #include <sys/param.h> |
| #endif |
| |
| #include "kernel_linux.h" |
| |
| struct ip_mib cached_ip_mib; |
| struct icmp_mib cached_icmp_mib; |
| struct tcp_mib cached_tcp_mib; |
| struct udp_mib cached_udp_mib; |
| |
| #define IP_STATS_LINE "Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu" |
| #define ICMP_STATS_LINE "Icmp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu" |
| #define TCP_STATS_LINE "Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu" |
| #define UDP_STATS_LINE "Udp: %lu %lu %lu %lu" |
| |
| #define IP_STATS_PREFIX_LEN 4 |
| #define ICMP_STATS_PREFIX_LEN 6 |
| #define TCP_STATS_PREFIX_LEN 5 |
| #define UDP_STATS_PREFIX_LEN 5 |
| |
| #ifndef MIB_STATS_CACHE_TIMEOUT |
| #define MIB_STATS_CACHE_TIMEOUT 5 |
| #endif |
| #ifndef LINUX_STATS_CACHE_TIMEOUT |
| #define LINUX_STATS_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT |
| #endif |
| marker_t linux_mibII_stats_cache_marker = NULL; |
| |
| 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; |
| } |
| |
| int |
| linux_read_ip_stat (struct ip_mib *ipstat) |
| { |
| memset ((char *) ipstat,(0), sizeof (*ipstat)); |
| if (linux_read_mibII_stats() == -1) |
| return -1; |
| memcpy( (char*)ipstat, (char*)&cached_ip_mib, sizeof (*ipstat)); |
| return 0; |
| } |
| |
| int |
| linux_read_icmp_stat (struct icmp_mib *icmpstat) |
| { |
| memset ((char *) icmpstat,(0), sizeof (*icmpstat)); |
| if (linux_read_mibII_stats() == -1) |
| return -1; |
| memcpy( (char*)icmpstat, (char*)&cached_icmp_mib, sizeof (*icmpstat)); |
| return 0; |
| } |
| |
| int |
| linux_read_tcp_stat (struct tcp_mib *tcpstat) |
| { |
| memset ((char *) tcpstat,(0), sizeof (*tcpstat)); |
| if (linux_read_mibII_stats() == -1) |
| return -1; |
| memcpy( (char*)tcpstat, (char*)&cached_tcp_mib, sizeof (*tcpstat)); |
| return 0; |
| } |
| |
| int |
| linux_read_udp_stat (struct udp_mib *udpstat) |
| { |
| memset ((char *) udpstat,(0), sizeof (*udpstat)); |
| if (linux_read_mibII_stats() == -1) |
| return -1; |
| memcpy( (char*)udpstat, (char*)&cached_udp_mib, sizeof (*udpstat)); |
| return 0; |
| } |