]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
Major update. Almost everything has changed.
authorlaforge <laforge>
Thu, 16 Nov 2000 17:20:52 +0000 (17:20 +0000)
committerlaforge <laforge>
Thu, 16 Nov 2000 17:20:52 +0000 (17:20 +0000)
- no more dynamic allocations at runtime - only once at startup
- less list traversal through interpreter and key hashes
- output plugins can request only certain results!

Makefile
conffile.c
extensions/ulogd_BASE.c
extensions/ulogd_OPRINT.c
extensions/ulogd_PWSNIFF.c
include/ulogd/ulogd.h
ulogd.c

index 6d80dfb41af5aad66acef81b00220e5b5f6041b7..2f15c62851d726068ff80520cc0b89b7d41eae00 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,13 +3,13 @@ LIBIPULOG=../libipulog
 INCIPULOG=-I../libipulog/include
 
 # Names of the plugins to be compiled
-ULOGD_SL:=BASE OPRINT PWSNIFF
+ULOGD_SL:=BASE OPRINT PWSNIFF #MYSQL
 
 #  Normally You should not need to change anything below
 #
 CC = gcc
 CFLAGS = -I. -Wall $(INCIPULOG) -O2
-#CFLAGS+=-g -DDEBUG
+CFLAGS+=-g -DDEBUG
 
 SH_CFLAGS:=$(CFLAGS) -fPIC
 
@@ -27,7 +27,7 @@ conffile.o: conffile.c
        $(CC) $(CFLAGS) -c $< -o $@
 
 ulogd: ulogd.c $(LIBIPULOG) ulogd.h conffile.o
-       $(CC) $(CFLAGS) -rdynamic -ldl -i ulogd.c conffile.o $(LIBIPULOG)/libipulog.a -o ulogd
+       $(CC) $(CFLAGS) -rdynamic -ldl ulogd.c -lmysqlclient conffile.o $(LIBIPULOG)/libipulog.a -o ulogd
 
 clean:
        rm -f ulogd *.o extensions/*.o extensions/*.so
index 2489c8db7bd70d8e6030c5bb18bcc1ba6146728f..04f54f2cc396447b0562df9091b75d17c9a4e419 100644 (file)
@@ -1,7 +1,7 @@
 /* config file parser functions
  * (C) 2000 by Harald Welte <laforge@gnumonks.org>
  *
- * $Id: conffile.c,v 1.5 2000/09/12 14:29:36 laforge Exp $
+ * $Id: conffile.c,v 1.6 2000/09/22 06:54:33 laforge Exp $
  * 
  * This code is distributed under the terms of GNU GPL */
 
@@ -115,7 +115,7 @@ int config_parse_file(int final)
        
        while (fgets(line, LINE_LEN, cfile))
        {
-               DEBUGC("line read\n");
+               DEBUGC("line read: %s\n", line);
                if (*line == '#')
                        continue;
 
@@ -123,18 +123,21 @@ int config_parse_file(int final)
                if (!word)
                        continue;
 
+#if 0
                /* if we do the final parse and word is not a config key */
                if (final && config_iskey(word)) {
                        DEBUGC("final and key '%s' not found\n", word);
                        err = -ERRUNKN;
                        goto cpf_error;
                }
+#endif
 
                args = line + strlen(word) + 1;
                *(args + strlen(args) - 1 ) = '\0';
-
+               
+               DEBUGC("parse_file: entering main loop\n");
                for (ce = config; ce; ce = ce->next) {
-                       DEBUGC("parse main loop\n");
+                       DEBUGC("parse main loop, key: %s\n", ce->key);
                        if (strcmp(ce->key, word)) {
                                continue;
                        }
@@ -164,12 +167,13 @@ int config_parse_file(int final)
                        }
                        break;
                }
