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"
27 #include "libiptc/libiptc.h"
29 #define MODULE_NAME "iptables"
33 * (Module-)Global variables
37 Files will go into iptables-chain/comment.rrd files
39 static char *file_template = "iptables-%s.rrd";
41 Config format should be Chain table chainname
42 So "Chain mangle incoming"
44 static char *config_keys[] =
49 static int config_keys_num = 1;
51 Removed packet count for now, should have config option if you want to save them
52 Although other collectd models don't seem to care much for options eitherway for what to log
54 static char *ds_def[] =
56 // "DS:packets:COUNTER:"COLLECTD_HEARTBEAT":0:U",
57 "DS:bytes:DERIVE:"COLLECTD_HEARTBEAT":0:U",
60 static int ds_num = 1;
63 Each table/chain combo that will be queried goes into this list
70 static ip_chain_t **chain_list = NULL;
71 static int chain_num = 0;
73 static int iptables_config (char *key, char *value)
75 if (strcasecmp (key, "Chain") == 0)
77 ip_chain_t temp, *final, **list;
81 memset( &temp, 0, sizeof( temp ));
83 /* simple parsing, only allow a space... */
84 chain = rindex(value, ' ' );
87 syslog (LOG_EMERG, "missing chain." );
90 tLen = (int)(chain - value);
91 if ( tLen > sizeof( temp.table ))
93 syslog (LOG_EMERG, "table too long." );
96 memcpy( temp.table, value, tLen );
99 strncpy( temp.name, chain, sizeof( temp.name ));
101 list = (ip_chain_t **) realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
104 syslog (LOG_EMERG, "Cannot allocate more memory.");
108 final = (ip_chain_t *) malloc( sizeof(temp) );
111 syslog (LOG_EMERG, "Cannot allocate memory.");
115 chain_list[chain_num++] = final;
124 static void iptables_init (void)
129 static void iptables_write (char *host, char *inst, char *val)
134 status = snprintf (file, BUFSIZE, file_template, inst);
137 else if (status >= BUFSIZE)
140 rrd_update_file (host, file, val, ds_def, ds_num);
144 static int submit_match( const struct ipt_entry_match *match, const struct ipt_entry *entry, const ip_chain_t *chain )
150 /* Only log rules that have a comment, although could probably also do numerical targets sometime */
151 if ( strcmp( match->u.user.name, "comment" ) )
155 This would also add the table name to the name, but seems a bit overkill
156 status = snprintf (name, BUFSIZE, "%s-%s/%s",
157 table->table, table->chain, match->data );
159 status = snprintf (name, BUFSIZE, "%s/%s", chain->name, match->data );
161 if ((status >= BUFSIZE) || (status < 1))
164 status = snprintf (buf, BUFSIZE, "%u:%lld",// ":lld",
165 (unsigned int) curtime,
166 // entry->counters.pcnt,
167 entry->counters.bcnt );
168 if ((status >= BUFSIZE) || (status < 1))
171 plugin_submit (MODULE_NAME, name, buf);
176 static void submit_chain( iptc_handle_t *handle, ip_chain_t *chain ) {
177 const struct ipt_entry *entry;
179 /* Find first rule for chain and use the iterate macro */
180 entry = iptc_first_rule( chain->name, handle );
182 IPT_MATCH_ITERATE( entry, submit_match, entry, chain );
183 entry = iptc_next_rule( entry, handle );
188 static void iptables_read (void) {
191 /* Init the iptc handle structure and query the correct table */
192 for( i = 0; i < chain_num; i++) {
193 iptc_handle_t handle;
196 chain = chain_list[i];
199 handle = iptc_init( chain->table );
202 submit_chain( &handle, chain );
203 iptc_free( &handle );
207 void module_register (void)
209 plugin_register (MODULE_NAME, iptables_init, iptables_read, iptables_write);
210 cf_register (MODULE_NAME, iptables_config, config_keys, config_keys_num);