From 5be5c62b23768d36b632c825d7459c9cdf575afa Mon Sep 17 00:00:00 2001 From: laforge Date: Wed, 2 Aug 2000 12:15:44 +0000 Subject: first usable revision --- ulogd/extensions/ulogd_BASE.c | 104 ++++++++------------------- ulogd/include/ulogd/ulogd.h | 30 +++++++- ulogd/ulogd.c | 159 +++++++++++++++++++++++++++--------------- 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 * 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 #include -#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 +/* 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 #include +#include #include #include #include @@ -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(""); - 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); - } -- cgit v1.2.3