summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 2fc8976)
raw | patch | inline | side by side (parent: 2fc8976)
author | Marco Chiappero <marco@absence.it> | |
Fri, 1 May 2009 15:22:52 +0000 (17:22 +0200) | ||
committer | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Sat, 2 May 2009 07:34:09 +0000 (09:34 +0200) |
Here is a stub but I have some trouble in making it work with "Chain6"
rules, maybe I don't know exactely how to deal with configuration keys.
I get "collectd[4887]: Plugin `iptables' did not register for value
`Chain6'". Is there something I'm forgetting?
There is another issue, the naming shema. I temporally changed the ipv6
vl.plugin to "ip6tables" in the meantime. Options are:
- different vl.plugin if possible (backward compatible)
- new vl.plugin_instance name schema with ip protocol (not backward
compatible)
- new vl.type "ip6t_packets" and "ip6t_bytes" (backward compatible but
taints the types.db with useless data)
A note about the code: I created two different submit_chain and
submit_match because using void pointers (and casting them afterwards)
in a single function it's a little bit obscure and complicated with no
real advantage. Sorry for some code duplication but in my opinion this
is smartest way.
Let me know your opinion, thank you.
Regards,
Marco
Signed-off-by: Florian Forster <octo@leeloo.lan.home.verplant.org>
rules, maybe I don't know exactely how to deal with configuration keys.
I get "collectd[4887]: Plugin `iptables' did not register for value
`Chain6'". Is there something I'm forgetting?
There is another issue, the naming shema. I temporally changed the ipv6
vl.plugin to "ip6tables" in the meantime. Options are:
- different vl.plugin if possible (backward compatible)
- new vl.plugin_instance name schema with ip protocol (not backward
compatible)
- new vl.type "ip6t_packets" and "ip6t_bytes" (backward compatible but
taints the types.db with useless data)
A note about the code: I created two different submit_chain and
submit_match because using void pointers (and casting them afterwards)
in a single function it's a little bit obscure and complicated with no
real advantage. Sorry for some code duplication but in my opinion this
is smartest way.
Let me know your opinion, thank you.
Regards,
Marco
Signed-off-by: Florian Forster <octo@leeloo.lan.home.verplant.org>
src/iptables.c | patch | blob | history |
diff --git a/src/iptables.c b/src/iptables.c
index 12275cd09921aa594ba0e2f80e49b6c3da296780..c8542a5f78b2378a6a61842bf0ab34da9bb46e91 100644 (file)
--- a/src/iptables.c
+++ b/src/iptables.c
* collectd - src/iptables.c
* Copyright (C) 2007 Sjoerd van der Berg
* Copyright (C) 2007 Florian octo Forster
+ * Copyright (C) 2009 Marco Chiappero
*
* 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
* Authors:
* Sjoerd van der Berg <harekiet at users.sourceforge.net>
* Florian Forster <octo at verplant.org>
+ * Marco Chiappero <marco at absence.it>
**/
#include "collectd.h"
#if OWN_LIBIPTC
# include "libiptc/libiptc.h"
+# include "libiptc/libip6tc.h"
#else
# include <libiptc/libiptc.h>
+# include <libiptc/libip6tc.h>
#endif
/*
static const char *config_keys[] =
{
"Chain",
- NULL
+ "Chain6"
};
-static int config_keys_num = 1;
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
/*
Each table/chain combo that will be queried goes into this list
*/
# define XT_TABLE_MAXNAMELEN 32
#endif
typedef struct {
+ enum
+ {
+ IPV4,
+ IPV6
+ } ip_version;
char table[XT_TABLE_MAXNAMELEN];
char chain[XT_TABLE_MAXNAMELEN];
union
static int iptables_config (const char *key, const char *value)
{
+ /* int ip_value; */
+ enum { IPV4, IPV6 } ip_protocol;
+
if (strcasecmp (key, "Chain") == 0)
+ ip_protocol = IPV4;
+ else if (strcasecmp (key, "Chain6") == 0)
+ ip_protocol = IPV6;
+
+ if (( ip_protocol == IPV4 ) || ( ip_protocol == IPV6 ))
{
ip_chain_t temp, *final, **list;
char *table;
return (1);
}
+ /*
+ * Time to fill the temp element
+ * Examine value string, it should look like:
+ * Chain[6] <table> <chain> [<comment|num> [name]]
+ */
+
+ /* set IPv4 or IPv6 */
+ temp.ip_version = ip_protocol;
+
/* Chain <table> <chain> [<comment|num> [name]] */
fields_num = strsplit (value_copy, fields, 4);
if (fields_num < 2)
return (0);
} /* int iptables_config */
+static int submit6_match (const struct ip6t_entry_match *match,
+ const struct ip6t_entry *entry,
+ const ip_chain_t *chain,
+ int rule_num)
+{
+ int status;
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ /* Select the rules to collect */
+ if (chain->rule_type == RTYPE_NUM)
+ {
+ if (chain->rule.num != rule_num)
+ return (0);
+ }
+ else
+ {
+ if (strcmp (match->u.user.name, "comment") != 0)
+ return (0);
+ if ((chain->rule_type == RTYPE_COMMENT)
+ && (strcmp (chain->rule.comment, (char *) match->data) != 0))
+ return (0);
+ }
+
+ vl.values = values;
+ vl.values_len = 1;
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "ip6tables", sizeof (vl.plugin));
+
+ status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
+ "%s-%s", chain->table, chain->chain);
+ if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance)))
+ return (0);
+
+ if (chain->name[0] != '\0')
+ {
+ sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance));
+ }
+ else
+ {
+ if (chain->rule_type == RTYPE_NUM)
+ ssnprintf (vl.type_instance, sizeof (vl.type_instance),
+ "%i", chain->rule.num);
+ else
+ sstrncpy (vl.type_instance, (char *) match->data,
+ sizeof (vl.type_instance));
+ }
+
+ sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
+ values[0].counter = (counter_t) entry->counters.bcnt;
+ plugin_dispatch_values (&vl);
+
+ sstrncpy (vl.type, "ipt_packets", sizeof (vl.type));
+ values[0].counter = (counter_t) entry->counters.pcnt;
+ plugin_dispatch_values (&vl);
+
+ return (0);
+} /* int submit_match */
+
+
/* This needs to return `int' for IPT_MATCH_ITERATE to work. */
static int submit_match (const struct ipt_entry_match *match,
const struct ipt_entry *entry,
plugin_dispatch_values (&vl);
return (0);
-} /* void submit_match */
+} /* int submit_match */
+
+
+/* ipv6 submit_chain */
+static void submit6_chain( ip6tc_handle_t *handle, ip_chain_t *chain )
+{
+ const struct ip6t_entry *entry;
+ int rule_num;
+
+ /* Find first rule for chain and use the iterate macro */
+ entry = ip6tc_first_rule( chain->chain, handle );
+ if (entry == NULL)
+ {
+ DEBUG ("ip6tc_first_rule failed: %s", ip6tc_strerror (errno));
+ return;
+ }
+
+ rule_num = 1;
+ while (entry)
+ {
+ if (chain->rule_type == RTYPE_NUM)
+ {
+ submit6_match (NULL, entry, chain, rule_num);
+ }
+ else
+ {
+ IP6T_MATCH_ITERATE( entry, submit6_match, entry, chain, rule_num );
+ }
+
+ entry = ip6tc_next_rule( entry, handle );
+ rule_num++;
+ } /* while (entry) */
+}
+
-static void submit_chain( iptc_handle_t *handle, ip_chain_t *chain ) {
+/* ipv4 submit_chain */
+static void submit_chain( iptc_handle_t *handle, ip_chain_t *chain )
+{
const struct ipt_entry *entry;
int rule_num;
{
int i;
int num_failures = 0;
+ ip_chain_t *chain;
/* Init the iptc handle structure and query the correct table */
for (i = 0; i < chain_num; i++)
{
- iptc_handle_t handle;
- ip_chain_t *chain;
-
chain = chain_list[i];
+
if (!chain)
{
DEBUG ("iptables plugin: chain == NULL");
continue;
}
- handle = iptc_init (chain->table);
- if (!handle)
- {
- ERROR ("iptables plugin: iptc_init (%s) failed: %s",
- chain->table, iptc_strerror (errno));
- num_failures++;
- continue;
- }
+ if ( chain->ip_version == IPV4 )
+ {
+ iptc_handle_t handle;
+ handle = iptc_init (chain->table);
+
+ if (!handle)
+ {
+ ERROR ("iptables plugin: iptc_init (%s) failed: %s",
+ chain->table, iptc_strerror (errno));
+ num_failures++;
+ continue;
+ }
+
+ submit_chain (&handle, chain);
+ iptc_free (&handle);
+ }
+ else if ( chain->ip_version == IPV6 )
+ {
+ ip6tc_handle_t handle;
+ handle = ip6tc_init (chain->table);
+
+ if (!handle)
+ {
+ ERROR ("iptables plugin: ip6tc_init (%s) failed: %s",
+ chain->table, ip6tc_strerror (errno));
+ num_failures++;
+ continue;
+ }
+
+ submit6_chain (&handle, chain);
+ ip6tc_free (&handle);
+ }
+ else num_failures++;
- submit_chain (&handle, chain);
- iptc_free (&handle);
} /* for (i = 0 .. chain_num) */
return ((num_failures < chain_num) ? 0 : -1);