]> arthur.barton.de Git - netdata.git/blob - src/macos_sysctl.c
Merge pull request #1998 from ktsaou/master
[netdata.git] / src / macos_sysctl.c
1 #include "common.h"
2 #include <sys/sysctl.h>
3 // NEEDED BY: do_bandwidth
4 #include <net/route.h>
5 // NEEDED BY do_tcp...
6 #include <sys/socketvar.h>
7 #include <netinet/tcp_var.h>
8 #include <netinet/tcp_fsm.h>
9 // NEEDED BY do_udp..., do_ip...
10 #include <netinet/ip_var.h>
11 // NEEDED BY do_udp...
12 #include <netinet/udp.h>
13 #include <netinet/udp_var.h>
14 // NEEDED BY do_icmp...
15 #include <netinet/ip.h>
16 #include <netinet/ip_icmp.h>
17 #include <netinet/icmp_var.h>
18 // NEEDED BY do_icmp6...
19 #include <netinet/icmp6.h>
20 // NEEDED BY do_uptime
21 #include <time.h>
22
23 // MacOS calculates load averages once every 5 seconds
24 #define MIN_LOADAVG_UPDATE_EVERY 5
25
26 int do_macos_sysctl(int update_every, usec_t dt) {
27     static int do_loadavg = -1, do_swap = -1, do_bandwidth = -1,
28                do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1, do_ecn = -1,
29                do_tcpext_syscookies = -1, do_tcpext_ofo = -1, do_tcpext_connaborts = -1,
30                do_udp_packets = -1, do_udp_errors = -1, do_icmp_packets = -1, do_icmpmsg = -1,
31                do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
32                do_ip6_packets = -1, do_ip6_fragsout = -1, do_ip6_fragsin = -1, do_ip6_errors = -1,
33                do_icmp6 = -1, do_icmp6_redir = -1, do_icmp6_errors = -1, do_icmp6_echos = -1,
34                do_icmp6_router = -1, do_icmp6_neighbor = -1, do_icmp6_types = -1, do_uptime = -1;
35
36
37     if (unlikely(do_loadavg == -1)) {
38         do_loadavg              = config_get_boolean("plugin:macos:sysctl", "enable load average", 1);
39         do_swap                 = config_get_boolean("plugin:macos:sysctl", "system swap", 1);
40         do_bandwidth            = config_get_boolean("plugin:macos:sysctl", "bandwidth", 1);
41         do_tcp_packets          = config_get_boolean("plugin:macos:sysctl", "ipv4 TCP packets", 1);
42         do_tcp_errors           = config_get_boolean("plugin:macos:sysctl", "ipv4 TCP errors", 1);
43         do_tcp_handshake        = config_get_boolean("plugin:macos:sysctl", "ipv4 TCP handshake issues", 1);
44         do_ecn                  = config_get_boolean_ondemand("plugin:macos:sysctl", "ECN packets", CONFIG_BOOLEAN_AUTO);
45         do_tcpext_syscookies    = config_get_boolean_ondemand("plugin:macos:sysctl", "TCP SYN cookies", CONFIG_BOOLEAN_AUTO);
46         do_tcpext_ofo           = config_get_boolean_ondemand("plugin:macos:sysctl", "TCP out-of-order queue", CONFIG_BOOLEAN_AUTO);
47         do_tcpext_connaborts    = config_get_boolean_ondemand("plugin:macos:sysctl", "TCP connection aborts", CONFIG_BOOLEAN_AUTO);
48         do_udp_packets          = config_get_boolean("plugin:macos:sysctl", "ipv4 UDP packets", 1);
49         do_udp_errors           = config_get_boolean("plugin:macos:sysctl", "ipv4 UDP errors", 1);
50         do_icmp_packets         = config_get_boolean("plugin:macos:sysctl", "ipv4 ICMP packets", 1);
51         do_icmpmsg              = config_get_boolean("plugin:macos:sysctl", "ipv4 ICMP messages", 1);
52         do_ip_packets           = config_get_boolean("plugin:macos:sysctl", "ipv4 packets", 1);
53         do_ip_fragsout          = config_get_boolean("plugin:macos:sysctl", "ipv4 fragments sent", 1);
54         do_ip_fragsin           = config_get_boolean("plugin:macos:sysctl", "ipv4 fragments assembly", 1);
55         do_ip_errors            = config_get_boolean("plugin:macos:sysctl", "ipv4 errors", 1);
56         do_ip6_packets          = config_get_boolean_ondemand("plugin:macos:sysctl", "ipv6 packets", CONFIG_BOOLEAN_AUTO);
57         do_ip6_fragsout         = config_get_boolean_ondemand("plugin:macos:sysctl", "ipv6 fragments sent", CONFIG_BOOLEAN_AUTO);
58         do_ip6_fragsin          = config_get_boolean_ondemand("plugin:macos:sysctl", "ipv6 fragments assembly", CONFIG_BOOLEAN_AUTO);
59         do_ip6_errors           = config_get_boolean_ondemand("plugin:macos:sysctl", "ipv6 errors", CONFIG_BOOLEAN_AUTO);
60         do_icmp6                = config_get_boolean_ondemand("plugin:macos:sysctl", "icmp", CONFIG_BOOLEAN_AUTO);
61         do_icmp6_redir          = config_get_boolean_ondemand("plugin:macos:sysctl", "icmp redirects", CONFIG_BOOLEAN_AUTO);
62         do_icmp6_errors         = config_get_boolean_ondemand("plugin:macos:sysctl", "icmp errors", CONFIG_BOOLEAN_AUTO);
63         do_icmp6_echos          = config_get_boolean_ondemand("plugin:macos:sysctl", "icmp echos", CONFIG_BOOLEAN_AUTO);
64         do_icmp6_router         = config_get_boolean_ondemand("plugin:macos:sysctl", "icmp router", CONFIG_BOOLEAN_AUTO);
65         do_icmp6_neighbor       = config_get_boolean_ondemand("plugin:macos:sysctl", "icmp neighbor", CONFIG_BOOLEAN_AUTO);
66         do_icmp6_types          = config_get_boolean_ondemand("plugin:macos:sysctl", "icmp types", CONFIG_BOOLEAN_AUTO);
67         do_uptime               = config_get_boolean("plugin:macos:sysctl", "system uptime", 1);
68     }
69
70     RRDSET *st;
71
72     int system_pagesize = getpagesize(); // wouldn't it be better to get value directly from hw.pagesize?
73     int i, n;
74     int common_error = 0;
75     size_t size;
76
77     // NEEDED BY: do_loadavg
78     static usec_t next_loadavg_dt = 0;
79     struct loadavg sysload;
80
81     // NEEDED BY: do_swap
82     struct xsw_usage swap_usage;
83
84     // NEEDED BY: do_bandwidth
85     int mib[6];
86     static char *ifstatdata = NULL;
87     char *lim, *next;
88     struct if_msghdr *ifm;
89     struct iftot {
90         u_long  ift_ibytes;
91         u_long  ift_obytes;
92     } iftot = {0, 0};
93
94     // NEEDED BY: do_tcp...
95     struct tcpstat tcpstat;
96     uint64_t tcps_states[TCP_NSTATES];
97
98     // NEEDED BY: do_udp...
99     struct udpstat udpstat;
100
101     // NEEDED BY: do_icmp...
102     struct icmpstat icmpstat;
103     struct icmp_total {
104         u_long  msgs_in;
105         u_long  msgs_out;
106     } icmp_total = {0, 0};
107
108     // NEEDED BY: do_ip...
109     struct ipstat ipstat;
110
111     // NEEDED BY: do_ip6...
112     /*
113      * Dirty workaround for /usr/include/netinet6/ip6_var.h absence.
114      * Struct ip6stat was copied from bsd/netinet6/ip6_var.h from xnu sources.
115      */
116 #define IP6S_SRCRULE_COUNT 16
117 #include <netinet6/scope6_var.h>
118     struct      ip6stat {
119         u_quad_t ip6s_total;            /* total packets received */
120         u_quad_t ip6s_tooshort;         /* packet too short */
121         u_quad_t ip6s_toosmall;         /* not enough data */
122         u_quad_t ip6s_fragments;        /* fragments received */
123         u_quad_t ip6s_fragdropped;      /* frags dropped(dups, out of space) */
124         u_quad_t ip6s_fragtimeout;      /* fragments timed out */
125         u_quad_t ip6s_fragoverflow;     /* fragments that exceeded limit */
126         u_quad_t ip6s_forward;          /* packets forwarded */
127         u_quad_t ip6s_cantforward;      /* packets rcvd for unreachable dest */
128         u_quad_t ip6s_redirectsent;     /* packets forwarded on same net */
129         u_quad_t ip6s_delivered;        /* datagrams delivered to upper level */
130         u_quad_t ip6s_localout;         /* total ip packets generated here */
131         u_quad_t ip6s_odropped;         /* lost packets due to nobufs, etc. */
132         u_quad_t ip6s_reassembled;      /* total packets reassembled ok */
133         u_quad_t ip6s_atmfrag_rcvd;     /* atomic fragments received */
134         u_quad_t ip6s_fragmented;       /* datagrams successfully fragmented */
135         u_quad_t ip6s_ofragments;       /* output fragments created */
136         u_quad_t ip6s_cantfrag;         /* don't fragment flag was set, etc. */
137         u_quad_t ip6s_badoptions;       /* error in option processing */
138         u_quad_t ip6s_noroute;          /* packets discarded due to no route */
139         u_quad_t ip6s_badvers;          /* ip6 version != 6 */
140         u_quad_t ip6s_rawout;           /* total raw ip packets generated */
141         u_quad_t ip6s_badscope;         /* scope error */
142         u_quad_t ip6s_notmember;        /* don't join this multicast group */
143         u_quad_t ip6s_nxthist[256];     /* next header history */
144         u_quad_t ip6s_m1;               /* one mbuf */
145         u_quad_t ip6s_m2m[32];          /* two or more mbuf */
146         u_quad_t ip6s_mext1;            /* one ext mbuf */
147         u_quad_t ip6s_mext2m;           /* two or more ext mbuf */
148         u_quad_t ip6s_exthdrtoolong;    /* ext hdr are not continuous */
149         u_quad_t ip6s_nogif;            /* no match gif found */
150         u_quad_t ip6s_toomanyhdr;       /* discarded due to too many headers */
151
152         /*
153          * statistics for improvement of the source address selection
154          * algorithm:
155          */
156         /* number of times that address selection fails */
157         u_quad_t ip6s_sources_none;
158         /* number of times that an address on the outgoing I/F is chosen */
159         u_quad_t ip6s_sources_sameif[SCOPE6_ID_MAX];
160         /* number of times that an address on a non-outgoing I/F is chosen */
161         u_quad_t ip6s_sources_otherif[SCOPE6_ID_MAX];
162         /*
163          * number of times that an address that has the same scope
164          * from the destination is chosen.
165          */
166         u_quad_t ip6s_sources_samescope[SCOPE6_ID_MAX];
167         /*
168          * number of times that an address that has a different scope
169          * from the destination is chosen.
170          */
171         u_quad_t ip6s_sources_otherscope[SCOPE6_ID_MAX];
172         /* number of times that a deprecated address is chosen */
173         u_quad_t ip6s_sources_deprecated[SCOPE6_ID_MAX];
174
175         u_quad_t ip6s_forward_cachehit;
176         u_quad_t ip6s_forward_cachemiss;
177
178         /* number of times that each rule of source selection is applied. */
179         u_quad_t ip6s_sources_rule[IP6S_SRCRULE_COUNT];
180
181         /* number of times we ignored address on expensive secondary interfaces */
182         u_quad_t ip6s_sources_skip_expensive_secondary_if;
183
184         /* pkt dropped, no mbufs for control data */
185         u_quad_t ip6s_pktdropcntrl;
186
187         /* total packets trimmed/adjusted  */
188         u_quad_t ip6s_adj;
189         /* hwcksum info discarded during adjustment */
190         u_quad_t ip6s_adj_hwcsum_clr;
191
192         /* duplicate address detection collisions */
193         u_quad_t ip6s_dad_collide;
194
195         /* DAD NS looped back */
196         u_quad_t ip6s_dad_loopcount;
197     } ip6stat;
198
199     // NEEDED BY: do_icmp6...
200     struct icmp6stat icmp6stat;
201     struct icmp6_total {
202         u_long  msgs_in;
203         u_long  msgs_out;
204     } icmp6_total = {0, 0};
205
206     // NEEDED BY: do_uptime
207     struct timespec boot_time, cur_time;
208
209     // --------------------------------------------------------------------
210
211     if (next_loadavg_dt <= dt) {
212         if (likely(do_loadavg)) {
213             if (unlikely(GETSYSCTL_BY_NAME("vm.loadavg", sysload))) {
214                 do_loadavg = 0;
215                 error("DISABLED: system.load");
216             } else {
217
218                 st = rrdset_find_bytype_localhost("system", "load");
219                 if (unlikely(!st)) {
220                     st = rrdset_create_localhost("system", "load", NULL, "load", NULL, "System Load Average", "load"
221                                                  , 100, (update_every < MIN_LOADAVG_UPDATE_EVERY)
222                                                         ? MIN_LOADAVG_UPDATE_EVERY : update_every, RRDSET_TYPE_LINE);
223                     rrddim_add(st, "load1", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
224                     rrddim_add(st, "load5", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
225                     rrddim_add(st, "load15", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
226                 }
227                 else rrdset_next(st);
228
229                 rrddim_set(st, "load1", (collected_number) ((double)sysload.ldavg[0] / sysload.fscale * 1000));
230                 rrddim_set(st, "load5", (collected_number) ((double)sysload.ldavg[1] / sysload.fscale * 1000));
231                 rrddim_set(st, "load15", (collected_number) ((double)sysload.ldavg[2] / sysload.fscale * 1000));
232                 rrdset_done(st);
233             }
234         }
235
236         next_loadavg_dt = st->update_every * USEC_PER_SEC;
237     }
238     else next_loadavg_dt -= dt;
239
240     // --------------------------------------------------------------------
241
242     if (likely(do_swap)) {
243         if (unlikely(GETSYSCTL_BY_NAME("vm.swapusage", swap_usage))) {
244             do_swap = 0;
245             error("DISABLED: system.swap");
246         } else {
247             st = rrdset_find_localhost("system.swap");
248             if (unlikely(!st)) {
249                 st = rrdset_create_localhost("system", "swap", NULL, "swap", NULL, "System Swap", "MB", 201
250                                              , update_every, RRDSET_TYPE_STACKED);
251                 rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
252
253                 rrddim_add(st, "free",    NULL, 1, 1048576, RRD_ALGORITHM_ABSOLUTE);
254                 rrddim_add(st, "used",    NULL, 1, 1048576, RRD_ALGORITHM_ABSOLUTE);
255             }
256             else rrdset_next(st);
257
258             rrddim_set(st, "free", swap_usage.xsu_avail);
259             rrddim_set(st, "used", swap_usage.xsu_used);
260             rrdset_done(st);
261         }
262     }
263
264     // --------------------------------------------------------------------
265
266     if (likely(do_bandwidth)) {
267         mib[0] = CTL_NET;
268         mib[1] = PF_ROUTE;
269         mib[2] = 0;
270         mib[3] = AF_INET;
271         mib[4] = NET_RT_IFLIST2;
272         mib[5] = 0;
273         if (unlikely(sysctl(mib, 6, NULL, &size, NULL, 0))) {
274             error("MACOS: sysctl(%s...) failed: %s", "net interfaces", strerror(errno));
275             do_bandwidth = 0;
276             error("DISABLED: system.ipv4");
277         } else {
278             ifstatdata = reallocz(ifstatdata, size);
279             if (unlikely(sysctl(mib, 6, ifstatdata, &size, NULL, 0) < 0)) {
280                 error("MACOS: sysctl(%s...) failed: %s", "net interfaces", strerror(errno));
281                 do_bandwidth = 0;
282                 error("DISABLED: system.ipv4");
283             } else {
284                 lim = ifstatdata + size;
285                 iftot.ift_ibytes = iftot.ift_obytes = 0;
286                 for (next = ifstatdata; next < lim; ) {
287                     ifm = (struct if_msghdr *)next;
288                     next += ifm->ifm_msglen;
289
290                     if (ifm->ifm_type == RTM_IFINFO2) {
291                         struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
292
293                         iftot.ift_ibytes += if2m->ifm_data.ifi_ibytes;
294                         iftot.ift_obytes += if2m->ifm_data.ifi_obytes;
295                     }
296                 }
297                 st = rrdset_find_localhost("system.ipv4");
298                 if (unlikely(!st)) {
299                     st = rrdset_create_localhost("system", "ipv4", NULL, "network", NULL, "IPv4 Bandwidth", "kilobits/s"
300                                                  , 500, update_every, RRDSET_TYPE_AREA);
301
302                     rrddim_add(st, "InOctets", "received", 8, 1024, RRD_ALGORITHM_INCREMENTAL);
303                     rrddim_add(st, "OutOctets", "sent", -8, 1024, RRD_ALGORITHM_INCREMENTAL);
304                 }
305                 else rrdset_next(st);
306
307                 rrddim_set(st, "InOctets", iftot.ift_ibytes);
308                 rrddim_set(st, "OutOctets", iftot.ift_obytes);
309                 rrdset_done(st);
310             }
311         }
312     }
313
314     // --------------------------------------------------------------------
315
316     // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
317     if (likely(do_tcp_packets || do_tcp_errors || do_tcp_handshake || do_tcpext_connaborts || do_tcpext_ofo || do_tcpext_syscookies || do_ecn)) {
318         if (unlikely(GETSYSCTL_BY_NAME("net.inet.tcp.stats", tcpstat))){
319             do_tcp_packets = 0;
320             error("DISABLED: ipv4.tcppackets");
321             do_tcp_errors = 0;
322             error("DISABLED: ipv4.tcperrors");
323             do_tcp_handshake = 0;
324             error("DISABLED: ipv4.tcphandshake");
325             do_tcpext_connaborts = 0;
326             error("DISABLED: ipv4.tcpconnaborts");
327             do_tcpext_ofo = 0;
328             error("DISABLED: ipv4.tcpofo");
329             do_tcpext_syscookies = 0;
330             error("DISABLED: ipv4.tcpsyncookies");
331             do_ecn = 0;
332             error("DISABLED: ipv4.ecnpkts");
333         } else {
334             if (likely(do_tcp_packets)) {
335                 st = rrdset_find_localhost("ipv4.tcppackets");
336                 if (unlikely(!st)) {
337                     st = rrdset_create_localhost("ipv4", "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets"
338                                                  , "packets/s", 2600, update_every, RRDSET_TYPE_LINE);
339
340                     rrddim_add(st, "InSegs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
341                     rrddim_add(st, "OutSegs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
342                 } else
343                     rrdset_next(st);
344
345                 rrddim_set(st, "InSegs", tcpstat.tcps_rcvtotal);
346                 rrddim_set(st, "OutSegs", tcpstat.tcps_sndtotal);
347                 rrdset_done(st);
348             }
349
350             // --------------------------------------------------------------------
351
352             if (likely(do_tcp_errors)) {
353                 st = rrdset_find_localhost("ipv4.tcperrors");
354                 if (unlikely(!st)) {
355                     st = rrdset_create_localhost("ipv4", "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors", "packets/s"
356                                                  , 2700, update_every, RRDSET_TYPE_LINE);
357                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
358
359                     rrddim_add(st, "InErrs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
360                     rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
361                     rrddim_add(st, "RetransSegs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
362                 } else
363                     rrdset_next(st);
364
365                 rrddim_set(st, "InErrs", tcpstat.tcps_rcvbadoff + tcpstat.tcps_rcvshort);
366                 rrddim_set(st, "InCsumErrors", tcpstat.tcps_rcvbadsum);
367                 rrddim_set(st, "RetransSegs", tcpstat.tcps_sndrexmitpack);
368                 rrdset_done(st);
369             }
370
371             // --------------------------------------------------------------------
372
373             if (likely(do_tcp_handshake)) {
374                 st = rrdset_find_localhost("ipv4.tcphandshake");
375                 if (unlikely(!st)) {
376                     st = rrdset_create_localhost("ipv4", "tcphandshake", NULL, "tcp", NULL, "IPv4 TCP Handshake Issues"
377                                                  , "events/s", 2900, update_every, RRDSET_TYPE_LINE);
378                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
379
380                     rrddim_add(st, "EstabResets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
381                     rrddim_add(st, "ActiveOpens", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
382                     rrddim_add(st, "PassiveOpens", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
383                     rrddim_add(st, "AttemptFails", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
384                 } else
385                     rrdset_next(st);
386
387                 rrddim_set(st, "EstabResets", tcpstat.tcps_drops);
388                 rrddim_set(st, "ActiveOpens", tcpstat.tcps_connattempt);
389                 rrddim_set(st, "PassiveOpens", tcpstat.tcps_accepts);
390                 rrddim_set(st, "AttemptFails", tcpstat.tcps_conndrops);
391                 rrdset_done(st);
392             }
393
394             // --------------------------------------------------------------------
395
396             if (do_tcpext_connaborts == CONFIG_BOOLEAN_YES || (do_tcpext_connaborts == CONFIG_BOOLEAN_AUTO && (tcpstat.tcps_rcvpackafterwin || tcpstat.tcps_rcvafterclose || tcpstat.tcps_rcvmemdrop || tcpstat.tcps_persistdrop))) {
397                 do_tcpext_connaborts = CONFIG_BOOLEAN_YES;
398                 st = rrdset_find_localhost("ipv4.tcpconnaborts");
399                 if (unlikely(!st)) {
400                     st = rrdset_create_localhost("ipv4", "tcpconnaborts", NULL, "tcp", NULL, "TCP Connection Aborts"
401                                                  , "connections/s", 3010, update_every, RRDSET_TYPE_LINE);
402
403                     rrddim_add(st, "TCPAbortOnData",    "baddata",     1, 1, RRD_ALGORITHM_INCREMENTAL);
404                     rrddim_add(st, "TCPAbortOnClose",   "userclosed",  1, 1, RRD_ALGORITHM_INCREMENTAL);
405                     rrddim_add(st, "TCPAbortOnMemory",  "nomemory",    1, 1, RRD_ALGORITHM_INCREMENTAL);
406                     rrddim_add(st, "TCPAbortOnTimeout", "timeout",     1, 1, RRD_ALGORITHM_INCREMENTAL);
407                 }
408                 else rrdset_next(st);
409
410                 rrddim_set(st, "TCPAbortOnData",    tcpstat.tcps_rcvpackafterwin);
411                 rrddim_set(st, "TCPAbortOnClose",   tcpstat.tcps_rcvafterclose);
412                 rrddim_set(st, "TCPAbortOnMemory",  tcpstat.tcps_rcvmemdrop);
413                 rrddim_set(st, "TCPAbortOnTimeout", tcpstat.tcps_persistdrop);
414                 rrdset_done(st);
415             }
416
417             // --------------------------------------------------------------------
418
419             if (do_tcpext_ofo == CONFIG_BOOLEAN_YES || (do_tcpext_ofo == CONFIG_BOOLEAN_AUTO && tcpstat.tcps_rcvoopack)) {
420                 do_tcpext_ofo = CONFIG_BOOLEAN_YES;
421                 st = rrdset_find_localhost("ipv4.tcpofo");
422                 if (unlikely(!st)) {
423                     st = rrdset_create_localhost("ipv4", "tcpofo", NULL, "tcp", NULL, "TCP Out-Of-Order Queue"
424                                                  , "packets/s", 3050, update_every, RRDSET_TYPE_LINE);
425
426                     rrddim_add(st, "TCPOFOQueue", "inqueue",  1, 1, RRD_ALGORITHM_INCREMENTAL);
427                 }
428                 else rrdset_next(st);
429
430                 rrddim_set(st, "TCPOFOQueue",   tcpstat.tcps_rcvoopack);
431                 rrdset_done(st);
432             }
433
434             // --------------------------------------------------------------------
435
436             if (do_tcpext_syscookies == CONFIG_BOOLEAN_YES || (do_tcpext_syscookies == CONFIG_BOOLEAN_AUTO && (tcpstat.tcps_sc_sendcookie || tcpstat.tcps_sc_recvcookie || tcpstat.tcps_sc_zonefail))) {
437                 do_tcpext_syscookies = CONFIG_BOOLEAN_YES;
438
439                 st = rrdset_find_localhost("ipv4.tcpsyncookies");
440                 if (unlikely(!st)) {
441                     st = rrdset_create_localhost("ipv4", "tcpsyncookies", NULL, "tcp", NULL, "TCP SYN Cookies"
442                                                  , "packets/s", 3100, update_every, RRDSET_TYPE_LINE);
443
444                     rrddim_add(st, "SyncookiesRecv",   "received",  1, 1, RRD_ALGORITHM_INCREMENTAL);
445                     rrddim_add(st, "SyncookiesSent",   "sent",     -1, 1, RRD_ALGORITHM_INCREMENTAL);
446                     rrddim_add(st, "SyncookiesFailed", "failed",   -1, 1, RRD_ALGORITHM_INCREMENTAL);
447                 }
448                 else rrdset_next(st);
449
450                 rrddim_set(st, "SyncookiesRecv",   tcpstat.tcps_sc_recvcookie);
451                 rrddim_set(st, "SyncookiesSent",   tcpstat.tcps_sc_sendcookie);
452                 rrddim_set(st, "SyncookiesFailed", tcpstat.tcps_sc_zonefail);
453                 rrdset_done(st);
454             }
455
456             // --------------------------------------------------------------------
457
458             if (do_ecn == CONFIG_BOOLEAN_YES || (do_ecn == CONFIG_BOOLEAN_AUTO && (tcpstat.tcps_ecn_recv_ce || tcpstat.tcps_ecn_not_supported))) {
459                 do_ecn = CONFIG_BOOLEAN_YES;
460                 st = rrdset_find_localhost("ipv4.ecnpkts");
461                 if (unlikely(!st)) {
462                     st = rrdset_create_localhost("ipv4", "ecnpkts", NULL, "ecn", NULL, "IPv4 ECN Statistics"
463                                                  , "packets/s", 8700, update_every, RRDSET_TYPE_LINE);
464                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
465
466                     rrddim_add(st, "InCEPkts", "CEP", 1, 1, RRD_ALGORITHM_INCREMENTAL);
467                     rrddim_add(st, "InNoECTPkts", "NoECTP", -1, 1, RRD_ALGORITHM_INCREMENTAL);
468                 }
469                 else rrdset_next(st);
470
471                 rrddim_set(st, "InCEPkts", tcpstat.tcps_ecn_recv_ce);
472                 rrddim_set(st, "InNoECTPkts", tcpstat.tcps_ecn_not_supported);
473                 rrdset_done(st);
474             }
475
476         }
477     }
478
479     // --------------------------------------------------------------------
480
481     // see http://net-snmp.sourceforge.net/docs/mibs/udp.html
482     if (likely(do_udp_packets || do_udp_errors)) {
483         if (unlikely(GETSYSCTL_BY_NAME("net.inet.udp.stats", udpstat))) {
484             do_udp_packets = 0;
485             error("DISABLED: ipv4.udppackets");
486             do_udp_errors = 0;
487             error("DISABLED: ipv4.udperrors");
488         } else {
489             if (likely(do_udp_packets)) {
490                 st = rrdset_find_localhost("ipv4.udppackets");
491                 if (unlikely(!st)) {
492                     st = rrdset_create_localhost("ipv4", "udppackets", NULL, "udp", NULL, "IPv4 UDP Packets"
493                                                  , "packets/s", 2601, update_every, RRDSET_TYPE_LINE);
494
495                     rrddim_add(st, "InDatagrams", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
496                     rrddim_add(st, "OutDatagrams", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
497                 } else
498                     rrdset_next(st);
499
500                 rrddim_set(st, "InDatagrams", udpstat.udps_ipackets);
501                 rrddim_set(st, "OutDatagrams", udpstat.udps_opackets);
502                 rrdset_done(st);
503             }
504
505             // --------------------------------------------------------------------
506
507             if (likely(do_udp_errors)) {
508                 st = rrdset_find_localhost("ipv4.udperrors");
509                 if (unlikely(!st)) {
510                     st = rrdset_create_localhost("ipv4", "udperrors", NULL, "udp", NULL, "IPv4 UDP Errors", "events/s"
511                                                  , 2701, update_every, RRDSET_TYPE_LINE);
512                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
513
514                     rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
515                     rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
516                     rrddim_add(st, "NoPorts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
517                     rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
518                     rrddim_add(st, "IgnoredMulti", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
519                 } else
520                     rrdset_next(st);
521
522                 rrddim_set(st, "InErrors", udpstat.udps_hdrops + udpstat.udps_badlen);
523                 rrddim_set(st, "NoPorts", udpstat.udps_noport);
524                 rrddim_set(st, "RcvbufErrors", udpstat.udps_fullsock);
525                 rrddim_set(st, "InCsumErrors", udpstat.udps_badsum + udpstat.udps_nosum);
526                 rrddim_set(st, "IgnoredMulti", udpstat.udps_filtermcast);
527                 rrdset_done(st);
528             }
529         }
530     }
531
532     // --------------------------------------------------------------------
533
534     if (likely(do_icmp_packets || do_icmpmsg)) {
535         if (unlikely(GETSYSCTL_BY_NAME("net.inet.icmp.stats", icmpstat))) {
536             do_icmp_packets = 0;
537             error("DISABLED: ipv4.icmp");
538             error("DISABLED: ipv4.icmp_errors");
539             do_icmpmsg = 0;
540             error("DISABLED: ipv4.icmpmsg");
541         } else {
542             for (i = 0; i <= ICMP_MAXTYPE; i++) {
543                 icmp_total.msgs_in += icmpstat.icps_inhist[i];
544                 icmp_total.msgs_out += icmpstat.icps_outhist[i];
545             }
546             icmp_total.msgs_in += icmpstat.icps_badcode + icmpstat.icps_badlen + icmpstat.icps_checksum + icmpstat.icps_tooshort;
547
548             // --------------------------------------------------------------------
549
550             if (likely(do_icmp_packets)) {
551                 st = rrdset_find_localhost("ipv4.icmp");
552                 if (unlikely(!st)) {
553                     st = rrdset_create_localhost("ipv4", "icmp", NULL, "icmp", NULL, "IPv4 ICMP Packets", "packets/s"
554                                                  , 2602, update_every, RRDSET_TYPE_LINE);
555
556                     rrddim_add(st, "InMsgs", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
557                     rrddim_add(st, "OutMsgs", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
558                 } else
559                     rrdset_next(st);
560
561                 rrddim_set(st, "InMsgs", icmp_total.msgs_in);
562                 rrddim_set(st, "OutMsgs", icmp_total.msgs_out);
563
564                 rrdset_done(st);
565
566                 // --------------------------------------------------------------------
567
568                 st = rrdset_find_localhost("ipv4.icmp_errors");
569                 if (unlikely(!st)) {
570                     st = rrdset_create_localhost("ipv4", "icmp_errors", NULL, "icmp", NULL, "IPv4 ICMP Errors"
571                                                  , "packets/s", 2603, update_every, RRDSET_TYPE_LINE);
572
573                     rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
574                     rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
575                     rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
576                 } else
577                     rrdset_next(st);
578
579                 rrddim_set(st, "InErrors", icmpstat.icps_badcode + icmpstat.icps_badlen + icmpstat.icps_checksum + icmpstat.icps_tooshort);
580                 rrddim_set(st, "OutErrors", icmpstat.icps_error);
581                 rrddim_set(st, "InCsumErrors", icmpstat.icps_checksum);
582
583                 rrdset_done(st);
584             }
585
586             // --------------------------------------------------------------------
587
588             if (likely(do_icmpmsg)) {
589                 st = rrdset_find_localhost("ipv4.icmpmsg");
590                 if (unlikely(!st)) {
591                     st = rrdset_create_localhost("ipv4", "icmpmsg", NULL, "icmp", NULL, "IPv4 ICMP Messsages"
592                                                  , "packets/s", 2604, update_every, RRDSET_TYPE_LINE);
593
594                     rrddim_add(st, "InEchoReps", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
595                     rrddim_add(st, "OutEchoReps", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
596                     rrddim_add(st, "InEchos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
597                     rrddim_add(st, "OutEchos", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
598                 } else
599                     rrdset_next(st);
600
601                     rrddim_set(st, "InEchoReps", icmpstat.icps_inhist[ICMP_ECHOREPLY]);
602                     rrddim_set(st, "OutEchoReps", icmpstat.icps_outhist[ICMP_ECHOREPLY]);
603                     rrddim_set(st, "InEchos", icmpstat.icps_inhist[ICMP_ECHO]);
604                     rrddim_set(st, "OutEchos", icmpstat.icps_outhist[ICMP_ECHO]);
605
606                 rrdset_done(st);
607             }
608         }
609     }
610
611     // --------------------------------------------------------------------
612
613     // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html
614     if (likely(do_ip_packets || do_ip_fragsout || do_ip_fragsin || do_ip_errors)) {
615         if (unlikely(GETSYSCTL_BY_NAME("net.inet.ip.stats", ipstat))) {
616             do_ip_packets = 0;
617             error("DISABLED: ipv4.packets");
618             do_ip_fragsout = 0;
619             error("DISABLED: ipv4.fragsout");
620             do_ip_fragsin = 0;
621             error("DISABLED: ipv4.fragsin");
622             do_ip_errors = 0;
623             error("DISABLED: ipv4.errors");
624         } else {
625             if (likely(do_ip_packets)) {
626                 st = rrdset_find_localhost("ipv4.packets");
627                 if (unlikely(!st)) {
628                     st = rrdset_create_localhost("ipv4", "packets", NULL, "packets", NULL, "IPv4 Packets", "packets/s"
629                                                  , 3000, update_every, RRDSET_TYPE_LINE);
630
631                     rrddim_add(st, "InReceives", "received", 1, 1, RRD_ALGORITHM_INCREMENTAL);
632                     rrddim_add(st, "OutRequests", "sent", -1, 1, RRD_ALGORITHM_INCREMENTAL);
633                     rrddim_add(st, "ForwDatagrams", "forwarded", 1, 1, RRD_ALGORITHM_INCREMENTAL);
634                     rrddim_add(st, "InDelivers", "delivered", 1, 1, RRD_ALGORITHM_INCREMENTAL);
635                 } else
636                     rrdset_next(st);
637
638                 rrddim_set(st, "OutRequests", ipstat.ips_localout);
639                 rrddim_set(st, "InReceives", ipstat.ips_total);
640                 rrddim_set(st, "ForwDatagrams", ipstat.ips_forward);
641                 rrddim_set(st, "InDelivers", ipstat.ips_delivered);
642                 rrdset_done(st);
643             }
644
645             // --------------------------------------------------------------------
646
647             if (likely(do_ip_fragsout)) {
648                 st = rrdset_find_localhost("ipv4.fragsout");
649                 if (unlikely(!st)) {
650                     st = rrdset_create_localhost("ipv4", "fragsout", NULL, "fragments", NULL, "IPv4 Fragments Sent"
651                                                  , "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
652                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
653
654                     rrddim_add(st, "FragOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
655                     rrddim_add(st, "FragFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
656                     rrddim_add(st, "FragCreates", "created", 1, 1, RRD_ALGORITHM_INCREMENTAL);
657                 } else
658                     rrdset_next(st);
659
660                 rrddim_set(st, "FragOKs", ipstat.ips_fragmented);
661                 rrddim_set(st, "FragFails", ipstat.ips_cantfrag);
662                 rrddim_set(st, "FragCreates", ipstat.ips_ofragments);
663                 rrdset_done(st);
664             }
665
666             // --------------------------------------------------------------------
667
668             if (likely(do_ip_fragsin)) {
669                 st = rrdset_find_localhost("ipv4.fragsin");
670                 if (unlikely(!st)) {
671                     st = rrdset_create_localhost("ipv4", "fragsin", NULL, "fragments", NULL, "IPv4 Fragments Reassembly"
672                                                  , "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
673                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
674
675                     rrddim_add(st, "ReasmOKs", "ok", 1, 1, RRD_ALGORITHM_INCREMENTAL);
676                     rrddim_add(st, "ReasmFails", "failed", -1, 1, RRD_ALGORITHM_INCREMENTAL);
677                     rrddim_add(st, "ReasmReqds", "all", 1, 1, RRD_ALGORITHM_INCREMENTAL);
678                 } else
679                     rrdset_next(st);
680
681                 rrddim_set(st, "ReasmOKs", ipstat.ips_fragments);
682                 rrddim_set(st, "ReasmFails", ipstat.ips_fragdropped);
683                 rrddim_set(st, "ReasmReqds", ipstat.ips_reassembled);
684                 rrdset_done(st);
685             }
686
687             // --------------------------------------------------------------------
688
689             if (likely(do_ip_errors)) {
690                 st = rrdset_find_localhost("ipv4.errors");
691                 if (unlikely(!st)) {
692                     st = rrdset_create_localhost("ipv4", "errors", NULL, "errors", NULL, "IPv4 Errors", "packets/s"
693                                                  , 3002, update_every, RRDSET_TYPE_LINE);
694                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
695
696                     rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
697                     rrddim_add(st, "OutDiscards", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
698
699                     rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
700                     rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
701
702                     rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
703                     rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
704                 } else
705                     rrdset_next(st);
706
707                 rrddim_set(st, "InDiscards", ipstat.ips_badsum + ipstat.ips_tooshort + ipstat.ips_toosmall + ipstat.ips_toolong);
708                 rrddim_set(st, "OutDiscards", ipstat.ips_odropped);
709                 rrddim_set(st, "InHdrErrors", ipstat.ips_badhlen + ipstat.ips_badlen + ipstat.ips_badoptions + ipstat.ips_badvers);
710                 rrddim_set(st, "InAddrErrors", ipstat.ips_badaddr);
711                 rrddim_set(st, "InUnknownProtos", ipstat.ips_noproto);
712                 rrddim_set(st, "OutNoRoutes", ipstat.ips_noroute);
713                 rrdset_done(st);
714             }
715         }
716     }
717  
718     // --------------------------------------------------------------------
719
720     if (likely(do_ip6_packets || do_ip6_fragsout || do_ip6_fragsin || do_ip6_errors)) {
721         if (unlikely(GETSYSCTL_BY_NAME("net.inet6.ip6.stats", ip6stat))) {
722             do_ip6_packets = 0;
723             error("DISABLED: ipv6.packets");
724             do_ip6_fragsout = 0;
725             error("DISABLED: ipv6.fragsout");
726             do_ip6_fragsin = 0;
727             error("DISABLED: ipv6.fragsin");
728             do_ip6_errors = 0;
729             error("DISABLED: ipv6.errors");
730         } else {
731             if (do_ip6_packets == CONFIG_BOOLEAN_YES || (do_ip6_packets == CONFIG_BOOLEAN_AUTO &&
732                                                           (ip6stat.ip6s_localout || ip6stat.ip6s_total ||
733                                                            ip6stat.ip6s_forward || ip6stat.ip6s_delivered))) {
734                 do_ip6_packets = CONFIG_BOOLEAN_YES;
735                 st = rrdset_find_localhost("ipv6.packets");
736                 if (unlikely(!st)) {
737                     st = rrdset_create_localhost("ipv6", "packets", NULL, "packets", NULL, "IPv6 Packets", "packets/s"
738                                                  , 3000, update_every, RRDSET_TYPE_LINE);
739
740                     rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
741                     rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
742                     rrddim_add(st, "forwarded", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
743                     rrddim_add(st, "delivers", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
744                 } else
745                     rrdset_next(st);
746
747                 rrddim_set(st, "sent", ip6stat.ip6s_localout);
748                 rrddim_set(st, "received", ip6stat.ip6s_total);
749                 rrddim_set(st, "forwarded", ip6stat.ip6s_forward);
750                 rrddim_set(st, "delivers", ip6stat.ip6s_delivered);
751                 rrdset_done(st);
752             }
753
754             // --------------------------------------------------------------------
755
756             if (do_ip6_fragsout == CONFIG_BOOLEAN_YES || (do_ip6_fragsout == CONFIG_BOOLEAN_AUTO &&
757                                                            (ip6stat.ip6s_fragmented || ip6stat.ip6s_cantfrag ||
758                                                             ip6stat.ip6s_ofragments))) {
759                 do_ip6_fragsout = CONFIG_BOOLEAN_YES;
760                 st = rrdset_find_localhost("ipv6.fragsout");
761                 if (unlikely(!st)) {
762                     st = rrdset_create_localhost("ipv6", "fragsout", NULL, "fragments", NULL, "IPv6 Fragments Sent"
763                                                  , "packets/s", 3010, update_every, RRDSET_TYPE_LINE);
764                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
765
766                     rrddim_add(st, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
767                     rrddim_add(st, "failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
768                     rrddim_add(st, "all", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
769                 } else
770                     rrdset_next(st);
771
772                 rrddim_set(st, "ok", ip6stat.ip6s_fragmented);
773                 rrddim_set(st, "failed", ip6stat.ip6s_cantfrag);
774                 rrddim_set(st, "all", ip6stat.ip6s_ofragments);
775                 rrdset_done(st);
776             }
777
778             // --------------------------------------------------------------------
779
780             if (do_ip6_fragsin == CONFIG_BOOLEAN_YES || (do_ip6_fragsin == CONFIG_BOOLEAN_AUTO &&
781                                                           (ip6stat.ip6s_reassembled || ip6stat.ip6s_fragdropped ||
782                                                            ip6stat.ip6s_fragtimeout || ip6stat.ip6s_fragments))) {
783                 do_ip6_fragsin = CONFIG_BOOLEAN_YES;
784                 st = rrdset_find_localhost("ipv6.fragsin");
785                 if (unlikely(!st)) {
786                     st = rrdset_create_localhost("ipv6", "fragsin", NULL, "fragments", NULL, "IPv6 Fragments Reassembly"
787                                                  , "packets/s", 3011, update_every, RRDSET_TYPE_LINE);
788                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
789
790                     rrddim_add(st, "ok", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
791                     rrddim_add(st, "failed", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
792                     rrddim_add(st, "timeout", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
793                     rrddim_add(st, "all", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
794                 } else
795                     rrdset_next(st);
796
797                 rrddim_set(st, "ok", ip6stat.ip6s_reassembled);
798                 rrddim_set(st, "failed", ip6stat.ip6s_fragdropped);
799                 rrddim_set(st, "timeout", ip6stat.ip6s_fragtimeout);
800                 rrddim_set(st, "all", ip6stat.ip6s_fragments);
801                 rrdset_done(st);
802             }
803
804             // --------------------------------------------------------------------
805
806             if (do_ip6_errors == CONFIG_BOOLEAN_YES || (do_ip6_errors == CONFIG_BOOLEAN_AUTO && (
807                     ip6stat.ip6s_toosmall ||
808                     ip6stat.ip6s_odropped ||
809                     ip6stat.ip6s_badoptions ||
810                     ip6stat.ip6s_badvers ||
811                     ip6stat.ip6s_exthdrtoolong ||
812                     ip6stat.ip6s_sources_none ||
813                     ip6stat.ip6s_tooshort ||
814                     ip6stat.ip6s_cantforward ||
815                     ip6stat.ip6s_noroute))) {
816                 do_ip6_errors = CONFIG_BOOLEAN_YES;
817                 st = rrdset_find_localhost("ipv6.errors");
818                 if (unlikely(!st)) {
819                     st = rrdset_create_localhost("ipv6", "errors", NULL, "errors", NULL, "IPv6 Errors", "packets/s"
820                                                  , 3002, update_every, RRDSET_TYPE_LINE);
821                     rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
822
823                     rrddim_add(st, "InDiscards", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
824                     rrddim_add(st, "OutDiscards", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
825
826                     rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
827                     rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
828                     rrddim_add(st, "InTruncatedPkts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
829                     rrddim_add(st, "InNoRoutes", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
830
831                     rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
832                 } else
833                     rrdset_next(st);
834
835                 rrddim_set(st, "InDiscards", ip6stat.ip6s_toosmall);
836                 rrddim_set(st, "OutDiscards", ip6stat.ip6s_odropped);
837
838                 rrddim_set(st, "InHdrErrors",
839                            ip6stat.ip6s_badoptions + ip6stat.ip6s_badvers + ip6stat.ip6s_exthdrtoolong);
840                 rrddim_set(st, "InAddrErrors", ip6stat.ip6s_sources_none);
841                 rrddim_set(st, "InTruncatedPkts", ip6stat.ip6s_tooshort);
842                 rrddim_set(st, "InNoRoutes", ip6stat.ip6s_cantforward);
843
844                 rrddim_set(st, "OutNoRoutes", ip6stat.ip6s_noroute);
845                 rrdset_done(st);
846             }
847         }
848     }
849
850     // --------------------------------------------------------------------
851
852     if (likely(do_icmp6 || do_icmp6_redir || do_icmp6_errors || do_icmp6_echos || do_icmp6_router || do_icmp6_neighbor || do_icmp6_types)) {
853         if (unlikely(GETSYSCTL_BY_NAME("net.inet6.icmp6.stats", icmp6stat))) {
854             do_icmp6 = 0;
855             error("DISABLED: ipv6.icmp");
856         } else {
857             for (i = 0; i <= ICMP6_MAXTYPE; i++) {
858                 icmp6_total.msgs_in += icmp6stat.icp6s_inhist[i];
859                 icmp6_total.msgs_out += icmp6stat.icp6s_outhist[i];
860             }
861             icmp6_total.msgs_in += icmp6stat.icp6s_badcode + icmp6stat.icp6s_badlen + icmp6stat.icp6s_checksum + icmp6stat.icp6s_tooshort;
862             if (do_icmp6 == CONFIG_BOOLEAN_YES || (do_icmp6 == CONFIG_BOOLEAN_AUTO && (icmp6_total.msgs_in || icmp6_total.msgs_out))) {
863                 do_icmp6 = CONFIG_BOOLEAN_YES;
864                 st = rrdset_find_localhost("ipv6.icmp");
865                 if (unlikely(!st)) {
866                     st = rrdset_create_localhost("ipv6", "icmp", NULL, "icmp", NULL, "IPv6 ICMP Messages", "messages/s"
867                                                  , 10000, update_every, RRDSET_TYPE_LINE);
868
869                     rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
870                     rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
871                 } else
872                     rrdset_next(st);
873
874                 rrddim_set(st, "sent", icmp6_total.msgs_in);
875                 rrddim_set(st, "received", icmp6_total.msgs_out);
876                 rrdset_done(st);
877             }
878
879             // --------------------------------------------------------------------
880
881             if (do_icmp6_redir == CONFIG_BOOLEAN_YES || (do_icmp6_redir == CONFIG_BOOLEAN_AUTO && (icmp6stat.icp6s_inhist[ND_REDIRECT] || icmp6stat.icp6s_outhist[ND_REDIRECT]))) {
882                 do_icmp6_redir = CONFIG_BOOLEAN_YES;
883                 st = rrdset_find_localhost("ipv6.icmpredir");
884                 if (unlikely(!st)) {
885                     st = rrdset_create_localhost("ipv6", "icmpredir", NULL, "icmp", NULL, "IPv6 ICMP Redirects"
886                                                  , "redirects/s", 10050, update_every, RRDSET_TYPE_LINE);
887
888                     rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
889                     rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
890                 } else
891                     rrdset_next(st);
892
893                 rrddim_set(st, "sent", icmp6stat.icp6s_inhist[ND_REDIRECT]);
894                 rrddim_set(st, "received", icmp6stat.icp6s_outhist[ND_REDIRECT]);
895                 rrdset_done(st);
896             }
897
898             // --------------------------------------------------------------------
899
900             if (do_icmp6_errors == CONFIG_BOOLEAN_YES || (do_icmp6_errors == CONFIG_BOOLEAN_AUTO && (
901                                                                             icmp6stat.icp6s_badcode ||
902                                                                             icmp6stat.icp6s_badlen ||
903                                                                             icmp6stat.icp6s_checksum ||
904                                                                             icmp6stat.icp6s_tooshort ||
905                                                                             icmp6stat.icp6s_error ||
906                                                                             icmp6stat.icp6s_inhist[ICMP6_DST_UNREACH] ||
907                                                                             icmp6stat.icp6s_inhist[ICMP6_TIME_EXCEEDED] ||
908                                                                             icmp6stat.icp6s_inhist[ICMP6_PARAM_PROB] ||
909                                                                             icmp6stat.icp6s_outhist[ICMP6_DST_UNREACH] ||
910                                                                             icmp6stat.icp6s_outhist[ICMP6_TIME_EXCEEDED] ||
911                                                                             icmp6stat.icp6s_outhist[ICMP6_PARAM_PROB]))) {
912                 do_icmp6_errors = CONFIG_BOOLEAN_YES;
913                 st = rrdset_find_localhost("ipv6.icmperrors");
914                 if (unlikely(!st)) {
915                     st = rrdset_create_localhost("ipv6", "icmperrors", NULL, "icmp", NULL, "IPv6 ICMP Errors"
916                                                  , "errors/s", 10100, update_every, RRDSET_TYPE_LINE);
917
918                     rrddim_add(st, "InErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
919                     rrddim_add(st, "OutErrors", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
920
921                     rrddim_add(st, "InCsumErrors", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
922                     rrddim_add(st, "InDestUnreachs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
923                     rrddim_add(st, "InPktTooBigs", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
924                     rrddim_add(st, "InTimeExcds", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
925                     rrddim_add(st, "InParmProblems", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
926                     rrddim_add(st, "OutDestUnreachs", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
927                     rrddim_add(st, "OutTimeExcds", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
928                     rrddim_add(st, "OutParmProblems", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
929                 } else
930                     rrdset_next(st);
931
932                 rrddim_set(st, "InErrors", icmp6stat.icp6s_badcode + icmp6stat.icp6s_badlen + icmp6stat.icp6s_checksum + icmp6stat.icp6s_tooshort);
933                 rrddim_set(st, "OutErrors", icmp6stat.icp6s_error);
934                 rrddim_set(st, "InCsumErrors", icmp6stat.icp6s_checksum);
935                 rrddim_set(st, "InDestUnreachs", icmp6stat.icp6s_inhist[ICMP6_DST_UNREACH]);
936                 rrddim_set(st, "InPktTooBigs", icmp6stat.icp6s_badlen);
937                 rrddim_set(st, "InTimeExcds", icmp6stat.icp6s_inhist[ICMP6_TIME_EXCEEDED]);
938                 rrddim_set(st, "InParmProblems", icmp6stat.icp6s_inhist[ICMP6_PARAM_PROB]);
939                 rrddim_set(st, "OutDestUnreachs", icmp6stat.icp6s_outhist[ICMP6_DST_UNREACH]);
940                 rrddim_set(st, "OutTimeExcds", icmp6stat.icp6s_outhist[ICMP6_TIME_EXCEEDED]);
941                 rrddim_set(st, "OutParmProblems", icmp6stat.icp6s_outhist[ICMP6_PARAM_PROB]);
942                 rrdset_done(st);
943             }
944
945             // --------------------------------------------------------------------
946
947             if (do_icmp6_echos == CONFIG_BOOLEAN_YES || (do_icmp6_echos == CONFIG_BOOLEAN_AUTO && (
948                                                                  icmp6stat.icp6s_inhist[ICMP6_ECHO_REQUEST] ||
949                                                                  icmp6stat.icp6s_outhist[ICMP6_ECHO_REQUEST] ||
950                                                                  icmp6stat.icp6s_inhist[ICMP6_ECHO_REPLY] ||
951                                                                  icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]))) {
952                 do_icmp6_echos = CONFIG_BOOLEAN_YES;
953                 st = rrdset_find_localhost("ipv6.icmpechos");
954                 if (unlikely(!st)) {
955                     st = rrdset_create_localhost("ipv6", "icmpechos", NULL, "icmp", NULL, "IPv6 ICMP Echo", "messages/s"
956                                                  , 10200, update_every, RRDSET_TYPE_LINE);
957
958                     rrddim_add(st, "InEchos", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
959                     rrddim_add(st, "OutEchos", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
960                     rrddim_add(st, "InEchoReplies", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
961                     rrddim_add(st, "OutEchoReplies", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
962                 } else
963                     rrdset_next(st);
964
965                 rrddim_set(st, "InEchos", icmp6stat.icp6s_inhist[ICMP6_ECHO_REQUEST]);
966                 rrddim_set(st, "OutEchos", icmp6stat.icp6s_outhist[ICMP6_ECHO_REQUEST]);
967                 rrddim_set(st, "InEchoReplies", icmp6stat.icp6s_inhist[ICMP6_ECHO_REPLY]);
968                 rrddim_set(st, "OutEchoReplies", icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]);
969                 rrdset_done(st);
970             }
971
972             // --------------------------------------------------------------------
973
974             if (do_icmp6_router == CONFIG_BOOLEAN_YES || (do_icmp6_router == CONFIG_BOOLEAN_AUTO && (
975                                                                     icmp6stat.icp6s_inhist[ND_ROUTER_SOLICIT] ||
976                                                                     icmp6stat.icp6s_outhist[ND_ROUTER_SOLICIT] ||
977                                                                     icmp6stat.icp6s_inhist[ND_ROUTER_ADVERT] ||
978                                                                     icmp6stat.icp6s_outhist[ND_ROUTER_ADVERT]))) {
979                 do_icmp6_router = CONFIG_BOOLEAN_YES;
980                 st = rrdset_find_localhost("ipv6.icmprouter");
981                 if (unlikely(!st)) {
982                     st = rrdset_create_localhost("ipv6", "icmprouter", NULL, "icmp", NULL, "IPv6 Router Messages"
983                                                  , "messages/s", 10400, update_every, RRDSET_TYPE_LINE);
984
985                     rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
986                     rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
987                     rrddim_add(st, "InAdvertisements", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
988                     rrddim_add(st, "OutAdvertisements", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
989                 } else
990                     rrdset_next(st);
991
992                 rrddim_set(st, "InSolicits", icmp6stat.icp6s_inhist[ND_ROUTER_SOLICIT]);
993                 rrddim_set(st, "OutSolicits", icmp6stat.icp6s_outhist[ND_ROUTER_SOLICIT]);
994                 rrddim_set(st, "InAdvertisements", icmp6stat.icp6s_inhist[ND_ROUTER_ADVERT]);
995                 rrddim_set(st, "OutAdvertisements", icmp6stat.icp6s_outhist[ND_ROUTER_ADVERT]);
996                 rrdset_done(st);
997             }
998
999             // --------------------------------------------------------------------
1000
1001             if (do_icmp6_neighbor == CONFIG_BOOLEAN_YES || (do_icmp6_neighbor == CONFIG_BOOLEAN_AUTO && (
1002                                                                     icmp6stat.icp6s_inhist[ND_NEIGHBOR_SOLICIT] ||
1003                                                                     icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT] ||
1004                                                                     icmp6stat.icp6s_inhist[ND_NEIGHBOR_ADVERT] ||
1005                                                                     icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]))) {
1006                 do_icmp6_neighbor = CONFIG_BOOLEAN_YES;
1007                 st = rrdset_find_localhost("ipv6.icmpneighbor");
1008                 if (unlikely(!st)) {
1009                     st = rrdset_create_localhost("ipv6", "icmpneighbor", NULL, "icmp", NULL, "IPv6 Neighbor Messages"
1010                                                  , "messages/s", 10500, update_every, RRDSET_TYPE_LINE);
1011
1012                     rrddim_add(st, "InSolicits", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1013                     rrddim_add(st, "OutSolicits", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1014                     rrddim_add(st, "InAdvertisements", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1015                     rrddim_add(st, "OutAdvertisements", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1016                 } else
1017                     rrdset_next(st);
1018
1019                 rrddim_set(st, "InSolicits", icmp6stat.icp6s_inhist[ND_NEIGHBOR_SOLICIT]);
1020                 rrddim_set(st, "OutSolicits", icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]);
1021                 rrddim_set(st, "InAdvertisements", icmp6stat.icp6s_inhist[ND_NEIGHBOR_ADVERT]);
1022                 rrddim_set(st, "OutAdvertisements", icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]);
1023                 rrdset_done(st);
1024             }
1025
1026             // --------------------------------------------------------------------
1027
1028             if (do_icmp6_types == CONFIG_BOOLEAN_YES || (do_icmp6_types == CONFIG_BOOLEAN_AUTO && (
1029                                                                     icmp6stat.icp6s_inhist[1] ||
1030                                                                     icmp6stat.icp6s_inhist[128] ||
1031                                                                     icmp6stat.icp6s_inhist[129] ||
1032                                                                     icmp6stat.icp6s_inhist[136] ||
1033                                                                     icmp6stat.icp6s_outhist[1] ||
1034                                                                     icmp6stat.icp6s_outhist[128] ||
1035                                                                     icmp6stat.icp6s_outhist[129] ||
1036                                                                     icmp6stat.icp6s_outhist[133] ||
1037                                                                     icmp6stat.icp6s_outhist[135] ||
1038                                                                     icmp6stat.icp6s_outhist[136]))) {
1039                 do_icmp6_types = CONFIG_BOOLEAN_YES;
1040                 st = rrdset_find_localhost("ipv6.icmptypes");
1041                 if (unlikely(!st)) {
1042                     st = rrdset_create_localhost("ipv6", "icmptypes", NULL, "icmp", NULL, "IPv6 ICMP Types"
1043                                                  , "messages/s", 10700, update_every, RRDSET_TYPE_LINE);
1044
1045                     rrddim_add(st, "InType1", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1046                     rrddim_add(st, "InType128", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1047                     rrddim_add(st, "InType129", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1048                     rrddim_add(st, "InType136", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
1049                     rrddim_add(st, "OutType1", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1050                     rrddim_add(st, "OutType128", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1051                     rrddim_add(st, "OutType129", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1052                     rrddim_add(st, "OutType133", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1053                     rrddim_add(st, "OutType135", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1054                     rrddim_add(st, "OutType143", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
1055                 } else
1056                     rrdset_next(st);
1057
1058                 rrddim_set(st, "InType1", icmp6stat.icp6s_inhist[1]);
1059                 rrddim_set(st, "InType128", icmp6stat.icp6s_inhist[128]);
1060                 rrddim_set(st, "InType129", icmp6stat.icp6s_inhist[129]);
1061                 rrddim_set(st, "InType136", icmp6stat.icp6s_inhist[136]);
1062                 rrddim_set(st, "OutType1", icmp6stat.icp6s_outhist[1]);
1063                 rrddim_set(st, "OutType128", icmp6stat.icp6s_outhist[128]);
1064                 rrddim_set(st, "OutType129", icmp6stat.icp6s_outhist[129]);
1065                 rrddim_set(st, "OutType133", icmp6stat.icp6s_outhist[133]);
1066                 rrddim_set(st, "OutType135", icmp6stat.icp6s_outhist[135]);
1067                 rrddim_set(st, "OutType143", icmp6stat.icp6s_outhist[143]);
1068                 rrdset_done(st);
1069             }
1070         }
1071     }
1072
1073     // --------------------------------------------------------------------
1074
1075     if (likely(do_uptime)) {
1076         if (unlikely(GETSYSCTL_BY_NAME("kern.boottime", boot_time))) {
1077             do_uptime = 0;
1078             error("DISABLED: system.uptime");
1079         } else {
1080             clock_gettime(CLOCK_REALTIME, &cur_time);
1081             st = rrdset_find_localhost("system.uptime");
1082
1083             if(unlikely(!st)) {
1084                 st = rrdset_create_localhost("system", "uptime", NULL, "uptime", NULL, "System Uptime", "seconds", 1000
1085                                              , update_every, RRDSET_TYPE_LINE);
1086                 rrddim_add(st, "uptime", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1087             }
1088             else rrdset_next(st);
1089
1090             rrddim_set(st, "uptime", cur_time.tv_sec - boot_time.tv_sec);
1091             rrdset_done(st);
1092         }
1093     }
1094
1095     return 0;
1096 }
1097
1098 int getsysctl_by_name(const char *name, void *ptr, size_t len)
1099 {
1100     size_t nlen = len;
1101
1102     if (unlikely(sysctlbyname(name, ptr, &nlen, NULL, 0) == -1)) {
1103         error("MACOS: sysctl(%s...) failed: %s", name, strerror(errno));
1104         return 1;
1105     }
1106     if (unlikely(nlen != len)) {
1107         error("MACOS: sysctl(%s...) expected %lu, got %lu", name, (unsigned long)len, (unsigned long)nlen);
1108         return 1;
1109     }
1110     return 0;
1111 }