]> arthur.barton.de Git - netdata.git/blob - src/proc_net_snmp.c
Merge pull request #973 from ktsaou/master
[netdata.git] / src / proc_net_snmp.c
1 #include "common.h"
2
3 #define RRD_TYPE_NET_SNMP           "ipv4"
4 #define RRD_TYPE_NET_SNMP_LEN       strlen(RRD_TYPE_NET_SNMP)
5
6 int do_proc_net_snmp(int update_every, unsigned long long dt) {
7     (void)dt;
8
9     static procfile *ff = NULL;
10     static int do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
11         do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1,
12         do_udp_packets = -1, do_udp_errors = -1, do_icmp_packets = -1, do_icmpmsg = -1, do_udplite_packets = -1;
13     static uint32_t hash_ip = 0, hash_icmp = 0, hash_tcp = 0, hash_udp = 0, hash_icmpmsg = 0, hash_udplite = 0;
14
15     if(unlikely(do_ip_packets == -1)) {
16         do_ip_packets       = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 packets", 1);
17         do_ip_fragsout      = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments sent", 1);
18         do_ip_fragsin       = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments assembly", 1);
19         do_ip_errors        = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 errors", 1);
20         do_tcp_sockets      = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP connections", 1);
21         do_tcp_packets      = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP packets", 1);
22         do_tcp_errors       = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP errors", 1);
23         do_tcp_handshake    = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP handshake issues", 1);
24         do_udp_packets      = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP packets", 1);
25         do_udp_errors       = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP errors", 1);
26         do_icmp_packets     = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 ICMP packets", 1);
27         do_icmpmsg          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 ICMP messages", 1);
28         do_udplite_packets  = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDPLite packets", 1);
29
30         hash_ip = simple_hash("Ip");
31         hash_tcp = simple_hash("Tcp");
32         hash_udp = simple_hash("Udp");
33         hash_icmp = simple_hash("Icmp");
34         hash_icmpmsg = simple_hash("IcmpMsg");
35         hash_udplite = simple_hash("UdpLite");
36     }
37
38     if(unlikely(!ff)) {
39         char filename[FILENAME_MAX + 1];
40         snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/snmp");
41         ff = procfile_open(config_get("plugin:proc:/proc/net/snmp", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
42     }
43     if(unlikely(!ff)) return 1;
44
45     ff = procfile_readall(ff);
46     if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
47
48     uint32_t lines = procfile_lines(ff), l;
49     uint32_t words;
50
51     RRDSET *st;
52
53     for(l = 0; l < lines ;l++) {
54         char *key = procfile_lineword(ff, l, 0);
55         uint32_t hash = simple_hash(key);
56
57         if(unlikely(hash == hash_ip && strcmp(key, "Ip") == 0)) {
58             l++;
59
60             if(strcmp(procfile_lineword(ff, l, 0), "Ip") != 0) {
61                 error("Cannot read Ip line from /proc/net/snmp.");
62                 break;
63             }
64
65             words = procfile_linewords(ff, l);
66             if(words < 20) {
67                 error("Cannot read /proc/net/snmp Ip line. Expected 20 params, read %u.", words);
68                 continue;
69             }
70
71             // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html
72             unsigned long long Forwarding, DefaultTTL, InReceives, InHdrErrors, InAddrErrors, ForwDatagrams, InUnknownProtos, InDiscards, InDelivers,
73                 OutRequests, OutDiscards, OutNoRoutes, ReasmTimeout, ReasmReqds, ReasmOKs, ReasmFails, FragOKs, FragFails, FragCreates;
74
75             //Forwarding      = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
76             //DefaultTTL      = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
77             InReceives      = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
78             InHdrErrors     = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
79             InAddrErrors    = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
80             ForwDatagrams   = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
81             InUnknownProtos = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
82             InDiscards      = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
83             InDelivers      = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
84             OutRequests     = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
85             OutDiscards     = strtoull(procfile_lineword(ff, l, 11), NULL, 10);
86             OutNoRoutes     = strtoull(procfile_lineword(ff, l, 12), NULL, 10);
87             //ReasmTimeout    = strtoull(procfile_lineword(ff, l, 13), NULL, 10);
88             ReasmReqds      = strtoull(procfile_lineword(ff, l, 14), NULL, 10);
89             ReasmOKs        = strtoull(procfile_lineword(ff, l, 15), NULL, 10);
90             ReasmFails      = strtoull(procfile_lineword(ff, l, 16), NULL, 10);
91             FragOKs         = strtoull(procfile_lineword(ff, l, 17), NULL, 10);
92             FragFails       = strtoull(procfile_lineword(ff, l, 18), NULL, 10);
93             FragCreates     = strtoull(procfile_lineword(ff, l, 19), NULL, 10);
94
95             // these are not counters
96             (void)Forwarding;      // is forwarding enabled?
97             (void)DefaultTTL;      // the default ttl on packets
98             (void)ReasmTimeout;    // Reassembly timeout
99
100             // --------------------------------------------------------------------
101
102             if(do_ip_packets) {
103                 st = rrdset_find(RRD_TYPE_NET_SNMP ".packets");
104                 if(!st) {
105                     st = rrdset_create(RRD_TYPE_NET_SNMP, "packets", NULL, "packets", NULL, "IPv4 Packets", "packets/s", 3000, update_every, RRDSET_TYPE_LINE);
106
107                     rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL);
108                     rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL);
109                     rrddim_add(st, "forwarded", NULL, 1, 1, RRDDIM_INCREMENTAL);
110                     rrddim_add(st, "delivered", NULL, 1, 1, RRDDIM_INCREMENTAL);
111                 }
112                 else rrdset_next(st);
113
114                 rrddim_set(st, "sent", OutRequests);
115                 rrddim_set(st, "received", InReceives);
116                 rrddim_set(st, "forwarded", ForwDatagrams);
117                 rrddim_set(st, "delivered", InDelivers);
118                 rrdset_done(st);
119             }
120
121             // --------------------------------------------------------------------
122
123             if(do_ip_fragsout) {
124                 st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsout");
125                 if(!st) {
126                     st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsout", NULL, "fragments", NULL, "IPv4 Fragments Sent", "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
127                     st->isdetail = 1;
128
129                     rrddim_add(st, "ok", NULL, 1, 1, RRDDIM_INCREMENTAL);
130                     rrddim_add(st, "failed", NULL, -1, 1, RRDDIM_INCREMENTAL);
131                     rrddim_add(st, "all", NULL, 1, 1, RRDDIM_INCREMENTAL);
132                 }
133                 else rrdset_next(st);
134
135                 rrddim_set(st, "ok", FragOKs);
136                 rrddim_set(st, "failed", FragFails);
137                 rrddim_set(st, "all", FragCreates);
138                 rrdset_done(st);
139             }
140
141             // --------------------------------------------------------------------
142
143             if(do_ip_fragsin) {
144                 st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsin");
145                 if(!st) {
146                     st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsin", NULL, "fragments", NULL, "IPv4 Fragments Reassembly", "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
147                     st->isdetail = 1;
148
149                     rrddim_add(st, "ok", NULL, 1, 1, RRDDIM_INCREMENTAL);
150                     rrddim_add(st, "failed", NULL, -1, 1, RRDDIM_INCREMENTAL);
151                     rrddim_add(st, "all", NULL, 1, 1, RRDDIM_INCREMENTAL);
152                 }
153                 else rrdset_next(st);
154
155                 rrddim_set(st, "ok", ReasmOKs);
156                 rrddim_set(st, "failed", ReasmFails);
157                 rrddim_set(st, "all", ReasmReqds);
158                 rrdset_done(st);
159             }
160
161             // --------------------------------------------------------------------
162
163             if(do_ip_errors) {
164                 st = rrdset_find(RRD_TYPE_NET_SNMP ".errors");
165                 if(!st) {
166                     st = rrdset_create(RRD_TYPE_NET_SNMP, "errors", NULL, "errors", NULL, "IPv4 Errors", "packets/s", 3002, update_every, RRDSET_TYPE_LINE);
167                     st->isdetail = 1;
168
169                     rrddim_add(st, "InDiscards", NULL, 1, 1, RRDDIM_INCREMENTAL);
170                     rrddim_add(st, "OutDiscards", NULL, -1, 1, RRDDIM_INCREMENTAL);
171
172                     rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRDDIM_INCREMENTAL);
173                     rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRDDIM_INCREMENTAL);
174
175                     rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRDDIM_INCREMENTAL);
176                     rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRDDIM_INCREMENTAL);
177                 }
178                 else rrdset_next(st);
179
180                 rrddim_set(st, "InDiscards", InDiscards);
181                 rrddim_set(st, "OutDiscards", OutDiscards);
182                 rrddim_set(st, "InHdrErrors", InHdrErrors);
183                 rrddim_set(st, "InAddrErrors", InAddrErrors);
184                 rrddim_set(st, "InUnknownProtos", InUnknownProtos);
185                 rrddim_set(st, "OutNoRoutes", OutNoRoutes);
186                 rrdset_done(st);
187             }
188         }
189         else if(unlikely(hash == hash_icmp && strcmp(key, "Icmp") == 0)) {
190             l++;
191
192             if(strcmp(procfile_lineword(ff, l, 0), "Icmp") != 0) {
193                 error("Cannot read Icmp line from /proc/net/snmp.");
194                 break;
195             }
196
197             words = procfile_linewords(ff, l);
198             if(words < 28) {
199                 error("Cannot read /proc/net/snmp Icmp line. Expected 28 params, read %u.", words);
200                 continue;
201             }
202
203             unsigned long long InMsgs, InErrors, InCsumErrors, InDestUnreachs, InTimeExcds, InParmProbs, InSrcQuenchs, InRedirects, InEchos,
204                 InEchoReps, InTimestamps, InTimestampReps, InAddrMasks, InAddrMaskReps, OutMsgs, OutErrors, OutDestUnreachs, OutTimeExcds,
205                 OutParmProbs, OutSrcQuenchs, OutRedirects, OutEchos, OutEchoReps, OutTimestamps, OutTimestampReps, OutAddrMasks, OutAddrMaskReps;
206
207             InMsgs           = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
208             InErrors         = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
209             InCsumErrors     = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
210             InDestUnreachs   = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
211             InTimeExcds      = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
212             InParmProbs      = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
213             InSrcQuenchs     = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
214             InRedirects      = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
215             InEchos          = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
216             InEchoReps       = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
217             InTimestamps     = strtoull(procfile_lineword(ff, l, 11), NULL, 10);
218             InTimestampReps  = strtoull(procfile_lineword(ff, l, 12), NULL, 10);
219             InAddrMasks      = strtoull(procfile_lineword(ff, l, 13), NULL, 10);
220             InAddrMaskReps   = strtoull(procfile_lineword(ff, l, 14), NULL, 10);
221
222             OutMsgs          = strtoull(procfile_lineword(ff, l, 15), NULL, 10);
223             OutErrors        = strtoull(procfile_lineword(ff, l, 16), NULL, 10);
224             OutDestUnreachs  = strtoull(procfile_lineword(ff, l, 17), NULL, 10);
225             OutTimeExcds     = strtoull(procfile_lineword(ff, l, 18), NULL, 10);
226             OutParmProbs     = strtoull(procfile_lineword(ff, l, 19), NULL, 10);
227             OutSrcQuenchs    = strtoull(procfile_lineword(ff, l, 20), NULL, 10);
228             OutRedirects     = strtoull(procfile_lineword(ff, l, 21), NULL, 10);
229             OutEchos         = strtoull(procfile_lineword(ff, l, 22), NULL, 10);
230             OutEchoReps      = strtoull(procfile_lineword(ff, l, 23), NULL, 10);
231             OutTimestamps    = strtoull(procfile_lineword(ff, l, 24), NULL, 10);
232             OutTimestampReps = strtoull(procfile_lineword(ff, l, 25), NULL, 10);
233             OutAddrMasks     = strtoull(procfile_lineword(ff, l, 26), NULL, 10);
234             OutAddrMaskReps  = strtoull(procfile_lineword(ff, l, 27), NULL, 10);
235
236             // --------------------------------------------------------------------
237
238             if(do_icmp_packets) {
239                 st = rrdset_find(RRD_TYPE_NET_SNMP ".icmp");
240                 if(!st) {
241                     st = rrdset_create(RRD_TYPE_NET_SNMP, "icmp", NULL, "icmp", NULL, "IPv4 ICMP Packets", "packets/s", 2602, update_every, RRDSET_TYPE_LINE);
242
243                     rrddim_add(st, "InMsgs",           NULL,  1, 1, RRDDIM_INCREMENTAL);
244                     rrddim_add(st, "OutMsgs",          NULL, -1, 1, RRDDIM_INCREMENTAL);
245
246                     rrddim_add(st, "InErrors",         NULL,  1, 1, RRDDIM_INCREMENTAL);
247                     rrddim_add(st, "OutErrors",        NULL, -1, 1, RRDDIM_INCREMENTAL);
248
249                     rrddim_add(st, "InDestUnreachs",   NULL,  1, 1, RRDDIM_INCREMENTAL);
250                     rrddim_add(st, "OutDestUnreachs",  NULL, -1, 1, RRDDIM_INCREMENTAL);
251
252                     rrddim_add(st, "InTimeExcds",      NULL,  1, 1, RRDDIM_INCREMENTAL);
253                     rrddim_add(st, "OutTimeExcds",     NULL, -1, 1, RRDDIM_INCREMENTAL);
254
255                     rrddim_add(st, "InParmProbs",      NULL,  1, 1, RRDDIM_INCREMENTAL);
256                     rrddim_add(st, "OutParmProbs",     NULL, -1, 1, RRDDIM_INCREMENTAL);
257
258                     rrddim_add(st, "InSrcQuenchs",     NULL,  1, 1, RRDDIM_INCREMENTAL);
259                     rrddim_add(st, "OutSrcQuenchs",    NULL, -1, 1, RRDDIM_INCREMENTAL);
260
261                     rrddim_add(st, "InRedirects",      NULL,  1, 1, RRDDIM_INCREMENTAL);
262                     rrddim_add(st, "OutRedirects",     NULL, -1, 1, RRDDIM_INCREMENTAL);
263
264                     rrddim_add(st, "InEchos",          NULL,  1, 1, RRDDIM_INCREMENTAL);
265                     rrddim_add(st, "OutEchos",         NULL, -1, 1, RRDDIM_INCREMENTAL);
266
267                     rrddim_add(st, "InEchoReps",       NULL,  1, 1, RRDDIM_INCREMENTAL);
268                     rrddim_add(st, "OutEchoReps",      NULL, -1, 1, RRDDIM_INCREMENTAL);
269
270                     rrddim_add(st, "InTimestamps",     NULL,  1, 1, RRDDIM_INCREMENTAL);
271                     rrddim_add(st, "OutTimestamps",    NULL, -1, 1, RRDDIM_INCREMENTAL);
272
273                     rrddim_add(st, "InTimestampReps",  NULL,  1, 1, RRDDIM_INCREMENTAL);
274                     rrddim_add(st, "OutTimestampReps", NULL, -1, 1, RRDDIM_INCREMENTAL);
275
276                     rrddim_add(st, "InAddrMasks",      NULL,  1, 1, RRDDIM_INCREMENTAL);
277                     rrddim_add(st, "OutAddrMasks",     NULL, -1, 1, RRDDIM_INCREMENTAL);
278
279                     rrddim_add(st, "InAddrMaskReps",   NULL,  1, 1, RRDDIM_INCREMENTAL);
280                     rrddim_add(st, "OutAddrMaskReps",  NULL, -1, 1, RRDDIM_INCREMENTAL);
281
282                     rrddim_add(st, "InCsumErrors",     NULL, 1, 1, RRDDIM_INCREMENTAL);
283                 }
284                 else rrdset_next(st);
285
286                 rrddim_set(st, "InMsgs", InMsgs);
287                 rrddim_set(st, "InErrors", InErrors);
288                 rrddim_set(st, "InCsumErrors", InCsumErrors);
289                 rrddim_set(st, "InDestUnreachs", InDestUnreachs);
290                 rrddim_set(st, "InTimeExcds", InTimeExcds);
291                 rrddim_set(st, "InParmProbs", InParmProbs);
292                 rrddim_set(st, "InSrcQuenchs", InSrcQuenchs);
293                 rrddim_set(st, "InRedirects", InRedirects);
294                 rrddim_set(st, "InEchos", InEchos);
295                 rrddim_set(st, "InEchoReps", InEchoReps);
296                 rrddim_set(st, "InTimestamps", InTimestamps);
297                 rrddim_set(st, "InTimestampReps", InTimestampReps);
298                 rrddim_set(st, "InAddrMasks", InAddrMasks);
299                 rrddim_set(st, "InAddrMaskReps", InAddrMaskReps);
300
301                 rrddim_set(st, "OutMsgs", OutMsgs);
302                 rrddim_set(st, "OutErrors", OutErrors);
303                 rrddim_set(st, "OutDestUnreachs", OutDestUnreachs);
304                 rrddim_set(st, "OutTimeExcds", OutTimeExcds);
305                 rrddim_set(st, "OutParmProbs", OutParmProbs);
306                 rrddim_set(st, "OutSrcQuenchs", OutSrcQuenchs);
307                 rrddim_set(st, "OutRedirects", OutRedirects);
308                 rrddim_set(st, "OutEchos", OutEchos);
309                 rrddim_set(st, "OutEchoReps", OutEchoReps);
310                 rrddim_set(st, "OutTimestamps", OutTimestamps);
311                 rrddim_set(st, "OutTimestampReps", OutTimestampReps);
312                 rrddim_set(st, "OutAddrMasks", OutAddrMasks);
313                 rrddim_set(st, "OutAddrMaskReps", OutAddrMaskReps);
314                 rrdset_done(st);
315             }
316         }
317         else if(unlikely(hash == hash_icmpmsg && strcmp(key, "IcmpMsg") == 0)) {
318             l++;
319
320             if(strcmp(procfile_lineword(ff, l, 0), "IcmpMsg") != 0) {
321                 error("Cannot read IcmpMsg line from /proc/net/snmp.");
322                 break;
323             }
324
325             words = procfile_linewords(ff, l);
326             if(words < 12) {
327                 error("Cannot read /proc/net/snmp IcmpMsg line. Expected 12 params, read %u.", words);
328                 continue;
329             }
330
331             unsigned long long InType0, InType3, InType4, InType5, InType8, InType11, OutType0, OutType3, OutType5, OutType8, OutType11;
332
333             InType0   = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
334             InType3   = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
335             InType4   = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
336             InType5   = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
337             InType8   = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
338             InType11  = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
339
340             OutType0  = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
341             OutType3  = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
342             OutType5  = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
343             OutType8  = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
344             OutType11 = strtoull(procfile_lineword(ff, l, 11), NULL, 10);
345
346             // --------------------------------------------------------------------
347
348             if(do_icmpmsg) {
349                 st = rrdset_find(RRD_TYPE_NET_SNMP ".icmpmsg");
350                 if(!st) {
351                     st = rrdset_create(RRD_TYPE_NET_SNMP, "icmpmsg", NULL, "icmp", NULL, "IPv4 ICMP Messsages", "packets/s", 2603, update_every, RRDSET_TYPE_LINE);
352
353                     rrddim_add(st, "InType0",  NULL,  1, 1, RRDDIM_INCREMENTAL);
354                     rrddim_add(st, "OutType0", NULL, -1, 1, RRDDIM_INCREMENTAL);
355
356                     rrddim_add(st, "InType3",  NULL,  1, 1, RRDDIM_INCREMENTAL);
357                     rrddim_add(st, "OutType3", NULL, -1, 1, RRDDIM_INCREMENTAL);
358
359                     rrddim_add(st, "InType5",  NULL,  1, 1, RRDDIM_INCREMENTAL);
360                     rrddim_add(st, "OutType5", NULL, -1, 1, RRDDIM_INCREMENTAL);
361
362                     rrddim_add(st, "InType8",  NULL,  1, 1, RRDDIM_INCREMENTAL);
363                     rrddim_add(st, "OutType8", NULL, -1, 1, RRDDIM_INCREMENTAL);
364
365                     rrddim_add(st, "InType11",  NULL,  1, 1, RRDDIM_INCREMENTAL);
366                     rrddim_add(st, "OutType11", NULL, -1, 1, RRDDIM_INCREMENTAL);
367
368                     rrddim_add(st, "InType4", NULL, 1, 1, RRDDIM_INCREMENTAL);
369                 }
370                 else rrdset_next(st);
371
372                 rrddim_set(st, "InType0", InType0);
373                 rrddim_set(st, "InType3", InType3);
374                 rrddim_set(st, "InType4", InType4);
375                 rrddim_set(st, "InType5", InType5);
376                 rrddim_set(st, "InType8", InType8);
377                 rrddim_set(st, "InType11", InType11);
378
379                 rrddim_set(st, "OutType0", OutType0);
380                 rrddim_set(st, "OutType3", OutType3);
381                 rrddim_set(st, "OutType5", OutType5);
382                 rrddim_set(st, "OutType8", OutType8);
383                 rrddim_set(st, "OutType11", OutType11);
384                 rrdset_done(st);
385             }
386         }
387         else if(unlikely(hash == hash_tcp && strcmp(key, "Tcp") == 0)) {
388             l++;
389
390             if(strcmp(procfile_lineword(ff, l, 0), "Tcp") != 0) {
391                 error("Cannot read Tcp line from /proc/net/snmp.");
392                 break;
393             }
394
395             words = procfile_linewords(ff, l);
396             if(words < 15) {
397                 error("Cannot read /proc/net/snmp Tcp line. Expected 15 params, read %u.", words);
398                 continue;
399             }
400
401             unsigned long long RtoAlgorithm, RtoMin, RtoMax, MaxConn, ActiveOpens, PassiveOpens, AttemptFails, EstabResets,
402                 CurrEstab, InSegs, OutSegs, RetransSegs, InErrs, OutRsts;
403
404             //RtoAlgorithm    = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
405             //RtoMin          = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
406             //RtoMax          = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
407             //MaxConn         = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
408             ActiveOpens     = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
409             PassiveOpens    = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
410             AttemptFails    = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
411             EstabResets     = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
412             CurrEstab       = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
413             InSegs          = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
414             OutSegs         = strtoull(procfile_lineword(ff, l, 11), NULL, 10);
415             RetransSegs     = strtoull(procfile_lineword(ff, l, 12), NULL, 10);
416             InErrs          = strtoull(procfile_lineword(ff, l, 13), NULL, 10);
417             OutRsts         = strtoull(procfile_lineword(ff, l, 14), NULL, 10);
418
419             // these are not counters
420             (void)RtoAlgorithm;
421             (void)RtoMin;
422             (void)RtoMax;
423             (void)MaxConn;
424
425             // --------------------------------------------------------------------
426
427             // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
428             if(do_tcp_sockets) {
429                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcpsock");
430                 if(!st) {
431                     st = rrdset_create(RRD_TYPE_NET_SNMP, "tcpsock", NULL, "tcp", NULL, "IPv4 TCP Connections", "active connections", 2500, update_every, RRDSET_TYPE_LINE);
432
433                     rrddim_add(st, "connections", NULL, 1, 1, RRDDIM_ABSOLUTE);
434                 }
435                 else rrdset_next(st);
436
437                 rrddim_set(st, "connections", CurrEstab);
438                 rrdset_done(st);
439             }
440
441             // --------------------------------------------------------------------
442
443             if(do_tcp_packets) {
444                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcppackets");
445                 if(!st) {
446                     st = rrdset_create(RRD_TYPE_NET_SNMP, "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets", "packets/s", 2600, update_every, RRDSET_TYPE_LINE);
447
448                     rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL);
449                     rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL);
450                 }
451                 else rrdset_next(st);
452
453                 rrddim_set(st, "received", InSegs);
454                 rrddim_set(st, "sent", OutSegs);
455                 rrdset_done(st);
456             }
457
458             // --------------------------------------------------------------------
459
460             if(do_tcp_errors) {
461                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcperrors");
462                 if(!st) {
463                     st = rrdset_create(RRD_TYPE_NET_SNMP, "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors", "packets/s", 2700, update_every, RRDSET_TYPE_LINE);
464                     st->isdetail = 1;
465
466                     rrddim_add(st, "InErrs", NULL, 1, 1, RRDDIM_INCREMENTAL);
467                     rrddim_add(st, "RetransSegs", NULL, -1, 1, RRDDIM_INCREMENTAL);
468                 }
469                 else rrdset_next(st);
470
471                 rrddim_set(st, "InErrs", InErrs);
472                 rrddim_set(st, "RetransSegs", RetransSegs);
473                 rrdset_done(st);
474             }
475
476             // --------------------------------------------------------------------
477
478             if(do_tcp_handshake) {
479                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcphandshake");
480                 if(!st) {
481                     st = rrdset_create(RRD_TYPE_NET_SNMP, "tcphandshake", NULL, "tcp", NULL, "IPv4 TCP Handshake Issues", "events/s", 2900, update_every, RRDSET_TYPE_LINE);
482                     st->isdetail = 1;
483
484                     rrddim_add(st, "EstabResets", NULL, 1, 1, RRDDIM_INCREMENTAL);
485                     rrddim_add(st, "OutRsts", NULL, -1, 1, RRDDIM_INCREMENTAL);
486                     rrddim_add(st, "ActiveOpens", NULL, 1, 1, RRDDIM_INCREMENTAL);
487                     rrddim_add(st, "PassiveOpens", NULL, 1, 1, RRDDIM_INCREMENTAL);
488                     rrddim_add(st, "AttemptFails", NULL, 1, 1, RRDDIM_INCREMENTAL);
489                 }
490                 else rrdset_next(st);
491
492                 rrddim_set(st, "EstabResets", EstabResets);
493                 rrddim_set(st, "OutRsts", OutRsts);
494                 rrddim_set(st, "ActiveOpens", ActiveOpens);
495                 rrddim_set(st, "PassiveOpens", PassiveOpens);
496                 rrddim_set(st, "AttemptFails", AttemptFails);
497                 rrdset_done(st);
498             }
499         }
500         else if(unlikely(hash == hash_udp && strcmp(key, "Udp") == 0)) {
501             l++;
502
503             if(strcmp(procfile_lineword(ff, l, 0), "Udp") != 0) {
504                 error("Cannot read Udp line from /proc/net/snmp.");
505                 break;
506             }
507
508             words = procfile_linewords(ff, l);
509             if(words < 7) {
510                 error("Cannot read /proc/net/snmp Udp line. Expected 7 params, read %u.", words);
511                 continue;
512             }
513
514             unsigned long long InDatagrams, NoPorts, InErrors, OutDatagrams, RcvbufErrors, SndbufErrors;
515
516             InDatagrams     = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
517             NoPorts         = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
518             InErrors        = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
519             OutDatagrams    = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
520             RcvbufErrors    = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
521             SndbufErrors    = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
522
523             // --------------------------------------------------------------------
524
525             // see http://net-snmp.sourceforge.net/docs/mibs/udp.html
526             if(do_udp_packets) {
527                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udppackets");
528                 if(!st) {
529                     st = rrdset_create(RRD_TYPE_NET_SNMP, "udppackets", NULL, "udp", NULL, "IPv4 UDP Packets", "packets/s", 2601, update_every, RRDSET_TYPE_LINE);
530
531                     rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL);
532                     rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL);
533                 }
534                 else rrdset_next(st);
535
536                 rrddim_set(st, "received", InDatagrams);
537                 rrddim_set(st, "sent", OutDatagrams);
538                 rrdset_done(st);
539             }
540
541             // --------------------------------------------------------------------
542
543             if(do_udp_errors) {
544                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udperrors");
545                 if(!st) {
546                     st = rrdset_create(RRD_TYPE_NET_SNMP, "udperrors", NULL, "udp", NULL, "IPv4 UDP Errors", "events/s", 2701, update_every, RRDSET_TYPE_LINE);
547                     st->isdetail = 1;
548
549                     rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRDDIM_INCREMENTAL);
550                     rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRDDIM_INCREMENTAL);
551                     rrddim_add(st, "InErrors", NULL, 1, 1, RRDDIM_INCREMENTAL);
552                     rrddim_add(st, "NoPorts", NULL, 1, 1, RRDDIM_INCREMENTAL);
553                 }
554                 else rrdset_next(st);
555
556                 rrddim_set(st, "InErrors", InErrors);
557                 rrddim_set(st, "NoPorts", NoPorts);
558                 rrddim_set(st, "RcvbufErrors", RcvbufErrors);
559                 rrddim_set(st, "SndbufErrors", SndbufErrors);
560                 rrdset_done(st);
561             }
562         }
563         else if(unlikely(hash == hash_udplite && strcmp(key, "UdpLite") == 0)) {
564             l++;
565
566             if(strcmp(procfile_lineword(ff, l, 0), "UdpLite") != 0) {
567                 error("Cannot read UdpLite line from /proc/net/snmp.");
568                 break;
569             }
570
571             words = procfile_linewords(ff, l);
572             if(words < 9) {
573                 error("Cannot read /proc/net/snmp UdpLite line. Expected 9 params, read %u.", words);
574                 continue;
575             }
576
577             unsigned long long InDatagrams, NoPorts, InErrors, OutDatagrams, RcvbufErrors, SndbufErrors, InCsumErrors, IgnoredMulti;
578
579             InDatagrams  = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
580             NoPorts      = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
581             InErrors     = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
582             OutDatagrams = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
583             RcvbufErrors = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
584             SndbufErrors = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
585             InCsumErrors = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
586             IgnoredMulti = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
587
588             // --------------------------------------------------------------------
589
590             if(do_udplite_packets) {
591                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udplite");
592                 if(!st) {
593                     st = rrdset_create(RRD_TYPE_NET_SNMP, "udplite", NULL, "udplite", NULL, "IPv4 UDPLite Packets", "packets/s", 2603, update_every, RRDSET_TYPE_LINE);
594
595                     rrddim_add(st, "InDatagrams", NULL, 1, 1, RRDDIM_INCREMENTAL);
596                     rrddim_add(st, "OutDatagrams", NULL, -1, 1, RRDDIM_INCREMENTAL);
597                 }
598                 else rrdset_next(st);
599
600                 rrddim_set(st, "InDatagrams", InDatagrams);
601                 rrddim_set(st, "OutDatagrams", OutDatagrams);
602                 rrdset_done(st);
603
604                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udplite_errors");
605                 if(!st) {
606                     st = rrdset_create(RRD_TYPE_NET_SNMP, "udplite_errors", NULL, "udplite", NULL, "IPv4 UDPLite Errors", "packets/s", 2604, update_every, RRDSET_TYPE_LINE);
607
608                     rrddim_add(st, "RcvbufErrors", NULL,  1, 1, RRDDIM_INCREMENTAL);
609                     rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRDDIM_INCREMENTAL);
610                     rrddim_add(st, "NoPorts",      NULL,  1, 1, RRDDIM_INCREMENTAL);
611                     rrddim_add(st, "IgnoredMulti", NULL,  1, 1, RRDDIM_INCREMENTAL);
612                     rrddim_add(st, "InErrors",     NULL,  1, 1, RRDDIM_INCREMENTAL);
613                     rrddim_add(st, "InCsumErrors", NULL,  1, 1, RRDDIM_INCREMENTAL);
614                 }
615                 else rrdset_next(st);
616
617                 rrddim_set(st, "NoPorts", NoPorts);
618                 rrddim_set(st, "InErrors", InErrors);
619                 rrddim_set(st, "InCsumErrors", InCsumErrors);
620                 rrddim_set(st, "RcvbufErrors", RcvbufErrors);
621                 rrddim_set(st, "SndbufErrors", SndbufErrors);
622                 rrddim_set(st, "IgnoredMulti", IgnoredMulti);
623                 rrdset_done(st);
624             }
625         }
626     }
627
628     return 0;
629 }
630