summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ulogd/extensions/ulogd_BASE.c216
-rw-r--r--ulogd/include/ulogd/ulogd.h55
-rw-r--r--ulogd/ulogd.c204
3 files changed, 475 insertions, 0 deletions
diff --git a/ulogd/extensions/ulogd_BASE.c b/ulogd/extensions/ulogd_BASE.c
new file mode 100644
index 0000000..6c9876e
--- /dev/null
+++ b/ulogd/extensions/ulogd_BASE.c
@@ -0,0 +1,216 @@
+/* ulogd_MAC.c, Version $Revision$
+ *
+ * ulogd logging interpreter for MAC addresses, TIME, etc.
+ *
+ * (C) 2000 by Harald Welte <laforge@sunbeam.franken.de>
+ * This software is released under the terms of GNU GPL
+ *
+ * $Id$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ulogd.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/icmp.h>
+
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+
+
+ulog_iret_t *_interp_mac(ulog_packet_msg_t *pkt)
+{
+ unsigned char *p;
+ int i;
+ char *buf;
+ ulog_iret_t *ret;
+
+ if (pkt->mac_len)
+ {
+ buf = (char *) malloc(3 * pkt->mac_len + 1);
+ *buf = 0;
+
+ p = pkt->mac;
+ for (i = 0; i < pkt->mac_len; i++, p++)
+ sprintf(buf, "%s%02x%c", buf, *p, i==pkt->mac_len-1 ? ' ':':');
+ ret = alloc_ret(ULOGD_RET_STRING,"raw.mac.addr");
+ ret->value = buf;
+ return ret;
+
+ }
+ return NULL;
+}
+
+ulog_iret_t *_interp_time(ulog_packet_msg_t *pkt)
+{
+ ulog_iret_t *ret, *ret2;
+ unsigned long *ptr;
+
+ ret = alloc_ret(ULOGD_RET_UINT64, "oob.time.sec");
+ ret2 = alloc_ret(ULOGD_RET_UINT64, "oob.time.usec");
+
+ ptr = (unsigned long *) malloc(sizeof(unsigned long));
+ *ptr = pkt->timestamp_sec;
+ ret->value = ptr;
+ ret->next = ret2;
+
+ ptr = (unsigned long *) malloc (sizeof(unsigned long));
+ *ptr = pkt->timestamp_usec;
+ ret2->value = ptr;
+
+ return ret;
+}
+
+ulog_iret_t *_interp_prefix(ulog_packet_msg_t *pkt)
+{
+ ulog_iret_t *ret;
+
+ ret = alloc_ret(ULOGD_RET_STRING, "oob.prefix");
+ ret->value = malloc(sizeof(pkt->prefix));
+ strcpy(ret->value, pkt->prefix);
+
+ return ret;
+}
+
+ulog_iret_t *_interp_mark(ulog_packet_msg_t *pkt)
+{
+ ulog_iret_t *ret;
+ u_int32_t *mk;
+
+ ret = alloc_ret(ULOGD_RET_UINT32, "oob.mark");
+ mk = (u_int32_t *) malloc(sizeof(u_int32_t));
+ *mk = pkt->mark;
+ ret->value = mk;
+
+ return ret;
+}
+
+ulog_iret_t *_interp_iphdr(ulog_packet_msg_t *pkt)
+{
+ ulog_iret_t *ret, *ret2;
+ struct iphdr *iph = (struct iphdr *) pkt->payload;
+ u_int32_t *ip;
+ u_int8_t *ui8;
+ u_int16_t *ui16;
+
+ ret = alloc_ret(ULOGD_RET_IPADDR, "ip.hdr.saddr");
+ ip = malloc(sizeof(u_int32_t));
+ *ip = iph->saddr;
+ ret->value = ip;
+
+ ret->next = ret2 = alloc_ret(ULOGD_RET_IPADDR, "ip.hdr.daddr");
+ ip = malloc(sizeof(u_int32_t));
+ *ip = iph->daddr;
+ ret2->value = ip;
+
+ ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.protocol");
+ ui8 = malloc(sizeof(u_int8_t));
+ *ui8 = iph->protocol;
+ ret2->value = ui8;
+
+ ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.tos");
+ ui8 = malloc(sizeof(u_int8_t));
+ *ui8 = ntohs(iph->tos);
+ ret2->value = ui8;
+
+ ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.ttl");
+ ui8 = malloc(sizeof(u_int8_t));
+ *ui8 = iph->ttl;
+ ret2->value = ui8;
+
+ ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT16, "ip.hdr.tot_len");
+ ui16 = malloc(sizeof(u_int16_t));
+ *ui16 = ntohs(iph->tot_len);
+ ret2->value = ui16;
+
+ ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.ihl");
+ ui8 = malloc(sizeof(u_int8_t));
+ *ui8 = iph->ihl;
+ ret2->value = ui8;
+
+ return ret;
+}
+
+ulog_iret_t *_interp_tcphdr(ulog_packet_msg_t *pkt)
+{
+ struct iphdr *iph = (struct iphdr *) pkt->payload;
+ struct tcphdr *tcph = (struct tcphdr *) (iph + iph->ihl);
+ ulog_iret_t *ret, *ret2;
+ u_int16_t *ui16;
+ u_int32_t *ui32;
+
+ if (iph->protocol != IPPROTO_TCP)
+ return NULL;
+
+ ret = alloc_ret(ULOGD_RET_UINT16, "tcp.hdr.sport");
+ ui16 = malloc(sizeof(u_int16_t));
+ *ui16 = ntohs(tcph->source);
+ ret->value = ui16;
+
+ ret->next = ret2 = alloc_ret(ULOGD_RET_UINT16, "tcp.hdr.sport");
+ ui16 = malloc(sizeof(u_int16_t));
+ *ui16 = ntohs(tcph->dest);
+ ret2->value = ui16;
+
+ ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT32, "tcp.hdr.seq");
+ ui32 = malloc(sizeof(u_int32_t));
+ *ui32 = ntohl(tcph->seq);
+ ret2->value = ui32;
+
+ ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT32, "tcp.hdr.ack_seq");
+ ui32 = malloc(sizeof(u_int32_t));
+ *ui32 = ntohl(tcph->ack_seq);
+ ret2->value = ui32;
+
+
+ return ret;
+}
+
+ulog_iret_t *_interp_icmp(ulog_packet_msg_t *pkt)
+{
+ struct iphdr *iph = (struct iphdr *) pkt->payload;
+ struct icmphdr *icmph = (struct icmphdr *) (iph + iph->ihl);
+ ulog_iret_t *ret, *ret2;
+ u_int8_t *ui8;
+
+ if (iph->protocol != IPPROTO_ICMP)
+ return NULL;
+
+ ret = alloc_ret(ULOGD_RET_UINT8, "icmp.hdr.type");
+ ui8 = malloc(sizeof(u_int8_t));
+ *ui8 = icmph->type;
+ ret->value = ui8;
+
+ return ret;
+
+}
+
+static ulog_interpreter_t base_ip[] = {
+
+ { NULL, "raw.mac", &_interp_mac },
+ { NULL, "oob.time", &_interp_time },
+ { NULL, "oob.prefix", &_interp_prefix },
+ { NULL, "oob.mark", &_interp_mark },
+ { NULL, "ip.hdr", &_interp_iphdr },
+ { NULL, "tcp.hdr", &_interp_tcphdr },
+ { NULL, "icmp.hdr", &_interp_icmp },
+ { NULL, "", NULL },
+};
+
+void _init(void)
+{
+ ulog_interpreter_t *ip = base_ip;
+ ulog_interpreter_t *p;
+
+ for (p = ip; p->interp; p++)
+ {
+ register_interpreter(p);
+ }
+
+}
diff --git a/ulogd/include/ulogd/ulogd.h b/ulogd/include/ulogd/ulogd.h
new file mode 100644
index 0000000..0f3378e
--- /dev/null
+++ b/ulogd/include/ulogd/ulogd.h
@@ -0,0 +1,55 @@
+#ifndef _ULOGD_H
+#define _ULOGD_H
+/* ulogd, Version $Revision: 1.1 $
+ *
+ * first try of a logging daemon for my netfilter ULOG target
+ * for the linux 2.4 netfilter subsystem.
+ *
+ * (C) 2000 by Harald Welte <laforge@sunbeam.franken.de>
+ *
+ * this code is released under the terms of GNU GPL
+ *
+ * $Id: ulog_test.c,v 1.1 2000/07/30 19:34:05 laforge Exp laforge $
+ */
+
+#include <libipulog/libipulog.h>
+
+/* types without length */
+#define ULOGD_RET_NONE 0x0000
+
+#define ULOGD_RET_INT8 0x0001
+#define ULOGD_RET_INT16 0x0002
+#define ULOGD_RET_INT32 0x0003
+#define ULOGD_RET_INT64 0x0004
+
+#define ULOGD_RET_UINT8 0x0011
+#define ULOGD_RET_UINT16 0x0012
+#define ULOGD_RET_UINT32 0x0013
+#define ULOGD_RET_UINT64 0x0014
+
+#define ULOGD_RET_STRING 0x0020
+
+#define ULOGD_RET_IPADDR 0x0100
+
+/* types with lenght field*/
+#define ULOGD_RET_OTHER 0xffff
+
+#define ULOGD_MAX_KEYLEN 32
+
+typedef struct ulog_iret {
+ struct ulog_iret *next;
+ u_int32_t len;
+ u_int16_t type;
+ char key[ULOGD_MAX_KEYLEN];
+ void *value;
+} ulog_iret_t;
+
+typedef struct ulog_interpreter {
+ struct ulog_interpreter *next;
+ char name[ULOGD_MAX_KEYLEN];
+ ulog_iret_t* (*interp)(ulog_packet_msg_t *pkt);
+} ulog_interpreter_t;
+
+void register_interpreter(ulog_interpreter_t *me);
+ulog_iret_t *alloc_ret(const u_int16_t type, const char*);
+#endif
diff --git a/ulogd/ulogd.c b/ulogd/ulogd.c
new file mode 100644
index 0000000..a7608f2
--- /dev/null
+++ b/ulogd/ulogd.c
@@ -0,0 +1,204 @@
+/* ulogd, Version $Revision: 1.1 $
+ *
+ * first try of a logging daemon for my netfilter ULOG target
+ * for the linux 2.4 netfilter subsystem.
+ *
+ * (C) 2000 by Harald Welte <laforge@sunbeam.franken.de>
+ *
+ * this code is released under the terms of GNU GPL
+ *
+ * $Id: ulog_test.c,v 1.1 2000/07/30 19:34:05 laforge Exp laforge $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <libipulog/libipulog.h>
+#include "ulogd.h"
+
+#define MYBUFSIZ 2048
+
+#define ulogd_error(format, args...) fprintf(stderr, format, ## args)
+#define DEBUGP ulogd_error
+
+#define ULOGD_PLUGIN_DIR "/usr/local/lib/ulogd"
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+
+/* linked list for all registered interpreters */
+static ulog_interpreter_t *ulogd_interpreters;
+
+/* try to lookup a registered interpreter for a given name */
+ulog_interpreter_t *find_interpreter(const char *name)
+{
+ ulog_interpreter_t *ptr;
+
+ for (ptr = ulogd_interpreters; ptr; ptr = ptr->next) {
+ if (strcmp(name, ptr->name) == 0)
+ break;
+ }
+
+ return ptr;
+}
+
+/* the function called by all interpreter plugins for registering their
+ * target. */
+void register_interpreter(ulog_interpreter_t *me)
+{
+ if (find_interpreter(me->name)) {
+ ulogd_error("interpreter `%s' already registered\n",
+ me->name);
+ exit(1);
+ }
+ DEBUGP("registering interpreter `%s'\n", me->name);
+ me->next = ulogd_interpreters;
+ ulogd_interpreters = me;
+}
+
+/* allocate a new ulog_iret_t. Called by interpreter plugins */
+ulog_iret_t *alloc_ret(const u_int16_t type, const char* key)
+{
+ ulog_iret_t *ptr = NULL;
+
+ ptr = (ulog_iret_t *) malloc(sizeof(ulog_iret_t));
+ memset(ptr, 0, sizeof(ulog_iret_t));
+ strcpy(ptr->key, key);
+ ptr->type = type;
+
+ return ptr;
+}
+
+/* free a ulog_iret_t* including all linked ones and the value pointers */
+void free_ret(ulog_iret_t *ret)
+{
+ ulog_iret_t *ptr = NULL;
+ ulog_iret_t *nextptr = NULL;
+
+ for (ptr = ret; ptr; ptr = nextptr) {
+ free(ptr->value);
+ if (ptr->next) {
+ nextptr = ptr->next;
+ } else {
+ nextptr = NULL;
+ }
+ free(ptr);
+ }
+}
+
+/* this should pass the result(s) to one or more registered output plugins,
+ * but is currently only printing them out */
+void propagate_results(ulog_iret_t *res)
+{
+ ulog_iret_t *ret;
+
+ for (ret = res; ret; ret = ret->next)
+ {
+ printf("%s=", ret->key);
+ switch (ret->type) {
+ case ULOGD_RET_STRING:
+ printf("%s\n", ret->value);
+ break;
+ case ULOGD_RET_INT16:
+ case ULOGD_RET_INT32:
+ printf("%d\n", ret->value);
+ break;
+ case ULOGD_RET_UINT8:
+ printf("%u\n", *(u_int8_t *)ret->value);
+ break;
+ case ULOGD_RET_UINT16:
+ printf("%u\n", *(u_int16_t *)ret->value);
+ break;
+ case ULOGD_RET_UINT32:
+ case ULOGD_RET_UINT64:
+ printf("%lu\n", *(u_int32_t *)ret->value);
+ break;
+ case ULOGD_RET_IPADDR:
+ printf("%u.%u.%u.%u\n",
+ NIPQUAD(*(u_int32_t *)ret->value));
+ break;
+ case ULOGD_RET_NONE:
+ printf("<none>");
+ break;
+ }
+ }
+}
+
+/* call all registered interpreters and hand the results over to
+ * propagate_results */
+void handle_packet(ulog_packet_msg_t *pkt)
+{
+ ulog_interpreter_t *ptr;
+ ulog_iret_t *ret;
+
+ for (ptr = ulogd_interpreters; ptr; ptr = ptr->next) {
+ ret = (*ptr->interp)(pkt);
+ if (ret) {
+ propagate_results(ret);
+ free_ret(ret);
+ }
+ }
+}
+
+/* silly plugin loader to dlopen() all available plugins */
+void load_plugins(void)
+{
+ DIR *ldir;
+ struct dirent *dent;
+ char *fname;
+
+ ldir = opendir(ULOGD_PLUGIN_DIR);
+ if (ldir) {
+ fname = (char *) malloc(NAME_MAX + strlen(ULOGD_PLUGIN_DIR)
+ + 3);
+ for (dent = readdir(ldir); dent; dent = readdir(ldir)) {
+ DEBUGP("load_plugins: %s\n", dent->d_name);
+ sprintf(fname, "%s/%s", ULOGD_PLUGIN_DIR, dent->d_name);
+ if (!dlopen(fname, RTLD_NOW))
+ ulogd_error("load_plugins: %s", dlerror());
+ }
+ free(fname);
+ } else
+ ulogd_error("no plugin directory\n");
+
+}
+
+main(int argc, char* argv[])
+{
+ struct ipulog_handle *h;
+ unsigned char* buf;
+ size_t len;
+ ulog_packet_msg_t *upkt;
+
+ load_plugins();
+
+ /* allocate a receive buffer */
+ buf = (unsigned char *) malloc(MYBUFSIZ);
+
+ /* create ipulog handle */
+ h = ipulog_create_handle(ipulog_group2gmask(32));
+ if (!h)
+ {
+ /* if some error occurrs, print it to stderr */
+ ipulog_perror(NULL);
+ exit(1);
+ }
+
+ /* endless loop receiving packets and handling them over to
+ * handle_packet */
+ while(1)
+ {
+ len = ipulog_read(h, buf, BUFSIZ, 1);
+ upkt = ipulog_get_packet(buf);
+ DEBUGP("==> packet received\n");
+ handle_packet(upkt);
+ }
+
+ /* just to give it a cleaner look */
+ ipulog_destroy_handle(h);
+
+}