From 835110044bd970518e10b28348ce6619818ce363 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 18 May 2008 18:35:35 +0200 Subject: Remove obsolete patches and files and move ulogd to repository top-level directory --- extensions/Makefile.in | 37 +++ extensions/chtons.h | 32 +++ extensions/printpkt.c | 276 +++++++++++++++++++++ extensions/printpkt.h | 7 + extensions/ulogd_BASE.c | 569 +++++++++++++++++++++++++++++++++++++++++++ extensions/ulogd_LOCAL.c | 102 ++++++++ extensions/ulogd_LOCALTIME.c | 0 extensions/ulogd_LOGEMU.c | 139 +++++++++++ extensions/ulogd_OPRINT.c | 149 +++++++++++ extensions/ulogd_PWSNIFF.c | 167 +++++++++++++ extensions/ulogd_SYSLOG.c | 149 +++++++++++ 11 files changed, 1627 insertions(+) create mode 100644 extensions/Makefile.in create mode 100644 extensions/chtons.h create mode 100644 extensions/printpkt.c create mode 100644 extensions/printpkt.h create mode 100644 extensions/ulogd_BASE.c create mode 100644 extensions/ulogd_LOCAL.c create mode 100644 extensions/ulogd_LOCALTIME.c create mode 100644 extensions/ulogd_LOGEMU.c create mode 100644 extensions/ulogd_OPRINT.c create mode 100644 extensions/ulogd_PWSNIFF.c create mode 100644 extensions/ulogd_SYSLOG.c (limited to 'extensions') diff --git a/extensions/Makefile.in b/extensions/Makefile.in new file mode 100644 index 0000000..589bf7b --- /dev/null +++ b/extensions/Makefile.in @@ -0,0 +1,37 @@ +# + +# Normally You should not need to change anything below +# +include @top_srcdir@/Rules.make + +CFLAGS+=-I@top_srcdir@ -I@top_srcdir@/libipulog/include -I@top_srcdir@/include +SH_CFLAGS:=$(CFLAGS) -fPIC + +SHARED_LIBS+=$(foreach T,$(ULOGD_SL),ulogd_$(T).so) + + +all: $(SHARED_LIBS) + +distrib: + +printpkt.o: printpkt.c + $(CC) $(SH_CFLAGS) -o $@ -c $< + +$(SHARED_LIBS): %.so: %_sh.o + $(LD) -shared -o $@ $< -lc + +ulogd_SYSLOG.so: printpkt.o ulogd_SYSLOG_sh.o + $(LD) -shared -o $@ $^ -lc + +%_sh.o: %.c + $(CC) $(SH_CFLAGS) -o $@ -c $< + +clean: + $(RM) $(SHARED_LIBS) *.o + +distclean: + $(RM) Makefile + +install: all + $(INSTALL) -m 755 -d $(DESTDIR)$(ULOGD_LIB_PATH) + $(INSTALL) -m 755 *.so $(DESTDIR)$(ULOGD_LIB_PATH) diff --git a/extensions/chtons.h b/extensions/chtons.h new file mode 100644 index 0000000..4506e33 --- /dev/null +++ b/extensions/chtons.h @@ -0,0 +1,32 @@ +#ifndef _CHTONS_H_ +#define _CHTONS_H_ + +#include + +#if __BYTE_ORDER == __BIG_ENDIAN +# define BITNR(X) ((X)^31) +# if !defined(__constant_htonl) +# define __constant_htonl(x) (x) +# endif +# if !defined(__constant_htons) +# define __constant_htons(x) (x) +# endif +#elif __BYTE_ORDER == __LITTLE_ENDIAN +# define BITNR(X) ((X)^7) +# if !defined(__constant_htonl) +# define __constant_htonl(x) \ + ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \ + (((unsigned long int)(x) & 0x0000ff00U) << 8) | \ + (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \ + (((unsigned long int)(x) & 0xff000000U) >> 24))) +# endif +# if !defined(__constant_htons) +# define __constant_htons(x) \ + ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \ + (((unsigned short int)(x) & 0xff00) >> 8))) +# endif +#else +# error "Don't know if bytes are big- or little-endian!" +#endif + +#endif diff --git a/extensions/printpkt.c b/extensions/printpkt.c new file mode 100644 index 0000000..a9e78d7 --- /dev/null +++ b/extensions/printpkt.c @@ -0,0 +1,276 @@ +/* printpkt.c + * + * build something looking like a iptables LOG message + * + * (C) 2000-2003 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef HOST_NAME_MAX +#warning this libc does not define HOST_NAME_MAX +#define HOST_NAME_MAX (255+1) +#endif + +#define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] + +struct intr_id { + char* name; + unsigned int id; +}; + +static char hostname[HOST_NAME_MAX+1]; + +#define INTR_IDS 35 +static struct intr_id intr_ids[INTR_IDS] = { + { "oob.time.sec", 0 }, + { "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 }, + { "ahesp.spi", 0 }, +}; + +#define GET_VALUE(x) ulogd_keyh[intr_ids[x].id].interp->result[ulogd_keyh[intr_ids[x].id].offset].value +#define GET_FLAGS(x) ulogd_keyh[intr_ids[x].id].interp->result[ulogd_keyh[intr_ids[x].id].offset].flags + +int printpkt_print(ulog_iret_t *res, char *buf, int prefix) +{ + char *timestr; + char *tmp; + time_t now; + + char *buf_cur = buf; + + if (prefix) { + now = (time_t) GET_VALUE(0).ui32; + timestr = ctime(&now) + 4; + + /* truncate time */ + if ((tmp = strchr(timestr, '\n'))) + *tmp = '\0'; + + /* truncate hostname */ + if ((tmp = strchr(hostname, '.'))) + *tmp = '\0'; + + /* print time and hostname */ + buf_cur += sprintf(buf_cur, "%.15s %s", timestr, hostname); + } + + if (*(char *) GET_VALUE(1).ptr) + buf_cur += sprintf(buf_cur, " %s", (char *) GET_VALUE(1).ptr); + + buf_cur += sprintf(buf_cur," IN=%s OUT=%s ", + (char *) GET_VALUE(2).ptr, + (char *) GET_VALUE(3).ptr); + + /* FIXME: configurable */ + buf_cur += sprintf(buf_cur, "MAC=%s ", + (GET_FLAGS(4) & ULOGD_RETF_VALID) ? (char *) GET_VALUE(4).ptr : ""); + + buf_cur += sprintf(buf_cur, "SRC=%s ", + inet_ntoa((struct in_addr) {htonl(GET_VALUE(5).ui32)})); + buf_cur += sprintf(buf_cur, "DST=%s ", + inet_ntoa((struct in_addr) {htonl(GET_VALUE(6).ui32)})); + + buf_cur += sprintf(buf_cur,"LEN=%u TOS=%02X PREC=0x%02X TTL=%u ID=%u ", + GET_VALUE(7).ui16, GET_VALUE(8).ui8 & IPTOS_TOS_MASK, + GET_VALUE(8).ui8 & IPTOS_PREC_MASK, GET_VALUE(9).ui8, + GET_VALUE(10).ui16); + + if (GET_VALUE(10).ui16 & IP_RF) + buf_cur += sprintf(buf_cur, "CE "); + + if (GET_VALUE(11).ui16 & IP_DF) + buf_cur += sprintf(buf_cur, "DF "); + + if (GET_VALUE(11).ui16 & IP_MF) + buf_cur += sprintf(buf_cur, "MF "); + + if (GET_VALUE(11).ui16 & IP_OFFMASK) + buf_cur += sprintf(buf_cur, "FRAG:%u ", + GET_VALUE(11).ui16 & IP_OFFMASK); + + switch (GET_VALUE(12).ui8) { + + case IPPROTO_TCP: + buf_cur += sprintf(buf_cur, "PROTO=TCP "); + buf_cur += sprintf(buf_cur, "SPT=%u DPT=%u ", + GET_VALUE(13).ui16, GET_VALUE(14).ui16); + /* FIXME: config */ + buf_cur += sprintf(buf_cur, "SEQ=%u ACK=%u ", + GET_VALUE(15).ui32, GET_VALUE(16).ui32); + + buf_cur += sprintf(buf_cur, "WINDOW=%u ", GET_VALUE(17).ui16); + +// buf_cur += sprintf(buf_cur, "RES=0x%02x ", + + if (GET_VALUE(18).b) + buf_cur += sprintf(buf_cur, "URG "); + + if (GET_VALUE(19).b) + buf_cur += sprintf(buf_cur, "ACK "); + + if (GET_VALUE(20).b) + buf_cur += sprintf(buf_cur, "PSH "); + + if (GET_VALUE(21).b) + buf_cur += sprintf(buf_cur, "RST "); + + if (GET_VALUE(22).b) + buf_cur += sprintf(buf_cur, "SYN "); + + if (GET_VALUE(23).b) + buf_cur += sprintf(buf_cur, "FIN "); + + buf_cur += sprintf(buf_cur, "URGP=%u ", GET_VALUE(24).ui16); + + break; + case IPPROTO_UDP: + + buf_cur += sprintf(buf_cur, "PROTO=UDP "); + + buf_cur += sprintf(buf_cur, "SPT=%u DPT=%u LEN=%u ", + GET_VALUE(25).ui16, GET_VALUE(26).ui16, + GET_VALUE(27).ui16); + break; + case IPPROTO_ICMP: + + buf_cur += sprintf(buf_cur, "PROTO=ICMP "); + + buf_cur += sprintf(buf_cur, "TYPE=%u CODE=%u ", + GET_VALUE(28).ui8, GET_VALUE(29).ui8); + + switch (GET_VALUE(28).ui8) { + case ICMP_ECHO: + case ICMP_ECHOREPLY: + buf_cur += sprintf(buf_cur, "ID=%u SEQ=%u ", + GET_VALUE(30).ui16, + GET_VALUE(31).ui16); + break; + case ICMP_PARAMETERPROB: + buf_cur += sprintf(buf_cur, "PARAMETER=%u ", + GET_VALUE(32).ui32 >> 24); + break; + case ICMP_REDIRECT: + buf_cur += sprintf(buf_cur, "GATEWAY=%s ", inet_ntoa((struct in_addr) {htonl(GET_VALUE(32).ui32)})); + break; + case ICMP_DEST_UNREACH: + if (GET_VALUE(29).ui8 == ICMP_FRAG_NEEDED) + buf_cur += sprintf(buf_cur, "MTU=%u ", + GET_VALUE(33).ui16); + break; + } + break; + case IPPROTO_ESP: + case IPPROTO_AH: + buf_cur += sprintf(buf_cur, "PROTO=%s ", GET_VALUE(12).ui8 == IPPROTO_ESP ? "ESP" : "AH"); + /* FIXME: "INCOMPLETE [%u bytes]" in case of short pkt */ + if (intr_ids[34].id > 0) { + buf_cur += sprintf(buf_cur, "SPI=0x%x ", GET_VALUE(34).ui32); + } + break; + default: + + buf_cur += sprintf(buf_cur, "PROTO=%u ", GET_VALUE(12).ui8); + } + strcat(buf_cur, "\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_log(ULOGD_ERROR, + "Cannot resolve keyhash id for %s\n", + cur_id->name); + return 1; + } + } + return 0; +} + +int printpkt_init(void) +{ + if (gethostname(hostname, sizeof(hostname)) < 0) { + ulogd_log(ULOGD_FATAL, "can't gethostname(): %s\n", + strerror(errno)); + exit(2); + } + hostname[sizeof(hostname)-1] = '\0'; + + if (get_ids()) + return 1; + + return 0; +} diff --git a/extensions/printpkt.h b/extensions/printpkt.h new file mode 100644 index 0000000..ce42de4 --- /dev/null +++ b/extensions/printpkt.h @@ -0,0 +1,7 @@ +#ifndef _PRINTPKT_H +#define _PRINTPKT_H + +int printpkt_print(ulog_iret_t *res, char *buf, int prefix); +int printpkt_init(void); + +#endif diff --git a/extensions/ulogd_BASE.c b/extensions/ulogd_BASE.c new file mode 100644 index 0000000..61bad21 --- /dev/null +++ b/extensions/ulogd_BASE.c @@ -0,0 +1,569 @@ +/* ulogd_MAC.c, Version $Revision$ + * + * ulogd interpreter plugin for + * o MAC addresses + * o NFMARK field + * o TIME + * o Interface names + * o IP header + * o TCP header + * o UDP header + * o ICMP header + * o AH/ESP header + * + * (C) 2000-2001 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + * $Id$ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*********************************************************************** + * Raw header + ***********************************************************************/ +static ulog_iret_t raw_rets[] = { + { .type = ULOGD_RET_STRING, + .flags = ULOGD_RETF_FREE, + .key = "raw.mac", + }, + { .type = ULOGD_RET_RAW, + .flags = ULOGD_RETF_NONE, + .key = "raw.pkt", + }, + { .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .key = "raw.pktlen", + }, +}; + +static ulog_iret_t *_interp_raw(ulog_interpreter_t *ip, + ulog_packet_msg_t *pkt) +{ + unsigned char *p; + int i, tmp, len = 0; + char *buf, *ptr = NULL; + ulog_iret_t *ret = ip->result; + size_t siz; + + if (pkt->mac_len) { + siz = 3 * pkt->mac_len + 1; + buf = (char *) malloc(siz); + if (!buf) { + ulogd_log(ULOGD_ERROR, "OOM!!!\n"); + return NULL; + } + *buf = '\0'; + + p = pkt->mac; + ptr = buf; + for (i = 0; i < pkt->mac_len; i++, p++) { + tmp = snprintf(ptr+len, siz-len, "%02x%s", + *p, i==pkt->mac_len-1 ? "":":"); + if (tmp < 0) + break; + if (tmp >= siz-len) { + buf[siz] = '\0'; + break; + } + len += tmp; + } + ret[0].value.ptr = buf; + ret[0].flags |= ULOGD_RETF_VALID; + } + + /* include pointer to raw ipv4 packet */ + ret[1].value.ptr = pkt->payload; + ret[1].flags |= ULOGD_RETF_VALID; + ret[2].value.ui32 = pkt->data_len; + ret[2].flags |= ULOGD_RETF_VALID; + + return ret; +} + +/*********************************************************************** + * OUT OF BAND + ***********************************************************************/ + +static ulog_iret_t oob_rets[] = { + { .type = ULOGD_RET_STRING, + .flags = ULOGD_RETF_NONE, + .key = "oob.prefix", + }, + { .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .key = "oob.time.sec", + }, + { .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .key = "oob.time.usec", + }, + { .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .key = "oob.mark", + }, + { .type = ULOGD_RET_STRING, + .flags = ULOGD_RETF_NONE, + .key = "oob.in", + }, + { .type = ULOGD_RET_STRING, + .flags = ULOGD_RETF_NONE, + .key = "oob.out", + }, +}; + +static ulog_iret_t *_interp_oob(struct ulog_interpreter *ip, + ulog_packet_msg_t *pkt) +{ + ulog_iret_t *ret = ip->result; + + ret[0].value.ptr = pkt->prefix; + ret[0].flags |= ULOGD_RETF_VALID; + + /* god knows why timestamp_usec contains crap if timestamp_sec == 0 + * if (pkt->timestamp_sec || pkt->timestamp_usec) { */ + if (pkt->timestamp_sec) { + 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; + } else { + ret[1].flags &= ~ULOGD_RETF_VALID; + 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; +} + +/*********************************************************************** + * IP HEADER + ***********************************************************************/ + +static ulog_iret_t iphdr_rets[] = { + { .type = ULOGD_RET_IPADDR, + .flags = ULOGD_RETF_NONE, + .key = "ip.saddr", + }, + { .type = ULOGD_RET_IPADDR, + .flags = ULOGD_RETF_NONE, + .key = "ip.daddr", + }, + { .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "ip.protocol", + }, + { .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "ip.tos", + }, + { .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "ip.ttl", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "ip.totlen", + }, + { .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "ip.ihl", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "ip.csum", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "ip.id", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "ip.fragoff", + }, +}; + +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; + + 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 = 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; + 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; +} + +/*********************************************************************** + * TCP HEADER + ***********************************************************************/ +static ulog_iret_t tcphdr_rets[] = { + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "tcp.sport", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "tcp.dport", + }, + { .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .key = "tcp.seq", + }, + { .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .key = "tcp.ackseq", + }, + { .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "tcp.offset", + }, + { .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "tcp.reserved", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "tcp.window", + }, + { .type = ULOGD_RET_BOOL, + .flags = ULOGD_RETF_NONE, + .key = "tcp.urg", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "tcp.urgp", + }, + { .type = ULOGD_RET_BOOL, + .flags = ULOGD_RETF_NONE, + .key = "tcp.ack", + }, + { .type = ULOGD_RET_BOOL, + .flags = ULOGD_RETF_NONE, + .key = "tcp.psh", + }, + { .type = ULOGD_RET_BOOL, + .flags = ULOGD_RETF_NONE, + .key = "tcp.rst", + }, + { .type = ULOGD_RET_BOOL, + .flags = ULOGD_RETF_NONE, + .key = "tcp.syn", + }, + { .type = ULOGD_RET_BOOL, + .flags = ULOGD_RETF_NONE, + .key = "tcp.fin", + }, + { .type = ULOGD_RET_BOOL, + .flags = ULOGD_RETF_NONE, + .key = "tcp.res1", + }, + { .type = ULOGD_RET_BOOL, + .flags = ULOGD_RETF_NONE, + .key = "tcp.res2", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "tcp.csum", + }, +}; + +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; + struct tcphdr *tcph = (struct tcphdr *) protoh; + ulog_iret_t *ret = ip->result; + + if (iph->protocol != IPPROTO_TCP) + return NULL; + + 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.ui8 = ntohs(tcph->doff); + ret[4].flags |= ULOGD_RETF_VALID; + ret[5].value.ui8 = ntohs(tcph->res1); + ret[5].flags |= ULOGD_RETF_VALID; + ret[6].value.ui16 = ntohs(tcph->window); + ret[6].flags |= ULOGD_RETF_VALID; + + ret[7].value.b = tcph->urg; + ret[7].flags |= ULOGD_RETF_VALID; + if (tcph->urg) { + ret[8].value.ui16 = ntohs(tcph->urg_ptr); + ret[8].flags |= ULOGD_RETF_VALID; + } + ret[9].value.b = tcph->ack; + ret[9].flags |= ULOGD_RETF_VALID; + ret[10].value.b = tcph->psh; + ret[10].flags |= ULOGD_RETF_VALID; + ret[11].value.b = tcph->rst; + ret[11].flags |= ULOGD_RETF_VALID; + ret[12].value.b = tcph->syn; + ret[12].flags |= ULOGD_RETF_VALID; + ret[13].value.b = tcph->fin; + ret[13].flags |= ULOGD_RETF_VALID; + ret[14].value.b = tcph->res1; + ret[14].flags |= ULOGD_RETF_VALID; + ret[15].value.b = tcph->res2; + ret[15].flags |= ULOGD_RETF_VALID; + ret[16].value.ui16 = ntohs(tcph->check); + ret[16].value.ui16 = ULOGD_RETF_VALID; + + return ret; +} + +/*********************************************************************** + * UDP HEADER + ***********************************************************************/ +static ulog_iret_t udphdr_rets[] = { + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "udp.sport", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "udp.dport", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "udp.len", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "udp.csum", + }, +}; + +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; + struct udphdr *udph = protoh; + ulog_iret_t *ret = ip->result; + + if (iph->protocol != IPPROTO_UDP) + return NULL; + + 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; + ret[3].value.ui16 = ntohs(udph->check); + ret[3].flags |= ULOGD_RETF_VALID; + + return ret; +} + +/*********************************************************************** + * ICMP HEADER + ***********************************************************************/ + +static ulog_iret_t icmphdr_rets[] = { + { .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "icmp.type", + }, + { .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .key = "icmp.code", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "icmp.echoid", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "icmp.echoseq", + }, + { .type = ULOGD_RET_IPADDR, + .flags = ULOGD_RETF_NONE, + .key = "icmp.gateway", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "icmp.fragmtu", + }, + { .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .key = "icmp.csum", + }, +}; + +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; + struct icmphdr *icmph = protoh; + ulog_iret_t *ret = ip->result; + + if (iph->protocol != IPPROTO_ICMP) + return NULL; + + 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; + } + ret[6].value.ui16 = icmph->checksum; + ret[6].flags |= ULOGD_RETF_VALID; + + return ret; +} + +/*********************************************************************** + * IPSEC HEADER + ***********************************************************************/ + +static ulog_iret_t ahesphdr_rets[] = { + { .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .key = "ahesp.spi", + }, +}; + +static ulog_iret_t *_interp_ahesp(struct ulog_interpreter *ip, + ulog_packet_msg_t *pkt) +{ + + ulog_iret_t *ret = ip->result; +#if 0 + struct iphdr *iph = (struct iphdr *) pkt->payload; + void *protoh = (u_int32_t *) (iph + iph->ihl); + 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[] = { + { .name = "raw", + .interp = &_interp_raw, + .key_num = 3, + .result = raw_rets }, + { .name = "oob", + .interp = &_interp_oob, + .key_num = 6, + .result = oob_rets }, + { .name = "ip", + .interp = &_interp_iphdr, + .key_num = 10, + .result = iphdr_rets }, + { .name = "tcp", + .interp = &_interp_tcphdr, + .key_num = 17, + .result = tcphdr_rets }, + { .name = "icmp", + .interp = &_interp_icmp, + .key_num = 7, + .result = icmphdr_rets }, + { .name = "udp", + .interp = &_interp_udp, + .key_num = 4, + .result = udphdr_rets }, + { .name = "ahesp", + .interp = &_interp_ahesp, + .key_num = 1, + .result = ahesphdr_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++) { + register_interpreter(p); + } +} + +void _init(void) +{ + _base_reg_ip(); +} diff --git a/extensions/ulogd_LOCAL.c b/extensions/ulogd_LOCAL.c new file mode 100644 index 0000000..6504ec6 --- /dev/null +++ b/extensions/ulogd_LOCAL.c @@ -0,0 +1,102 @@ +/* ulogd_LOCAL.c, Version 0.3 + * + * ulogd interpreter plugin for: - local time of packet + * - hostname of localhost + * + * (C) 2001-2002 by Florent AIDE + * with the help of Moez MKADMI + * shamelessly ripped from Harald Welte + * + * 2002 extended by Martin Kaehmer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + */ + +#include +#include +#include +#include +#include + +#ifdef DEBUG_LOCAL +#define DEBUGP(x) ulogd_log(ULOGD_DEBUG, x) +#else +#define DEBUGP(format, args...) +#endif + + +static char hostname[255]; + +static ulog_iret_t *_interp_local(ulog_interpreter_t *ip, + ulog_packet_msg_t *pkt) +{ + struct timeval tv; + ulog_iret_t *ret = ip->result; + + /* Get date */ + gettimeofday(&tv, NULL); + + /* put date */ + ret[0].value.ui32 = (unsigned long) tv.tv_sec; + ret[0].flags |= ULOGD_RETF_VALID; + + ret[1].value.ptr = hostname; + ret[1].flags |= ULOGD_RETF_VALID; + + return ret; +} + +static ulog_iret_t local_rets[] = { + { .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .key = "local.time", + }, + { .type = ULOGD_RET_STRING, + .flags = ULOGD_RETF_NONE, + .key = "local.hostname", + }, +}; + +static ulog_interpreter_t local_ip[] = { + { NULL, "local", 0, &_interp_local, 2, local_rets }, + { NULL, "", 0, NULL, 0, NULL }, +}; + +static void _local_reg_ip(void) +{ + ulog_interpreter_t *ip = local_ip; + ulog_interpreter_t *p; + + for (p = ip; p->interp; p++) + register_interpreter(p); +} + +void _init(void) +{ + /* get hostname */ + char *tmp; + if (gethostname(hostname, sizeof(hostname)) < 0) { + ulogd_log(ULOGD_FATAL, "can't gethostname(): %s\n", + strerror(errno)); + exit(2); + } + hostname[sizeof(hostname)-1] = '\0'; + /* strip off everything after first '.' */ + if ((tmp = strchr(hostname, '.'))) + *tmp = '\0'; + + _local_reg_ip(); +} diff --git a/extensions/ulogd_LOCALTIME.c b/extensions/ulogd_LOCALTIME.c new file mode 100644 index 0000000..e69de29 diff --git a/extensions/ulogd_LOGEMU.c b/extensions/ulogd_LOGEMU.c new file mode 100644 index 0000000..5473668 --- /dev/null +++ b/extensions/ulogd_LOGEMU.c @@ -0,0 +1,139 @@ +/* ulogd_LOGEMU.c, Version $Revision$ + * + * 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-2001 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + * + */ + +#include +#include +#include +#include +#include +#include +#include "printpkt.c" + +#ifndef ULOGD_LOGEMU_DEFAULT +#define ULOGD_LOGEMU_DEFAULT "/var/log/ulogd.syslogemu" +#endif + +#ifndef ULOGD_LOGEMU_SYNC_DEFAULT +#define ULOGD_LOGEMU_SYNC_DEFAULT 0 +#endif + +#define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] + +static config_entry_t syslogf_ce = { + .key = "file", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + .u = { .string = ULOGD_LOGEMU_DEFAULT } +}; + +static config_entry_t syslsync_ce = { + .next = &syslogf_ce, + .key = "sync", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u = { .value = ULOGD_LOGEMU_SYNC_DEFAULT } +}; + +static FILE *of = NULL; + +static int _output_logemu(ulog_iret_t *res) +{ + static char buf[4096]; + + printpkt_print(res, buf, 1); + + fprintf(of, "%s", buf); + + if (syslsync_ce.u.value) + fflush(of); + + return 0; +} + +static void signal_handler_logemu(int signal) +{ + FILE *old=of; + + switch (signal) { + case SIGHUP: + ulogd_log(ULOGD_NOTICE, "syslogemu: reopening logfile\n"); + of = fopen(syslogf_ce.u.string, "a"); + if (!of) { + ulogd_log(ULOGD_FATAL, "can't open syslogemu: %s\n", + strerror(errno)); + of=old; + } else { + fclose(old); + } + break; + default: + break; + } +} + + +static int init_logemu(void) { + /* FIXME: error handling */ + config_parse_file("LOGEMU", &syslsync_ce); + +#ifdef DEBUG_LOGEMU + of = stdout; +#else + of = fopen(syslogf_ce.u.string, "a"); + if (!of) { + ulogd_log(ULOGD_FATAL, "can't open syslogemu: %s\n", + strerror(errno)); + exit(2); + } +#endif + if (printpkt_init()) { + ulogd_log(ULOGD_ERROR, "can't resolve all keyhash id's\n"); + } + + return 1; +} + +static void fini_logemu(void) { + if (of != stdout) + fclose(of); +} + +static ulog_output_t logemu_op = { + .name = "syslogemu", + .init = &init_logemu, + .fini = &fini_logemu, + .output = &_output_logemu, + .signal = &signal_handler_logemu, +}; + +void _init(void) +{ + register_output(&logemu_op); +} diff --git a/extensions/ulogd_OPRINT.c b/extensions/ulogd_OPRINT.c new file mode 100644 index 0000000..ed34382 --- /dev/null +++ b/extensions/ulogd_OPRINT.c @@ -0,0 +1,149 @@ +/* ulogd_MAC.c, Version $Revision$ + * + * ulogd output target for logging to a file + * + * (C) 2000-2001 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + * + */ + +#include +#include +#include +#include +#include + +#ifndef ULOGD_OPRINT_DEFAULT +#define ULOGD_OPRINT_DEFAULT "/var/log/ulogd.pktlog" +#endif + +#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; + +static int _output_print(ulog_iret_t *res) +{ + ulog_iret_t *ret; + + fprintf(of, "===>PACKET BOUNDARY\n"); + for (ret = res; ret; ret = ret->cur_next) { + fprintf(of,"%s=", ret->key); + switch (ret->type) { + case ULOGD_RET_STRING: + fprintf(of, "%s\n", (char *) ret->value.ptr); + break; + case ULOGD_RET_BOOL: + case ULOGD_RET_INT8: + case ULOGD_RET_INT16: + case ULOGD_RET_INT32: + fprintf(of, "%d\n", ret->value.i32); + break; + case ULOGD_RET_UINT8: + case ULOGD_RET_UINT16: + case ULOGD_RET_UINT32: + fprintf(of, "%u\n", ret->value.ui32); + break; + case ULOGD_RET_IPADDR: + fprintf(of, "%u.%u.%u.%u\n", + HIPQUAD(ret->value.ui32)); + break; + case ULOGD_RET_NONE: + fprintf(of, "\n"); + break; + default: + fprintf(of, "\n"); + break; + } + } + return 0; +} + +static config_entry_t outf_ce = { + .key = "file", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + .u = { .string = ULOGD_OPRINT_DEFAULT } +}; + +static void sighup_handler_print(int signal) +{ + FILE *old=of; + + switch (signal) { + case SIGHUP: + ulogd_log(ULOGD_NOTICE, "PKTLOG: reopening logfile\n"); + of = fopen(outf_ce.u.string, "a"); + if (!of) { + ulogd_log(ULOGD_FATAL, "can't open PKTLOG: %s\n", + strerror(errno)); + of=old; + } else { + fclose(old); + } + break; + default: + break; + } +} + +static int oprint_init(void) +{ +#ifdef DEBUG + of = stdout; +#else + config_parse_file("OPRINT", &outf_ce); + + of = fopen(outf_ce.u.string, "a"); + if (!of) { + ulogd_log(ULOGD_FATAL, "can't open PKTLOG: %s\n", + strerror(errno)); + exit(2); + } +#endif + return 0; +} + +static void oprint_fini(void) +{ + if (of != stdout) + fclose(of); + + return; +} + +static ulog_output_t oprint_op = { + .name = "oprint", + .output = &_output_print, + .signal = &sighup_handler_print, + .init = &oprint_init, + .fini = &oprint_fini, +}; + +void _init(void) +{ + register_output(&oprint_op); +} diff --git a/extensions/ulogd_PWSNIFF.c b/extensions/ulogd_PWSNIFF.c new file mode 100644 index 0000000..d205cdd --- /dev/null +++ b/extensions/ulogd_PWSNIFF.c @@ -0,0 +1,167 @@ +/* ulogd_PWSNIFF.c, Version $Revision$ + * + * ulogd logging interpreter for POP3 / FTP like plaintext passwords. + * + * (C) 2000-2003 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "chtons.h" +#include + +#ifdef DEBUG_PWSNIFF +#define DEBUGP(x) ulogd_log(ULOGD_DEBUG, x) +#else +#define DEBUGP(format, args...) +#endif + + +#define PORT_POP3 110 +#define PORT_FTP 21 + +static u_int16_t pwsniff_ports[] = { + __constant_htons(PORT_POP3), + __constant_htons(PORT_FTP), + /* feel free to include any other ports here, provided that their + * user/password syntax is the same */ +}; + +#define PWSNIFF_MAX_PORTS 2 + +static char *_get_next_blank(char* begp, char *endp) +{ + char *ptr; + + for (ptr = begp; ptr < endp; ptr++) { + if (*ptr == ' ' || *ptr == '\n' || *ptr == '\r') { + return ptr-1; + } + } + return NULL; +} + +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 = ip->result; + int len, pw_len, i, cont = 0; + + len = pw_len = 0; + begp = pw_begp = NULL; + + if (iph->protocol != IPPROTO_TCP) + return NULL; + + for (i = 0; i < PWSNIFF_MAX_PORTS; i++) + { + if (tcph->dest == pwsniff_ports[i]) { + cont = 1; + break; + } + } + if (!cont) + return NULL; + + DEBUGP("----> pwsniff detected, tcplen=%d, struct=%d, iphtotlen=%d, ihl=%d\n", tcplen, sizeof(struct tcphdr), ntohs(iph->tot_len), iph->ihl); + + for (ptr = (unsigned char *) tcph + sizeof(struct tcphdr); + ptr < (unsigned char *) tcph + tcplen; ptr++) + { + if (!strncasecmp((char *)ptr, "USER ", 5)) { + begp = ptr+5; + endp = (unsigned char *)_get_next_blank((char *)begp, (char *)tcph + tcplen); + if (endp) + len = endp - begp + 1; + } + if (!strncasecmp((char *)ptr, "PASS ", 5)) { + pw_begp = ptr+5; + pw_endp = (unsigned char *)_get_next_blank((char *)pw_begp, + (char *)tcph + tcplen); + if (pw_endp) + pw_len = pw_endp - pw_begp + 1; + } + } + + if (len) { + ret[0].value.ptr = (char *) malloc(len+1); + ret[0].flags |= ULOGD_RETF_VALID; + if (!ret[0].value.ptr) { + ulogd_log(ULOGD_ERROR, "OOM (size=%u)\n", len); + return NULL; + } + strncpy(ret[0].value.ptr, (char *)begp, len); + *((char *)ret[0].value.ptr + len) = '\0'; + } + if (pw_len) { + ret[1].value.ptr = (char *) malloc(pw_len+1); + ret[1].flags |= ULOGD_RETF_VALID; + if (!ret[1].value.ptr){ + ulogd_log(ULOGD_ERROR, "OOM (size=%u)\n", pw_len); + return NULL; + } + strncpy(ret[1].value.ptr, (char *)pw_begp, pw_len); + *((char *)ret[1].value.ptr + pw_len) = '\0'; + + } + return ret; +} + +static ulog_iret_t pwsniff_rets[] = { + { .type = ULOGD_RET_STRING, + .flags = ULOGD_RETF_FREE, + .key = "pwsniff.user", + }, + { .type = ULOGD_RET_STRING, + .flags = ULOGD_RETF_FREE, + .key = "pwsniff.pass", + }, +}; + +static ulog_interpreter_t base_ip[] = { + { .name = "pwsniff", + .interp = &_interp_pwsniff, + .key_num = 2, + .result = pwsniff_rets }, + { NULL, "", 0, NULL, 0, NULL }, +}; + +static 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/extensions/ulogd_SYSLOG.c b/extensions/ulogd_SYSLOG.c new file mode 100644 index 0000000..3b8dd44 --- /dev/null +++ b/extensions/ulogd_SYSLOG.c @@ -0,0 +1,149 @@ +/* ulogd_SYSLOG.c, Version $Revision$ + * + * ulogd output target for real syslog() logging + * + * This target produces a syslog entries identical to the LOG target. + * + * (C) 2003 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "printpkt.h" + +#ifndef SYSLOG_FACILITY_DEFAULT +#define SYSLOG_FACILITY_DEFAULT "LOG_KERN" +#endif + +#ifndef SYSLOG_LEVEL_DEFAULT +#define SYSLOG_LEVEL_DEFAULT "LOG_NOTICE" +#endif + +static config_entry_t facility_ce = { + .key = "facility", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + .u = { .string = SYSLOG_FACILITY_DEFAULT } +}; + +static config_entry_t level_ce = { + .next = &facility_ce, + .key = "level", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + .u = { .string = SYSLOG_LEVEL_DEFAULT } +}; + +static int syslog_level, syslog_facility; + +static int _output_syslog(ulog_iret_t *res) +{ + static char buf[4096]; + + printpkt_print(res, buf, 0); + syslog(syslog_level|syslog_facility, buf); + + return 0; +} + +static int syslog_init(void) +{ + /* FIXME: error handling */ + config_parse_file("SYSLOG", &level_ce); + + if (!strcmp(facility_ce.u.string, "LOG_DAEMON")) + syslog_facility = LOG_DAEMON; + else if (!strcmp(facility_ce.u.string, "LOG_KERN")) + syslog_facility = LOG_KERN; + else if (!strcmp(facility_ce.u.string, "LOG_LOCAL0")) + syslog_facility = LOG_LOCAL0; + else if (!strcmp(facility_ce.u.string, "LOG_LOCAL1")) + syslog_facility = LOG_LOCAL1; + else if (!strcmp(facility_ce.u.string, "LOG_LOCAL2")) + syslog_facility = LOG_LOCAL2; + else if (!strcmp(facility_ce.u.string, "LOG_LOCAL3")) + syslog_facility = LOG_LOCAL3; + else if (!strcmp(facility_ce.u.string, "LOG_LOCAL4")) + syslog_facility = LOG_LOCAL4; + else if (!strcmp(facility_ce.u.string, "LOG_LOCAL5")) + syslog_facility = LOG_LOCAL5; + else if (!strcmp(facility_ce.u.string, "LOG_LOCAL6")) + syslog_facility = LOG_LOCAL6; + else if (!strcmp(facility_ce.u.string, "LOG_LOCAL7")) + syslog_facility = LOG_LOCAL7; + else if (!strcmp(facility_ce.u.string, "LOG_USER")) + syslog_facility = LOG_USER; + else { + ulogd_log(ULOGD_FATAL, "unknown facility '%s'\n", + facility_ce.u.string); + exit(2); + } + + if (!strcmp(level_ce.u.string, "LOG_EMERG")) + syslog_level = LOG_EMERG; + else if (!strcmp(level_ce.u.string, "LOG_ALERT")) + syslog_level = LOG_ALERT; + else if (!strcmp(level_ce.u.string, "LOG_CRIT")) + syslog_level = LOG_CRIT; + else if (!strcmp(level_ce.u.string, "LOG_ERR")) + syslog_level = LOG_ERR; + else if (!strcmp(level_ce.u.string, "LOG_WARNING")) + syslog_level = LOG_WARNING; + else if (!strcmp(level_ce.u.string, "LOG_NOTICE")) + syslog_level = LOG_NOTICE; + else if (!strcmp(level_ce.u.string, "LOG_INFO")) + syslog_level = LOG_INFO; + else if (!strcmp(level_ce.u.string, "LOG_DEBUG")) + syslog_level = LOG_DEBUG; + else { + ulogd_log(ULOGD_FATAL, "unknown level '%s'\n", + level_ce.u.string); + exit(2); + } + + openlog("ulogd", LOG_NDELAY|LOG_PID, syslog_facility); + + return 0; +} + +static void syslog_fini(void) +{ + closelog(); +} + +static ulog_output_t syslog_op = { + .name = "syslog", + .init = &syslog_init, + .fini = &syslog_fini, + .output = &_output_syslog, +}; + + +void _init(void) +{ + if (printpkt_init()) + ulogd_log(ULOGD_ERROR, "can't resolve all keyhash id's\n"); + + register_output(&syslog_op); +} -- cgit v1.2.3