]> arthur.barton.de Git - netdata.git/blob - src/proc_net_snmp.c
added more fping alarms; added the ability to have alarms that never send CLEAR notif...
[netdata.git] / src / proc_net_snmp.c
1 #include "common.h"
2
3 #define RRD_TYPE_NET_SNMP           "ipv4"
4
5 struct netstat_columns {
6     char *name;
7     uint32_t hash;
8     unsigned long long value;
9     int multiplier;     // not needed everywhere
10     char *label;        // not needed everywhere
11 };
12
13 static struct netstat_columns ip_data[] = {
14 //    { "Forwarding", 0, 0, 1, NULL },
15 //    { "DefaultTTL", 0, 0, 1, NULL },
16     { "InReceives", 0, 0, 1, NULL },
17     { "InHdrErrors", 0, 0, 1, NULL },
18     { "InAddrErrors", 0, 0, 1, NULL },
19     { "ForwDatagrams", 0, 0, 1, NULL },
20     { "InUnknownProtos", 0, 0, 1, NULL },
21     { "InDiscards", 0, 0, 1, NULL },
22     { "InDelivers", 0, 0, 1, NULL },
23     { "OutRequests", 0, 0, 1, NULL },
24     { "OutDiscards", 0, 0, 1, NULL },
25     { "OutNoRoutes", 0, 0, 1, NULL },
26 //    { "ReasmTimeout", 0, 0, 1, NULL },
27     { "ReasmReqds", 0, 0, 1, NULL },
28     { "ReasmOKs", 0, 0, 1, NULL },
29     { "ReasmFails", 0, 0, 1, NULL },
30     { "FragOKs", 0, 0, 1, NULL },
31     { "FragFails", 0, 0, 1, NULL },
32     { "FragCreates", 0, 0, 1, NULL },
33     { NULL, 0, 0, 0, NULL }
34 };
35
36 static struct netstat_columns icmp_data[] = {
37     { "InMsgs", 0, 0, 1, NULL },
38     { "OutMsgs", 0, 0, -1, NULL },
39     { "InErrors", 0, 0, 1, NULL },
40     { "OutErrors", 0, 0, -1, NULL },
41     { "InCsumErrors", 0, 0, 1, NULL },
42
43     // all these are available in icmpmsg
44 //    { "InDestUnreachs", 0, 0, 1, NULL },
45 //    { "OutDestUnreachs", 0, 0, -1, NULL },
46 //    { "InTimeExcds", 0, 0, 1, NULL },
47 //    { "OutTimeExcds", 0, 0, -1, NULL },
48 //    { "InParmProbs", 0, 0, 1, NULL },
49 //    { "OutParmProbs", 0, 0, -1, NULL },
50 //    { "InSrcQuenchs", 0, 0, 1, NULL },
51 //    { "OutSrcQuenchs", 0, 0, -1, NULL },
52 //    { "InRedirects", 0, 0, 1, NULL },
53 //    { "OutRedirects", 0, 0, -1, NULL },
54 //    { "InEchos", 0, 0, 1, NULL },
55 //    { "OutEchos", 0, 0, -1, NULL },
56 //    { "InEchoReps", 0, 0, 1, NULL },
57 //    { "OutEchoReps", 0, 0, -1, NULL },
58 //    { "InTimestamps", 0, 0, 1, NULL },
59 //    { "OutTimestamps", 0, 0, -1, NULL },
60 //    { "InTimestampReps", 0, 0, 1, NULL },
61 //    { "OutTimestampReps", 0, 0, -1, NULL },
62 //    { "InAddrMasks", 0, 0, 1, NULL },
63 //    { "OutAddrMasks", 0, 0, -1, NULL },
64 //    { "InAddrMaskReps", 0, 0, 1, NULL },
65 //    { "OutAddrMaskReps", 0, 0, -1, NULL },
66
67     { NULL, 0, 0, 0, NULL }
68 };
69
70 static struct netstat_columns icmpmsg_data[] = {
71     { "InType0", 0, 0, 1, "InEchoReps" },
72     { "OutType0", 0, 0, -1, "OutEchoReps" },
73 //    { "InType1", 0, 0, 1, NULL },                   // unassigned
74 //    { "OutType1", 0, 0, -1, NULL },                 // unassigned
75 //    { "InType2", 0, 0, 1, NULL },                   // unassigned
76 //    { "OutType2", 0, 0, -1, NULL },                 // unassigned
77     { "InType3", 0, 0, 1, "InDestUnreachs" },
78     { "OutType3", 0, 0, -1, "OutDestUnreachs" },
79 //    { "InType4", 0, 0, 1, "InSrcQuenchs" },         // deprecated
80 //    { "OutType4", 0, 0, -1, "OutSrcQuenchs" },      // deprecated
81     { "InType5", 0, 0, 1, "InRedirects" },
82     { "OutType5", 0, 0, -1, "OutRedirects" },
83 //    { "InType6", 0, 0, 1, "InAlterHostAddr" },      // deprecated
84 //    { "OutType6", 0, 0, -1, "OutAlterHostAddr" },   // deprecated
85 //    { "InType7", 0, 0, 1, NULL },                   // unassigned
86 //    { "OutType7", 0, 0, -1, NULL },                 // unassigned
87     { "InType8", 0, 0, 1, "InEchos" },
88     { "OutType8", 0, 0, -1, "OutEchos" },
89     { "InType9", 0, 0, 1, "InRouterAdvert" },
90     { "OutType9", 0, 0, -1, "OutRouterAdvert" },
91     { "InType10", 0, 0, 1, "InRouterSelect" },
92     { "OutType10", 0, 0, -1, "OutRouterSelect" },
93     { "InType11", 0, 0, 1, "InTimeExcds" },
94     { "OutType11", 0, 0, -1, "OutTimeExcds" },
95     { "InType12", 0, 0, 1, "InParmProbs" },
96     { "OutType12", 0, 0, -1, "OutParmProbs" },
97     { "InType13", 0, 0, 1, "InTimestamps" },
98     { "OutType13", 0, 0, -1, "OutTimestamps" },
99     { "InType14", 0, 0, 1, "InTimestampReps" },
100     { "OutType14", 0, 0, -1, "OutTimestampReps" },
101 //    { "InType15", 0, 0, 1, "InInfos" },             // deprecated
102 //    { "OutType15", 0, 0, -1, "OutInfos" },          // deprecated
103 //    { "InType16", 0, 0, 1, "InInfoReps" },          // deprecated
104 //    { "OutType16", 0, 0, -1, "OutInfoReps" },       // deprecated
105 //    { "InType17", 0, 0, 1, "InAddrMasks" },         // deprecated
106 //    { "OutType17", 0, 0, -1, "OutAddrMasks" },      // deprecated
107 //    { "InType18", 0, 0, 1, "InAddrMaskReps" },      // deprecated
108 //    { "OutType18", 0, 0, -1, "OutAddrMaskReps" },   // deprecated
109 //    { "InType30", 0, 0, 1, "InTraceroute" },        // deprecated
110 //    { "OutType30", 0, 0, -1, "OutTraceroute" },     // deprecated
111     { NULL, 0, 0, 0, NULL }
112 };
113
114 static struct netstat_columns tcp_data[] = {
115 //    { "RtoAlgorithm", 0, 0, 1, NULL },
116 //    { "RtoMin", 0, 0, 1, NULL },
117 //    { "RtoMax", 0, 0, 1, NULL },
118 //    { "MaxConn", 0, 0, 1, NULL },
119     { "ActiveOpens", 0, 0, 1, NULL },
120     { "PassiveOpens", 0, 0, 1, NULL },
121     { "AttemptFails", 0, 0, 1, NULL },
122     { "EstabResets", 0, 0, 1, NULL },
123     { "CurrEstab", 0, 0, 1, NULL },
124     { "InSegs", 0, 0, 1, NULL },
125     { "OutSegs", 0, 0, 1, NULL },
126     { "RetransSegs", 0, 0, 1, NULL },
127     { "InErrs", 0, 0, 1, NULL },
128     { "OutRsts", 0, 0, 1, NULL },
129     { "InCsumErrors", 0, 0, 1, NULL },
130     { NULL, 0, 0, 0, NULL }
131 };
132
133 static struct netstat_columns udp_data[] = {
134     { "InDatagrams", 0, 0, 1, NULL },
135     { "NoPorts", 0, 0, 1, NULL },
136     { "InErrors", 0, 0, 1, NULL },
137     { "OutDatagrams", 0, 0, 1, NULL },
138     { "RcvbufErrors", 0, 0, 1, NULL },
139     { "SndbufErrors", 0, 0, 1, NULL },
140     { "InCsumErrors", 0, 0, 1, NULL },
141     { "IgnoredMulti", 0, 0, 1, NULL },
142     { NULL, 0, 0, 0, NULL }
143 };
144
145 static struct netstat_columns udplite_data[] = {
146     { "InDatagrams", 0, 0, 1, NULL },
147     { "NoPorts", 0, 0, 1, NULL },
148     { "InErrors", 0, 0, 1, NULL },
149     { "OutDatagrams", 0, 0, 1, NULL },
150     { "RcvbufErrors", 0, 0, 1, NULL },
151     { "SndbufErrors", 0, 0, 1, NULL },
152     { "InCsumErrors", 0, 0, 1, NULL },
153     { "IgnoredMulti", 0, 0, 1, NULL },
154     { NULL, 0, 0, 0, NULL }
155 };
156
157 static void hash_array(struct netstat_columns *nc) {
158     int i;
159
160     for(i = 0; nc[i].name ;i++)
161         nc[i].hash = simple_hash(nc[i].name);
162 }
163
164 static unsigned long long *netstat_columns_find(struct netstat_columns *nc, const char *name) {
165     uint32_t i, hash = simple_hash(name);
166
167     for(i = 0; nc[i].name ;i++)
168         if(unlikely(nc[i].hash == hash && !strcmp(nc[i].name, name)))
169             return &nc[i].value;
170
171     fatal("Cannot find key '%s' in /proc/net/snmp internal array.", name);
172 }
173
174 static void parse_line_pair(procfile *ff, struct netstat_columns *nc, size_t header_line, size_t values_line) {
175     size_t hwords = procfile_linewords(ff, header_line);
176     size_t vwords = procfile_linewords(ff, values_line);
177     size_t w, i;
178
179     if(unlikely(vwords > hwords)) {
180         error("File /proc/net/snmp on header line %zu has %zu words, but on value line %zu has %zu words.", header_line, hwords, values_line, vwords);
181         vwords = hwords;
182     }
183
184     for(w = 1; w < vwords ;w++) {
185         char *key = procfile_lineword(ff, header_line, w);
186         uint32_t hash = simple_hash(key);
187
188         for(i = 0 ; nc[i].name ;i++) {
189             if(unlikely(hash == nc[i].hash && !strcmp(key, nc[i].name))) {
190                 nc[i].value = str2ull(procfile_lineword(ff, values_line, w));
191                 break;
192             }
193         }
194     }
195 }
196
197 int do_proc_net_snmp(int update_every, usec_t dt) {
198     (void)dt;
199
200     static procfile *ff = NULL;
201     static int do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
202         do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1,
203         do_udp_packets = -1, do_udp_errors = -1, do_icmp_packets = -1, do_icmpmsg = -1, do_udplite_packets = -1;
204     static uint32_t hash_ip = 0, hash_icmp = 0, hash_tcp = 0, hash_udp = 0, hash_icmpmsg = 0, hash_udplite = 0;
205
206     //static unsigned long long *ip_Forwarding = NULL;
207     //static unsigned long long *ip_DefaultTTL = NULL;
208     static unsigned long long *ip_InReceives = NULL;
209     static unsigned long long *ip_InHdrErrors = NULL;
210     static unsigned long long *ip_InAddrErrors = NULL;
211     static unsigned long long *ip_ForwDatagrams = NULL;
212     static unsigned long long *ip_InUnknownProtos = NULL;
213     static unsigned long long *ip_InDiscards = NULL;
214     static unsigned long long *ip_InDelivers = NULL;
215     static unsigned long long *ip_OutRequests = NULL;
216     static unsigned long long *ip_OutDiscards = NULL;
217     static unsigned long long *ip_OutNoRoutes = NULL;
218     //static unsigned long long *ip_ReasmTimeout = NULL;
219     static unsigned long long *ip_ReasmReqds = NULL;
220     static unsigned long long *ip_ReasmOKs = NULL;
221     static unsigned long long *ip_ReasmFails = NULL;
222     static unsigned long long *ip_FragOKs = NULL;
223     static unsigned long long *ip_FragFails = NULL;
224     static unsigned long long *ip_FragCreates = NULL;
225
226     static unsigned long long *icmp_InMsgs = NULL;
227     static unsigned long long *icmp_OutMsgs = NULL;
228     static unsigned long long *icmp_InErrors = NULL;
229     static unsigned long long *icmp_OutErrors = NULL;
230     static unsigned long long *icmp_InCsumErrors = NULL;
231
232     //static unsigned long long *tcp_RtoAlgorithm = NULL;
233     //static unsigned long long *tcp_RtoMin = NULL;
234     //static unsigned long long *tcp_RtoMax = NULL;
235     //static unsigned long long *tcp_MaxConn = NULL;
236     static unsigned long long *tcp_ActiveOpens = NULL;
237     static unsigned long long *tcp_PassiveOpens = NULL;
238     static unsigned long long *tcp_AttemptFails = NULL;
239     static unsigned long long *tcp_EstabResets = NULL;
240     static unsigned long long *tcp_CurrEstab = NULL;
241     static unsigned long long *tcp_InSegs = NULL;
242     static unsigned long long *tcp_OutSegs = NULL;
243     static unsigned long long *tcp_RetransSegs = NULL;
244     static unsigned long long *tcp_InErrs = NULL;
245     static unsigned long long *tcp_OutRsts = NULL;
246     static unsigned long long *tcp_InCsumErrors = NULL;
247
248     static unsigned long long *udp_InDatagrams = NULL;
249     static unsigned long long *udp_NoPorts = NULL;
250     static unsigned long long *udp_InErrors = NULL;
251     static unsigned long long *udp_OutDatagrams = NULL;
252     static unsigned long long *udp_RcvbufErrors = NULL;
253     static unsigned long long *udp_SndbufErrors = NULL;
254     static unsigned long long *udp_InCsumErrors = NULL;
255     static unsigned long long *udp_IgnoredMulti = NULL;
256
257     static unsigned long long *udplite_InDatagrams = NULL;
258     static unsigned long long *udplite_NoPorts = NULL;
259     static unsigned long long *udplite_InErrors = NULL;
260     static unsigned long long *udplite_OutDatagrams = NULL;
261     static unsigned long long *udplite_RcvbufErrors = NULL;
262     static unsigned long long *udplite_SndbufErrors = NULL;
263     static unsigned long long *udplite_InCsumErrors = NULL;
264     static unsigned long long *udplite_IgnoredMulti = NULL;
265
266     if(unlikely(do_ip_packets == -1)) {
267         do_ip_packets       = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 packets", 1);
268         do_ip_fragsout      = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments sent", 1);
269         do_ip_fragsin       = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments assembly", 1);
270         do_ip_errors        = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 errors", 1);
271         do_tcp_sockets      = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP connections", 1);
272         do_tcp_packets      = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP packets", 1);
273         do_tcp_errors       = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP errors", 1);
274         do_tcp_handshake    = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP handshake issues", 1);
275         do_udp_packets      = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP packets", 1);
276         do_udp_errors       = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP errors", 1);
277         do_icmp_packets     = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 ICMP packets", 1);
278         do_icmpmsg          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 ICMP messages", 1);
279         do_udplite_packets  = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDPLite packets", 1);
280
281         hash_ip = simple_hash("Ip");
282         hash_tcp = simple_hash("Tcp");
283         hash_udp = simple_hash("Udp");
284         hash_icmp = simple_hash("Icmp");
285         hash_icmpmsg = simple_hash("IcmpMsg");
286         hash_udplite = simple_hash("UdpLite");
287
288         hash_array(ip_data);
289         hash_array(tcp_data);
290         hash_array(udp_data);
291         hash_array(icmp_data);
292         hash_array(icmpmsg_data);
293         hash_array(udplite_data);
294
295         //ip_Forwarding = netstat_columns_find(ip_data, "Forwarding");
296         //ip_DefaultTTL = netstat_columns_find(ip_data, "DefaultTTL");
297         ip_InReceives = netstat_columns_find(ip_data, "InReceives");
298         ip_InHdrErrors = netstat_columns_find(ip_data, "InHdrErrors");
299         ip_InAddrErrors = netstat_columns_find(ip_data, "InAddrErrors");
300         ip_ForwDatagrams = netstat_columns_find(ip_data, "ForwDatagrams");
301         ip_InUnknownProtos = netstat_columns_find(ip_data, "InUnknownProtos");
302         ip_InDiscards = netstat_columns_find(ip_data, "InDiscards");
303         ip_InDelivers = netstat_columns_find(ip_data, "InDelivers");
304         ip_OutRequests = netstat_columns_find(ip_data, "OutRequests");
305         ip_OutDiscards = netstat_columns_find(ip_data, "OutDiscards");
306         ip_OutNoRoutes = netstat_columns_find(ip_data, "OutNoRoutes");
307         //ip_ReasmTimeout = netstat_columns_find(ip_data, "ReasmTimeout");
308         ip_ReasmReqds = netstat_columns_find(ip_data, "ReasmReqds");
309         ip_ReasmOKs = netstat_columns_find(ip_data, "ReasmOKs");
310         ip_ReasmFails = netstat_columns_find(ip_data, "ReasmFails");
311         ip_FragOKs = netstat_columns_find(ip_data, "FragOKs");
312         ip_FragFails = netstat_columns_find(ip_data, "FragFails");
313         ip_FragCreates = netstat_columns_find(ip_data, "FragCreates");
314
315         icmp_InMsgs = netstat_columns_find(icmp_data, "InMsgs");
316         icmp_OutMsgs = netstat_columns_find(icmp_data, "OutMsgs");
317         icmp_InErrors = netstat_columns_find(icmp_data, "InErrors");
318         icmp_OutErrors = netstat_columns_find(icmp_data, "OutErrors");
319         icmp_InCsumErrors = netstat_columns_find(icmp_data, "InCsumErrors");
320
321         //tcp_RtoAlgorithm = netstat_columns_find(tcp_data, "RtoAlgorithm");
322         //tcp_RtoMin = netstat_columns_find(tcp_data, "RtoMin");
323         //tcp_RtoMax = netstat_columns_find(tcp_data, "RtoMax");
324         //tcp_MaxConn = netstat_columns_find(tcp_data, "MaxConn");
325         tcp_ActiveOpens = netstat_columns_find(tcp_data, "ActiveOpens");
326         tcp_PassiveOpens = netstat_columns_find(tcp_data, "PassiveOpens");
327         tcp_AttemptFails = netstat_columns_find(tcp_data, "AttemptFails");
328         tcp_EstabResets = netstat_columns_find(tcp_data, "EstabResets");
329         tcp_CurrEstab = netstat_columns_find(tcp_data, "CurrEstab");
330         tcp_InSegs = netstat_columns_find(tcp_data, "InSegs");
331         tcp_OutSegs = netstat_columns_find(tcp_data, "OutSegs");
332         tcp_RetransSegs = netstat_columns_find(tcp_data, "RetransSegs");
333         tcp_InErrs = netstat_columns_find(tcp_data, "InErrs");
334         tcp_OutRsts = netstat_columns_find(tcp_data, "OutRsts");
335         tcp_InCsumErrors = netstat_columns_find(tcp_data, "InCsumErrors");
336
337         udp_InDatagrams = netstat_columns_find(udp_data, "InDatagrams");
338         udp_NoPorts = netstat_columns_find(udp_data, "NoPorts");
339         udp_InErrors = netstat_columns_find(udp_data, "InErrors");
340         udp_OutDatagrams = netstat_columns_find(udp_data, "OutDatagrams");
341         udp_RcvbufErrors = netstat_columns_find(udp_data, "RcvbufErrors");
342         udp_SndbufErrors = netstat_columns_find(udp_data, "SndbufErrors");
343         udp_InCsumErrors = netstat_columns_find(udp_data, "InCsumErrors");
344         udp_IgnoredMulti = netstat_columns_find(udp_data, "IgnoredMulti");
345
346         udplite_InDatagrams = netstat_columns_find(udplite_data, "InDatagrams");
347         udplite_NoPorts = netstat_columns_find(udplite_data, "NoPorts");
348         udplite_InErrors = netstat_columns_find(udplite_data, "InErrors");
349         udplite_OutDatagrams = netstat_columns_find(udplite_data, "OutDatagrams");
350         udplite_RcvbufErrors = netstat_columns_find(udplite_data, "RcvbufErrors");
351         udplite_SndbufErrors = netstat_columns_find(udplite_data, "SndbufErrors");
352         udplite_InCsumErrors = netstat_columns_find(udplite_data, "InCsumErrors");
353         udplite_IgnoredMulti = netstat_columns_find(udplite_data, "IgnoredMulti");
354     }
355
356     if(unlikely(!ff)) {
357         char filename[FILENAME_MAX + 1];
358         snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/snmp");
359         ff = procfile_open(config_get("plugin:proc:/proc/net/snmp", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
360         if(unlikely(!ff)) return 1;
361     }
362
363     ff = procfile_readall(ff);
364     if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
365
366     size_t lines = procfile_lines(ff), l;
367     size_t words;
368
369     RRDSET *st;
370
371     for(l = 0; l < lines ;l++) {
372         char *key = procfile_lineword(ff, l, 0);
373         uint32_t hash = simple_hash(key);
374
375         if(unlikely(hash == hash_ip && strcmp(key, "Ip") == 0)) {
376             size_t h = l++;
377
378             if(strcmp(procfile_lineword(ff, l, 0), "Ip") != 0) {
379                 error("Cannot read Ip line from /proc/net/snmp.");
380                 break;
381             }
382
383             words = procfile_linewords(ff, l);
384             if(words < 3) {
385                 error("Cannot read /proc/net/snmp Ip line. Expected 3+ params, read %zu.", words);
386                 continue;
387             }
388
389             // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html
390             parse_line_pair(ff, ip_data, h, l);
391
392             // --------------------------------------------------------------------
393
394             if(do_ip_packets) {
395                 st = rrdset_find(RRD_TYPE_NET_SNMP ".packets");
396                 if(!st) {
397                     st = rrdset_create(RRD_TYPE_NET_SNMP, "packets", NULL, "packets", NULL, "IPv4 Packets", "packets/s", 3000, update_every, RRDSET_TYPE_LINE);
398
399                     rrddim_add(st, "InReceives",    "received",  1, 1, RRDDIM_INCREMENTAL);
400                     rrddim_add(st, "OutRequests",   "sent",     -1, 1, RRDDIM_INCREMENTAL);
401                     rrddim_add(st, "ForwDatagrams", "forwarded", 1, 1, RRDDIM_INCREMENTAL);
402                     rrddim_add(st, "InDelivers",    "delivered", 1, 1, RRDDIM_INCREMENTAL);
403                 }
404                 else rrdset_next(st);
405
406                 rrddim_set(st, "OutRequests",   *ip_OutRequests);
407                 rrddim_set(st, "InReceives",    *ip_InReceives);
408                 rrddim_set(st, "ForwDatagrams", *ip_ForwDatagrams);
409                 rrddim_set(st, "InDelivers",    *ip_InDelivers);
410                 rrdset_done(st);
411             }
412
413             // --------------------------------------------------------------------
414
415             if(do_ip_fragsout) {
416                 st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsout");
417                 if(!st) {
418                     st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsout", NULL, "fragments", NULL, "IPv4 Fragments Sent", "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
419                     st->isdetail = 1;
420
421                     rrddim_add(st, "FragOKs",     "ok",      1, 1, RRDDIM_INCREMENTAL);
422                     rrddim_add(st, "FragFails",   "failed", -1, 1, RRDDIM_INCREMENTAL);
423                     rrddim_add(st, "FragCreates", "created", 1, 1, RRDDIM_INCREMENTAL);
424                 }
425                 else rrdset_next(st);
426
427                 rrddim_set(st, "FragOKs",     *ip_FragOKs);
428                 rrddim_set(st, "FragFails",   *ip_FragFails);
429                 rrddim_set(st, "FragCreates", *ip_FragCreates);
430                 rrdset_done(st);
431             }
432
433             // --------------------------------------------------------------------
434
435             if(do_ip_fragsin) {
436                 st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsin");
437                 if(!st) {
438                     st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsin", NULL, "fragments", NULL, "IPv4 Fragments Reassembly", "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
439                     st->isdetail = 1;
440
441                     rrddim_add(st, "ReasmOKs",   "ok",      1, 1, RRDDIM_INCREMENTAL);
442                     rrddim_add(st, "ReasmFails", "failed", -1, 1, RRDDIM_INCREMENTAL);
443                     rrddim_add(st, "ReasmReqds", "all",     1, 1, RRDDIM_INCREMENTAL);
444                 }
445                 else rrdset_next(st);
446
447                 rrddim_set(st, "ReasmOKs",   *ip_ReasmOKs);
448                 rrddim_set(st, "ReasmFails", *ip_ReasmFails);
449                 rrddim_set(st, "ReasmReqds", *ip_ReasmReqds);
450                 rrdset_done(st);
451             }
452
453             // --------------------------------------------------------------------
454
455             if(do_ip_errors) {
456                 st = rrdset_find(RRD_TYPE_NET_SNMP ".errors");
457                 if(!st) {
458                     st = rrdset_create(RRD_TYPE_NET_SNMP, "errors", NULL, "errors", NULL, "IPv4 Errors", "packets/s", 3002, update_every, RRDSET_TYPE_LINE);
459                     st->isdetail = 1;
460
461                     rrddim_add(st, "InDiscards",      NULL,  1, 1, RRDDIM_INCREMENTAL);
462                     rrddim_add(st, "OutDiscards",     NULL, -1, 1, RRDDIM_INCREMENTAL);
463
464                     rrddim_add(st, "InHdrErrors",     NULL,  1, 1, RRDDIM_INCREMENTAL);
465                     rrddim_add(st, "OutNoRoutes",     NULL, -1, 1, RRDDIM_INCREMENTAL);
466
467                     rrddim_add(st, "InAddrErrors",    NULL,  1, 1, RRDDIM_INCREMENTAL);
468                     rrddim_add(st, "InUnknownProtos", NULL,  1, 1, RRDDIM_INCREMENTAL);
469                 }
470                 else rrdset_next(st);
471
472                 rrddim_set(st, "InDiscards",      *ip_InDiscards);
473                 rrddim_set(st, "OutDiscards",     *ip_OutDiscards);
474                 rrddim_set(st, "InHdrErrors",     *ip_InHdrErrors);
475                 rrddim_set(st, "InAddrErrors",    *ip_InAddrErrors);
476                 rrddim_set(st, "InUnknownProtos", *ip_InUnknownProtos);
477                 rrddim_set(st, "OutNoRoutes",     *ip_OutNoRoutes);
478                 rrdset_done(st);
479             }
480         }
481         else if(unlikely(hash == hash_icmp && strcmp(key, "Icmp") == 0)) {
482             size_t h = l++;
483
484             if(strcmp(procfile_lineword(ff, l, 0), "Icmp") != 0) {
485                 error("Cannot read Icmp line from /proc/net/snmp.");
486                 break;
487             }
488
489             words = procfile_linewords(ff, l);
490             if(words < 3) {
491                 error("Cannot read /proc/net/snmp Icmp line. Expected 3+ params, read %zu.", words);
492                 continue;
493             }
494
495             parse_line_pair(ff, icmp_data, h, l);
496
497             // --------------------------------------------------------------------
498
499             if(do_icmp_packets) {
500                 st = rrdset_find(RRD_TYPE_NET_SNMP ".icmp");
501                 if(!st) {
502                     st = rrdset_create(RRD_TYPE_NET_SNMP, "icmp", NULL, "icmp", NULL, "IPv4 ICMP Packets", "packets/s", 2602, update_every, RRDSET_TYPE_LINE);
503
504                     rrddim_add(st, "InMsgs",  "received",  1, 1, RRDDIM_INCREMENTAL);
505                     rrddim_add(st, "OutMsgs", "sent",     -1, 1, RRDDIM_INCREMENTAL);
506                 }
507                 else rrdset_next(st);
508
509                 rrddim_set(st, "InMsgs",  *icmp_InMsgs);
510                 rrddim_set(st, "OutMsgs", *icmp_OutMsgs);
511
512                 rrdset_done(st);
513
514                 st = rrdset_find(RRD_TYPE_NET_SNMP ".icmp_errors");
515                 if(!st) {
516                     st = rrdset_create(RRD_TYPE_NET_SNMP, "icmp_errors", NULL, "icmp", NULL, "IPv4 ICMP Errors", "packets/s", 2603, update_every, RRDSET_TYPE_LINE);
517
518                     rrddim_add(st, "InErrors",     NULL,  1, 1, RRDDIM_INCREMENTAL);
519                     rrddim_add(st, "OutErrors",    NULL, -1, 1, RRDDIM_INCREMENTAL);
520                     rrddim_add(st, "InCsumErrors", NULL,  1, 1, RRDDIM_INCREMENTAL);
521                 }
522                 else rrdset_next(st);
523
524                 rrddim_set(st, "InErrors",     *icmp_InErrors);
525                 rrddim_set(st, "OutErrors",    *icmp_OutErrors);
526                 rrddim_set(st, "InCsumErrors", *icmp_InCsumErrors);
527
528                 rrdset_done(st);
529             }
530         }
531         else if(unlikely(hash == hash_icmpmsg && strcmp(key, "IcmpMsg") == 0)) {
532             size_t h = l++;
533
534             if(strcmp(procfile_lineword(ff, l, 0), "IcmpMsg") != 0) {
535                 error("Cannot read IcmpMsg line from /proc/net/snmp.");
536                 break;
537             }
538
539             parse_line_pair(ff, icmpmsg_data, h, l);
540
541             // --------------------------------------------------------------------
542
543             if(do_icmpmsg) {
544                 int i;
545
546                 st = rrdset_find(RRD_TYPE_NET_SNMP ".icmpmsg");
547                 if(!st) {
548                     st = rrdset_create(RRD_TYPE_NET_SNMP, "icmpmsg", NULL, "icmp", NULL, "IPv4 ICMP Messsages", "packets/s", 2604, update_every, RRDSET_TYPE_LINE);
549
550                     for(i = 0; icmpmsg_data[i].name ;i++)
551                         rrddim_add(st, icmpmsg_data[i].name, icmpmsg_data[i].label,  icmpmsg_data[i].multiplier, 1, RRDDIM_INCREMENTAL);
552                 }
553                 else rrdset_next(st);
554
555                 for(i = 0; icmpmsg_data[i].name ;i++)
556                     rrddim_set(st, icmpmsg_data[i].name, icmpmsg_data[i].value);
557
558                 rrdset_done(st);
559             }
560         }
561         else if(unlikely(hash == hash_tcp && strcmp(key, "Tcp") == 0)) {
562             size_t h = l++;
563
564             if(strcmp(procfile_lineword(ff, l, 0), "Tcp") != 0) {
565                 error("Cannot read Tcp line from /proc/net/snmp.");
566                 break;
567             }
568
569             words = procfile_linewords(ff, l);
570             if(words < 3) {
571                 error("Cannot read /proc/net/snmp Tcp line. Expected 3+ params, read %zu.", words);
572                 continue;
573             }
574
575             parse_line_pair(ff, tcp_data, h, l);
576
577             // --------------------------------------------------------------------
578
579             // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
580             if(do_tcp_sockets) {
581                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcpsock");
582                 if(!st) {
583                     st = rrdset_create(RRD_TYPE_NET_SNMP, "tcpsock", NULL, "tcp", NULL, "IPv4 TCP Connections", "active connections", 2500, update_every, RRDSET_TYPE_LINE);
584
585                     rrddim_add(st, "CurrEstab", "connections", 1, 1, RRDDIM_ABSOLUTE);
586                 }
587                 else rrdset_next(st);
588
589                 rrddim_set(st, "CurrEstab", *tcp_CurrEstab);
590                 rrdset_done(st);
591             }
592
593             // --------------------------------------------------------------------
594
595             if(do_tcp_packets) {
596                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcppackets");
597                 if(!st) {
598                     st = rrdset_create(RRD_TYPE_NET_SNMP, "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets", "packets/s", 2600, update_every, RRDSET_TYPE_LINE);
599
600                     rrddim_add(st, "InSegs",  "received", 1, 1, RRDDIM_INCREMENTAL);
601                     rrddim_add(st, "OutSegs", "sent",    -1, 1, RRDDIM_INCREMENTAL);
602                 }
603                 else rrdset_next(st);
604
605                 rrddim_set(st, "InSegs",  *tcp_InSegs);
606                 rrddim_set(st, "OutSegs", *tcp_OutSegs);
607                 rrdset_done(st);
608             }
609
610             // --------------------------------------------------------------------
611
612             if(do_tcp_errors) {
613                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcperrors");
614                 if(!st) {
615                     st = rrdset_create(RRD_TYPE_NET_SNMP, "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors", "packets/s", 2700, update_every, RRDSET_TYPE_LINE);
616                     st->isdetail = 1;
617
618                     rrddim_add(st, "InErrs",       NULL,  1, 1, RRDDIM_INCREMENTAL);
619                     rrddim_add(st, "InCsumErrors", NULL,  1, 1, RRDDIM_INCREMENTAL);
620                     rrddim_add(st, "RetransSegs",  NULL, -1, 1, RRDDIM_INCREMENTAL);
621                 }
622                 else rrdset_next(st);
623
624                 rrddim_set(st, "InErrs",       *tcp_InErrs);
625                 rrddim_set(st, "InCsumErrors", *tcp_InCsumErrors);
626                 rrddim_set(st, "RetransSegs",  *tcp_RetransSegs);
627                 rrdset_done(st);
628             }
629
630             // --------------------------------------------------------------------
631
632             if(do_tcp_handshake) {
633                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcphandshake");
634                 if(!st) {
635                     st = rrdset_create(RRD_TYPE_NET_SNMP, "tcphandshake", NULL, "tcp", NULL, "IPv4 TCP Handshake Issues", "events/s", 2900, update_every, RRDSET_TYPE_LINE);
636                     st->isdetail = 1;
637
638                     rrddim_add(st, "EstabResets",  NULL,  1, 1, RRDDIM_INCREMENTAL);
639                     rrddim_add(st, "OutRsts",      NULL, -1, 1, RRDDIM_INCREMENTAL);
640                     rrddim_add(st, "ActiveOpens",  NULL,  1, 1, RRDDIM_INCREMENTAL);
641                     rrddim_add(st, "PassiveOpens", NULL,  1, 1, RRDDIM_INCREMENTAL);
642                     rrddim_add(st, "AttemptFails", NULL,  1, 1, RRDDIM_INCREMENTAL);
643                 }
644                 else rrdset_next(st);
645
646                 rrddim_set(st, "EstabResets",  *tcp_EstabResets);
647                 rrddim_set(st, "OutRsts",      *tcp_OutRsts);
648                 rrddim_set(st, "ActiveOpens",  *tcp_ActiveOpens);
649                 rrddim_set(st, "PassiveOpens", *tcp_PassiveOpens);
650                 rrddim_set(st, "AttemptFails", *tcp_AttemptFails);
651                 rrdset_done(st);
652             }
653         }
654         else if(unlikely(hash == hash_udp && strcmp(key, "Udp") == 0)) {
655             size_t h = l++;
656
657             if(strcmp(procfile_lineword(ff, l, 0), "Udp") != 0) {
658                 error("Cannot read Udp line from /proc/net/snmp.");
659                 break;
660             }
661
662             words = procfile_linewords(ff, l);
663             if(words < 3) {
664                 error("Cannot read /proc/net/snmp Udp line. Expected 3+ params, read %zu.", words);
665                 continue;
666             }
667
668             parse_line_pair(ff, udp_data, h, l);
669
670             // --------------------------------------------------------------------
671
672             // see http://net-snmp.sourceforge.net/docs/mibs/udp.html
673             if(do_udp_packets) {
674                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udppackets");
675                 if(!st) {
676                     st = rrdset_create(RRD_TYPE_NET_SNMP, "udppackets", NULL, "udp", NULL, "IPv4 UDP Packets", "packets/s", 2601, update_every, RRDSET_TYPE_LINE);
677
678                     rrddim_add(st, "InDatagrams",  "received", 1, 1, RRDDIM_INCREMENTAL);
679                     rrddim_add(st, "OutDatagrams", "sent",    -1, 1, RRDDIM_INCREMENTAL);
680                 }
681                 else rrdset_next(st);
682
683                 rrddim_set(st, "InDatagrams",  *udp_InDatagrams);
684                 rrddim_set(st, "OutDatagrams", *udp_OutDatagrams);
685                 rrdset_done(st);
686             }
687
688             // --------------------------------------------------------------------
689
690             if(do_udp_errors) {
691                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udperrors");
692                 if(!st) {
693                     st = rrdset_create(RRD_TYPE_NET_SNMP, "udperrors", NULL, "udp", NULL, "IPv4 UDP Errors", "events/s", 2701, update_every, RRDSET_TYPE_LINE);
694                     st->isdetail = 1;
695
696                     rrddim_add(st, "RcvbufErrors", NULL,  1, 1, RRDDIM_INCREMENTAL);
697                     rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRDDIM_INCREMENTAL);
698                     rrddim_add(st, "InErrors",     NULL,  1, 1, RRDDIM_INCREMENTAL);
699                     rrddim_add(st, "NoPorts",      NULL,  1, 1, RRDDIM_INCREMENTAL);
700                     rrddim_add(st, "InCsumErrors", NULL,  1, 1, RRDDIM_INCREMENTAL);
701                     rrddim_add(st, "IgnoredMulti", NULL,  1, 1, RRDDIM_INCREMENTAL);
702                 }
703                 else rrdset_next(st);
704
705                 rrddim_set(st, "InErrors",     *udp_InErrors);
706                 rrddim_set(st, "NoPorts",      *udp_NoPorts);
707                 rrddim_set(st, "RcvbufErrors", *udp_RcvbufErrors);
708                 rrddim_set(st, "SndbufErrors", *udp_SndbufErrors);
709                 rrddim_set(st, "InCsumErrors", *udp_InCsumErrors);
710                 rrddim_set(st, "IgnoredMulti", *udp_IgnoredMulti);
711                 rrdset_done(st);
712             }
713         }
714         else if(unlikely(hash == hash_udplite && strcmp(key, "UdpLite") == 0)) {
715             size_t h = l++;
716
717             if(strcmp(procfile_lineword(ff, l, 0), "UdpLite") != 0) {
718                 error("Cannot read UdpLite line from /proc/net/snmp.");
719                 break;
720             }
721
722             words = procfile_linewords(ff, l);
723             if(words < 3) {
724                 error("Cannot read /proc/net/snmp UdpLite line. Expected 3+ params, read %zu.", words);
725                 continue;
726             }
727
728             parse_line_pair(ff, udplite_data, h, l);
729
730             // --------------------------------------------------------------------
731
732             if(do_udplite_packets) {
733                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udplite");
734                 if(!st) {
735                     st = rrdset_create(RRD_TYPE_NET_SNMP, "udplite", NULL, "udplite", NULL, "IPv4 UDPLite Packets", "packets/s", 2603, update_every, RRDSET_TYPE_LINE);
736
737                     rrddim_add(st, "InDatagrams",  "received", 1, 1, RRDDIM_INCREMENTAL);
738                     rrddim_add(st, "OutDatagrams", "sent",    -1, 1, RRDDIM_INCREMENTAL);
739                 }
740                 else rrdset_next(st);
741
742                 rrddim_set(st, "InDatagrams",  *udplite_InDatagrams);
743                 rrddim_set(st, "OutDatagrams", *udplite_OutDatagrams);
744                 rrdset_done(st);
745
746                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udplite_errors");
747                 if(!st) {
748                     st = rrdset_create(RRD_TYPE_NET_SNMP, "udplite_errors", NULL, "udplite", NULL, "IPv4 UDPLite Errors", "packets/s", 2604, update_every, RRDSET_TYPE_LINE);
749
750                     rrddim_add(st, "RcvbufErrors", NULL,  1, 1, RRDDIM_INCREMENTAL);
751                     rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRDDIM_INCREMENTAL);
752                     rrddim_add(st, "NoPorts",      NULL,  1, 1, RRDDIM_INCREMENTAL);
753                     rrddim_add(st, "IgnoredMulti", NULL,  1, 1, RRDDIM_INCREMENTAL);
754                     rrddim_add(st, "InErrors",     NULL,  1, 1, RRDDIM_INCREMENTAL);
755                     rrddim_add(st, "InCsumErrors", NULL,  1, 1, RRDDIM_INCREMENTAL);
756                 }
757                 else rrdset_next(st);
758
759                 rrddim_set(st, "NoPorts",      *udplite_NoPorts);
760                 rrddim_set(st, "InErrors",     *udplite_InErrors);
761                 rrddim_set(st, "InCsumErrors", *udplite_InCsumErrors);
762                 rrddim_set(st, "RcvbufErrors", *udplite_RcvbufErrors);
763                 rrddim_set(st, "SndbufErrors", *udplite_SndbufErrors);
764                 rrddim_set(st, "IgnoredMulti", *udplite_IgnoredMulti);
765                 rrdset_done(st);
766             }
767         }
768     }
769
770     return 0;
771 }
772