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