From 813cfffe619513b3136d8980c022728cde81c3e3 Mon Sep 17 00:00:00 2001 From: Marek Becka Date: Wed, 26 Jul 2017 06:12:12 -0400 Subject: [PATCH] New plugin: synproxy --- Makefile.am | 6 +++ configure.ac | 4 ++ src/synproxy.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/types.db | 2 + 4 files changed, 126 insertions(+) create mode 100644 src/synproxy.c diff --git a/Makefile.am b/Makefile.am index cd5dbea7..c93e3645 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1554,6 +1554,12 @@ endif endif +if BUILD_PLUGIN_SYNPROXY +pkglib_LTLIBRARIES += synproxy.la +synproxy_la_SOURCES = synproxy.c +synproxy_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + if BUILD_PLUGIN_SYSLOG pkglib_LTLIBRARIES += syslog.la syslog_la_SOURCES = src/syslog.c diff --git a/configure.ac b/configure.ac index f50df28a..8f2a9ab3 100644 --- a/configure.ac +++ b/configure.ac @@ -6169,6 +6169,7 @@ plugin_python="no" plugin_serial="no" plugin_smart="no" plugin_swap="no" +plugin_synproxy="no" plugin_tape="no" plugin_tcpconns="no" plugin_ted="no" @@ -6213,6 +6214,7 @@ if test "x$ac_system" = "xLinux"; then plugin_protocols="yes" plugin_serial="yes" plugin_swap="yes" + plugin_synproxy="yes" plugin_tcpconns="yes" plugin_thermal="yes" plugin_uptime="yes" @@ -6625,6 +6627,7 @@ AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugi AC_PLUGIN([snmp_agent], [$with_libnetsnmpagent], [SNMP agent plugin]) AC_PLUGIN([statsd], [yes], [StatsD plugin]) AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics]) +AC_PLUGIN([synproxy], [$plugin_synproxy], [Synproxy stats plugin]) AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin]) AC_PLUGIN([table], [yes], [Parsing of tabular data]) AC_PLUGIN([tail], [yes], [Parsing of logfiles]) @@ -7042,6 +7045,7 @@ AC_MSG_RESULT([ snmp . . . . . . . . $enable_snmp]) AC_MSG_RESULT([ snmp_agent . . . . . $enable_snmp_agent]) AC_MSG_RESULT([ statsd . . . . . . . $enable_statsd]) AC_MSG_RESULT([ swap . . . . . . . . $enable_swap]) +AC_MSG_RESULT([ synproxy . . . . . . $enable_synproxy]) AC_MSG_RESULT([ syslog . . . . . . . $enable_syslog]) AC_MSG_RESULT([ table . . . . . . . . $enable_table]) AC_MSG_RESULT([ tail_csv . . . . . . $enable_tail_csv]) diff --git a/src/synproxy.c b/src/synproxy.c new file mode 100644 index 00000000..eea65baa --- /dev/null +++ b/src/synproxy.c @@ -0,0 +1,114 @@ +/** + * collectd - src/synproxy.c + * Copyright (C) 2017 Marek Becka + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Marek Becka + **/ + +#include "collectd.h" + +#include "common.h" +#include "plugin.h" + +#if !KERNEL_LINUX +#error "No applicable input method." +#endif + +static const char *synproxy_stat_path = "/proc/net/stat/synproxy"; + +static const char *column_names[] = { + "entries", "syn_received", "invalid", "valid", "retransmission", "reopened" +}; +static const char *column_types[] = { + "current_connections", "synproxy_connections", "synproxy_cookies", + "synproxy_cookies", "synproxy_cookies", "synproxy_connections" +}; + +static void synproxy_submit(value_t *results) { + value_list_t vl = VALUE_LIST_INIT; + + for (unsigned n = 1; n < 6; n++) { + vl.values = &results[n]; + vl.values_len = 1; + + sstrncpy(vl.plugin, "synproxy", sizeof(vl.plugin)); + sstrncpy(vl.type, column_types[n], sizeof(vl.type)); + sstrncpy(vl.type_instance, column_names[n], sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); + } +} + +static int synproxy_read(void) { + FILE *fh; + char buf[1024]; + value_t results[6]; + int is_header = 1, status = 0; + + fh = fopen(synproxy_stat_path, "r"); + if (fh == NULL) { + ERROR("synproxy plugin: unable to open %s", synproxy_stat_path); + return -1; + } + + memset(results, 0, sizeof(results)); + + while (fgets(buf, sizeof(buf), fh) != NULL) { + int numfields; + char *fields[6], *endprt; + + if (is_header) { + is_header = 0; + continue; + } + + numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields != 6) { + ERROR("synproxy plugin: unexpected number of columns in %s", + synproxy_stat_path); + status = -1; + break; + } + + /* 1st column (entries) is hardcoded to 0 in kernel code */ + for (unsigned n = 1; n < 6; n++) { + char *endptr = NULL; + errno = 0; + + results[n].derive += strtoull(fields[n], &endprt, 16); + if ((endptr == fields[n]) || errno != 0) { + ERROR("synproxy plugin: unable to parse value: %s", fields[n]); + status = -1; + goto err_close; + } + } + } + +err_close: + fclose(fh); + + if (status == 0) { + synproxy_submit(results); + } + + return status; +} + +void module_register(void) { + plugin_register_read("synproxy", synproxy_read); +} /* void module_register */ + diff --git a/src/types.db b/src/types.db index 9ba33e8f..a0a17824 100644 --- a/src/types.db +++ b/src/types.db @@ -232,6 +232,8 @@ spam_score value:GAUGE:U:U spl value:GAUGE:U:U swap value:GAUGE:0:1099511627776 swap_io value:DERIVE:0:U +synproxy_connections value:DERIVE:0:U +synproxy_cookies value:DERIVE:0:U tcp_connections value:GAUGE:0:4294967295 temperature value:GAUGE:U:U threads value:GAUGE:0:U -- 2.11.0