2 * collectd - src/iptables.c
3 * Copyright (C) 2007 Sjoerd van der Berg
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * Sjoerd van der Berg <harekiet at users.sourceforge.net>
26 #include "configfile.h"
28 #if HAVE_LIBIPTC_LIBIPTC_H
29 # include <libiptc/libiptc.h>
32 #define MODULE_NAME "iptables"
36 * (Module-)Global variables
40 * Files will go into iptables-chain/comment.rrd files
42 static char *file_template = "iptables-%s.rrd";
45 * Config format should be `Chain table chainname',
46 * e. g. `Chain mangle incoming'
48 static char *config_keys[] =
53 static int config_keys_num = 1;
55 Removed packet count for now, should have config option if you want to save them
56 Although other collectd models don't seem to care much for options eitherway for what to log
58 static char *ds_def[] =
60 // "DS:packets:COUNTER:"COLLECTD_HEARTBEAT":0:U",
61 "DS:bytes:DERIVE:"COLLECTD_HEARTBEAT":0:U",
64 static int ds_num = 1;
67 Each table/chain combo that will be queried goes into this list
74 static ip_chain_t **chain_list = NULL;
75 static int chain_num = 0;
77 static int iptables_config (char *key, char *value)
79 if (strcasecmp (key, "Chain") == 0)
81 ip_chain_t temp, *final, **list;
85 memset( &temp, 0, sizeof( temp ));
87 /* simple parsing, only allow a space... */
88 chain = rindex(value, ' ' );
91 syslog (LOG_EMERG, "missing chain." );
94 tLen = (int)(chain - value);
95 if ( tLen > sizeof( temp.table ))
97 syslog (LOG_EMERG, "table too long." );
100 memcpy( temp.table, value, tLen );
101 temp.table[tLen] = 0;
103 strncpy( temp.name, chain, sizeof( temp.name ));
105 list = (ip_chain_t **) realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
108 syslog (LOG_EMERG, "Cannot allocate more memory.");
112 final = (ip_chain_t *) malloc( sizeof(temp) );
115 syslog (LOG_EMERG, "Cannot allocate memory.");
119 chain_list[chain_num++] = final;
128 static void iptables_init (void)
133 static void iptables_write (char *host, char *inst, char *val)
138 status = snprintf (file, BUFSIZE, file_template, inst);
141 else if (status >= BUFSIZE)
144 rrd_update_file (host, file, val, ds_def, ds_num);
148 static int submit_match (const struct ipt_entry_match *match,
149 const struct ipt_entry *entry, const ip_chain_t *chain)
155 /* Only log rules that have a comment, although could probably also do numerical targets sometime */
156 if ( strcmp( match->u.user.name, "comment" ) )
160 This would also add the table name to the name, but seems a bit overkill
161 status = snprintf (name, BUFSIZE, "%s-%s/%s",
162 table->table, table->chain, match->data );
164 status = snprintf (name, BUFSIZE, "%s/%s", chain->name, match->data );
166 if ((status >= BUFSIZE) || (status < 1))
169 status = snprintf (buf, BUFSIZE, "%u:%lld", /* ":lld", */
170 (unsigned int) curtime,
171 /* entry->counters.pcnt, */
172 entry->counters.bcnt );
173 if ((status >= BUFSIZE) || (status < 1))
176 plugin_submit (MODULE_NAME, name, buf);
179 } /* int submit_match */
181 static void submit_chain( iptc_handle_t *handle, ip_chain_t *chain ) {
182 const struct ipt_entry *entry;
184 /* Find first rule for chain and use the iterate macro */
185 entry = iptc_first_rule( chain->name, handle );
187 IPT_MATCH_ITERATE( entry, submit_match, entry, chain );
188 entry = iptc_next_rule( entry, handle );
193 static void iptables_read (void) {
196 /* Init the iptc handle structure and query the correct table */
197 for( i = 0; i < chain_num; i++) {
198 iptc_handle_t handle;
201 chain = chain_list[i];
204 handle = iptc_init( chain->table );
207 submit_chain( &handle, chain );
208 iptc_free( &handle );
212 void module_register (void)
214 plugin_register (MODULE_NAME, iptables_init, iptables_read, iptables_write);
215 cf_register (MODULE_NAME, iptables_config, config_keys, config_keys_num);
222 * vim:shiftwidth=4:softtabstop=4:tabstop=8