]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
Initial revision
authorlaforge <laforge>
Wed, 2 Aug 2000 08:41:55 +0000 (08:41 +0000)
committerlaforge <laforge>
Wed, 2 Aug 2000 08:41:55 +0000 (08:41 +0000)
extensions/ulogd_BASE.c [new file with mode: 0644]
include/ulogd/ulogd.h [new file with mode: 0644]
ulogd.c [new file with mode: 0644]

diff --git a/extensions/ulogd_BASE.c b/extensions/ulogd_BASE.c
new file mode 100644 (file)
index 0000000..6c9876e
--- /dev/null
@@ -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/include/ulogd/ulogd.h b/include/ulogd/ulogd.h
new file mode 100644 (file)
index 0000000..0f3378e
--- /dev/null
@@ -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.c b/ulogd.c
new file mode 100644 (file)
index 0000000..a7608f2
--- /dev/null
+++ b/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);
+
+}