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