+               DEBUGC("parse_file: exiting main loop\n");
        }
 
 
        for (ce = config; ce; ce = ce->next) {
                DEBUGC("ce post loop, ce=%s\n", ce->key);
-               if ((ce->options & CONFIG_OPT_MANDATORY) && (ce->hit == 0)) {
+               if ((ce->options & CONFIG_OPT_MANDATORY) && (ce->hit == 0) && final) {
                        DEBUGC("mandatory config directive %s not found\n",
                                ce->key);
                        config_errce = ce;
index 391ac59954694c9c094fd19dd7528e8f202eb6ed..5d4ef2f0b51d37e77fe60f99d9d5a936643540e8 100644 (file)
@@ -1,11 +1,11 @@
-/* ulogd_MAC.c, Version $Revision: 1.5 $
+/* ulogd_MAC.c, Version $Revision: 1.6 $
  *
  * ulogd logging interpreter for MAC addresses, TIME, IP and TCP headers, etc.
  *
  * (C) 2000 by Harald Welte <laforge@gnumonks.org>
  * This software is released under the terms of GNU GPL
  *
- * $Id: ulogd_BASE.c,v 1.5 2000/09/22 06:54:33 laforge Exp $
+ * $Id: ulogd_BASE.c,v 1.6 2000/09/26 06:25:02 laforge Exp $
  *
  */
 
 #include <linux/icmp.h>
 #include <linux/udp.h>
 
-ulog_iret_t *_interp_mac(ulog_packet_msg_t *pkt)
+/***********************************************************************
+ *                     Raw header
+ ***********************************************************************/
+static ulog_iret_t mac_rets[1] = {
+       { NULL, NULL, 0, ULOGD_RET_STRING, ULOGD_RETF_FREE, "raw.mac", NULL },
+};
+
+ulog_iret_t *_interp_mac(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt)
 {
        unsigned char *p;
        int i;
        char *buf;
-       ulog_iret_t *ret;
+       ulog_iret_t *ret = ip->result;
        
        if (pkt->mac_len) {
                buf = (char *) malloc(3 * pkt->mac_len + 1);
@@ -32,201 +39,223 @@ ulog_iret_t *_interp_mac(ulog_packet_msg_t *pkt)
                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.ptr = buf;
+               ret[0].value.ptr = buf;
+               ret[0].flags |= ULOGD_RETF_VALID;
                return ret;
 
        }
        return NULL;
 }
 
-ulog_iret_t *_interp_time(ulog_packet_msg_t *pkt)
-{
-       ulog_iret_t *ret, *ret2;
-       
-       ret = alloc_ret(ULOGD_RET_UINT32, "oob.time.sec");
-       ret2 = alloc_ret(ULOGD_RET_UINT32, "oob.time.usec");
-
-       ret->value.ui32 = pkt->timestamp_sec;
-       ret->next = ret2;
+/***********************************************************************
+ *                     OUT OF BAND
+ ***********************************************************************/
 
-       ret2->value.ui32 = pkt->timestamp_usec;
-       
-       return ret;
-}
+static ulog_iret_t oob_rets[] = {
+       { NULL, NULL, 0, ULOGD_RET_STRING, ULOGD_RETF_NONE, "oob.prefix", NULL },
+       { NULL, NULL, 0, ULOGD_RET_UINT32, ULOGD_RETF_NONE, "oob.time.sec", NULL },
+       { NULL, NULL, 0, ULOGD_RET_UINT32, ULOGD_RETF_NONE, "oob.time.usec", NULL },
+       { NULL, NULL, 0, ULOGD_RET_UINT32, ULOGD_RETF_NONE, "oob.mark", NULL },
+};
 
-ulog_iret_t *_interp_prefix(ulog_packet_msg_t *pkt)
+ulog_iret_t *_interp_oob(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt)
 {
-       ulog_iret_t *ret;
-       
-       ret = alloc_ret(ULOGD_RET_STRING, "oob.prefix");
-       ret->value.ptr = malloc(sizeof(pkt->prefix));
-       strcpy(ret->value.ptr, pkt->prefix);
+       ulog_iret_t *ret = ip->result;
+
+       ret[0].value.ptr = pkt->prefix;
+       ret[0].flags |= ULOGD_RETF_VALID;
+       ret[1].value.ui32 = pkt->timestamp_sec;
+       ret[1].flags |= ULOGD_RETF_VALID;
+       ret[2].value.ui32 = pkt->timestamp_usec;
+       ret[2].flags |= ULOGD_RETF_VALID;
+       ret[3].value.ui32 = pkt->mark;
+       ret[3].flags |= ULOGD_RETF_VALID;
        
        return ret;
 }
 
-ulog_iret_t *_interp_mark(ulog_packet_msg_t *pkt)
-{
-       ulog_iret_t *ret;
-
-       ret = alloc_ret(ULOGD_RET_UINT32, "oob.mark");
-       ret->value.ui32 = pkt->mark;
-
-       return ret;     
-}
+/***********************************************************************
+ *                     IP HEADER
+ ***********************************************************************/
+
+static ulog_iret_t iphdr_rets[] = {
+       { NULL, NULL, 0, ULOGD_RET_IPADDR, ULOGD_RETF_NONE, "ip.saddr", 0 },
+       { NULL, NULL, 0, ULOGD_RET_IPADDR, ULOGD_RETF_NONE, "ip.daddr", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT8, ULOGD_RETF_NONE, "ip.protocol", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT8, ULOGD_RETF_NONE, "ip.tos", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT8, ULOGD_RETF_NONE, "ip.ttl", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "ip.totlen", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT8, ULOGD_RETF_NONE, "ip.ihl", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "ip.csum",  0 },
+};
 
-ulog_iret_t *_interp_iphdr(ulog_packet_msg_t *pkt)
+ulog_iret_t *_interp_iphdr(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt)
 {
-       ulog_iret_t *ret, *ret2;
+       ulog_iret_t *ret = ip->result;
        struct iphdr *iph = (struct iphdr *) pkt->payload;
 
-       ret = alloc_ret(ULOGD_RET_IPADDR, "ip.hdr.saddr");
-       ret->value.ui32 = ntohl(iph->saddr);
-
-       ret->next = ret2 = alloc_ret(ULOGD_RET_IPADDR, "ip.hdr.daddr");
-       ret2->value.ui32 = ntohl(iph->daddr);
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.protocol");
-       ret2->value.ui8 = iph->protocol;
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.tos");
-       ret2->value.ui8 = ntohs(iph->tos);
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.ttl");
-       ret2->value.ui8 = iph->ttl;
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT16, "ip.hdr.tot_len");
-       ret2->value.ui16 = ntohs(iph->tot_len);
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT8, "ip.hdr.ihl");
-       ret2->value.ui8 = iph->ihl;
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT16, "ip.hdr.csum");
-       ret2->value.ui16 = ntohs(iph->check);
+       ret[0].value.ui32 = ntohl(iph->saddr);
+       ret[0].flags |= ULOGD_RETF_VALID;
+       ret[1].value.ui32 = ntohl(iph->daddr);
+       ret[1].flags |= ULOGD_RETF_VALID;
+       ret[2].value.ui8 = iph->protocol;
+       ret[2].flags |= ULOGD_RETF_VALID;
+       ret[3].value.ui8 = ntohs(iph->tos);
+       ret[3].flags |= ULOGD_RETF_VALID;
+       ret[4].value.ui8 = iph->ttl;
+       ret[4].flags |= ULOGD_RETF_VALID;
+       ret[5].value.ui16 = ntohs(iph->tot_len);
+       ret[5].flags |= ULOGD_RETF_VALID;
+       ret[6].value.ui8 = iph->ihl;
+       ret[6].flags |= ULOGD_RETF_VALID;
+       ret[7].value.ui16 = ntohs(iph->check);
+       ret[7].flags |= ULOGD_RETF_VALID;
 
        return ret;
 }
 
