]> arthur.barton.de Git - netdata.git/blob - src/proc_net_snmp.c
build: migrate to autotools
[netdata.git] / src / proc_net_snmp.c
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "common.h"
9 #include "log.h"
10 #include "appconfig.h"
11 #include "procfile.h"
12 #include "rrd.h"
13 #include "plugin_proc.h"
14
15 #define RRD_TYPE_NET_SNMP                       "ipv4"
16 #define RRD_TYPE_NET_SNMP_LEN           strlen(RRD_TYPE_NET_SNMP)
17
18 int do_proc_net_snmp(int update_every, unsigned long long dt) {
19         static procfile *ff = NULL;
20         static int do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
21                 do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1, 
22                 do_udp_packets = -1, do_udp_errors = -1;
23
24         if(do_ip_packets == -1)         do_ip_packets           = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 packets", 1);
25         if(do_ip_fragsout == -1)        do_ip_fragsout          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragrments sent", 1);
26         if(do_ip_fragsin == -1)         do_ip_fragsin           = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments assembly", 1);
27         if(do_ip_errors == -1)          do_ip_errors            = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 errors", 1);
28         if(do_tcp_sockets == -1)        do_tcp_sockets          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP connections", 1);
29         if(do_tcp_packets == -1)        do_tcp_packets          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP packets", 1);
30         if(do_tcp_errors == -1)         do_tcp_errors           = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP errors", 1);
31         if(do_tcp_handshake == -1)      do_tcp_handshake        = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP handshake issues", 1);
32         if(do_udp_packets == -1)        do_udp_packets          = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP packets", 1);
33         if(do_udp_errors == -1)         do_udp_errors           = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP errors", 1);
34
35         if(dt) {};
36
37         if(!ff) {
38                 char filename[FILENAME_MAX + 1];
39                 snprintf(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/snmp");
40                 ff = procfile_open(config_get("plugin:proc:/proc/net/snmp", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
41         }
42         if(!ff) return 1;
43
44         ff = procfile_readall(ff);
45         if(!ff) return 0; // we return 0, so that we will retry to open it next time
46
47         uint32_t lines = procfile_lines(ff), l;
48         uint32_t words;
49
50         RRDSET *st;
51
52         for(l = 0; l < lines ;l++) {
53                 if(strcmp(procfile_lineword(ff, l, 0), "Ip") == 0) {
54                         l++;
55
56                         if(strcmp(procfile_lineword(ff, l, 0), "Ip") != 0) {
57                                 error("Cannot read Ip line from /proc/net/snmp.");
58                                 break;
59                         }
60
61                         words = procfile_linewords(ff, l);
62                         if(words < 20) {
63                                 error("Cannot read /proc/net/snmp Ip line. Expected 20 params, read %d.", words);
64                                 continue;
65                         }
66
67                         // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html
68                         unsigned long long Forwarding, DefaultTTL, InReceives, InHdrErrors, InAddrErrors, ForwDatagrams, InUnknownProtos, InDiscards, InDelivers,
69                                 OutRequests, OutDiscards, OutNoRoutes, ReasmTimeout, ReasmReqds, ReasmOKs, ReasmFails, FragOKs, FragFails, FragCreates;
70
71                         Forwarding              = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
72                         DefaultTTL              = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
73                         InReceives              = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
74                         InHdrErrors             = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
75                         InAddrErrors    = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
76                         ForwDatagrams   = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
77                         InUnknownProtos = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
78                         InDiscards              = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
79                         InDelivers              = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
80                         OutRequests             = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
81                         OutDiscards             = strtoull(procfile_lineword(ff, l, 11), NULL, 10);
82                         OutNoRoutes             = strtoull(procfile_lineword(ff, l, 12), NULL, 10);
83                         ReasmTimeout    = strtoull(procfile_lineword(ff, l, 13), NULL, 10);
84                         ReasmReqds              = strtoull(procfile_lineword(ff, l, 14), NULL, 10);
85                         ReasmOKs                = strtoull(procfile_lineword(ff, l, 15), NULL, 10);
86                         ReasmFails              = strtoull(procfile_lineword(ff, l, 16), NULL, 10);
87                         FragOKs                 = strtoull(procfile_lineword(ff, l, 17), NULL, 10);
88                         FragFails               = strtoull(procfile_lineword(ff, l, 18), NULL, 10);
89                         FragCreates             = strtoull(procfile_lineword(ff, l, 19), NULL, 10);
90                         
91                         // these are not counters
92                         if(Forwarding) {};              // is forwarding enabled?
93                         if(DefaultTTL) {};              // the default ttl on packets
94                         if(ReasmTimeout) {};    // reassemply timeout
95
96                         // this counter is not used
97                         if(InDelivers) {};              // total number of packets delivered to IP user-protcols
98
99                         // --------------------------------------------------------------------
100
101                         if(do_ip_packets) {
102                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".packets");
103                                 if(!st) {
104                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "packets", NULL, RRD_TYPE_NET_SNMP, "IPv4 Packets", "packets/s", 3000, update_every, RRDSET_TYPE_LINE);
105
106                                         rrddim_add(st, "received", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
107                                         rrddim_add(st, "sent", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
108                                         rrddim_add(st, "forwarded", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
109                                 }
110                                 else rrdset_next(st);
111
112                                 rrddim_set(st, "sent", OutRequests);
113                                 rrddim_set(st, "received", InReceives);
114                                 rrddim_set(st, "forwarded", ForwDatagrams);
115                                 rrdset_done(st);
116                         }
117
118                         // --------------------------------------------------------------------
119
120                         if(do_ip_fragsout) {
121                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsout");
122                                 if(!st) {
123                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsout", NULL, RRD_TYPE_NET_SNMP, "IPv4 Fragments Sent", "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
124                                         st->isdetail = 1;
125
126                                         rrddim_add(st, "ok", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
127                                         rrddim_add(st, "failed", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
128                                         rrddim_add(st, "all", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
129                                 }
130                                 else rrdset_next(st);
131
132                                 rrddim_set(st, "ok", FragOKs);
133                                 rrddim_set(st, "failed", FragFails);
134                                 rrddim_set(st, "all", FragCreates);
135                                 rrdset_done(st);
136                         }
137
138                         // --------------------------------------------------------------------
139
140                         if(do_ip_fragsin) {
141                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsin");
142                                 if(!st) {
143                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsin", NULL, RRD_TYPE_NET_SNMP, "IPv4 Fragments Reassembly", "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
144                                         st->isdetail = 1;
145
146                                         rrddim_add(st, "ok", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
147                                         rrddim_add(st, "failed", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
148                                         rrddim_add(st, "all", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
149                                 }
150                                 else rrdset_next(st);
151
152                                 rrddim_set(st, "ok", ReasmOKs);
153                                 rrddim_set(st, "failed", ReasmFails);
154                                 rrddim_set(st, "all", ReasmReqds);
155                                 rrdset_done(st);
156                         }
157
158                         // --------------------------------------------------------------------
159
160                         if(do_ip_errors) {
161                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".errors");
162                                 if(!st) {
163                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "errors", NULL, RRD_TYPE_NET_SNMP, "IPv4 Errors", "packets/s", 3002, update_every, RRDSET_TYPE_LINE);
164                                         st->isdetail = 1;
165
166                                         rrddim_add(st, "InDiscards", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
167                                         rrddim_add(st, "OutDiscards", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
168
169                                         rrddim_add(st, "InHdrErrors", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
170                                         rrddim_add(st, "InAddrErrors", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
171                                         rrddim_add(st, "InUnknownProtos", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
172
173                                         rrddim_add(st, "OutNoRoutes", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
174                                 }
175                                 else rrdset_next(st);
176
177                                 rrddim_set(st, "InDiscards", InDiscards);
178                                 rrddim_set(st, "OutDiscards", OutDiscards);
179                                 rrddim_set(st, "InHdrErrors", InHdrErrors);
180                                 rrddim_set(st, "InAddrErrors", InAddrErrors);
181                                 rrddim_set(st, "InUnknownProtos", InUnknownProtos);
182                                 rrddim_set(st, "OutNoRoutes", OutNoRoutes);
183                                 rrdset_done(st);
184                         }
185                 }
186                 else if(strcmp(procfile_lineword(ff, l, 0), "Tcp") == 0) {
187                         l++;
188
189                         if(strcmp(procfile_lineword(ff, l, 0), "Tcp") != 0) {
190                                 error("Cannot read Tcp line from /proc/net/snmp.");
191                                 break;
192                         }
193
194                         words = procfile_linewords(ff, l);
195                         if(words < 15) {
196                                 error("Cannot read /proc/net/snmp Tcp line. Expected 15 params, read %d.", words);
197                                 continue;
198                         }
199
200                         unsigned long long RtoAlgorithm, RtoMin, RtoMax, MaxConn, ActiveOpens, PassiveOpens, AttemptFails, EstabResets,
201                                 CurrEstab, InSegs, OutSegs, RetransSegs, InErrs, OutRsts;
202
203                         RtoAlgorithm    = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
204                         RtoMin                  = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
205                         RtoMax                  = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
206                         MaxConn                 = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
207                         ActiveOpens             = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
208                         PassiveOpens    = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
209                         AttemptFails    = strtoull(procfile_lineword(ff, l, 7), NULL, 10);
210                         EstabResets             = strtoull(procfile_lineword(ff, l, 8), NULL, 10);
211                         CurrEstab               = strtoull(procfile_lineword(ff, l, 9), NULL, 10);
212                         InSegs                  = strtoull(procfile_lineword(ff, l, 10), NULL, 10);
213                         OutSegs                 = strtoull(procfile_lineword(ff, l, 11), NULL, 10);
214                         RetransSegs             = strtoull(procfile_lineword(ff, l, 12), NULL, 10);
215                         InErrs                  = strtoull(procfile_lineword(ff, l, 13), NULL, 10);
216                         OutRsts                 = strtoull(procfile_lineword(ff, l, 14), NULL, 10);
217
218                         // these are not counters
219                         if(RtoAlgorithm) {};
220                         if(RtoMin) {};
221                         if(RtoMax) {};
222                         if(MaxConn) {};
223
224                         // --------------------------------------------------------------------
225                         
226                         // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
227                         if(do_tcp_sockets) {
228                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcpsock");
229                                 if(!st) {
230                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "tcpsock", NULL, "tcp", "IPv4 TCP Connections", "active connections", 2500, update_every, RRDSET_TYPE_LINE);
231
232                                         rrddim_add(st, "connections", NULL, 1, 1, RRDDIM_ABSOLUTE);
233                                 }
234                                 else rrdset_next(st);
235
236                                 rrddim_set(st, "connections", CurrEstab);
237                                 rrdset_done(st);
238                         }
239
240                         // --------------------------------------------------------------------
241                         
242                         if(do_tcp_packets) {
243                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcppackets");
244                                 if(!st) {
245                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "tcppackets", NULL, "tcp", "IPv4 TCP Packets", "packets/s", 2600, update_every, RRDSET_TYPE_LINE);
246
247                                         rrddim_add(st, "received", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
248                                         rrddim_add(st, "sent", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
249                                 }
250                                 else rrdset_next(st);
251
252                                 rrddim_set(st, "received", InSegs);
253                                 rrddim_set(st, "sent", OutSegs);
254                                 rrdset_done(st);
255                         }
256
257                         // --------------------------------------------------------------------
258                         
259                         if(do_tcp_errors) {
260                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcperrors");
261                                 if(!st) {
262                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "tcperrors", NULL, "tcp", "IPv4 TCP Errors", "packets/s", 2700, update_every, RRDSET_TYPE_LINE);
263                                         st->isdetail = 1;
264
265                                         rrddim_add(st, "InErrs", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
266                                         rrddim_add(st, "RetransSegs", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
267                                 }
268                                 else rrdset_next(st);
269
270                                 rrddim_set(st, "InErrs", InErrs);
271                                 rrddim_set(st, "RetransSegs", RetransSegs);
272                                 rrdset_done(st);
273                         }
274
275                         // --------------------------------------------------------------------
276                         
277                         if(do_tcp_handshake) {
278                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".tcphandshake");
279                                 if(!st) {
280                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "tcphandshake", NULL, "tcp", "IPv4 TCP Handshake Issues", "events/s", 2900, update_every, RRDSET_TYPE_LINE);
281                                         st->isdetail = 1;
282
283                                         rrddim_add(st, "EstabResets", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
284                                         rrddim_add(st, "OutRsts", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
285                                         rrddim_add(st, "ActiveOpens", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
286                                         rrddim_add(st, "PassiveOpens", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
287                                         rrddim_add(st, "AttemptFails", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
288                                 }
289                                 else rrdset_next(st);
290
291                                 rrddim_set(st, "EstabResets", EstabResets);
292                                 rrddim_set(st, "OutRsts", OutRsts);
293                                 rrddim_set(st, "ActiveOpens", ActiveOpens);
294                                 rrddim_set(st, "PassiveOpens", PassiveOpens);
295                                 rrddim_set(st, "AttemptFails", AttemptFails);
296                                 rrdset_done(st);
297                         }
298                 }
299                 else if(strcmp(procfile_lineword(ff, l, 0), "Udp") == 0) {
300                         l++;
301
302                         if(strcmp(procfile_lineword(ff, l, 0), "Udp") != 0) {
303                                 error("Cannot read Udp line from /proc/net/snmp.");
304                                 break;
305                         }
306
307                         words = procfile_linewords(ff, l);
308                         if(words < 7) {
309                                 error("Cannot read /proc/net/snmp Udp line. Expected 7 params, read %d.", words);
310                                 continue;
311                         }
312
313                         unsigned long long InDatagrams, NoPorts, InErrors, OutDatagrams, RcvbufErrors, SndbufErrors;
314
315                         InDatagrams             = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
316                         NoPorts                 = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
317                         InErrors                = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
318                         OutDatagrams    = strtoull(procfile_lineword(ff, l, 4), NULL, 10);
319                         RcvbufErrors    = strtoull(procfile_lineword(ff, l, 5), NULL, 10);
320                         SndbufErrors    = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
321
322                         // --------------------------------------------------------------------
323                         
324                         // see http://net-snmp.sourceforge.net/docs/mibs/udp.html
325                         if(do_udp_packets) {
326                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udppackets");
327                                 if(!st) {
328                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "udppackets", NULL, "udp", "IPv4 UDP Packets", "packets/s", 2601, update_every, RRDSET_TYPE_LINE);
329
330                                         rrddim_add(st, "received", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
331                                         rrddim_add(st, "sent", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
332                                 }
333                                 else rrdset_next(st);
334
335                                 rrddim_set(st, "received", InDatagrams);
336                                 rrddim_set(st, "sent", OutDatagrams);
337                                 rrdset_done(st);
338                         }
339
340                         // --------------------------------------------------------------------
341                         
342                         if(do_udp_errors) {
343                                 st = rrdset_find(RRD_TYPE_NET_SNMP ".udperrors");
344                                 if(!st) {
345                                         st = rrdset_create(RRD_TYPE_NET_SNMP, "udperrors", NULL, "udp", "IPv4 UDP Errors", "events/s", 2701, update_every, RRDSET_TYPE_LINE);
346                                         st->isdetail = 1;
347
348                                         rrddim_add(st, "RcvbufErrors", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
349                                         rrddim_add(st, "SndbufErrors", NULL, -1, 1 * update_every, RRDDIM_INCREMENTAL);
350                                         rrddim_add(st, "InErrors", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
351                                         rrddim_add(st, "NoPorts", NULL, 1, 1 * update_every, RRDDIM_INCREMENTAL);
352                                 }
353                                 else rrdset_next(st);
354
355                                 rrddim_set(st, "InErrors", InErrors);
356                                 rrddim_set(st, "NoPorts", NoPorts);
357                                 rrddim_set(st, "RcvbufErrors", RcvbufErrors);
358                                 rrddim_set(st, "SndbufErrors", SndbufErrors);
359                                 rrdset_done(st);
360                         }
361                 }
362         }
363         
364         return 0;
365 }
366