diff options
author | Lennart Poettering <lennart@poettering.net> | 2004-05-09 23:20:43 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2004-05-09 23:20:43 +0000 |
commit | 63d51b566ea270b45b5b34b1feab37b8faa28232 (patch) | |
tree | 42b190637551ceae31982f2591bec64c7b0b370a /daemon/main.c | |
parent | ad9b08e8c6fb69636812a625e341ebbe83460a23 (diff) |
main fieryfilter worktrunk@31
git-svn-id: file:///home/lennart/svn/public/fieryfilter/fieryfilter@31 79e6afc9-17da-0310-ae3c-b873bff394f4
Diffstat (limited to 'daemon/main.c')
-rw-r--r-- | daemon/main.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/daemon/main.c b/daemon/main.c new file mode 100644 index 0000000..253bf35 --- /dev/null +++ b/daemon/main.c @@ -0,0 +1,198 @@ +#define _GNU_SOURCE + +#include <signal.h> +#include <grp.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <daemon-log.h> +#include <daemon-signal.h> +#include <daemon-fork.h> +#include <daemon-pid.h> + +#include <config.h> + +#include "common.h" +#include "main.h" +#include "ipqapi.h" +#include "client.h" +#include "icmp.h" +#include "packet.h" + +gboolean opt_fork = TRUE; +gboolean opt_syslog = TRUE; + +fd_set listen_wfds, listen_rfds, select_wfds, select_rfds; + +gboolean fail = FALSE; + +guint32 default_verdict = 15; // ICMP packet filtered +//guint32 default_verdict = 1; // Accept + +gboolean log_packets = FALSE; + +static gboolean _verdict_func(ipq_packet_msg_t*m) { + if (log_packets) + daemon_log(LOG_DEBUG, "[%lu] Still unanswered, verdicting", m->packet_id); + ipqapi_verdict(m, default_verdict); + return FALSE; +} + +int init() { + if (daemon_signal_init(SIGPIPE, SIGUSR1, SIGUSR2, SIGHUP, SIGINT, SIGQUIT, SIGTERM, -1) < 0) + return -1; + + FD_ZERO(&listen_wfds); + FD_ZERO(&listen_rfds); + + if (ipqapi_init() < 0) + return -1; + + if (client_init() < 0 ) + return -1; + + if (icmp_init() < 0) + return -1; + + return 0; +} + +void done() { + ipqapi_done(); + client_done(); + icmp_done(); + packets_free(); + daemon_signal_done(); +} + +int loop() { + int r; + + daemon_log(LOG_INFO, "%s "VERSION" sucessfully initialized.", daemon_log_ident); + + while (!fail) { + int sig; + + select_rfds = listen_rfds; + select_wfds = listen_wfds; + + if (select(FD_SETSIZE, &select_rfds, &select_wfds, NULL, NULL) < 0 && errno != EINTR) { + daemon_log(LOG_ERR, "select: %s", strerror(errno)); + goto finish; + } + + if ((sig = daemon_signal_next()) >= 0) { + + switch (sig) { + case SIGINT: + case SIGQUIT: + case SIGTERM: + daemon_log(LOG_INFO, "Recieved signal <%s>, exiting cleanly", strsignal(sig)); + r = 0; + goto finish; + + case SIGHUP: + daemon_log(LOG_INFO, "Recieved signal <%s>, reporting status info:", strsignal(sig)); + daemon_log(LOG_INFO, "%u packets total, %u packets in queue", get_total_packets(), get_queued_packets()); + break; + + case SIGUSR1: + case SIGUSR2: + log_packets = sig == SIGUSR1; + daemon_log(LOG_INFO, "Recieved signal <%s>, %s packet logging", strsignal(sig), log_packets ? "enabling" : "disabling"); + break; + + case SIGPIPE: + break; + + default: + daemon_log(LOG_WARNING, "Recieved signal <%s>, ignoring.", strsignal(sig)); + } + + } else { + if (client_work() < 0) + goto finish; + + if (ipqapi_work() < 0) + goto finish; + } + + packet_foreach(client_is_connected(), _verdict_func); + } + + r = 0; + +finish: + + daemon_log(LOG_INFO, "%s exiting.", daemon_log_ident); + + return r; +} + + +int start() { + struct group *gr; + setuid(geteuid()); + + if (!(gr = getgrnam("fieryfilter"))) { + daemon_log(LOG_ERR, "Could not find group fieryfilter"); + return 1; + } + + if (setgid(gr->gr_gid) != 0) { + daemon_log(LOG_ERR, "setgid(): %s", strerror(errno)); + return 1; + } + + if (opt_fork) { + pid_t pid; + + daemon_retval_init(); + + if ((pid = daemon_fork()) < 0) + return 1; + else if (pid != 0) { + int r = daemon_retval_wait(10); + return r < 0 ? 1 : r; + } else { + daemon_log_use_syslog = opt_syslog; + + if (init() < 0) { + daemon_retval_send(1); + done(); + return 1; + } + + daemon_retval_send(0); + } + } else { + daemon_log_use_syslog = opt_syslog; + + if (init() < 0) { + done(); + return 1; + } + } + + + if (loop() < 0) { + done(); + return 1; + } + + done(); + return 0; + +} + +int main(int argc, char *argv[]) { + if ((daemon_log_ident = strrchr(argv[0], '/'))) + daemon_log_ident++; + else + daemon_log_ident = argv[0]; + + daemon_log_use_syslog = FALSE; + + return start(); +} |