2 * Linux kernel interface
6 #include <net-snmp/net-snmp-config.h>
7 #include <net-snmp/net-snmp-includes.h>
8 #include <net-snmp/agent/net-snmp-agent-includes.h>
10 #include "util_funcs.h"
15 #include <sys/types.h>
17 #include <sys/param.h>
20 #include "kernel_linux.h"
22 struct ip_mib cached_ip_mib;
23 struct icmp_mib cached_icmp_mib;
24 struct tcp_mib cached_tcp_mib;
25 struct udp_mib cached_udp_mib;
27 #define IP_STATS_LINE "Ip: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu"
28 #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"
29 #define TCP_STATS_LINE "Tcp: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu"
30 #define UDP_STATS_LINE "Udp: %lu %lu %lu %lu"
32 #define IP_STATS_PREFIX_LEN 4
33 #define ICMP_STATS_PREFIX_LEN 6
34 #define TCP_STATS_PREFIX_LEN 5
35 #define UDP_STATS_PREFIX_LEN 5
37 #ifndef MIB_STATS_CACHE_TIMEOUT
38 #define MIB_STATS_CACHE_TIMEOUT 5
40 #ifndef LINUX_STATS_CACHE_TIMEOUT
41 #define LINUX_STATS_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT
43 marker_t linux_mibII_stats_cache_marker = NULL;
46 linux_read_mibII_stats(void)
48 FILE *in = fopen("/proc/net/snmp", "r");
52 free(linux_mibII_stats_cache_marker);
53 linux_mibII_stats_cache_marker = NULL;
57 if (linux_mibII_stats_cache_marker &&
59 (linux_mibII_stats_cache_marker,
60 LINUX_STATS_CACHE_TIMEOUT * 1000))) {
65 if (linux_mibII_stats_cache_marker)
66 atime_setMarker(linux_mibII_stats_cache_marker);
68 linux_mibII_stats_cache_marker = atime_newMarker();
71 while (line == fgets(line, sizeof(line), in)) {
72 if (!strncmp(line, IP_STATS_LINE, IP_STATS_PREFIX_LEN)) {
73 sscanf(line, IP_STATS_LINE,
74 &cached_ip_mib.ipForwarding,
75 &cached_ip_mib.ipDefaultTTL,
76 &cached_ip_mib.ipInReceives,
77 &cached_ip_mib.ipInHdrErrors,
78 &cached_ip_mib.ipInAddrErrors,
79 &cached_ip_mib.ipForwDatagrams,
80 &cached_ip_mib.ipInUnknownProtos,
81 &cached_ip_mib.ipInDiscards,
82 &cached_ip_mib.ipInDelivers,
83 &cached_ip_mib.ipOutRequests,
84 &cached_ip_mib.ipOutDiscards,
85 &cached_ip_mib.ipOutNoRoutes,
86 &cached_ip_mib.ipReasmTimeout,
87 &cached_ip_mib.ipReasmReqds,
88 &cached_ip_mib.ipReasmOKs,
89 &cached_ip_mib.ipReasmFails,
90 &cached_ip_mib.ipFragOKs,
91 &cached_ip_mib.ipFragFails,
92 &cached_ip_mib.ipFragCreates);
93 cached_ip_mib.ipRoutingDiscards = 0; /* XXX */
94 } else if (!strncmp(line, ICMP_STATS_LINE, ICMP_STATS_PREFIX_LEN)) {
95 sscanf(line, ICMP_STATS_LINE,
96 &cached_icmp_mib.icmpInMsgs,
97 &cached_icmp_mib.icmpInErrors,
98 &cached_icmp_mib.icmpInDestUnreachs,
99 &cached_icmp_mib.icmpInTimeExcds,
100 &cached_icmp_mib.icmpInParmProbs,
101 &cached_icmp_mib.icmpInSrcQuenchs,
102 &cached_icmp_mib.icmpInRedirects,
103 &cached_icmp_mib.icmpInEchos,
104 &cached_icmp_mib.icmpInEchoReps,
105 &cached_icmp_mib.icmpInTimestamps,
106 &cached_icmp_mib.icmpInTimestampReps,
107 &cached_icmp_mib.icmpInAddrMasks,
108 &cached_icmp_mib.icmpInAddrMaskReps,
109 &cached_icmp_mib.icmpOutMsgs,
110 &cached_icmp_mib.icmpOutErrors,
111 &cached_icmp_mib.icmpOutDestUnreachs,
112 &cached_icmp_mib.icmpOutTimeExcds,
113 &cached_icmp_mib.icmpOutParmProbs,
114 &cached_icmp_mib.icmpOutSrcQuenchs,
115 &cached_icmp_mib.icmpOutRedirects,
116 &cached_icmp_mib.icmpOutEchos,
117 &cached_icmp_mib.icmpOutEchoReps,
118 &cached_icmp_mib.icmpOutTimestamps,
119 &cached_icmp_mib.icmpOutTimestampReps,
120 &cached_icmp_mib.icmpOutAddrMasks,
121 &cached_icmp_mib.icmpOutAddrMaskReps);
122 } else if (!strncmp(line, TCP_STATS_LINE, TCP_STATS_PREFIX_LEN)) {
123 int ret = sscanf(line, TCP_STATS_LINE,
124 &cached_tcp_mib.tcpRtoAlgorithm,
125 &cached_tcp_mib.tcpRtoMin,
126 &cached_tcp_mib.tcpRtoMax,
127 &cached_tcp_mib.tcpMaxConn,
128 &cached_tcp_mib.tcpActiveOpens,
129 &cached_tcp_mib.tcpPassiveOpens,
130 &cached_tcp_mib.tcpAttemptFails,
131 &cached_tcp_mib.tcpEstabResets,
132 &cached_tcp_mib.tcpCurrEstab,
133 &cached_tcp_mib.tcpInSegs,
134 &cached_tcp_mib.tcpOutSegs,
135 &cached_tcp_mib.tcpRetransSegs,
136 &cached_tcp_mib.tcpInErrs,
137 &cached_tcp_mib.tcpOutRsts);
138 cached_tcp_mib.tcpInErrsValid = (ret > 12) ? 1 : 0;
139 cached_tcp_mib.tcpOutRstsValid = (ret > 13) ? 1 : 0;
140 } else if (!strncmp(line, UDP_STATS_LINE, UDP_STATS_PREFIX_LEN)) {
141 sscanf(line, UDP_STATS_LINE,
142 &cached_udp_mib.udpInDatagrams,
143 &cached_udp_mib.udpNoPorts,
144 &cached_udp_mib.udpInErrors,
145 &cached_udp_mib.udpOutDatagrams);
151 * Tweak illegal values:
153 * valid values for ipForwarding are 1 == yup, 2 == nope
154 * a 0 is forbidden, so patch:
156 if (!cached_ip_mib.ipForwarding)
157 cached_ip_mib.ipForwarding = 2;
160 * 0 is illegal for tcpRtoAlgorithm
161 * so assume `other' algorithm:
163 if (!cached_tcp_mib.tcpRtoAlgorithm)
164 cached_tcp_mib.tcpRtoAlgorithm = 1;
169 linux_read_ip_stat(struct ip_mib *ipstat)
171 memset((char *) ipstat, (0), sizeof(*ipstat));
172 if (linux_read_mibII_stats() == -1)
174 memcpy((char *) ipstat, (char *) &cached_ip_mib, sizeof(*ipstat));
179 linux_read_icmp_stat(struct icmp_mib *icmpstat)
181 memset((char *) icmpstat, (0), sizeof(*icmpstat));
182 if (linux_read_mibII_stats() == -1)
184 memcpy((char *) icmpstat, (char *) &cached_icmp_mib,
190 linux_read_tcp_stat(struct tcp_mib *tcpstat)
192 memset((char *) tcpstat, (0), sizeof(*tcpstat));
193 if (linux_read_mibII_stats() == -1)
195 memcpy((char *) tcpstat, (char *) &cached_tcp_mib, sizeof(*tcpstat));
200 linux_read_udp_stat(struct udp_mib *udpstat)
202 memset((char *) udpstat, (0), sizeof(*udpstat));
203 if (linux_read_mibII_stats() == -1)
205 memcpy((char *) udpstat, (char *) &cached_udp_mib, sizeof(*udpstat));