From f408fe697949b03805fa4bfd64d563136fdcded9 Mon Sep 17 00:00:00 2001 From: laforge Date: Thu, 16 Nov 2000 21:15:29 +0000 Subject: - new syslog emulation output target - lot of bugfixes --- Makefile | 2 +- extensions/ulogd_BASE.c | 115 ++++++++++++++++++---- extensions/ulogd_LOGEMU.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++ include/ulogd/ulogd.h | 22 ++++- ulogd.c | 25 +++-- 5 files changed, 376 insertions(+), 31 deletions(-) create mode 100644 extensions/ulogd_LOGEMU.c diff --git a/Makefile b/Makefile index 2f15c62..1199bf7 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ LIBIPULOG=../libipulog INCIPULOG=-I../libipulog/include # Names of the plugins to be compiled -ULOGD_SL:=BASE OPRINT PWSNIFF #MYSQL +ULOGD_SL:=BASE OPRINT PWSNIFF LOGEMU #MYSQL # Normally You should not need to change anything below # diff --git a/extensions/ulogd_BASE.c b/extensions/ulogd_BASE.c index 5d4ef2f..a13d843 100644 --- a/extensions/ulogd_BASE.c +++ b/extensions/ulogd_BASE.c @@ -1,11 +1,11 @@ -/* ulogd_MAC.c, Version $Revision: 1.6 $ +/* ulogd_MAC.c, Version $Revision: 1.7 $ * * ulogd logging interpreter for MAC addresses, TIME, IP and TCP headers, etc. * * (C) 2000 by Harald Welte * This software is released under the terms of GNU GPL * - * $Id: ulogd_BASE.c,v 1.6 2000/09/26 06:25:02 laforge Exp $ + * $Id: ulogd_BASE.c,v 1.7 2000/11/16 17:20:52 laforge Exp $ * */ @@ -25,20 +25,26 @@ 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) +static ulog_iret_t *_interp_mac(struct ulog_interpreter *ip, + ulog_packet_msg_t *pkt) { unsigned char *p; int i; - char *buf; + char *buf, *oldbuf = NULL; ulog_iret_t *ret = ip->result; - + if (pkt->mac_len) { buf = (char *) malloc(3 * pkt->mac_len + 1); - *buf = 0; + if (!buf) { + ulogd_error("OOM!!!\n"); + return NULL; + } + *buf = '\0'; p = pkt->mac; + oldbuf = buf; for (i = 0; i < pkt->mac_len; i++, p++) - sprintf(buf, "%s%02x%c", buf, *p, i==pkt->mac_len-1 ? ' ':':'); + sprintf(buf, "%s%02x%c", oldbuf, *p, i==pkt->mac_len-1 ? ' ':':'); ret[0].value.ptr = buf; ret[0].flags |= ULOGD_RETF_VALID; return ret; @@ -56,9 +62,12 @@ static ulog_iret_t oob_rets[] = { { 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 }, + { NULL, NULL, 0, ULOGD_RET_STRING, ULOGD_RETF_NONE, "oob.in", NULL }, + { NULL, NULL, 0, ULOGD_RET_STRING, ULOGD_RETF_NONE, "oob.out", NULL }, }; -ulog_iret_t *_interp_oob(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) +static ulog_iret_t *_interp_oob(struct ulog_interpreter *ip, + ulog_packet_msg_t *pkt) { ulog_iret_t *ret = ip->result; @@ -70,6 +79,10 @@ ulog_iret_t *_interp_oob(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) ret[2].flags |= ULOGD_RETF_VALID; ret[3].value.ui32 = pkt->mark; ret[3].flags |= ULOGD_RETF_VALID; + ret[4].value.ptr = pkt->indev_name; + ret[4].flags |= ULOGD_RETF_VALID; + ret[5].value.ptr = pkt->outdev_name; + ret[5].flags |= ULOGD_RETF_VALID; return ret; } @@ -86,10 +99,13 @@ static ulog_iret_t iphdr_rets[] = { { 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 }, + { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "ip.csum", 0 }, + { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "ip.id", 0 }, + { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "ip.fragoff", 0 }, }; -ulog_iret_t *_interp_iphdr(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) +static ulog_iret_t *_interp_iphdr(struct ulog_interpreter *ip, + ulog_packet_msg_t *pkt) { ulog_iret_t *ret = ip->result; struct iphdr *iph = (struct iphdr *) pkt->payload; @@ -110,6 +126,10 @@ ulog_iret_t *_interp_iphdr(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) ret[6].flags |= ULOGD_RETF_VALID; ret[7].value.ui16 = ntohs(iph->check); ret[7].flags |= ULOGD_RETF_VALID; + ret[8].value.ui16 = ntohs(iph->id); + ret[8].flags |= ULOGD_RETF_VALID; + ret[9].value.ui16 = ntohs(iph->frag_off); + ret[9].flags |= ULOGD_RETF_VALID; return ret; } @@ -132,7 +152,8 @@ static ulog_iret_t tcphdr_rets[] = { { 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) +static 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; @@ -188,9 +209,11 @@ ulog_iret_t *_interp_tcphdr(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) 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 }, + { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "udp.len", 0 }, }; -ulog_iret_t *_interp_udp(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) + +static 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; @@ -215,10 +238,16 @@ ulog_iret_t *_interp_udp(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) ***********************************************************************/ static ulog_iret_t icmphdr_rets[] = { - { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "icmp.type", 0 }, + { NULL, NULL, 0, ULOGD_RET_UINT8, ULOGD_RETF_NONE, "icmp.type", 0 }, + { NULL, NULL, 0, ULOGD_RET_UINT8, ULOGD_RETF_NONE, "icmp.code", 0 }, + { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "icmp.echoid", 0 }, + { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "icmp.echoseq", 0 }, + { NULL, NULL, 0, ULOGD_RET_IPADDR, ULOGD_RETF_NONE, "icmp.gateway", 0 }, + { NULL, NULL, 0, ULOGD_RET_UINT16, ULOGD_RETF_NONE, "icmp.fragmtu", 0 }, }; -ulog_iret_t *_interp_icmp(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) +static 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); @@ -230,18 +259,68 @@ ulog_iret_t *_interp_icmp(struct ulog_interpreter *ip, ulog_packet_msg_t *pkt) ret[0].value.ui8 = icmph->type; ret[0].flags |= ULOGD_RETF_VALID; + ret[1].value.ui8 = icmph->code; + ret[1].flags |= ULOGD_RETF_VALID; + switch(icmph->type) { + case ICMP_ECHO: + case ICMP_ECHOREPLY: + ret[2].value.ui16 = ntohs(icmph->un.echo.id); + ret[2].flags |= ULOGD_RETF_VALID; + ret[3].value.ui16 = ntohs(icmph->un.echo.sequence); + ret[3].flags |= ULOGD_RETF_VALID; + break; + case ICMP_REDIRECT: + case ICMP_PARAMETERPROB: + ret[4].value.ui32 = ntohl(icmph->un.gateway); + ret[4].flags |= ULOGD_RETF_VALID; + break; + case ICMP_DEST_UNREACH: + if (icmph->code == ICMP_FRAG_NEEDED) { + ret[5].value.ui16 = ntohs(icmph->un.frag.mtu); + ret[5].flags |= ULOGD_RETF_VALID; + } + break; + } return ret; +} + +/*********************************************************************** + * IPSEC HEADER + ***********************************************************************/ + +static ulog_iret_t ahesphdr_rets[] = { + { NULL, NULL, 0, ULOGD_RET_UINT8, ULOGD_RETF_NONE, "ahesp.spi", 0 }, +}; + +static ulog_iret_t *_interp_ahesp(struct ulog_interpreter *ip, + ulog_packet_msg_t *pkt) +{ + struct iphdr *iph = (struct iphdr *) pkt->payload; + ulog_iret_t *ret = ip->result; + void *protoh = (u_int32_t *) (iph + iph->ihl); +#if 0 + struct esphdr *esph = protoh; + if (iph->protocol != IPPROTO_ESP) + return NULL; + + ret[0].value.ui32 = ntohl(esph->spi); + ret[0].flags |= ULOGD_RETF_VALID; +#endif + + return ret; } + 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, "oob", 0, &_interp_oob, 6, &oob_rets }, + { NULL, "ip", 0, &_interp_iphdr, 10, &iphdr_rets }, { NULL, "tcp", 0, &_interp_tcphdr, 12, &tcphdr_rets }, - { NULL, "icmp", 0, &_interp_icmp, 1, &icmphdr_rets }, + { NULL, "icmp", 0, &_interp_icmp, 6, &icmphdr_rets }, { NULL, "udp", 0, &_interp_udp, 3, &udphdr_rets }, + { NULL, "ahesp", 0, &_interp_ahesp, 1, &ahesphdr_rets }, { NULL, "", 0, NULL, 0, { NULL } }, }; diff --git a/extensions/ulogd_LOGEMU.c b/extensions/ulogd_LOGEMU.c new file mode 100644 index 0000000..086e35e --- /dev/null +++ b/extensions/ulogd_LOGEMU.c @@ -0,0 +1,243 @@ +/* ulogd_LOGEMU.c, Version $Revision: 1.4 $ + * + * ulogd output target for syslog logging emulation + * this target produces a file which looks the same like the syslog-entries + * of the LOG target. + * + * (C) 2000 by Harald Welte + * This software is released under the terms of GNU GPL + * + * $Id: ulogd_LOGEMU.c,v 1.4 2000/09/22 06:54:33 laforge Exp $ + * + */ + +#include +#include +#include +#include +#include +#include "ulogd.h" +#include "conffile.h" + +#define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] + +#define HIPQUAD(addr) \ + ((unsigned char *)&addr)[3], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[0] + +static FILE *of = NULL; + +struct intr_id { + char* name; + unsigned int id; +}; + +#define INTR_IDS 33 +static struct intr_id intr_ids[INTR_IDS] = { + { "oob.prefix", 0 }, + { "oob.in", 0 }, + { "oob.out", 0 }, + { "raw.mac", 0 }, + { "ip.saddr", 0 }, + { "ip.daddr", 0 }, + { "ip.totlen", 0 }, + { "ip.tos", 0 }, + { "ip.ttl", 0 }, + { "ip.id", 0 }, + { "ip.fragoff", 0 }, + { "ip.protocol", 0 }, + { "tcp.sport", 0 }, + { "tcp.dport", 0 }, + { "tcp.seq", 0 }, + { "tcp.ackseq", 0 }, + { "tcp.window", 0 }, + { "tcp.urg", 0 }, + { "tcp.ack", 0 }, + { "tcp.psh", 0 }, + { "tcp.rst", 0 }, + { "tcp.syn", 0 }, + { "tcp.fin", 0 }, + { "tcp.urgp", 0 }, + { "udp.sport", 0 }, + { "udp.dport", 0 }, + { "udp.len", 0 }, + { "icmp.type", 0 }, + { "icmp.code", 0 }, + { "icmp.echoid", 0 }, + { "icmp.echoseq", 0 }, + { "icmp.gateway", 0 }, + { "icmp.fragmtu", 0 }, + { "ah.spi", 0 }, +}; + +#define GET_VALUE(x) ulogd_keyh[intr_ids[x].id].interp->result[ulogd_keyh[intr_ids[x].id].offset].value +#define IS_VALID(x) (ulogd_keyh[intr_ids[x].id].interp->result[ulogd_keyh[intr_ids[x].id].offset].flags & ULOGD_RETF_VALID) + +int _output_logemu(ulog_iret_t *res) +{ + fprintf(of, "%sIN=%s OUT=%s ", + (char *) GET_VALUE(0).ptr, + (char *) GET_VALUE(1).ptr, + (char *) GET_VALUE(2).ptr); + + /* FIXME: configurable */ + fprintf(of, "MAC=%s ", (char *) GET_VALUE(3).ptr); + + fprintf(of, "SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ", + HIPQUAD(GET_VALUE(4).ui32), HIPQUAD(GET_VALUE(5).ui32)); + + fprintf(of, "LEN=%u TOS=%02X PREC=0x%02X TTL=%u ID=%u ", + GET_VALUE(6).ui16, GET_VALUE(7).ui8 & IPTOS_TOS_MASK, + GET_VALUE(7).ui8 & IPTOS_PREC_MASK, GET_VALUE(8).ui8, + GET_VALUE(9).ui16); + + if (GET_VALUE(10).ui16 & IP_RF) + fprintf(of, "CE "); + + if (GET_VALUE(10).ui16 & IP_DF) + fprintf(of, "DF "); + + if (GET_VALUE(10).ui16 & IP_MF) + fprintf(of, "MF "); + + if (GET_VALUE(10).ui16 & IP_OFFMASK) + fprintf(of, "FRAG:%u ", GET_VALUE(10).ui16 & IP_OFFMASK); + + switch (GET_VALUE(11).ui8) { + + case IPPROTO_TCP: + fprintf(of, "PROTO=TCP "); + fprintf(of, "SPT=%u DPT=%u ", GET_VALUE(12).ui16, + GET_VALUE(13).ui16); + /* FIXME: config */ + fprintf(of, "SEQ=%u ACK=%u ", GET_VALUE(14).ui32, + GET_VALUE(15).ui32); + + fprintf(of, "WINDOW=%u ", GET_VALUE(16).ui16); + +// fprintf(of, "RES=0x%02x ", + + if (GET_VALUE(17).b) + fprintf(of, "URG "); + + if (GET_VALUE(18).b) + fprintf(of, "ACK "); + + if (GET_VALUE(19).b) + fprintf(of, "PSH "); + + if (GET_VALUE(20).b) + fprintf(of, "RST "); + + if (GET_VALUE(21).b) + fprintf(of, "SYN "); + + if (GET_VALUE(22).b) + fprintf(of, "FIN "); + + fprintf(of, "URGP=%u ", GET_VALUE(23).ui16); + + break; + case IPPROTO_UDP: + + fprintf(of, "PROTO=UDP "); + + fprintf(of, "SPT=%u DPT=%u LEN=%u ", + GET_VALUE(24).ui16, GET_VALUE(25).ui16, + GET_VALUE(26).ui16); + break; + case IPPROTO_ICMP: + + fprintf(of, "PROTO=ICMP "); + + fprintf(of, "TYPE=%u CODE=%u ", GET_VALUE(27).ui8, + GET_VALUE(28).ui8); + + switch (GET_VALUE(27).ui8) { + case ICMP_ECHO: + case ICMP_ECHOREPLY: + fprintf(of, "ID=%u SEQ=%u ", + GET_VALUE(29).ui16, + GET_VALUE(30).ui16); + break; + case ICMP_PARAMETERPROB: + fprintf(of, "PARAMETER=%u ", + GET_VALUE(31).ui32 >> 24); + break; + case ICMP_REDIRECT: + fprintf(of, "GATEWAY=%u.%u.%u.%u ", + HIPQUAD(GET_VALUE(31).ui32)); + break; + case ICMP_DEST_UNREACH: + if (GET_VALUE(28).ui8 == ICMP_FRAG_NEEDED) + fprintf(of, "MTU=%u ", + GET_VALUE(32).ui16); + break; + } + break; + } + fprintf(of,"\n"); + return 0; +} +/* get all key id's for the keys we are intrested in */ +static int get_ids(void) +{ + int i; + struct intr_id *cur_id; + + for (i = 0; i < INTR_IDS; i++) { + cur_id = &intr_ids[i]; + cur_id->id = keyh_getid(cur_id->name); + if (!cur_id->id) { + ulogd_error("Cannot resolve keyhash id for %s\n", cur_id->name); + return 1; + } + } + return 0; +} + +static ulog_output_t logemu_op[] = { + { NULL, "logemu", &_output_logemu }, + { NULL, "", NULL }, +}; + +/* register output plugin with ulogd */ +static void _logemu_reg_op(void) +{ + ulog_output_t *op = logemu_op; + ulog_output_t *p; + + for (p = op; p->output; p++) + register_output(p); +} + +static config_entry_t syslogf_ce = { NULL, "syslogfile", CONFIG_TYPE_STRING, + CONFIG_OPT_NONE, 0, + { string: "/var/log/ulogd.syslogemu" } }; +void _init(void) +{ +#ifdef DEBUG_LOGEMU + of = stdout; +#else + config_register_key(&syslogf_ce); + config_parse_file(0); + + of = fopen(syslogf_ce.u.string, "a"); + if (!of) { + ulogd_error("ulogd_LOGEMU: can't open syslogemu: %s\n", strerror(errno)); + exit(2); + } +#endif + if (get_ids()) { + ulogd_error("ulogd_LOGEMU: can't resolve all keyhash id's\n"); + exit(2); + } + + _logemu_reg_op(); +} diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h index 883cf10..186de9e 100644 --- a/include/ulogd/ulogd.h +++ b/include/ulogd/ulogd.h @@ -1,6 +1,6 @@ #ifndef _ULOGD_H #define _ULOGD_H -/* ulogd, Version $Revision: 1.7 $ +/* ulogd, Version $Revision: 1.8 $ * * first try of a logging daemon for my netfilter ULOG target * for the linux 2.4 netfilter subsystem. @@ -9,7 +9,7 @@ * * this code is released under the terms of GNU GPL * - * $Id: ulogd.h,v 1.7 2000/09/12 14:29:37 laforge Exp $ + * $Id: ulogd.h,v 1.8 2000/11/16 17:20:52 laforge Exp $ */ #include @@ -131,4 +131,22 @@ void ulogd_log(int level, const char *message, ...); /* get an interpreter hash id by name */ unsigned int interh_getid(const char *name); +/* get a key id if you have the name */ +unsigned int keyh_getid(const char *name); + +/* get a result for a given key id */ +ulog_iret_t *keyh_getres(unsigned int id); + +/* the key hash itself */ +struct ulogd_keyh_entry ulogd_keyh[100]; + +/* entries of the key hash */ +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 */ +}; + + + #endif diff --git a/ulogd.c b/ulogd.c index 883c91e..a60cf5f 100644 --- a/ulogd.c +++ b/ulogd.c @@ -1,4 +1,4 @@ -/* ulogd, Version $Revision: 1.10 $ +/* ulogd, Version $Revision: 1.11 $ * * 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.10 2000/09/12 14:29:37 laforge Exp $ + * $Id: ulogd.c,v 1.11 2000/11/16 17:20:52 laforge Exp $ */ #include @@ -94,13 +94,7 @@ static void interh_dump(void) } -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]; +struct ulogd_keyh_entry ulogd_keyh[100]; static unsigned int ulogd_keyh_ids; /* allocate a new key_id */ @@ -146,6 +140,17 @@ inline char *keyh_getname(unsigned int id) return ulogd_keyh[id].interp->name; } +ulog_iret_t *keyh_getres(unsigned int id) +{ + ulog_iret_t *ret; + + ret = &ulogd_keyh[id].interp->result[ulogd_keyh[id].offset]; + + if (ret->flags & ULOGD_RETF_VALID) + return ret; + + return NULL; +} /* try to lookup a registered interpreter for a given name */ static ulog_interpreter_t *find_interpreter(const char *name) @@ -369,7 +374,7 @@ static int parse_conffile(int final) break; case -ERRUNKN: ulogd_error("ERROR: unknown config key\n"); - config_errce->key); +/* config_errce->key); */ break; } return 1; -- cgit v1.2.3