summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-05-18 18:35:35 +0200
committerPatrick McHardy <kaber@trash.net>2008-05-18 18:35:35 +0200
commit835110044bd970518e10b28348ce6619818ce363 (patch)
tree76abdc04a3b9b8a29e3daded34cb2779a939df9b /extensions
parentdce17ab4526920f1930f1fee4245ea66c33093ec (diff)
Remove obsolete patches and files and move ulogd to repository top-level directory
Diffstat (limited to 'extensions')
-rw-r--r--extensions/Makefile.in37
-rw-r--r--extensions/chtons.h32
-rw-r--r--extensions/printpkt.c276
-rw-r--r--extensions/printpkt.h7
-rw-r--r--extensions/ulogd_BASE.c569
-rw-r--r--extensions/ulogd_LOCAL.c102
-rw-r--r--extensions/ulogd_LOCALTIME.c0
-rw-r--r--extensions/ulogd_LOGEMU.c139
-rw-r--r--extensions/ulogd_OPRINT.c149
-rw-r--r--extensions/ulogd_PWSNIFF.c167
-rw-r--r--extensions/ulogd_SYSLOG.c149
11 files changed, 1627 insertions, 0 deletions
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 <endian.h>
+
+#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 <laforge@gnumonks.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <ulogd/ulogd.h>
+#include <ulogd/conffile.h>
+
+#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 <laforge@gnumonks.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/ip.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <ulogd/ulogd.h>
+
+/***********************************************************************
+ * 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 <faide@alphacent.com>
+ * with the help of Moez MKADMI <moez.mka@voila.fr>
+ * shamelessly ripped from Harald Welte
+ *
+ * 2002 extended by Martin Kaehmer <teg@mompl.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <ulogd/ulogd.h>
+
+#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
--- /dev/null
+++ b/extensions/ulogd_LOCALTIME.c
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 <laforge@gnumonks.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ulogd/ulogd.h>
+#include <ulogd/conffile.h>
+#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 <laforge@gnumonks.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ulogd/ulogd.h>
+#include <ulogd/conffile.h>
+
+#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, "<none>\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 <laforge@gnumonks.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/ip.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include "chtons.h"
+#include <ulogd/ulogd.h>
+
+#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 <laforge@gnumonks.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <ulogd/ulogd.h>
+#include <ulogd/conffile.h>
+#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);
+}