From cf6bc4f21f8f379c80fd814a5e1b8f1cef02036b Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 22 Aug 2004 21:42:28 +0000 Subject: commit my latest changes from Ottawa (July 2004) --- ARCHITECTURE | 2 +- filter/raw2packet/ulogd_raw2packet_BASE.c | 41 +++++++-- include/ipfix_protocol.h | 29 +++++++ include/ulogd/select.h | 2 + include/ulogd/ulogd.h | 134 ++++++++++++++++++------------ input/packet/ulogd_inppkt_ULOG.c | 59 +++---------- output/ulogd_output_OPRINT.c | 58 +++++++++---- 7 files changed, 197 insertions(+), 128 deletions(-) create mode 100644 include/ipfix_protocol.h diff --git a/ARCHITECTURE b/ARCHITECTURE index 20976b0..c9264b3 100644 --- a/ARCHITECTURE +++ b/ARCHITECTURE @@ -59,4 +59,4 @@ Architecture of ulogd2 - problems: - multiple interpreters can return same value (i.e. sport/dport) - + - some outputs/filters will require _ALL_ keys (e.g. OPRINT) diff --git a/filter/raw2packet/ulogd_raw2packet_BASE.c b/filter/raw2packet/ulogd_raw2packet_BASE.c index ff60105..31d9cc7 100644 --- a/filter/raw2packet/ulogd_raw2packet_BASE.c +++ b/filter/raw2packet/ulogd_raw2packet_BASE.c @@ -401,8 +401,6 @@ static ulog_iret_t *_interp_ahesp(struct ulog_interpreter *ip, static ulog_interpreter_t base_ip[] = { - { NULL, "raw", 0, &_interp_raw, 3, raw_rets }, - { NULL, "oob", 0, &_interp_oob, 6, oob_rets }, { NULL, "ip", 0, &_interp_iphdr, 10, iphdr_rets }, { NULL, "tcp", 0, &_interp_tcphdr, 17, tcphdr_rets }, { NULL, "icmp", 0, &_interp_icmp, 7, icmphdr_rets }, @@ -411,18 +409,43 @@ static ulog_interpreter_t base_ip[] = { { NULL, "", 0, NULL, 0, NULL }, }; -void _base_reg_ip(void) +static struct ulogd_pluginstance *base_init(struct ulogd_plugin *pl) { - ulog_interpreter_t *ip = base_ip; - ulog_interpreter_t *p; + struct ulogd_pluginstance *bpi = malloc(sizeof(*bpi)); - for (p = ip; p->interp; p++) { - register_interpreter(p); - } + if (!bpi) + return NULL; + + bpi->plugin = pl; + bpi->input = FIXME; + bpi->output = FIXME; + + return bpi; +} +static int base_fini(struct ulogd_pluginstance *upi) +{ + return 0; } +static struct ulogd_plugin base_plugin = { + .name = "BASE", + .input = { + .keys =; + .num_keys = 1, + .type = ULOGD_DTYPE_RAW, + }, + .output = { + .keys = &base_keys, + .num_keys = 39, + .type = ULOGD_DTYPE_PKT, + }, + .interp = &base_interp, + .construct = &base_init, + .destructor = &base_fini, +}; + void _init(void) { - _base_reg_ip(); + ulogd_register_plugin(&base_plugin); } diff --git a/include/ipfix_protocol.h b/include/ipfix_protocol.h new file mode 100644 index 0000000..3bcf05c --- /dev/null +++ b/include/ipfix_protocol.h @@ -0,0 +1,29 @@ +#ifndef _IPFIX_PROTOCOL_H +#define _IPFIX_PROTOCOL_H + +/* This header file defines structures for the IPFIX protocol in accordance with + * draft-ietf-ipfix-protocol-03.txt */ + +/* Section 8.1 */ +struct ipfix_msg_hdr { + u_int16_t version; + u_int16_t length; + u_int32_t export_time; + u_int32_t seq; + u_int32_t source_id; +}; + +/* Section 8.2 */ +struct ipfix_ietf_field { + u_int16_t type; + u_int16_t length; +}; + +struct ipfix_vendor_field { + u_int16_t type; + u_int16_t length; + u_int32_t enterprise_num; +}; + + +#endif diff --git a/include/ulogd/select.h b/include/ulogd/select.h index 9562a6e..4558555 100644 --- a/include/ulogd/select.h +++ b/include/ulogd/select.h @@ -1,6 +1,8 @@ #ifndef ULOGD_SELECT_H #define ULOGD_SELECT_H +#include + #define ULOGD_FD_F_READ 0x0001 #define ULOGD_FD_F_WRITE 0x0002 diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h index d79fbba..db8df34 100644 --- a/include/ulogd/ulogd.h +++ b/include/ulogd/ulogd.h @@ -12,7 +12,7 @@ * $Id$ */ -#include +#include #include #include /* need this because of extension-sighandler */ @@ -45,6 +45,8 @@ #define ULOGD_RETF_NONE 0x0000 #define ULOGD_RETF_VALID 0x0001 /* contains a valid result */ #define ULOGD_RETF_FREE 0x0002 /* ptr needs to be free()d */ +#define ULOGD_RETF_NEEDED 0x0004 /* this parameter is actually needed + * by some downstream plugin */ /* maximum length of ulogd key */ @@ -58,11 +60,17 @@ extern FILE *logfile; -typedef struct ulog_iret { +enum ulogd_dtype { + ULOGD_DTYPE_NULL, + ULOGD_DTYPE_RAW, + ULOGD_DTYPE_PACKET, + ULOGD_DTYPE_FLOW, +}; + +/* structure describing an input / output parameter of a plugin */ +typedef struct ulogd_key { /* next interpreter return (key) in the global list */ struct ulog_iret *next; - /* next interpreter in linked list for current result */ - struct ulog_iret *cur_next; /* length of the returned value (only for lengthed types */ u_int32_t len; /* type of the returned value (ULOGD_IRET_...) */ @@ -70,52 +78,78 @@ typedef struct ulog_iret { /* flags (i.e. free, ...) */ u_int16_t flags; /* name of this key */ - char key[ULOGD_MAX_KEYLEN]; - /* and finally the returned value */ + char name[ULOGD_MAX_KEYLEN]; + /* IETF IPFIX attribute ID */ + struct { + u_int32_t vendor; + u_int16_t field_id; + } ipfix; + union { - u_int8_t b; - u_int8_t ui8; - u_int16_t ui16; - u_int32_t ui32; - u_int64_t ui64; - int8_t i8; - int16_t i16; - int32_t i32; - int64_t i64; - void *ptr; - } value; -} ulog_iret_t; - -typedef struct ulog_interpreter { - /* next interpreter in old-style linked list */ - struct ulog_interpreter *next; - /* name of this interpreter (predefined by plugin) */ + /* and finally the returned value */ + union { + u_int8_t b; + u_int8_t ui8; + u_int16_t ui16; + u_int32_t ui32; + u_int64_t ui64; + int8_t i8; + int16_t i16; + int32_t i32; + int64_t i64; + void *ptr; + } value; + struct ulog_ket *source; + } u; +} ulogd_iret_t; + +typedef struct ulogd_plugin { + /* global list of plugins */ + struct list_head list; + /* name of this plugin (predefined by plugin) */ char name[ULOGD_MAX_KEYLEN]; - /* ID for this interpreter (dynamically assigned) */ + /* ID for this plugin (dynamically assigned) */ unsigned int id; + struct { + /* possible input keys of this interpreter */ + struct ulogd_key *keys; + /* number of keys this interpreter has */ + unsigned int num_keys; + /* type */ + enum ulogd_dtype type; + } input; + struct { + /* possible input keys of this interpreter */ + struct ulogd_key *keys; + /* number of keys this interpreter has */ + unsigned int num_keys; + /* type */ + enum ulogd_dtype type; + } output; + /* function to call for each packet */ - ulog_iret_t* (*interp)(struct ulog_interpreter *ip, - ulog_packet_msg_t *pkt); - /* number of keys this interpreter has */ - unsigned int key_num; - /* keys of this particular interpreter */ - ulog_iret_t *result; -} ulog_interpreter_t; - -typedef struct ulog_output { - /* next output in the linked list */ - struct ulog_output *next; - /* name of this ouput plugin */ - char name[ULOGD_MAX_KEYLEN]; - /* callback for initialization */ - int (*init)(void); - /* callback for de-initialization */ - void (*fini)(void); - /* callback function */ - int (*output)(ulog_iret_t *ret); - /* callback function for signals (SIGHUP, ..) */ - void (*signal)(int signal); -} ulog_output_t; + int (*interp)(struct ulogd_pluginstance *instance); + /* function to construct a new pluginstance */ + struct ulogd_pluginstance *(*constructor)(struct ulogd_plugin *pl); + /* function to destruct an existing pluginstance */ + int (*destructor)(struct ulogd_pluginstance *instance); + /* configuration parameters */ + config_entry_t *configs; +} ulogd_interpreter_t; + +/* an instance of a plugin, element in a stack */ +typedef struct ulogd_pluginstance { + /* local list of plugins in this stack */ + struct list_head list; + /* plugin (master) */ + struct ulogd_plugin *plugin; + /* per-instance input keys */ + struct ulogd_input *input; + /* per-instance output keys */ + struct ulogd_iret *output; + /* private data */ + char private[0]; +} ulogd_pluginstance_t; /* entries of the key hash */ struct ulogd_keyh_entry { @@ -129,10 +163,7 @@ struct ulogd_keyh_entry { ***********************************************************************/ /* register a new interpreter plugin */ -void register_interpreter(ulog_interpreter_t *me); - -/* register a new output target */ -void register_output(ulog_output_t *me); +void ulogd_register_plugin(ulog_plugin_t *me); /* allocate a new ulog_iret_t */ ulog_iret_t *alloc_ret(const u_int16_t type, const char*); @@ -158,7 +189,8 @@ ulog_iret_t *keyh_getres(unsigned int id); extern struct ulogd_keyh_entry *ulogd_keyh; #define IS_VALID(x) (x.flags & ULOGD_RETF_VALID) - #define SET_VALID(x) (x.flags |= ULOGD_RETF_VALID) +#define IS_NEEDED(x) (x.flags & ULOGD_RETF_NEEDED) +#define SET_NEEDED(x) (x.flags |= ULOGD_RETF_NEEDED) #endif /* _ULOGD_H */ diff --git a/input/packet/ulogd_inppkt_ULOG.c b/input/packet/ulogd_inppkt_ULOG.c index c11575a..ee3840d 100644 --- a/input/packet/ulogd_inppkt_ULOG.c +++ b/input/packet/ulogd_inppkt_ULOG.c @@ -17,6 +17,11 @@ * RMEM_DEFAULT size. */ #define ULOGD_BUFSIZE_DEFAULT 150000 +struct ulog_input { + struct ipulog_handle *libulog_h; + static unsigned char *libulog_buf; + static struct ulogd_fd ulog_fd; +}; /* configuration entries */ static config_entry_t bufsiz_ce = { NULL, "bufsize", CONFIG_TYPE_INT, @@ -100,7 +105,7 @@ static struct ulogd_key output_keys[] = { }, }; -static int interp(struct ulogd_pluginstance *ip, ulog_packet_msg_t *pkt) +static int interp_packet(struct ulogd_pluginstance *ip, ulog_packet_msg_t *pkt) { unsigned char *p; int i; @@ -156,52 +161,10 @@ static int interp(struct ulogd_pluginstance *ip, ulog_packet_msg_t *pkt) return ret; } -struct ulog_input { - struct ipulog_handle *libulog_h; - static unsigned char *libulog_buf; - static struct ulogd_fd ulog_fd; -}; - -/* call all registered interpreters and hand the results over to - * propagate_results */ -static void handle_packet(ulog_packet_msg_t *pkt) -{ -#if 0 - ulog_iret_t *ret; - ulog_iret_t *allret = NULL; - ulog_interpreter_t *ip; - - unsigned int i,j; - - /* If there are no interpreters registered yet, - * ignore this packet */ - if (!ulogd_interh_ids) { - ulogd_log(ULOGD_NOTICE, - "packet received, but no interpreters found\n"); - return; - } - - for (i = 1; i <= ulogd_interh_ids; i++) { - ip = ulogd_interh[i]; - /* call interpreter */ - if ((ret = ((ip)->interp)(ip, pkt))) { - /* create references for result linked-list */ - for (j = 0; j < ip->key_num; j++) { - if (IS_VALID(ip->result[j])) { - ip->result[j].cur_next = allret; - allret = &ip->result[j]; - } - } - } - } - propagate_results(allret); - clean_results(ulogd_interpreters->result); -#endif -} - static struct ulog_read_cb(int fd, void *param) { - struct ulog_input *u = (struct ulog_input *)param; + struct ulogd_pluginstance *upi = (struct ulogd_pluginstance *)param; + struct ulog_input *u = (struct ulog_input *)param->private; ulog_packet_msg_t *upkt; int len; @@ -217,7 +180,7 @@ static struct ulog_read_cb(int fd, void *param) while ((upkt = ipulog_get_packet(u->libulog_h, u->libulog_buf, len))) { DEBUGP("==> ulog packet received\n"); - handle_packet(upkt); + interp_packet(upi, upkt); } } return 0; @@ -248,7 +211,7 @@ static struct ulogd_pluginstance *init(struct ulogd_plugin *pl) ui->ulog_fd.fd = ui->libulog_h->fd; ui->ulog_fd.cb = &ulog_read_cb; - ui->ulog_fd.data = ui; + ui->ulog_fd.data = upi; ulogd_register_fd(&ui->ulog_fd); @@ -262,7 +225,6 @@ out_buf: static int fini(struct ulogd_pluginstance *pi) { - } struct ulogd_plugin libulog_plugin = { @@ -276,7 +238,6 @@ struct ulogd_plugin libulog_plugin = { .num = 10, }, .constructor = &init, - .interp = &input, .destructor = &fini, .configs = &rmem_ce, }; diff --git a/output/ulogd_output_OPRINT.c b/output/ulogd_output_OPRINT.c index 186e3c9..ea5ff6a 100644 --- a/output/ulogd_output_OPRINT.c +++ b/output/ulogd_output_OPRINT.c @@ -43,11 +43,13 @@ ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[0] -static FILE *of = NULL; +struct oprint_priv { + static FILE *of = NULL; +}; -static int _output_print(ulog_iret_t *res) +static int oprint_interp(struct ulogd_pluginstance *instance) { - ulog_iret_t *ret; + ulog_iret_t *ret = instance->input.keys; fprintf(of, "===>PACKET BOUNDARY\n"); for (ret = res; ret; ret = ret->cur_next) { @@ -102,40 +104,60 @@ static void sighup_handler_print(int signal) } } -static int oprint_init(void) +static struct ulogd_pluginstance *oprint_init(struct ulogd_plugin *pl) { + struct oprint_priv *op; + struct ulogd_pluginstance *opi = malloc(sizeof(*opi)+sizeof(*op)); + + if (!opi) + return NULL; + + op = (struct oprint_priv *) opi->private; + opi->plugin = pl; + /* FIXME: opi->input */ + opi->output = NULL; + #ifdef DEBUG - of = stdout; + op->of = stdout; #else config_parse_file("OPRINT", &outf_ce); - of = fopen(outf_ce.u.string, "a"); - if (!of) { + op->of = fopen(outf_ce.u.string, "a"); + if (!op->of) { ulogd_log(ULOGD_FATAL, "can't open PKTLOG: %s\n", strerror(errno)); exit(2); } #endif - return 0; + return opi; } -static void oprint_fini(void) +static int oprint_fini(struct ulogd_pluginstance *pi) { - if (of != stdout) - fclose(of); + struct oprint_priv *op = (struct oprint_priv *) pi->priv; + + if (op->of != stdout) + fclose(op->of); - return; + return 1; } -static ulog_output_t oprint_op = { - .name = "oprint", - .output = &_output_print, +static struct ulogd_plugin oprint_plugin = { + .name = "OPRINT", + .input = { + .type = ULOGD_DTYPE_PKT, + }, + .output = { + .type = ULOGD_DTYPE_NULL, + }, + .interp = &oprint_interp, + .constructor = &oprint_init, + .destructor = &oprint_fini, .signal = &sighup_handler_print, - .init = &oprint_init, - .fini = &oprint_fini, + .configs = &outf_ce, }; void _init(void) { - register_output(&oprint_op); + ulogd_register_output(&oprint_plugin); } -- cgit v1.2.3