#include "common.h" #define RRD_TYPE_NET_SNMP "ipv4" #define RRD_TYPE_NET_SNMP_LEN strlen(RRD_TYPE_NET_SNMP) int do_proc_net_snmp(int update_every, unsigned long long dt) { static procfile *ff = NULL; static int do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1, do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1, do_udp_packets = -1, do_udp_errors = -1; if(do_ip_packets == -1) do_ip_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 packets", 1); if(do_ip_fragsout == -1) do_ip_fragsout = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments sent", 1); if(do_ip_fragsin == -1) do_ip_fragsin = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 fragments assembly", 1); if(do_ip_errors == -1) do_ip_errors = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 errors", 1); if(do_tcp_sockets == -1) do_tcp_sockets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP connections", 1); if(do_tcp_packets == -1) do_tcp_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP packets", 1); if(do_tcp_errors == -1) do_tcp_errors = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP errors", 1); if(do_tcp_handshake == -1) do_tcp_handshake = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 TCP handshake issues", 1); if(do_udp_packets == -1) do_udp_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP packets", 1); if(do_udp_errors == -1) do_udp_errors = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 UDP errors", 1); if(dt) {}; if(!ff) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/net/snmp"); ff = procfile_open(config_get("plugin:proc:/proc/net/snmp", "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT); } if(!ff) return 1; ff = procfile_readall(ff); if(!ff) return 0; // we return 0, so that we will retry to open it next time uint32_t lines = procfile_lines(ff), l; uint32_t words; RRDSET *st; for(l = 0; l < lines ;l++) { if(strcmp(procfile_lineword(ff, l, 0), "Ip") == 0) { l++; if(strcmp(procfile_lineword(ff, l, 0), "Ip") != 0) { error("Cannot read Ip line from /proc/net/snmp."); break; } words = procfile_linewords(ff, l); if(words < 20) { error("Cannot read /proc/net/snmp Ip line. Expected 20 params, read %u.", words); continue; } // see also http://net-snmp.sourceforge.net/docs/mibs/ip.html unsigned long long Forwarding, DefaultTTL, InReceives, InHdrErrors, InAddrErrors, ForwDatagrams, InUnknownProtos, InDiscards, InDelivers, OutRequests, OutDiscards, OutNoRoutes, ReasmTimeout, ReasmReqds, ReasmOKs, ReasmFails, FragOKs, FragFails, FragCreates; Forwarding = strtoull(procfile_lineword(ff, l, 1), NULL, 10); DefaultTTL = strtoull(procfile_lineword(ff, l, 2), NULL, 10); InReceives = strtoull(procfile_lineword(ff, l, 3), NULL, 10); InHdrErrors = strtoull(procfile_lineword(ff, l, 4), NULL, 10); InAddrErrors = strtoull(procfile_lineword(ff, l, 5), NULL, 10); ForwDatagrams = strtoull(procfile_lineword(ff, l, 6), NULL, 10); InUnknownProtos = strtoull(procfile_lineword(ff, l, 7), NULL, 10); InDiscards = strtoull(procfile_lineword(ff, l, 8), NULL, 10); InDelivers = strtoull(procfile_lineword(ff, l, 9), NULL, 10); OutRequests = strtoull(procfile_lineword(ff, l, 10), NULL, 10); OutDiscards = strtoull(procfile_lineword(ff, l, 11), NULL, 10); OutNoRoutes = strtoull(procfile_lineword(ff, l, 12), NULL, 10); ReasmTimeout = strtoull(procfile_lineword(ff, l, 13), NULL, 10); ReasmReqds = strtoull(procfile_lineword(ff, l, 14), NULL, 10); ReasmOKs = strtoull(procfile_lineword(ff, l, 15), NULL, 10); ReasmFails = strtoull(procfile_lineword(ff, l, 16), NULL, 10); FragOKs = strtoull(procfile_lineword(ff, l, 17), NULL, 10); FragFails = strtoull(procfile_lineword(ff, l, 18), NULL, 10); FragCreates = strtoull(procfile_lineword(ff, l, 19), NULL, 10); // these are not counters if(Forwarding) {}; // is forwarding enabled? if(DefaultTTL) {}; // the default ttl on packets if(ReasmTimeout) {}; // Reassembly timeout // this counter is not used if(InDelivers) {}; // total number of packets delivered to IP user-protocols // -------------------------------------------------------------------- if(do_ip_packets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".packets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "packets", NULL, "packets", NULL, "IPv4 Packets", "packets/s", 3000, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "forwarded", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "sent", OutRequests); rrddim_set(st, "received", InReceives); rrddim_set(st, "forwarded", ForwDatagrams); rrdset_done(st); } // -------------------------------------------------------------------- if(do_ip_fragsout) { st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsout"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsout", NULL, "fragments", NULL, "IPv4 Fragments Sent", "packets/s", 3010, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "ok", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "failed", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "all", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "ok", FragOKs); rrddim_set(st, "failed", FragFails); rrddim_set(st, "all", FragCreates); rrdset_done(st); } // -------------------------------------------------------------------- if(do_ip_fragsin) { st = rrdset_find(RRD_TYPE_NET_SNMP ".fragsin"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "fragsin", NULL, "fragments", NULL, "IPv4 Fragments Reassembly", "packets/s", 3011, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "ok", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "failed", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "all", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "ok", ReasmOKs); rrddim_set(st, "failed", ReasmFails); rrddim_set(st, "all", ReasmReqds); rrdset_done(st); } // -------------------------------------------------------------------- if(do_ip_errors) { st = rrdset_find(RRD_TYPE_NET_SNMP ".errors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "errors", NULL, "errors", NULL, "IPv4 Errors", "packets/s", 3002, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InDiscards", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutDiscards", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InHdrErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InAddrErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InUnknownProtos", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutNoRoutes", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InDiscards", InDiscards); rrddim_set(st, "OutDiscards", OutDiscards); rrddim_set(st, "InHdrErrors", InHdrErrors); rrddim_set(st, "InAddrErrors", InAddrErrors); rrddim_set(st, "InUnknownProtos", InUnknownProtos); rrddim_set(st, "OutNoRoutes", OutNoRoutes); rrdset_done(st); } } else if(strcmp(procfile_lineword(ff, l, 0), "Tcp") == 0) { l++; if(strcmp(procfile_lineword(ff, l, 0), "Tcp") != 0) { error("Cannot read Tcp line from /proc/net/snmp."); break; } words = procfile_linewords(ff, l); if(words < 15) { error("Cannot read /proc/net/snmp Tcp line. Expected 15 params, read %u.", words); continue; } unsigned long long RtoAlgorithm, RtoMin, RtoMax, MaxConn, ActiveOpens, PassiveOpens, AttemptFails, EstabResets, CurrEstab, InSegs, OutSegs, RetransSegs, InErrs, OutRsts; RtoAlgorithm = strtoull(procfile_lineword(ff, l, 1), NULL, 10); RtoMin = strtoull(procfile_lineword(ff, l, 2), NULL, 10); RtoMax = strtoull(procfile_lineword(ff, l, 3), NULL, 10); MaxConn = strtoull(procfile_lineword(ff, l, 4), NULL, 10); ActiveOpens = strtoull(procfile_lineword(ff, l, 5), NULL, 10); PassiveOpens = strtoull(procfile_lineword(ff, l, 6), NULL, 10); AttemptFails = strtoull(procfile_lineword(ff, l, 7), NULL, 10); EstabResets = strtoull(procfile_lineword(ff, l, 8), NULL, 10); CurrEstab = strtoull(procfile_lineword(ff, l, 9), NULL, 10); InSegs = strtoull(procfile_lineword(ff, l, 10), NULL, 10); OutSegs = strtoull(procfile_lineword(ff, l, 11), NULL, 10); RetransSegs = strtoull(procfile_lineword(ff, l, 12), NULL, 10); InErrs = strtoull(procfile_lineword(ff, l, 13), NULL, 10); OutRsts = strtoull(procfile_lineword(ff, l, 14), NULL, 10); // these are not counters if(RtoAlgorithm) {}; if(RtoMin) {}; if(RtoMax) {}; if(MaxConn) {}; // -------------------------------------------------------------------- // see http://net-snmp.sourceforge.net/docs/mibs/tcp.html if(do_tcp_sockets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".tcpsock"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "tcpsock", NULL, "tcp", NULL, "IPv4 TCP Connections", "active connections", 2500, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "connections", NULL, 1, 1, RRDDIM_ABSOLUTE); } else rrdset_next(st); rrddim_set(st, "connections", CurrEstab); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcp_packets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".tcppackets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "tcppackets", NULL, "tcp", NULL, "IPv4 TCP Packets", "packets/s", 2600, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "received", InSegs); rrddim_set(st, "sent", OutSegs); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcp_errors) { st = rrdset_find(RRD_TYPE_NET_SNMP ".tcperrors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "tcperrors", NULL, "tcp", NULL, "IPv4 TCP Errors", "packets/s", 2700, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "InErrs", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "RetransSegs", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InErrs", InErrs); rrddim_set(st, "RetransSegs", RetransSegs); rrdset_done(st); } // -------------------------------------------------------------------- if(do_tcp_handshake) { st = rrdset_find(RRD_TYPE_NET_SNMP ".tcphandshake"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "tcphandshake", NULL, "tcp", NULL, "IPv4 TCP Handshake Issues", "events/s", 2900, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "EstabResets", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "OutRsts", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "ActiveOpens", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "PassiveOpens", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "AttemptFails", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "EstabResets", EstabResets); rrddim_set(st, "OutRsts", OutRsts); rrddim_set(st, "ActiveOpens", ActiveOpens); rrddim_set(st, "PassiveOpens", PassiveOpens); rrddim_set(st, "AttemptFails", AttemptFails); rrdset_done(st); } } else if(strcmp(procfile_lineword(ff, l, 0), "Udp") == 0) { l++; if(strcmp(procfile_lineword(ff, l, 0), "Udp") != 0) { error("Cannot read Udp line from /proc/net/snmp."); break; } words = procfile_linewords(ff, l); if(words < 7) { error("Cannot read /proc/net/snmp Udp line. Expected 7 params, read %u.", words); continue; } unsigned long long InDatagrams, NoPorts, InErrors, OutDatagrams, RcvbufErrors, SndbufErrors; InDatagrams = strtoull(procfile_lineword(ff, l, 1), NULL, 10); NoPorts = strtoull(procfile_lineword(ff, l, 2), NULL, 10); InErrors = strtoull(procfile_lineword(ff, l, 3), NULL, 10); OutDatagrams = strtoull(procfile_lineword(ff, l, 4), NULL, 10); RcvbufErrors = strtoull(procfile_lineword(ff, l, 5), NULL, 10); SndbufErrors = strtoull(procfile_lineword(ff, l, 6), NULL, 10); // -------------------------------------------------------------------- // see http://net-snmp.sourceforge.net/docs/mibs/udp.html if(do_udp_packets) { st = rrdset_find(RRD_TYPE_NET_SNMP ".udppackets"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "udppackets", NULL, "udp", NULL, "IPv4 UDP Packets", "packets/s", 2601, update_every, RRDSET_TYPE_LINE); rrddim_add(st, "received", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "sent", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "received", InDatagrams); rrddim_set(st, "sent", OutDatagrams); rrdset_done(st); } // -------------------------------------------------------------------- if(do_udp_errors) { st = rrdset_find(RRD_TYPE_NET_SNMP ".udperrors"); if(!st) { st = rrdset_create(RRD_TYPE_NET_SNMP, "udperrors", NULL, "udp", NULL, "IPv4 UDP Errors", "events/s", 2701, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "RcvbufErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "SndbufErrors", NULL, -1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "InErrors", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "NoPorts", NULL, 1, 1, RRDDIM_INCREMENTAL); } else rrdset_next(st); rrddim_set(st, "InErrors", InErrors); rrddim_set(st, "NoPorts", NoPorts); rrddim_set(st, "RcvbufErrors", RcvbufErrors); rrddim_set(st, "SndbufErrors", SndbufErrors); rrdset_done(st); } } } return 0; }