-ulog_iret_t *_interp_tcphdr(ulog_packet_msg_t *pkt)
+/***********************************************************************
+ *                     TCP HEADER
+ ***********************************************************************/
+static ulog_iret_t tcphdr_rets[] = {
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "tcp.sport", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "tcp.dport", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT32, ULOGD_RETF_NONE, "tcp.seq", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT32, ULOGD_RETF_NONE, "tcp.ackseq", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "tcp.window", 0 },
+       { NULL, NULL, 0, ULOGD_RET_BOOL, ULOGD_RETF_NONE, "tcp.urg", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "tcp.urgp", 0 },
+       { NULL, NULL, 0, ULOGD_RET_BOOL, ULOGD_RETF_NONE, "tcp.ack", 0 },
+       { NULL, NULL, 0, ULOGD_RET_BOOL, ULOGD_RETF_NONE, "tcp.psh", 0 },
+       { NULL, NULL, 0, ULOGD_RET_BOOL, ULOGD_RETF_NONE, "tcp.rst", 0 },
+       { NULL, NULL, 0, ULOGD_RET_BOOL, ULOGD_RETF_NONE, "tcp.syn", 0 },
+       { NULL, NULL, 0, ULOGD_RET_BOOL, ULOGD_RETF_NONE, "tcp.fin", 0 },
+};
+
+ulog_iret_t *_interp_tcphdr(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt)
 {
        struct iphdr *iph = (struct iphdr *) pkt->payload;
        void *protoh = (u_int32_t *)iph + iph->ihl;
        struct tcphdr *tcph = (struct tcphdr *) protoh;
-       ulog_iret_t *ret, *ret2;
+       ulog_iret_t *ret = ip->result;
 
        if (iph->protocol != IPPROTO_TCP)
                return NULL;
        
-       ret = alloc_ret(ULOGD_RET_UINT16, "tcp.hdr.sport");
-       ret->value.ui16 = ntohs(tcph->source);
-
-       ret->next = ret2 = alloc_ret(ULOGD_RET_UINT16, "tcp.hdr.dport");
-       ret2->value.ui16 = ntohs(tcph->dest);
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT32, "tcp.hdr.seq");
-       ret2->value.ui32 = ntohl(tcph->seq);
-       
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT32, "tcp.hdr.ack_seq");
-       ret2->value.ui32 = ntohl(tcph->ack_seq);
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT16, "tcp.hdr.window");
-       ret2->value.ui16 = ntohs(tcph->window);
-
+       ret[0].value.ui16 = ntohs(tcph->source);
+       ret[0].flags |= ULOGD_RETF_VALID;
+       ret[1].value.ui16 = ntohs(tcph->dest);
+       ret[1].flags |= ULOGD_RETF_VALID;
+       ret[2].value.ui32 = ntohl(tcph->seq);
+       ret[2].flags |= ULOGD_RETF_VALID;
+       ret[3].value.ui32 = ntohl(tcph->ack_seq);
+       ret[3].flags |= ULOGD_RETF_VALID;
+       ret[4].value.ui16 = ntohs(tcph->window);
+       ret[4].flags |= ULOGD_RETF_VALID;
        if (tcph->urg) {
-               ret2 = ret2->next = alloc_ret(ULOGD_RET_BOOL, "tcp.hdr.urg");
-               ret2->value.b = 1;
-               
-               ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT16, "tcp.hdr.urgp");
-               ret2->value.ui16 = ntohs(tcph->urg_ptr);
+               ret[5].value.b = tcph->urg;
+               ret[5].flags |= ULOGD_RETF_VALID;
+               ret[6].value.ui16 = ntohs(tcph->urg_ptr);
+               ret[6].flags |= ULOGD_RETF_VALID;
        }
        if (tcph->ack) {
-               ret2 = ret2->next = alloc_ret(ULOGD_RET_BOOL, "tcp.hdr.ack");
-               ret2->value.b = 1;
+               ret[7].value.b = tcph->ack;
+               ret[7].flags |= ULOGD_RETF_VALID;
        }
        if (tcph->psh) {
-               ret2 = ret2->next = alloc_ret(ULOGD_RET_BOOL, "tcp.hdr.psh");
-               ret2->value.b = 1;
+               ret[8].value.b = tcph->psh;
+               ret[8].flags |= ULOGD_RETF_VALID;
        }
        if (tcph->rst) {
-               ret2 = ret2->next = alloc_ret(ULOGD_RET_BOOL, "tcp.hdr.rst");
-               ret2->value.b = 1;
+               ret[9].value.b = tcph->rst;
+               ret[9].flags |= ULOGD_RETF_VALID;
        }
        if (tcph->syn) {
-               ret2 = ret2->next = alloc_ret(ULOGD_RET_BOOL, "tcp.hdr.syn");
-               ret2->value.b = 1;
+               ret[10].value.b = tcph->syn;
+               ret[10].flags |= ULOGD_RETF_VALID;
        }
        if (tcph->fin) {
-               ret2 = ret2->next = alloc_ret(ULOGD_RET_BOOL, "tcp.hdr.fin");
-               ret2->value.b = 1;
+               ret[11].value.b = tcph->fin;
+               ret[11].flags |= ULOGD_RETF_VALID;
        }
        
        return ret;
 }
 
