From fcda89e78e544230bc5a5132257cd108a6314a76 Mon Sep 17 00:00:00 2001 From: laforge Date: Sat, 8 Oct 2005 08:42:42 +0000 Subject: port PCAP to ulogd2 --- output/pcap/Makefile.am | 9 ++ output/pcap/Makefile.in | 30 ----- output/pcap/ulogd_PCAP.c | 238 ------------------------------------- output/pcap/ulogd_output_PCAP.c | 252 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 268 deletions(-) create mode 100644 output/pcap/Makefile.am delete mode 100644 output/pcap/Makefile.in delete mode 100644 output/pcap/ulogd_PCAP.c create mode 100644 output/pcap/ulogd_output_PCAP.c diff --git a/output/pcap/Makefile.am b/output/pcap/Makefile.am new file mode 100644 index 0000000..b4bdb99 --- /dev/null +++ b/output/pcap/Makefile.am @@ -0,0 +1,9 @@ + +INCLUDES = $(all_includes) -I$(top_srcdir)/include +LIBS=-lpcap + +pkglib_LTLIBRARIES = ulogd_output_PCAP.la + +ulogd_output_PCAP_la_SOURCES = ulogd_output_PCAP.c +ulogd_output_PCAP_la_LDFLAGS = -module + diff --git a/output/pcap/Makefile.in b/output/pcap/Makefile.in deleted file mode 100644 index d469c2b..0000000 --- a/output/pcap/Makefile.in +++ /dev/null @@ -1,30 +0,0 @@ -# -include @top_srcdir@/Rules.make - -CFLAGS+=-I@top_srcdir@ -I@top_srcdir@/libipulog/include -I@top_srcdir@/include -SH_CFLAGS:=$(CFLAGS) -fPIC - -# Normally You should not need to change anything below -# - -SHARED_LIBS=ulogd_PCAP.so - -all: $(SHARED_LIBS) - -distrib: - -$(SHARED_LIBS): %.so: %_sh.o - $(LD) -shared -o $@ $< -lc -lpcap - -%_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/output/pcap/ulogd_PCAP.c b/output/pcap/ulogd_PCAP.c deleted file mode 100644 index 83959a8..0000000 --- a/output/pcap/ulogd_PCAP.c +++ /dev/null @@ -1,238 +0,0 @@ -/* ulogd_PCAP.c, Version $Revision$ - * - * ulogd output target for writing pcap-style files (like tcpdump) - * - * FIXME: descr. - * - * - * (C) 2002 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 - -#ifndef ULOGD_PCAP_DEFAULT -#define ULOGD_PCAP_DEFAULT "/var/log/ulogd.pcap" -#endif - -#ifndef ULOGD_PCAP_SYNC_DEFAULT -#define ULOGD_PCAP_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 pcapf_ce = { - .key = "file", - .type = CONFIG_TYPE_STRING, - .options = CONFIG_OPT_NONE, - .u.string = ULOGD_PCAP_DEFAULT, -}; - -static config_entry_t pcapsync_ce = { - .next = &pcapf_ce, - .key = "sync", - .type = CONFIG_TYPE_INT, - .options = CONFIG_OPT_NONE, - .u.value = ULOGD_PCAP_SYNC_DEFAULT, -}; - -static FILE *of = NULL; - -struct intr_id { - char* name; - unsigned int id; -}; - -#define INTR_IDS 5 -static struct intr_id intr_ids[INTR_IDS] = { - { "raw.pkt", 0 }, - { "raw.pktlen", 0 }, - { "ip.totlen", 0 }, - { "oob.time.sec", 0 }, - { "oob.time.usec", 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 - -static int pcap_output(ulog_iret_t *res) -{ - struct pcap_pkthdr pchdr; - - pchdr.caplen = GET_VALUE(1).ui32; - pchdr.len = GET_VALUE(2).ui32; - - if (GET_FLAGS(3) & ULOGD_RETF_VALID - && GET_FLAGS(4) & ULOGD_RETF_VALID) { - pchdr.ts.tv_sec = GET_VALUE(3).ui32; - pchdr.ts.tv_usec = GET_VALUE(4).ui32; - } else { - /* use current system time */ - gettimeofday(&pchdr.ts, NULL); - } - - if (fwrite(&pchdr, sizeof(pchdr), 1, of) != 1) { - ulogd_log(ULOGD_ERROR, "Error during write: %s\n", - strerror(errno)); - return 1; - } - if (fwrite(GET_VALUE(0).ptr, pchdr.caplen, 1, of) != 1) { - ulogd_log(ULOGD_ERROR, "Error during write: %s\n", - strerror(errno)); - return 1; - } - - if (pcapf_ce.u.value) - fflush(of); - - return 0; -} - -/* stolen from libpcap savefile.c */ -#define LINKTYPE_RAW 101 -#define TCPDUMP_MAGIC 0xa1b2c3d4 - -static int write_pcap_header(void) -{ - struct pcap_file_header pcfh; - int ret; - - pcfh.magic = TCPDUMP_MAGIC; - pcfh.version_major = PCAP_VERSION_MAJOR; - pcfh.version_minor = PCAP_VERSION_MINOR; - pcfh.thiszone = timezone; - pcfh.sigfigs = 0; - pcfh.snaplen = 64 * 1024; /* we don't know the length in advance */ - pcfh.linktype = LINKTYPE_RAW; - - ret = fwrite(&pcfh, sizeof(pcfh), 1, of); - fflush(of); - - return ret; -} - -/* 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; -} - -void append_create_outfile(void) { - struct stat st_dummy; - int exist = 0; - - if (stat(pcapf_ce.u.string, &st_dummy) == 0 && st_dummy.st_size > 0) { - exist = 1; - } - - if (!exist) { - of = fopen(pcapf_ce.u.string, "w"); - if (!of) { - ulogd_log(ULOGD_FATAL, "can't open pcap file: %s\n", - strerror(errno)); - exit(2); - } - if (!write_pcap_header()) { - ulogd_log(ULOGD_FATAL, "can't write pcap header: %s\n", - strerror(errno)); - exit(2); - } - } else { - of = fopen(pcapf_ce.u.string, "a"); - if (!of) { - ulogd_log(ULOGD_FATAL, "can't open pcap file: %s\n", - strerror(errno)); - exit(2); - } - } -} - -static void pcap_signal_handler(int signal) -{ - switch (signal) { - case SIGHUP: - ulogd_log(ULOGD_NOTICE, "pcap: reopening capture file\n"); - fclose(of); - append_create_outfile(); - break; - default: - break; - } -} - -static int pcap_init(void) -{ - /* FIXME: error handling */ - config_parse_file("PCAP", &pcapsync_ce); - -#ifdef DEBUG_PCAP - of = stdout; -#else - append_create_outfile(); -#endif - return 0; -} - -static void pcap_fini(void) -{ - if (of) - fclose(of); -} - -static ulog_output_t pcap_op = { - .name = "pcap", - .init = &pcap_init, - .fini = &pcap_fini, - .output = &pcap_output, - .signal = &pcap_signal_handler, -}; - -void _init(void) -{ - if (get_ids()) { - ulogd_log(ULOGD_ERROR, "can't resolve all keyhash id's\n"); - } - - register_output(&pcap_op); -} diff --git a/output/pcap/ulogd_output_PCAP.c b/output/pcap/ulogd_output_PCAP.c new file mode 100644 index 0000000..55cd7f1 --- /dev/null +++ b/output/pcap/ulogd_output_PCAP.c @@ -0,0 +1,252 @@ +/* ulogd_PCAP.c, Version $Revision$ + * + * ulogd output target for writing pcap-style files (like tcpdump) + * + * FIXME: descr. + * + * + * (C) 2002 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 + +#ifndef ULOGD_PCAP_DEFAULT +#define ULOGD_PCAP_DEFAULT "/var/log/ulogd.pcap" +#endif + +#ifndef ULOGD_PCAP_SYNC_DEFAULT +#define ULOGD_PCAP_SYNC_DEFAULT 0 +#endif + +#define NIPQUAD(addr) \ + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3] + +static struct config_keyset pcap_kset = { + .num_ces = 2, + .ces = { + { + .key = "file", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + .u.string = ULOGD_PCAP_DEFAULT, + }, + { + .key = "sync", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u.value = ULOGD_PCAP_SYNC_DEFAULT, + }, + }, +}; + +static struct pcap_instance { + FILE *of; +}; + +struct intr_id { + char* name; + unsigned int id; +}; + +#define INTR_IDS 5 +static struct ulogd_key pcap_keys[INTR_IDS] = { + { .name = "raw.pkt" }, + { .name = "raw.pktlen" }, + { .name = "ip.totlen" }, + { .name = "oob.time.sec" }, + { .name = "oob.time.usec" }, +}; + +#define GET_VALUE(res, x) (res[x].u.source->u.value) +#define GET_FLAGS(res, x) (res[x].u.source->flags) + +static int pcap_output(struct ulogd_pluginstance *upi) +{ + struct pcap_instance *pi = (struct pcap_instance *) &upi->private; + struct ulogd_key *res = upi->input; + struct pcap_pkthdr pchdr; + + pchdr.caplen = GET_VALUE(res, 1).ui32; + pchdr.len = GET_VALUE(res, 2).ui32; + + if (GET_FLAGS(res, 3) & ULOGD_RETF_VALID + && GET_FLAGS(res, 4) & ULOGD_RETF_VALID) { + pchdr.ts.tv_sec = GET_VALUE(res, 3).ui32; + pchdr.ts.tv_usec = GET_VALUE(res, 4).ui32; + } else { + /* use current system time */ + gettimeofday(&pchdr.ts, NULL); + } + + if (fwrite(&pchdr, sizeof(pchdr), 1, pi->of) != 1) { + ulogd_log(ULOGD_ERROR, "Error during write: %s\n", + strerror(errno)); + return 1; + } + if (fwrite(GET_VALUE(res, 0).ptr, pchdr.caplen, 1, pi->of) != 1) { + ulogd_log(ULOGD_ERROR, "Error during write: %s\n", + strerror(errno)); + return 1; + } + + if (upi->config_kset->ces[1].u.value) + fflush(of); + + return 0; +} + +/* stolen from libpcap savefile.c */ +#define LINKTYPE_RAW 101 +#define TCPDUMP_MAGIC 0xa1b2c3d4 + +static int write_pcap_header(struct pcap_instance *pi) +{ + struct pcap_file_header pcfh; + int ret; + + pcfh.magic = TCPDUMP_MAGIC; + pcfh.version_major = PCAP_VERSION_MAJOR; + pcfh.version_minor = PCAP_VERSION_MINOR; + pcfh.thiszone = timezone; + pcfh.sigfigs = 0; + pcfh.snaplen = 64 * 1024; /* we don't know the length in advance */ + pcfh.linktype = LINKTYPE_RAW; + + ret = fwrite(&pcfh, sizeof(pcfh), 1, pi->of); + fflush(pi->of); + + return ret; +} + +static int append_create_outfile(struct ulogd_pluginstance *upi) +{ + struct pcap_instance *pi = (struct pcap_instance *) &upi->private; + char *filename = upi->config_kset->ces[0].u.string; + struct stat st_dummy; + int exist = 0; + + if (stat(filename, &st_dummy) == 0 && st_dummy.st_size > 0) + exist = 1; + + if (!exist) { + of = fopen(filename, "w"); + if (!of) { + ulogd_log(ULOGD_ERROR, "can't open pcap file: %s\n", + strerror(errno)); + return -1; + } + if (!write_pcap_header()) { + ulogd_log(ULOGD_ERROR, "can't write pcap header: %s\n", + strerror(errno)); + return -1; + } + } else { + of = fopen(filename, "a"); + if (!of) { + ulogd_log(ULOGD_ERROR, "can't open pcap file: %s\n", + strerror(errno)); + return -1; + } + } + + return 0; +} + +static void pcap_signal_handler(struct ulogd_pluginstance *upi, int signal) +{ + struct pcap_instance *pi = (struct pcap_instance *) &upi->private; + + switch (signal) { + case SIGHUP: + ulogd_log(ULOGD_NOTICE, "reopening capture file\n"); + fclose(pi->of); + append_create_outfile(upi); + break; + default: + break; + } +} + +static int configure_pcap(struct ulogd_pluginstance *upi, + struct ulogd_pluginstance_stack *stack) +{ + return config_parse_file(upi->id, upi->config_kset); +} + +static int start_pcap(struct ulogd_pluginstance *upi) +{ + return append_create_outfile(upi); +} + +static int stop_pcap(struct ulogd_pluginstance *upi) +{ + struct pcap_instance *pi = (struct pcap_instance *) &upi->private; + + if (pi->of) + fclose(pi->of); + + return 0; +} + +static struct ulogd_plugin pcap_plugin = { + .name = "PCAP", + .input = { + .keys = pcap_keys, + .num_keys = ARRAY_SIZE(pcap_keys), + .type = ULOGD_DTYPE_PACKET, + }, + .output = { + .type = ULOGD_DTYPE_SINK, + }, + .config_kset = &pcap_kset, + .priv_size = sizeof(struct pcap_instance), + + .configure = &configure_pcap, + .start = &start_pcap, + .stop = &stop_pcap, + .signal = &signal_pcap, + .interp = &interp_pcap, +}; + +static ulog_output_t pcap_op = { + .name = "pcap", + .init = &pcap_init, + .fini = &pcap_fini, + .output = &pcap_output, + .signal = &pcap_signal_handler, +}; + +void __attribute__ ((constructor)) init(void); + +void init(void) +{ + ulogd_register_plugin(&pcap_plugin); +} -- cgit v1.2.3