From 63d51b566ea270b45b5b34b1feab37b8faa28232 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 9 May 2004 23:20:43 +0000 Subject: main fieryfilter work git-svn-id: file:///home/lennart/svn/public/fieryfilter/fieryfilter@31 79e6afc9-17da-0310-ae3c-b873bff394f4 --- daemon/ipqapi.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 daemon/ipqapi.c (limited to 'daemon/ipqapi.c') diff --git a/daemon/ipqapi.c b/daemon/ipqapi.c new file mode 100644 index 0000000..b0649bc --- /dev/null +++ b/daemon/ipqapi.c @@ -0,0 +1,118 @@ +#include +#include + +#include + +#include "icmp.h" +#include "ipqapi.h" +#include "main.h" +#include "client.h" +#include "packet.h" + +#define BUFSIZE (10*1024) + +static struct ipq_handle *ipq = NULL; + +int ipqapi_init() { + int status; + + if (!(ipq = ipq_create_handle(0, PF_INET))) { + daemon_log(LOG_ERR, "ipq_create_handle(): %s", ipq_errstr()); + return -1; + } + + if ((status = ipq_set_mode(ipq, IPQ_COPY_PACKET, BUFSIZE)) < 0) { + daemon_log(LOG_ERR, "ipq_set_mode(): %s", ipq_errstr()); + daemon_log(LOG_INFO, "Perhaps you should run 'modprobe ip_queue'?"); + ipq_destroy_handle(ipq); + ipq = NULL; + return -1; + } + + FD_SET(ipq->fd, &listen_rfds); + + return 0; +} + +void ipqapi_done() { + if (ipq) { + FD_CLR(ipq->fd, &listen_rfds); + ipq_destroy_handle(ipq); + } + + ipq = NULL; +} + +int ipqapi_work() { + int status; + static guint8 buf[BUFSIZE]; + + if (!FD_ISSET(ipq->fd, &select_rfds)) + return 0; + + if ((status = ipq_read(ipq, buf, BUFSIZE, 0)) < 0) { + daemon_log(LOG_ERR, "ipq_read(): %s", ipq_errstr()); + return -1; + } + + switch (ipq_message_type(buf)) { + case NLMSG_ERROR: + daemon_log(LOG_ERR, "Received error message: %s\n", strerror(ipq_get_msgerr(buf))); + return -1; + + case IPQM_PACKET: { + ipq_packet_msg_t *m = ipq_get_packet(buf); + + if (!m->timestamp_sec) + time(&m->timestamp_sec); + + if (log_packets) + daemon_log(LOG_DEBUG, "[%lu] Recieved packet, forwarding to client", m->packet_id); + + if (client_is_connected()) { + packet_new(m); + client_send_enqueue(message_new(MSG_PACKET, (guint8*) m, sizeof(ipq_packet_msg_t)+m->data_len)); + } else { + if (log_packets) + daemon_log(LOG_DEBUG, "[%lu] No clients listening, verdicting", m->packet_id); + + if (ipqapi_verdict(m, default_verdict) < 0) { + daemon_log(LOG_ERR, "Sending verdict failed."); + return -1; + } + } + + return 0; + } + + default: + daemon_log(LOG_WARNING, "Recieved invalid IPQ message."); + return -1; + } +} + +int ipqapi_verdict(ipq_packet_msg_t *m, guint32 resp) { + int nf = NF_DROP, icmp = 0; + + if (resp > 17) resp = 17; + + if (resp == 0) + nf = NF_DROP; + else if (resp == 1) + nf = NF_ACCEPT; + else { + nf = NF_DROP; + icmp = 1; + } + + if (ipq_set_verdict(ipq, m->packet_id, nf, 0, NULL) < 0) { + daemon_log(LOG_ERR, "ipq_set_verdict(): %s", ipq_errstr()); + return -1; + } + + + if (icmp) + return reply_icmp_error(m, resp-2); + + return 0; +} -- cgit