summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--doc/stats/conntrackd.conf22
-rw-r--r--include/conntrackd.h6
-rw-r--r--include/log.h7
-rw-r--r--src/cache_iterators.c10
-rw-r--r--src/ignore_pool.c4
-rw-r--r--src/log.c56
-rw-r--r--src/main.c14
-rw-r--r--src/netlink.c6
-rw-r--r--src/network.c4
-rw-r--r--src/read_config_yy.y70
-rw-r--r--src/run.c26
-rw-r--r--src/stats-mode.c9
-rw-r--r--src/sync-mode.c5
14 files changed, 182 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index bf79b6a..83e1524 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,8 @@ o rename `examples' directory to `doc'
o add support for related conntracks (requires Linux kernel >= 2.6.22)
o show error and warning messages to stderr
o hash lookup speedups based on comments from netdev's discussions
+o add support for connection logging to the statistics mode via Logfile
+o minor irrelevant fixes for uncommon error paths and fix several typos
version 0.9.5 (2007/07/29)
------------------------------
diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf
index 07deaa8..198b8a3 100644
--- a/doc/stats/conntrackd.conf
+++ b/doc/stats/conntrackd.conf
@@ -49,6 +49,23 @@ General {
SocketBufferSizeMaxGrown 655355
}
+Stats {
+ #
+ # Enable connection logging. Default is off.
+ # Logfile: on, off, or a filename
+ # Default file: (/var/log/conntrackd-stats.log)
+ #
+ LogFile on
+
+ #
+ # Enable connection logging via Syslog. Default is off.
+ # Syslog: on, off or a facility name (daemon (default) or local0..7)
+ # If you set the facility, use the same as in the General clause,
+ # otherwise you'll get a warning message.
+ #
+ #Syslog on
+}
+
#
# Ignore traffic for a certain set of IP's: Usually
# all the IP assigned to the firewall since local
@@ -69,8 +86,3 @@ IgnoreProtocol {
# VRRP
# numeric numbers also valid
}
-
-#
-# Strip NAT traffic
-#
-StripNAT
diff --git a/include/conntrackd.h b/include/conntrackd.h
index 1bb3879..e5b8a4e 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -31,6 +31,7 @@
#define DEFAULT_CONFIGFILE "/etc/conntrackd/conntrackd.conf"
#define DEFAULT_LOCKFILE "/var/lock/conntrackd.lock"
#define DEFAULT_LOGFILE "/var/log/conntrackd.log"
+#define DEFAULT_STATS_LOGFILE "/var/log/conntrackd-stats.log"
#define DEFAULT_SYSLOG_FACILITY LOG_DAEMON
enum {
@@ -87,6 +88,10 @@ struct ct_conf {
unsigned int resend_buffer_size;/* FTFW protocol */
unsigned int window_size;
int cache_write_through;
+ struct {
+ char logfile[FILENAME_MAXLEN];
+ int syslog_facility;
+ } stats;
};
#define STATE(x) st.x
@@ -94,6 +99,7 @@ struct ct_conf {
struct ct_general_state {
sigset_t block;
FILE *log;
+ FILE *stats_log;
int local;
struct ct_mode *mode;
struct ignore_pool *ignore_pool;
diff --git a/include/log.h b/include/log.h
index f6f450c..467ae8f 100644
--- a/include/log.h
+++ b/include/log.h
@@ -1,10 +1,9 @@
#ifndef _LOG_H_
#define _LOG_H_
-#include <stdio.h>
-
-FILE *init_log(char *filename);
+int init_log();
void dlog(FILE *fd, int priority, char *format, ...);
-void close_log(FILE *fd);
+void dlog_ct(FILE *fd, struct nf_conntrack *ct);
+void close_log();
#endif
diff --git a/src/cache_iterators.c b/src/cache_iterators.c
index c29100c..85f87ab 100644
--- a/src/cache_iterators.c
+++ b/src/cache_iterators.c
@@ -120,14 +120,14 @@ void cache_commit(struct cache *c)
commit_exist = c->commit_exist - commit_exist;
/* log results */
- dlog(STATE(log), LOG_INFO, "Committed %u new entries", commit_ok);
+ dlog(STATE(log), LOG_NOTICE, "Committed %u new entries", commit_ok);
if (commit_exist)
- dlog(STATE(log), LOG_INFO, "%u entries ignored, "
- "already exist", commit_exist);
+ dlog(STATE(log), LOG_NOTICE, "%u entries ignored, "
+ "already exist", commit_exist);
if (commit_fail)
- dlog(STATE(log), LOG_INFO, "%u entries can't be "
- "committed", commit_fail);
+ dlog(STATE(log), LOG_NOTICE, "%u entries can't be "
+ "committed", commit_fail);
}
static int do_flush(void *data1, void *data2)
diff --git a/src/ignore_pool.c b/src/ignore_pool.c
index 619c2fa..ee457ba 100644
--- a/src/ignore_pool.c
+++ b/src/ignore_pool.c
@@ -118,7 +118,7 @@ int __ignore_pool_test_ipv6(struct ignore_pool *ip, struct nf_conntrack *ct)
int ignore_pool_test(struct ignore_pool *ip, struct nf_conntrack *ct)
{
- int ret;
+ int ret = 0;
switch(nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO)) {
case AF_INET:
@@ -128,7 +128,7 @@ int ignore_pool_test(struct ignore_pool *ip, struct nf_conntrack *ct)
ret = __ignore_pool_test_ipv6(ip, ct);
break;
default:
- dlog(STATE(log), "unknown conntrack layer 3 protocol?");
+ dlog(STATE(log), LOG_WARNING, "unknown layer 3 protocol?");
break;
}
diff --git a/src/log.c b/src/log.c
index 5fea1c3..e3f2102 100644
--- a/src/log.c
+++ b/src/log.c
@@ -24,22 +24,31 @@
#include <string.h>
#include "conntrackd.h"
-FILE *init_log(char *filename)
+int init_log(void)
{
- FILE *fd = NULL;
+ if (CONFIG(logfile)[0]) {
+ STATE(log) = fopen(CONFIG(logfile), "a+");
+ if (STATE(log) == NULL) {
+ fprintf(stderr, "can't open log file `%s'\n",
+ CONFIG(logfile));
+ return -1;
+ }
+ }
- if (filename[0]) {
- fd = fopen(filename, "a+");
- if (fd == NULL) {
- fprintf(stderr, "can't open log file `%s'\n", filename);
- return NULL;
+ if (CONFIG(stats).logfile[0]) {
+ STATE(stats_log) = fopen(CONFIG(stats).logfile, "a+");
+ if (STATE(stats_log) == NULL) {
+ fprintf(stderr, "can't open log file `%s'\n",
+ CONFIG(stats).logfile);
+ return -1;
}
}
- if (CONFIG(syslog_facility) != -1)
+ if (CONFIG(syslog_facility) != -1 ||
+ CONFIG(stats).syslog_facility != -1)
openlog(PACKAGE, LOG_PID, CONFIG(syslog_facility));
- return fd;
+ return 0;
}
void dlog(FILE *fd, int priority, char *format, ...)
@@ -85,10 +94,33 @@ void dlog(FILE *fd, int priority, char *format, ...)
}
}
-void close_log(FILE *fd)
+void dlog_ct(FILE *fd, struct nf_conntrack *ct)
+{
+ time_t t;
+ char buf[1024];
+ char *tmp;
+
+ if (fd) {
+ t = time(NULL);
+ ctime_r(&t, buf);
+ tmp = buf + strlen(buf);
+ buf[strlen(buf)-1]='\t';
+ nfct_snprintf(buf+strlen(buf), 1024-strlen(buf), ct, 0, 0, 0);
+ fprintf(fd, "%s\n", buf);
+ fflush(fd);
+ }
+
+ if (CONFIG(stats).syslog_facility != -1)
+ syslog(LOG_INFO, "%s", tmp);
+}
+
+void close_log(void)
{
- if (fd != NULL)
- fclose(fd);
+ if (STATE(log) != NULL)
+ fclose(STATE(log));
+
+ if (STATE(stats_log) != NULL)
+ fclose(STATE(stats_log));
if (CONFIG(syslog_facility) != -1)
closelog();
diff --git a/src/main.c b/src/main.c
index 3a54911..e0ca46d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -246,8 +246,7 @@ int main(int argc, char *argv[])
/*
* Setting up logging
*/
- STATE(log) = init_log(CONFIG(logfile));
- if (config_set && !STATE(log)) {
+ if (config_set && init_log() == -1) {
fprintf(stderr, "can't open logfile `%s\n'", CONFIG(logfile));
exit(EXIT_FAILURE);
}
@@ -255,7 +254,7 @@ int main(int argc, char *argv[])
if (type == REQUEST) {
if (do_local_request(action, &conf.local, local_step) == -1) {
fprintf(stderr, "can't connect: is conntrackd "
- "running? appropiate permissions?\n");
+ "running? appropriate permissions?\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
@@ -276,22 +275,21 @@ int main(int argc, char *argv[])
pid_t pid;
if ((pid = fork()) == -1) {
- dlog(STATE(log), LOG_ERR, "fork() failed: "
- "%s", strerror(errno));
+ perror("fork has failed: ");
exit(EXIT_FAILURE);
} else if (pid)
exit(EXIT_SUCCESS);
- dlog(STATE(log), LOG_INFO, "--- starting in daemon mode ---");
+ dlog(STATE(log), LOG_NOTICE, "-- starting in daemon mode --");
} else
- dlog(STATE(log), LOG_INFO, "--- starting in console mode ---");
+ dlog(STATE(log), LOG_NOTICE, "-- starting in console mode --");
/*
* initialization process
*/
if (init(mode) == -1) {
- close_log(STATE(log));
+ close_log();
fprintf(stderr, "ERROR: conntrackd cannot start, please "
"check the logfile for more info\n");
unlink(CONFIG(lockfile));
diff --git a/src/netlink.c b/src/netlink.c
index d453fe1..ab945d8 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -185,9 +185,9 @@ void nl_resize_socket_buffer(struct nfct_handle *h)
CONFIG(netlink_buffer_size) = nfnl_rcvbufsiz(nfct_nfnlh(h), s);
/* notify the sysadmin */
- dlog(STATE(log), LOG_INFO, "netlink socket buffer size "
- "has been set to %u bytes",
- CONFIG(netlink_buffer_size));
+ dlog(STATE(log), LOG_NOTICE, "netlink socket buffer size "
+ "has been set to %u bytes",
+ CONFIG(netlink_buffer_size));
}
int nl_dump_conntrack_table(void)
diff --git a/src/network.c b/src/network.c
index 9bd3469..a20c1e0 100644
--- a/src/network.c
+++ b/src/network.c
@@ -221,8 +221,8 @@ int mcast_track_seq(u_int32_t seq, u_int32_t *exp_seq)
/* out of sequence: replayed/delayed packet? */
if (before(seq, STATE_SYNC(last_seq_recv)+1))
- dlog(STATE(log), "delayed packet? exp=%u rcv=%u",
- STATE_SYNC(last_seq_recv)+1, seq);
+ dlog(STATE(log), LOG_WARNING, "delayed packet? exp=%u rcv=%u",
+ STATE_SYNC(last_seq_recv)+1, seq);
out:
*exp_seq = STATE_SYNC(last_seq_recv)+1;
diff --git a/src/read_config_yy.y b/src/read_config_yy.y
index 92806f8..ebb1c73 100644
--- a/src/read_config_yy.y
+++ b/src/read_config_yy.y
@@ -123,6 +123,11 @@ syslog_facility : T_SYSLOG T_STRING
"ignoring.\n", $2);
return;
}
+
+ if (conf.stats.syslog_facility != -1 &&
+ conf.syslog_facility != conf.stats.syslog_facility)
+ fprintf(stderr, "WARNING: Conflicting Syslog facility "
+ "values, defaulting to General.\n");
};
lock : T_LOCK T_PATH_VAL
@@ -549,16 +554,74 @@ family : T_FAMILY T_STRING
conf.family = AF_INET;
};
-stats: T_SYNC '{' stats_list '}';
+stats: T_STATS '{' stats_list '}';
stats_list:
| stats_list stat_line
;
-stat_line:
- |
+stat_line: stat_logfile_bool
+ | stat_logfile_path
+ | stat_syslog_bool
+ | stat_syslog_facility
;
+stat_logfile_bool : T_LOG T_ON
+{
+ strncpy(conf.stats.logfile, DEFAULT_STATS_LOGFILE, FILENAME_MAXLEN);
+};
+
+stat_logfile_bool : T_LOG T_OFF
+{
+};
+
+stat_logfile_path : T_LOG T_PATH_VAL
+{
+ strncpy(conf.stats.logfile, $2, FILENAME_MAXLEN);
+};
+
+stat_syslog_bool : T_SYSLOG T_ON
+{
+ conf.stats.syslog_facility = DEFAULT_SYSLOG_FACILITY;
+};
+
+stat_syslog_bool : T_SYSLOG T_OFF
+{
+ conf.stats.syslog_facility = -1;
+}
+
+stat_syslog_facility : T_SYSLOG T_STRING
+{
+ if (!strcmp($2, "daemon"))
+ conf.stats.syslog_facility = LOG_DAEMON;
+ else if (!strcmp($2, "local0"))
+ conf.stats.syslog_facility = LOG_LOCAL0;
+ else if (!strcmp($2, "local1"))
+ conf.stats.syslog_facility = LOG_LOCAL1;
+ else if (!strcmp($2, "local2"))
+ conf.stats.syslog_facility = LOG_LOCAL2;
+ else if (!strcmp($2, "local3"))
+ conf.stats.syslog_facility = LOG_LOCAL3;
+ else if (!strcmp($2, "local4"))
+ conf.stats.syslog_facility = LOG_LOCAL4;
+ else if (!strcmp($2, "local5"))
+ conf.stats.syslog_facility = LOG_LOCAL5;
+ else if (!strcmp($2, "local6"))
+ conf.stats.syslog_facility = LOG_LOCAL6;
+ else if (!strcmp($2, "local7"))
+ conf.stats.syslog_facility = LOG_LOCAL7;
+ else {
+ fprintf(stderr, "'%s' is not a known syslog facility, "
+ "ignoring.\n", $2);
+ return;
+ }
+
+ if (conf.syslog_facility != -1 &&
+ conf.stats.syslog_facility != conf.syslog_facility)
+ fprintf(stderr, "WARNING: Conflicting Syslog facility "
+ "values, defaulting to General.\n");
+};
+
%%
int
@@ -580,6 +643,7 @@ init_config(char *filename)
/* Zero may be a valid facility */
CONFIG(syslog_facility) = -1;
+ CONFIG(stats).syslog_facility = -1;
yyrestart(fp);
yyparse();
diff --git a/src/run.c b/src/run.c
index 9ce9923..0411fcb 100644
--- a/src/run.c
+++ b/src/run.c
@@ -40,7 +40,7 @@ void killer(int foo)
STATE(mode)->kill();
destroy_alarm_scheduler();
unlink(CONFIG(lockfile));
- dlog(STATE(log), LOG_INFO, "------- shutdown received ----");
+ dlog(STATE(log), LOG_NOTICE, "---- shutdown received ----");
close_log(STATE(log));
sigprocmask(SIG_UNBLOCK, &STATE(block), NULL);
@@ -60,18 +60,16 @@ void local_handler(int fd, void *data)
ret = read(fd, &type, sizeof(type));
if (ret == -1) {
- dlog(STATE(log), LOG_INFO, "can't read from unix socket");
+ dlog(STATE(log), LOG_ERR, "can't read from unix socket");
return;
}
- if (ret == 0) {
- dlog(STATE(log), LOG_INFO, "local request: nothing received?");
+ if (ret == 0)
return;
- }
switch(type) {
case FLUSH_MASTER:
- dlog(STATE(log), LOG_NOTICE, "`conntrackd -F' is deprecated. "
- "Use conntrack -F instead.");
+ dlog(STATE(log), LOG_WARNING, "`conntrackd -F' is deprecated. "
+ "Use conntrack -F instead.");
if (fork() == 0) {
execlp("conntrack", "conntrack", "-F", NULL);
exit(EXIT_SUCCESS);
@@ -84,7 +82,7 @@ void local_handler(int fd, void *data)
}
if (!STATE(mode)->local(fd, type, data))
- dlog(STATE(log), LOG_ERR, "unknown local request %d", type);
+ dlog(STATE(log), LOG_WARNING, "unknown local request %d", type);
}
int init(int mode)
@@ -152,7 +150,7 @@ int init(int mode)
if (signal(SIGCHLD, child) == SIG_ERR)
return -1;
- dlog(STATE(log), LOG_INFO, "initialization completed");
+ dlog(STATE(log), LOG_NOTICE, "initialization completed");
return 0;
}
@@ -181,7 +179,8 @@ static void __run(long credit, int step)
if (errno == EINTR)
return;
- dlog(STATE(log), "select() failed: %s", strerror(errno));
+ dlog(STATE(log), LOG_WARNING,
+ "select failed: %s", strerror(errno));
return;
}
@@ -218,8 +217,8 @@ static void __run(long credit, int step)
case EAGAIN:
break;
default:
- dlog(STATE(log), "event catch says: %s",
- strerror(errno));
+ dlog(STATE(log), LOG_WARNING,
+ "event catch says: %s", strerror(errno));
break;
}
}
@@ -251,7 +250,8 @@ void run(void)
timer_stop(&timer);
if (timer_adjust_credit(&timer))
- dlog(STATE(log), "alarm run takes too long!");
+ dlog(STATE(log), LOG_WARNING,
+ "alarm run takes too long!");
step = (step + 1) < STEPS_PER_SECONDS ? step + 1 : 0;
}
diff --git a/src/stats-mode.c b/src/stats-mode.c
index 1d68e02..e817c4e 100644
--- a/src/stats-mode.c
+++ b/src/stats-mode.c
@@ -88,6 +88,8 @@ static int local_handler_stats(int fd, int type, void *data)
static void dump_stats(struct nf_conntrack *ct)
{
+ nfct_attr_unset(ct, ATTR_TIMEOUT);
+
if (cache_update_force(STATE_STATS(cache), ct))
debug_ct(ct, "resync entry");
}
@@ -140,6 +142,8 @@ static void overrun_stats()
static void event_new_stats(struct nf_conntrack *ct)
{
+ nfct_attr_unset(ct, ATTR_TIMEOUT);
+
if (cache_add(STATE_STATS(cache), ct)) {
debug_ct(ct, "cache new");
} else {
@@ -153,6 +157,8 @@ static void event_new_stats(struct nf_conntrack *ct)
static void event_update_stats(struct nf_conntrack *ct)
{
+ nfct_attr_unset(ct, ATTR_TIMEOUT);
+
if (!cache_update_force(STATE_STATS(cache), ct)) {
debug_ct(ct, "can't update");
return;
@@ -162,8 +168,11 @@ static void event_update_stats(struct nf_conntrack *ct)
static int event_destroy_stats(struct nf_conntrack *ct)
{
+ nfct_attr_unset(ct, ATTR_TIMEOUT);
+
if (cache_del(STATE_STATS(cache), ct)) {
debug_ct(ct, "cache destroy");
+ dlog_ct(STATE(stats_log), ct);
return 1;
} else {
debug_ct(ct, "can't destroy!");
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 7cd2b84..7c42c78 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -273,13 +273,14 @@ static int local_handler_sync(int fd, int type, void *data)
case COMMIT:
ret = fork();
if (ret == 0) {
- dlog(STATE(log), LOG_INFO, "committing external cache");
+ dlog(STATE(log), LOG_NOTICE,
+ "committing external cache");
cache_commit(STATE_SYNC(external));
exit(EXIT_SUCCESS);
}
break;
case FLUSH_CACHE:
- dlog(STATE(log), LOG_INFO, "flushing caches");
+ dlog(STATE(log), LOG_NOTICE, "flushing caches");
cache_flush(STATE_SYNC(internal));
cache_flush(STATE_SYNC(external));
break;