-ulog_iret_t *_interp_udp(ulog_packet_msg_t *pkt)
+/***********************************************************************
+ *                     UDP HEADER
+ ***********************************************************************/
+static ulog_iret_t udphdr_rets[] = {
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "udp.sport", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "udp.dport", 0 },
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "upd.len", 0 },
+};
+ulog_iret_t *_interp_udp(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt)
 {
        struct iphdr *iph = (struct iphdr *) pkt->payload;
        void *protoh = (u_int32_t *)iph + iph->ihl;
        struct udphdr *udph = protoh;
-       ulog_iret_t *ret, *ret2;
+       ulog_iret_t *ret = ip->result;
 
        if (iph->protocol != IPPROTO_UDP)
                return NULL;
 
-       ret = alloc_ret(ULOGD_RET_UINT16, "udp.hdr.sport");
-       ret->value.ui16 = ntohs(udph->source);
-
-       ret2 = ret->next = alloc_ret(ULOGD_RET_UINT16, "udp.hdr.dport");
-       ret2->value.ui16 = ntohs(udph->dest);
-
-       ret2 = ret2->next = alloc_ret(ULOGD_RET_UINT16, "udp.hdr.len");
-       ret2->value.ui16 = ntohs(udph->len);
+       ret[0].value.ui16 = ntohs(udph->source);
+       ret[0].flags |= ULOGD_RETF_VALID;
+       ret[1].value.ui16 = ntohs(udph->dest);
+       ret[1].flags |= ULOGD_RETF_VALID;
+       ret[2].value.ui16 = ntohs(udph->len);
+       ret[2].flags |= ULOGD_RETF_VALID;
        
        return ret;
 }
 
-ulog_iret_t *_interp_icmp(ulog_packet_msg_t *pkt)
+/***********************************************************************
+ *                     ICMP HEADER
+ ***********************************************************************/
+
+static ulog_iret_t icmphdr_rets[] = {
+       { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "icmp.type", 0 },
+};
+
+ulog_iret_t *_interp_icmp(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt)
 {
        struct iphdr *iph = (struct iphdr *) pkt->payload;
        void *protoh = (u_int32_t *) (iph + iph->ihl);
        struct icmphdr *icmph = protoh;
-       ulog_iret_t *ret;
+       ulog_iret_t *ret = ip->result;
 
        if (iph->protocol != IPPROTO_ICMP)
                return NULL;
        
-       ret = alloc_ret(ULOGD_RET_UINT8, "icmp.hdr.type");
-       ret->value.ui8 = icmph->type;
+       ret[0].value.ui8 = icmph->type;
+       ret[0].flags |= ULOGD_RETF_VALID;
 
        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, "udp.hdr", &_interp_udp },
