diff options
Diffstat (limited to 'agent/mibgroup/mibII/kernel_linux.c')
-rw-r--r-- | agent/mibgroup/mibII/kernel_linux.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/agent/mibgroup/mibII/kernel_linux.c b/agent/mibgroup/mibII/kernel_linux.c new file mode 100644 index 0000000..bb6f867 --- /dev/null +++ b/agent/mibgroup/mibII/kernel_linux.c @@ -0,0 +1,221 @@ +/* + * Linux kernel interface + * + */ + +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +#include "util_funcs.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 UDP6_STATS_LINE "Udp6" + +#define IP_STATS_PREFIX_LEN 4 +#define ICMP_STATS_PREFIX_LEN 6 +#define TCP_STATS_PREFIX_LEN 5 +#define UDP_STATS_PREFIX_LEN 5 +#define UDP6_STATS_PREFIX_LEN 4 + + +int +linux_read_mibII_stats(void) +{ + FILE *in = fopen("/proc/net/snmp", "r"); +#ifdef NETSNMP_ENABLE_IPV6 + FILE *in6; + unsigned long value; +#endif + char line[1024]; + + if (!in) { + DEBUGMSGTL(("mibII/kernel_linux","Unable to open /proc/net/snmp")); + return -1; + } + + + 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); + +#ifdef NETSNMP_ENABLE_IPV6 + in6 = fopen("/proc/net/snmp6", "r"); + if (in6) { + + while (line == fgets(line, sizeof(line), in6)) { + + if (('U' != line[0]) || + (0 != strncmp(line, UDP6_STATS_LINE, UDP6_STATS_PREFIX_LEN))) + continue; + + sscanf(line, "%*s %lu" , &value); + + if ('O' == line[4]) /* Udp6OutDatagrams */ + cached_udp_mib.udpOutDatagrams += value; + else if ('N' == line[4]) /* Udp6NoPorts */ + cached_udp_mib.udpNoPorts += value; + else if ('D' == line[6]) /* Udp6InDatagrams */ + cached_udp_mib.udpInDatagrams += value; + else if ('E' == line[6]) /* Udp6InErrors */ + cached_udp_mib.udpInErrors += value; + + } + fclose(in6); + } else { + DEBUGMSGTL(("mibII/kernel_linux","Unable to open /proc/net/snmp6")); + } + +#endif + + /* + * 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; +} |