summaryrefslogtreecommitdiffstats
path: root/ulogd
diff options
context:
space:
mode:
Diffstat (limited to 'ulogd')
-rw-r--r--ulogd/Makefile6
-rw-r--r--ulogd/conffile.c14
-rw-r--r--ulogd/extensions/ulogd_BASE.c267
-rw-r--r--ulogd/extensions/ulogd_OPRINT.c6
-rw-r--r--ulogd/extensions/ulogd_PWSNIFF.c42
-rw-r--r--ulogd/include/ulogd/ulogd.h41
-rw-r--r--ulogd/ulogd.c205
7 files changed, 379 insertions, 202 deletions
diff --git a/ulogd/Makefile b/ulogd/Makefile
index 6d80dfb..2f15c62 100644
--- a/ulogd/Makefile
+++ b/ulogd/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
diff --git a/ulogd/conffile.c b/ulogd/conffile.c
index 2489c8d..04f54f2 100644
--- a/ulogd/conffile.c
+++ b/ulogd/conffile.c
@@ -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;
diff --git a/ulogd/extensions/ulogd_BASE.c b/ulogd/extensions/ulogd_BASE.c
index 391ac59..5d4ef2f 100644
--- a/ulogd/extensions/ulogd_BASE.c
+++ b/ulogd/extensions/ulogd_BASE.c
@@ -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 $
*
*/
@@ -18,12 +18,19 @@
#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();
diff --git a/ulogd/extensions/ulogd_OPRINT.c b/ulogd/extensions/ulogd_OPRINT.c
index 0b551b6..3fa42ed 100644
--- a/ulogd/extensions/ulogd_OPRINT.c
+++ b/ulogd/extensions/ulogd_OPRINT.c
@@ -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:
diff --git a/ulogd/extensions/ulogd_PWSNIFF.c b/ulogd/extensions/ulogd_PWSNIFF.c
index f8e1327..cc0f19e 100644
--- a/ulogd/extensions/ulogd_PWSNIFF.c
+++ b/ulogd/extensions/ulogd_PWSNIFF.c
@@ -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)
diff --git a/ulogd/include/ulogd/ulogd.h b/ulogd/include/ulogd/ulogd.h
index 24986b0..883cf10 100644
--- a/ulogd/include/ulogd/ulogd.h
+++ b/ulogd/include/ulogd/ulogd.h
@@ -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 */
@@ -34,11 +35,16 @@
#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
@@ -51,10 +57,19 @@
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/ulogd.c b/ulogd/ulogd.c
index a91be2c..883c91e 100644
--- a/ulogd/ulogd.c
+++ b/ulogd/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>
@@ -48,36 +48,147 @@
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;
}