-       { NULL, "", NULL }, 
+static ulog_interpreter_t base_ip[] = {
+       { NULL, "raw", 0, &_interp_mac, 1, &mac_rets },
+       { NULL, "oob", 0, &_interp_oob, 4, &oob_rets },
+       { NULL, "ip", 0, &_interp_iphdr, 8, &iphdr_rets },
+       { NULL, "tcp", 0, &_interp_tcphdr, 12, &tcphdr_rets },
+       { NULL, "icmp", 0, &_interp_icmp, 1, &icmphdr_rets },
+       { NULL, "udp", 0, &_interp_udp, 3, &udphdr_rets },
+       { NULL, "", 0, NULL, 0, { NULL } }, 
 };
+
 void _base_reg_ip(void)
 {
        ulog_interpreter_t *ip = base_ip;
        ulog_interpreter_t *p;
 
-       for (p = ip; p->interp; p++)
+       for (p = ip; p->interp; p++) {
                register_interpreter(p);
+       }
 
 }
 
-
 void _init(void)
 {
        _base_reg_ip();
index 0b551b68a15bb678d2ee32cdd4cf914101420222..3fa42ed601b522b509895ccb0cbd393c492ddeae 100644 (file)
@@ -1,11 +1,11 @@
-/* ulogd_MAC.c, Version $Revision: 1.3 $
+/* ulogd_MAC.c, Version $Revision: 1.4 $
  *
  * ulogd output target for logging to a file 
  *
  * (C) 2000 by Harald Welte <laforge@gnumonks.org>
  * This software is released under the terms of GNU GPL
  *
- * $Id: ulogd_OPRINT.c,v 1.3 2000/09/12 14:29:37 laforge Exp $
+ * $Id: ulogd_OPRINT.c,v 1.4 2000/09/22 06:54:33 laforge Exp $
  *
  */
 
@@ -34,7 +34,7 @@ int _output_print(ulog_iret_t *res)
        ulog_iret_t *ret;
        
        fprintf(of, "===>PACKET BOUNDARY\n");
-       for (ret = res; ret; ret = ret->next) {
+       for (ret = res; ret; ret = ret->cur_next) {
                fprintf(of,"%s=", ret->key);
                switch (ret->type) {
                        case ULOGD_RET_STRING:
index f8e13275fa6be76a53e6067120a13ae815f4a685..cc0f19e748acb4dcc62089bb244dbab0b767622e 100644 (file)
@@ -1,11 +1,11 @@
-/* ulogd_PWSNIFF.c, Version $Revision: 1.1 $
+/* ulogd_PWSNIFF.c, Version $Revision: 1.2 $
  *
  * ulogd logging interpreter for POP3 / FTP like plaintext passwords.
  *
  * (C) 2000 by Harald Welte <laforge@gnumonks.org>
  * This software is released under the terms of GNU GPL
  *
- * $Id: ulogd_PWSNIFF.c,v 1.1 2000/08/17 08:03:22 laforge Exp $
+ * $Id: ulogd_PWSNIFF.c,v 1.2 2000/09/22 06:54:33 laforge Exp $
  *
  */
 
@@ -46,15 +46,14 @@ static char *_get_next_blank(char* begp, char *endp)
        return NULL;
 }
 
-static ulog_iret_t *_interp_pwsniff(ulog_packet_msg_t *pkt)
+static ulog_iret_t *_interp_pwsniff(ulog_interpreter_t *ip, ulog_packet_msg_t *pkt)
 {
        struct iphdr *iph = (struct iphdr *) pkt->payload;
        void *protoh = (u_int32_t *)iph + iph->ihl;
        struct tcphdr *tcph = protoh;
        u_int32_t tcplen = ntohs(iph->tot_len) - iph->ihl * 4;
        unsigned char  *ptr, *begp, *pw_begp, *endp, *pw_endp;
-       ulog_iret_t *ret = NULL;
-       ulog_iret_t *ret2;
+       ulog_iret_t *ret = ip->result;
        int len, pw_len, i, cont = 0;
 
        len = pw_len = 0;
@@ -94,37 +93,36 @@ static ulog_iret_t *_interp_pwsniff(ulog_packet_msg_t *pkt)
        }
 
        if (len) {
-               ret = alloc_ret(ULOGD_RET_STRING, "pwsniff.user");
-               ret->value.ptr = (char *) malloc(len+1);
-               if (!ret->value.ptr) {
+               ret[0].value.ptr = (char *) malloc(len+1);
+               ret[0].flags |= ULOGD_RETF_VALID;
+               if (!ret[0].value.ptr) {
                        ulogd_error("_interp_pwsniff: OOM (size=%u)\n", len);
-                       free(ret);
                        return NULL;
                }
-               strncpy(ret->value.ptr, begp, len);
-               *((char *)ret->value.ptr + len + 1) = '\0';
+               strncpy(ret[0].value.ptr, begp, len);
+               *((char *)ret[0].value.ptr + len + 1) = '\0';
        }
        if (pw_len) {
-               ret2 = alloc_ret(ULOGD_RET_STRING,"pwsniff.pass");
-               ret2->value.ptr = (char *) malloc(pw_len+1);
-               if (!ret2->value.ptr){
+               ret[1].value.ptr = (char *) malloc(pw_len+1);
+               ret[1].flags |= ULOGD_RETF_VALID;
+               if (!ret[1].value.ptr){
                        ulogd_error("_interp_pwsniff: OOM (size=%u)\n", pw_len);
-                       free(ret2);
                        return NULL;
                }
-               strncpy(ret2->value.ptr, pw_begp, pw_len);
-               *((char *)ret2->value.ptr + pw_len + 1) = '\0';
+               strncpy(ret[1].value.ptr, pw_begp, pw_len);
+               *((char *)ret[1].value.ptr + pw_len + 1) = '\0';
 
-               if (ret) 
-                       ret->next = ret2;
-               else
-                       ret = ret2;
        }
        return ret;
 }
+
+static ulog_iret_t pwsniff_rets[] = {
+       { NULL, NULL, 0, ULOGD_RET_STRING, ULOGD_RETF_FREE, "pwsniff.user", 0 },
+       { NULL, NULL, 0, ULOGD_RET_STRING, ULOGD_RETF_FREE, "pwsniff.pass", 0 },
+};
 static ulog_interpreter_t base_ip[] = { 
 
-       { NULL, "pwsniff", &_interp_pwsniff },
+       { NULL, "pwsniff", 0, &_interp_pwsniff, 2, &pwsniff_rets },
        { NULL, "", NULL }, 
 };
 void _base_reg_ip(void)
index 24986b07319eda4ec405423c15f8d0838bbd6c51..883cf10b7b952e5f91f292c188e5ebceee844200 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef _ULOGD_H
 #define _ULOGD_H
-/* ulogd, Version $Revision: 1.6 $
+/* ulogd, Version $Revision: 1.7 $
  *
  * first try of a logging daemon for my netfilter ULOG target
  * for the linux 2.4 netfilter subsystem.
@@ -9,10 +9,11 @@
  *
  * this code is released under the terms of GNU GPL
  *
- * $Id: ulogd.h,v 1.6 2000/09/12 13:43:34 laforge Exp $
+ * $Id: ulogd.h,v 1.7 2000/09/12 14:29:37 laforge Exp $
  */
 
 #include <libipulog/libipulog.h>
+#include <stdio.h>
 
 /* All types with MSB = 1 make use of value.ptr
  * other types use one of the union's member */
 
 #define ULOGD_RET_IPADDR       0x0100
 
-/* types with lenght field*/
+/* types with length field */
 #define ULOGD_RET_STRING       0x8020
 #define ULODG_RET_RAW          0x8030
 
-#define ULOGD_RET_OTHER                0xffff
+
+/* FLAGS */
+#define ULOGD_RETF_NONE                0x0000
+#define ULOGD_RETF_VALID       0x0001
+#define ULOGD_RETF_FREE                0x0002
+
 
 /* maximum length of ulogd key */
 #define ULOGD_MAX_KEYLEN 32
 extern FILE *logfile;
 
 typedef struct ulog_iret {
+       /* next interpreter return (key) in the global list */
        struct ulog_iret *next;
+       /* next interpreter in linked list for current result */
+       struct ulog_iret *cur_next;
+       /* length of the returned value (only for lengthed types */
        u_int32_t len;
+       /* type of the returned value (ULOGD_IRET_...) */
        u_int16_t type;
+       /* flags (i.e. free, ...) */
+       u_int16_t flags;
+       /* name of this key */
        char key[ULOGD_MAX_KEYLEN];
+       /* and finally the returned value */
        union {
                u_int8_t        b;
                u_int8_t        ui8;
@@ -70,14 +85,27 @@ typedef struct ulog_iret {
 } ulog_iret_t;
 
 typedef struct ulog_interpreter {
+       /* next interpreter in old-style linked list */
        struct ulog_interpreter *next;
+       /* name of this interpreter (predefined by plugin) */
        char name[ULOGD_MAX_KEYLEN];
-       ulog_iret_t* (*interp)(ulog_packet_msg_t *pkt);
+       /* ID for this interpreter (dynamically assigned) */
+       unsigned int id;
+       /* function to call for each packet */
+       ulog_iret_t* (*interp)(struct ulog_interpreter *ip, 
+                               ulog_packet_msg_t *pkt);
+       /* number of keys this interpreter has */
+       unsigned int key_num;
+       /* keys of this particular interpreter */
+       ulog_iret_t *result;
 } ulog_interpreter_t;
 
 typedef struct ulog_output {
+       /* next output in the linked list */
        struct ulog_output *next;
+       /* name of this ouput plugin */
        char name[ULOGD_MAX_KEYLEN];
+       /* callback function */
        int* (*output)(ulog_iret_t *ret);
 } ulog_output_t;
 
@@ -100,4 +128,7 @@ void ulogd_log(int level, const char *message, ...);
 /* backwards compatibility */
 #define ulogd_error(format, args...) ulogd_log(ULOGD_ERROR, format, ## args)
 
+/* get an interpreter hash id by name */
+unsigned int interh_getid(const char *name);
+
 #endif
diff --git a/ulogd.c b/ulogd.c
index a91be2c1c4d1698358601eef47a7466aa8cd51fe..883c91e79b2ca49048a1bbf803249bbe760b6094 100644 (file)
--- a/ulogd.c
+++ b/ulogd.c
@@ -1,4 +1,4 @@
-/* ulogd, Version $Revision: 1.9 $
+/* ulogd, Version $Revision: 1.10 $
  *
  * first try of a logging daemon for my netfilter ULOG target
  * for the linux 2.4 netfilter subsystem.
@@ -7,7 +7,7 @@
  *
  * this code is released under the terms of GNU GPL
  *
- * $Id: ulogd.c,v 1.9 2000/09/12 13:43:34 laforge Exp $
+ * $Id: ulogd.c,v 1.10 2000/09/12 14:29:37 laforge Exp $
  */
 
 #include <stdio.h>
 
 
 FILE *logfile = NULL;
-
 /* 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;
 
+/***********************************************************************
+ * INTERPRETER AND KEY HASH FUNCTIONS
+ ***********************************************************************/
+
+/* hashtable for all registered interpreters */
+static ulog_interpreter_t *ulogd_interh[100];
+static unsigned int ulogd_interh_ids;
+
+/* allocate a new interpreter id and write it into the interpreter struct */
+static unsigned int interh_allocid(ulog_interpreter_t *ip)
+{
+       unsigned int id;
+
+       id = ++ulogd_interh_ids;
+       ip->id = id;
+       ulogd_interh[id] = ip;
+       return id;
+}
+
+/* get interpreter d by name */
+unsigned int interh_getid(const char *name)
+{
+       int i;
+       for (i = 1; i <= ulogd_interh_ids; i++)
+               if (!strcmp(name, (ulogd_interh[i])->name))
+                       return i;
+
+       return 0;
+}
+
+/* dump out the contents of the interpreter hash */
+static void interh_dump(void)
+{
+       int i;
+
+       for (i = 1; i <= ulogd_interh_ids; i++)
+               printf("ulogd_interh[%d] = %s\n", i, (ulogd_interh[i])->name);
+
+}
+
+struct ulogd_keyh_entry {
+       ulog_interpreter_t *interp;     /* interpreter for this key */
+       unsigned int offset;            /* offset within interpreter */
+       const char *name;               /* name of this particular key */
+};
+
+static struct ulogd_keyh_entry ulogd_keyh[100];
+static unsigned int ulogd_keyh_ids;
+
+/* allocate a new key_id */
+static unsigned int keyh_allocid(ulog_interpreter_t *ip, unsigned int offset,
+                               const char *name)
+{
+       unsigned int id;
+
+       id = ++ulogd_keyh_ids;
+
+       ulogd_keyh[id].interp = ip;
+       ulogd_keyh[id].offset = offset;
+       ulogd_keyh[id].name = name;
+
+       return id;
+}
+
+static void keyh_dump(void)
+{
+       int i;
+
+       printf("dumping keyh\n");
+       for (i = 1; i <= ulogd_keyh_ids; i++)
+               printf("ulogd_keyh[%d] = %s:%d\n", i, ulogd_keyh[i].interp->name, 
+                               ulogd_keyh[i].offset);
+
+}
+
+/* get keyid by name */
+unsigned int keyh_getid(const char *name)
+{
+       int i;
+       for (i = 1; i <= ulogd_keyh_ids; i++)
+               if (!strcmp(name, ulogd_keyh[i].name))
+                       return i;
+
+       return 0;
+}
+
+/* get key name by keyid */
+inline char *keyh_getname(unsigned int id)
+{
+       return ulogd_keyh[id].interp->name;
+}
+
+
 /* try to lookup a registered interpreter for a given name */
 static 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)
-                               return ptr;
-       }
+       int id;
+       
+       id = interh_getid(name);
+       if (!id)
+               return NULL;
 
-       return NULL;
+       return ulogd_interh[id];
 }
 
 /* the function called by all interpreter plugins for registering their
  * target. */ 
 void register_interpreter(ulog_interpreter_t *me)
 {
+       int i;
+
+       /* check if we already have an interpreter with this name */
        if (find_interpreter(me->name)) {
                ulogd_error("interpreter `%s' already registered\n",
                                me->name);
                exit(1);
        }
+
        ulogd_log(ULOGD_NOTICE, "registering interpreter `%s'\n", me->name);
+
+       /* allocate a new interpreter id for it */
+       interh_allocid(me);
+
+       /* - allocate one keyh_id for each result of this interpreter 
+        * - link the elements to each other */
+       for (i = 0; i < me->key_num; i++) {
+               keyh_allocid(me, i, me->result[i].key);
+               if (i != me->key_num - 1)
+                       me->result[i].next = &me->result[i+1];
+       }
+
+       if (ulogd_interpreters)
+               me->result[me->key_num - 1].next = &ulogd_interpreters->result[0];
+
+       /* all work done, we can prepend the new interpreter to the list */
        me->next = ulogd_interpreters;
        ulogd_interpreters = me;
 }
@@ -121,25 +232,7 @@ ulog_iret_t *alloc_ret(const u_int16_t type, const char* key)
        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) {
-               if ((ptr->type | 0x7fff) == 0xffff) {
-                       free(ptr->value.ptr);
-                       }
-               if (ptr->next) {
-                       nextptr = ptr->next;
-               } else {
-                       nextptr = NULL;
-               }
-               free(ptr);
-       }
-}
-
+/* log message to the logfile */
 void ulogd_log(int level, const char *format, ...)
 {
        char *timestr;
@@ -156,6 +249,7 @@ void ulogd_log(int level, const char *format, ...)
 
        tm = time(NULL);
        timestr = ctime(&tm);
+       timestr[strlen(timestr)-1] = '\0';
        fprintf(outfd, "%s <%1.1d>", timestr, level);
        
        vfprintf(outfd, format, ap);
@@ -172,28 +266,46 @@ static void propagate_results(ulog_iret_t *ret)
        }
 }
 
