summaryrefslogtreecommitdiffstats
path: root/ulogd
diff options
context:
space:
mode:
Diffstat (limited to 'ulogd')
-rw-r--r--ulogd/extensions/ulogd_BASE.c104
-rw-r--r--ulogd/include/ulogd/ulogd.h30
-rw-r--r--ulogd/ulogd.c159
3 files changed, 161 insertions, 132 deletions
diff --git a/ulogd/extensions/ulogd_BASE.c b/ulogd/extensions/ulogd_BASE.c
index 6c9876e..8506d42 100644
--- a/ulogd/extensions/ulogd_BASE.c
+++ b/ulogd/extensions/ulogd_BASE.c
@@ -1,11 +1,11 @@
-/* ulogd_MAC.c, Version $Revision$
+/* ulogd_MAC.c, Version $Revision: 1.1 $
*
* 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$
+ * $Id: ulogd_BASE.c,v 1.1 2000/08/02 08:51:15 laforge Exp laforge $
*
*/
@@ -17,13 +17,6 @@
#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;
@@ -40,7 +33,7 @@ ulog_iret_t *_interp_mac(ulog_packet_msg_t *pkt)
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;
+ ret->value.ptr = buf;
return ret;
}
@@ -50,19 +43,14 @@ ulog_iret_t *_interp_mac(ulog_packet_msg_t *pkt)
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");
+ ret = alloc_ret(ULOGD_RET_UINT32, "oob.time.sec");
+ ret2 = alloc_ret(ULOGD_RET_UINT32, "oob.time.usec");
- ptr = (unsigned long *) malloc(sizeof(unsigned long));
- *ptr = pkt->timestamp_sec;
- ret->value = ptr;
+ ret->value.ui32 = pkt->timestamp_sec;
ret->next = ret2;
- ptr = (unsigned long *) malloc (sizeof(unsigned long));
- *ptr = pkt->timestamp_usec;
- ret2->value = ptr;
+ ret2->value.ui32 = pkt->timestamp_usec;
return ret;
}
@@ -72,8 +60,8 @@ 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);
+ ret->value.ptr = malloc(sizeof(pkt->prefix));
+ strcpy(ret->value.ptr, pkt->prefix);
return ret;
}
@@ -81,12 +69,9 @@ ulog_iret_t *_interp_prefix(ulog_packet_msg_t *pkt)
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;
+ ret->value.ui32 = pkt->mark;
return ret;
}
@@ -95,44 +80,27 @@ 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->value.ui32 = ntohl(iph->saddr);
ret->next = ret2 = alloc_ret(ULOGD_RET_IPADDR, "ip.hdr.daddr");
- ip = malloc(sizeof(u_int32_t));
- *ip = iph->daddr;
- ret2->value = ip;
+ ret2->value.ui32 = ntohl(iph->daddr);
ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.protocol");
- ui8 = malloc(sizeof(u_int8_t));
- *ui8 = iph->protocol;
- ret2->value = ui8;
+ ret2->value.ui8 = iph->protocol;
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->value.ui8 = ntohs(iph->tos);
ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.ttl");
- ui8 = malloc(sizeof(u_int8_t));
- *ui8 = iph->ttl;
- ret2->value = ui8;
+ ret2->value.ui8 = iph->ttl;
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->value.ui16 = ntohs(iph->tot_len);
ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.ihl");
- ui8 = malloc(sizeof(u_int8_t));
- *ui8 = iph->ihl;
- ret2->value = ui8;
+ ret2->value.ui8 = iph->ihl;
return ret;
}
@@ -142,32 +110,21 @@ 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->value.ui16 = ntohs(tcph->source);
ret->next = ret2 = alloc_ret(ULOGD_RET_UINT16, "tcp.hdr.sport");
- ui16 = malloc(sizeof(u_int16_t));
- *ui16 = ntohs(tcph->dest);
- ret2->value = ui16;
+ ret->value.ui16 = ntohs(tcph->dest);
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;
+ ret->value.ui32 = ntohl(tcph->seq);
+ ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT32, "tcp.hdr.ack_seq");
+ ret->value.ui32 = ntohl(tcph->ack_seq);
return ret;
}
@@ -177,20 +134,18 @@ 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;
+ ret->value.ui8 = icmph->type;
return ret;
}
+
static ulog_interpreter_t base_ip[] = {
{ NULL, "raw.mac", &_interp_mac },
@@ -202,15 +157,18 @@ static ulog_interpreter_t base_ip[] = {
{ NULL, "icmp.hdr", &_interp_icmp },
{ NULL, "", NULL },
};
-
-void _init(void)
+void _base_reg_ip(void)
{
ulog_interpreter_t *ip = base_ip;
ulog_interpreter_t *p;
for (p = ip; p->interp; p++)
- {
register_interpreter(p);
- }
}
+
+
+void _init(void)
+{
+ _base_reg_ip();
+}
diff --git a/ulogd/include/ulogd/ulogd.h b/ulogd/include/ulogd/ulogd.h
index 0f3378e..fbb373c 100644
--- a/ulogd/include/ulogd/ulogd.h
+++ b/ulogd/include/ulogd/ulogd.h
@@ -9,11 +9,14 @@
*
* 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 $
+ * $Id: ulogd.h,v 1.1 2000/08/02 08:41:57 laforge Exp laforge $
*/
#include <libipulog/libipulog.h>
+/* All types with MSB = 1 make use of value.ptr
+ * other types use one of the union's member */
+
/* types without length */
#define ULOGD_RET_NONE 0x0000
@@ -27,7 +30,7 @@
#define ULOGD_RET_UINT32 0x0013
#define ULOGD_RET_UINT64 0x0014
-#define ULOGD_RET_STRING 0x0020
+#define ULOGD_RET_STRING 0x8020
#define ULOGD_RET_IPADDR 0x0100
@@ -36,12 +39,25 @@
#define ULOGD_MAX_KEYLEN 32
+#define ulogd_error(format, args...) fprintf(logfile, format, ## args)
+static FILE *logfile;
+
typedef struct ulog_iret {
struct ulog_iret *next;
u_int32_t len;
u_int16_t type;
char key[ULOGD_MAX_KEYLEN];
- void *value;
+ union {
+ u_int8_t ui8;
+ u_int16_t ui16;
+ u_int32_t ui32;
+ u_int64_t ui64;
+ int8_t i8;
+ int16_t i16;
+ int32_t i32;
+ int64_t i64;
+ void *ptr;
+ } value;
} ulog_iret_t;
typedef struct ulog_interpreter {
@@ -50,6 +66,14 @@ typedef struct ulog_interpreter {
ulog_iret_t* (*interp)(ulog_packet_msg_t *pkt);
} ulog_interpreter_t;
+typedef struct ulog_output {
+ struct ulog_output *next;
+ char name[ULOGD_MAX_KEYLEN];
+ int* (*output)(ulog_iret_t *ret);
+} ulog_output_t;
+
void register_interpreter(ulog_interpreter_t *me);
+void register_output(ulog_output_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
index a7608f2..2059531 100644
--- a/ulogd/ulogd.c
+++ b/ulogd/ulogd.c
@@ -7,11 +7,12 @@
*
* 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 $
+ * $Id: ulogd.c,v 1.1 2000/08/02 08:41:55 laforge Exp laforge $
*/
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <dirent.h>
@@ -20,19 +21,27 @@
#define MYBUFSIZ 2048
-#define ulogd_error(format, args...) fprintf(stderr, format, ## args)
+
#define DEBUGP ulogd_error
+#ifndef ULOGD_PLUGIN_DIR
#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]
+#endif
+
+#ifndef ULOGD_LOGFILE
+#define ULOGD_LOGFILE "/var/log/ulogd.log"
+#endif
+
+#ifndef ULOGD_NLGROUP
+#define ULOGD_NLGROUP 32
+#endif
/* linked list for all registered interpreters */
static ulog_interpreter_t *ulogd_interpreters;
+/* linked list for all registered output targets */
+static ulog_output_t *ulogd_outputs;
+
/* try to lookup a registered interpreter for a given name */
ulog_interpreter_t *find_interpreter(const char *name)
{
@@ -40,10 +49,10 @@ ulog_interpreter_t *find_interpreter(const char *name)
for (ptr = ulogd_interpreters; ptr; ptr = ptr->next) {
if (strcmp(name, ptr->name) == 0)
- break;
+ return ptr;
}
- return ptr;
+ return NULL;
}
/* the function called by all interpreter plugins for registering their
@@ -60,6 +69,32 @@ void register_interpreter(ulog_interpreter_t *me)
ulogd_interpreters = me;
}
+/* try to lookup a registered output plugin for a given name */
+ulog_output_t *find_output(const char *name)
+{
+ ulog_output_t *ptr;
+
+ for (ptr = ulogd_outputs; ptr; ptr = ptr->next) {
+ if (strcmp(name, ptr->name) == 0)
+ return ptr;
+ }
+
+ return NULL;
+}
+
+/* the function called by all output plugins for registering themselves */
+void register_output(ulog_output_t *me)
+{
+ if (find_output(me->name)) {
+ ulogd_error("output `%s' already registered\n",
+ me->name);
+ exit(1);
+ }
+ DEBUGP("registering output `%s'\n", me->name);
+ me->next = ulogd_outputs;
+ ulogd_outputs = me;
+}
+
/* allocate a new ulog_iret_t. Called by interpreter plugins */
ulog_iret_t *alloc_ret(const u_int16_t type, const char* key)
{
@@ -80,7 +115,9 @@ void free_ret(ulog_iret_t *ret)
ulog_iret_t *nextptr = NULL;
for (ptr = ret; ptr; ptr = nextptr) {
- free(ptr->value);
+ if ((ptr->type | 0x7fff) == 0xffff) {
+ free(ptr->value.ptr);
+ }
if (ptr->next) {
nextptr = ptr->next;
} else {
@@ -90,41 +127,16 @@ void free_ret(ulog_iret_t *ret)
}
}
+
/* 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)
+void propagate_results(ulog_iret_t *ret)
{
- ulog_iret_t *ret;
+ ulog_output_t *p;
- for (ret = res; ret; ret = ret->next)
+ for (p = ulogd_outputs; p; p = p->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;
- }
+ (*p->output)(ret);
}
}
@@ -133,15 +145,23 @@ void propagate_results(ulog_iret_t *res)
void handle_packet(ulog_packet_msg_t *pkt)
{
ulog_interpreter_t *ptr;
- ulog_iret_t *ret;
+ ulog_iret_t *ret, *b;
+ ulog_iret_t *allret = NULL;
+ /* call each registered interpreter */
for (ptr = ulogd_interpreters; ptr; ptr = ptr->next) {
ret = (*ptr->interp)(pkt);
if (ret) {
- propagate_results(ret);
- free_ret(ret);
+ /* prepend the results to allret */
+ if (allret) {
+ for (b = ret; b->next; b = b->next);
+ b->next = allret;
+ }
+ allret = ret;
}
}
+ propagate_results(allret);
+ free_ret(allret);
}
/* silly plugin loader to dlopen() all available plugins */
@@ -156,10 +176,12 @@ void load_plugins(void)
fname = (char *) malloc(NAME_MAX + strlen(ULOGD_PLUGIN_DIR)
+ 3);
for (dent = readdir(ldir); dent; dent = readdir(ldir)) {
+ if (strncmp(dent->d_name,"ulogd", 5) == 0) {
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
@@ -167,20 +189,32 @@ void load_plugins(void)
}
-main(int argc, char* argv[])
+int logfile_open(const char *name)
+{
+ logfile = fopen(name, "a");
+ if (!logfile)
+ {
+ fprintf(stderr, "ERROR: unable to open logfile: %s\n", strerror(errno));
+ exit(2);
+ }
+ return 0;
+}
+
+int main(int argc, char* argv[])
{
struct ipulog_handle *h;
unsigned char* buf;
size_t len;
ulog_packet_msg_t *upkt;
+ logfile_open(ULOGD_LOGFILE);
load_plugins();
/* allocate a receive buffer */
buf = (unsigned char *) malloc(MYBUFSIZ);
/* create ipulog handle */
- h = ipulog_create_handle(ipulog_group2gmask(32));
+ h = ipulog_create_handle(ipulog_group2gmask(ULOGD_NLGROUP));
if (!h)
{
/* if some error occurrs, print it to stderr */
@@ -188,17 +222,30 @@ main(int argc, char* argv[])
exit(1);
}
- /* endless loop receiving packets and handling them over to
- * handle_packet */
- while(1)
+ if (!fork())
+ {
+
+ /*
+ fclose(stdout);
+ fclose(stderr);
+ */
+
+ /* 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);
+ free(buf);
+ fclose(logfile);
+ } else
{
- len = ipulog_read(h, buf, BUFSIZ, 1);
- upkt = ipulog_get_packet(buf);
- DEBUGP("==> packet received\n");
- handle_packet(upkt);
+ exit(0);
}
-
- /* just to give it a cleaner look */
- ipulog_destroy_handle(h);
-
}