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/ipqapi.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/ipqapi.c')
-rw-r--r-- | daemon/ipqapi.c | 118 |
1 files changed, 118 insertions, 0 deletions
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 <string.h> +#include <time.h> + +#include <daemon-log.h> + +#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; +} |