+/* clean results (set all values to 0 and free pointers) */
+static void clean_results(ulog_iret_t *ret)
+{
+       ulog_iret_t *r;
+
+       for (r = ret; r; r = r->next) {
+               if (r->flags & ULOGD_RETF_FREE)
+                       free(r->value.ptr);
+               memset(&r->value, 0, sizeof(r->value));
+               r->flags &= ~ULOGD_RETF_VALID;
+       }
+}
+
+#define IS_VALID(x)    (x.flags & ULOGD_RETF_VALID)
+
 /* call all registered interpreters and hand the results over to 
  * propagate_results */
 static void handle_packet(ulog_packet_msg_t *pkt)
 {
-       ulog_interpreter_t *ptr;
-       ulog_iret_t *ret, *b;
+       ulog_iret_t *ret;
         ulog_iret_t *allret = NULL;
-
-       /* call each registered interpreter */
-       for (ptr = ulogd_interpreters; ptr; ptr = ptr->next) {
-               ret = (*ptr->interp)(pkt);
-               if (ret) {
-                       /* prepend the results to allret */
-                       if (allret) { 
-                               for (b = ret; b->next; b = b->next);
-                               b->next = allret;
+       ulog_interpreter_t *ip;
+
+       unsigned int i,j;
+
+       for (i = 1; i <= ulogd_interh_ids; i++) {
+               ip = ulogd_interh[i];
+               /* call interpreter */
+               if (ret = ((ip)->interp)(ip, pkt)) {
+                       /* create references for result linked-list */
+                       for (j = 0; j < ip->key_num; j++) {
+                               if (IS_VALID(ip->result[j])) {
+                                       ip->result[j].cur_next = allret;
+                                       allret = &ip->result[j];
+                               }
                        }
-                       allret = ret;
                }
-       }       
+       }
        propagate_results(allret);
-       free_ret(allret);
+       clean_results(ulogd_interpreters->result);
 }
 
 /* silly plugin loader to dlopen() all available plugins */
@@ -212,13 +324,16 @@ static void load_plugins(char *dir)
                        DEBUGP("load_plugins: %s\n", dent->d_name);
                        sprintf(fname, "%s/%s", dir, dent->d_name);
                        if (!dlopen(fname, RTLD_NOW))
-                               ulogd_error("load_plugins: %s", dlerror());
+                               ulogd_error("load_plugins: %s\n", dlerror());
                        }
                }
                free(fname);
        } else
                ulogd_error("No plugin directory: %s\n", dir);
 
+       interh_dump();
+       keyh_dump();
+
 }
 
 static int logfile_open(const char *name)
@@ -253,7 +368,7 @@ static int parse_conffile(int final)
                        ulogd_error("ERROR: option occurred more than once\n");
                        break;
                case -ERRUNKN:
-                       ulogd_error("ERROR: unknown config key, %s\n",
+                       ulogd_error("ERROR: unknown config key\n");
                                config_errce->key);
                        break;
        }