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