From b88db902b05194f0ce444e1f6acb795f5b0fb6b3 Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 10 Oct 2004 21:31:54 +0000 Subject: intermediate development snapshot --- Changes | 6 ++ README | 6 +- include/ulogd/ulogd.h | 35 ++++---- input/packet/ulogd_inppkt_ULOG.c | 31 ++++++- output/mysql/ulogd_MYSQL.c | 63 ++++++++------ output/ulogd_output_OPRINT.c | 10 ++- ulogd.c | 181 +++++++++++++++++++++++++-------------- 7 files changed, 217 insertions(+), 115 deletions(-) diff --git a/Changes b/Changes index 886f86e..cbba483 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,9 @@ +Version 2.00alpha (2004-Oct-03) +- Total re-work. ulogd2 is almost unrelated to the ULOG netfilter target. + Instead, it has become a generic logging framework for anything from + firewall logs, flow-based accounting to kernel network performance + statistics. + Version 1.10 (2003-Oct-xx) - Change format of configuration file. Now every plugin has it's own section in the config file, making the whole parsing procedure easier - and diff --git a/README b/README index 3510007..545e7f7 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ Userspace logging facility for iptables / linux 2.4 -$Id: README,v 1.7 2002/04/16 12:44:41 laforge Exp $ +$Id$ Project Homepage: http://www.gnumonks.org/projects/ulogd Mailinglist: http://lists.gnumonks.org/mailman/listinfo/ulogd/ @@ -88,10 +88,10 @@ Setting --ulog-cprange to 0 does always copy the whole packet. Default is 0 ===> COPYRIGHT + CREDITS -The code is (C) 2000-2003 by Harald Welte +The code is (C) 2000-2004 by Harald Welte Thanks also to the valuable Contributions of Daniel Stone, Alexander Janssen and Michael Stolovitzsky. -Credits to Rusty Russel, James Morris, Marc Boucher and all the other +Credits to Rusty Russell, James Morris, Marc Boucher and all the other netfilter hackers. diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h index b3ce46e..7c3aa15 100644 --- a/include/ulogd/ulogd.h +++ b/include/ulogd/ulogd.h @@ -68,9 +68,9 @@ enum ulogd_dtype { }; /* structure describing an input / output parameter of a plugin */ -typedef struct ulogd_key { +struct ulogd_key { /* next interpreter return (key) in the global list */ - struct ulog_iret *next; + struct ulogd_iret *next; /* length of the returned value (only for lengthed types */ u_int32_t len; /* type of the returned value (ULOGD_IRET_...) */ @@ -99,11 +99,11 @@ typedef struct ulogd_key { int64_t i64; void *ptr; } value; - struct ulog_ket *source; + struct ulogd_iret *source; } u; -} ulogd_iret_t; +}; -typedef struct ulogd_plugin { +struct ulogd_plugin { /* global list of plugins */ struct list_head list; /* name of this plugin (predefined by plugin) */ @@ -134,28 +134,33 @@ typedef struct ulogd_plugin { /* function to destruct an existing pluginstance */ int (*destructor)(struct ulogd_pluginstance *instance); /* configuration parameters */ - config_entry_t *configs; -} ulogd_interpreter_t; + struct config_keyest config_kset; +}; /* an instance of a plugin, element in a stack */ -typedef struct ulogd_pluginstance { - /* global list of pluginstance stacks */ +struct ulogd_pluginstance { + /* global list of pluginstance stacks. only valid for first item */ struct list_head stack_list; /* local list of plugins in this stack */ struct list_head list; /* plugin (master) */ struct ulogd_plugin *plugin; + /* name / id of this instance*/ + char id[ULOGD_MAX_KEYLEN]; /* per-instance input keys */ struct ulogd_input *input; /* per-instance output keys */ struct ulogd_iret *output; + /* per-instance config parameters (array) */ + config_entry_t *configs; + unsigned int num_configs; /* private data */ char private[0]; -} ulogd_pluginstance_t; +}; /* entries of the key hash */ struct ulogd_keyh_entry { - ulog_interpreter_t *interp; /* interpreter for this key */ + struct ulogd_plugin *interp; /* interpreter for this key */ unsigned int offset; /* offset within interpreter */ const char *name; /* name of this particular key */ }; @@ -165,10 +170,10 @@ struct ulogd_keyh_entry { ***********************************************************************/ /* register a new interpreter plugin */ -void ulogd_register_plugin(ulog_plugin_t *me); +void ulogd_register_plugin(struct ulogd_plugin *me); -/* allocate a new ulog_iret_t */ -ulog_iret_t *alloc_ret(const u_int16_t type, const char*); +/* allocate a new ulogd_iret */ +struct ulogd_iret *alloc_ret(const u_int16_t type, const char*); /* write a message to the daemons' logfile */ void __ulogd_log(int level, char *file, int line, const char *message, ...); @@ -185,7 +190,7 @@ unsigned int interh_getid(const char *name); unsigned int keyh_getid(const char *name); /* get a result for a given key id */ -ulog_iret_t *keyh_getres(unsigned int id); +struct ulogd_iret *keyh_getres(unsigned int id); /* the key hash itself */ extern struct ulogd_keyh_entry *ulogd_keyh; diff --git a/input/packet/ulogd_inppkt_ULOG.c b/input/packet/ulogd_inppkt_ULOG.c index ee3840d..640b86c 100644 --- a/input/packet/ulogd_inppkt_ULOG.c +++ b/input/packet/ulogd_inppkt_ULOG.c @@ -24,6 +24,33 @@ struct ulog_input { }; /* configuration entries */ + +static struct config_entry ulog_ces[] = { + { + .key = "bufsize", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u.value = ULOGD_BUFSIZE_DEFAULT, + }, + { + .key = "nlgroup", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u.value = ULOGD_NLGROUP_DEFAULT, + }, + { + .key = "rmem", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u.value = ULOGD_RMEM_DEFAULT, + }, +}; + +#define bufsiz_ce(x) (x[0]) +#define nlgroup_ce(x) (x[1]) +#define rmem_cd(x) (x[2]) + +#if 0 static config_entry_t bufsiz_ce = { NULL, "bufsize", CONFIG_TYPE_INT, CONFIG_OPT_NONE, 0, { value: ULOGD_BUFSIZE_DEFAULT } }; @@ -35,6 +62,7 @@ static config_entry_t nlgroup_ce = { &bufsiz_ce, "nlgroup", CONFIG_TYPE_INT, static config_entry_t rmem_ce = { &nlgroup_ce, "rmem", CONFIG_TYPE_INT, CONFIG_OPT_NONE, 0, { value: ULOGD_RMEM_DEFAULT } }; +#endif static struct ulogd_key output_keys[] = { @@ -239,7 +267,8 @@ struct ulogd_plugin libulog_plugin = { }, .constructor = &init, .destructor = &fini, - .configs = &rmem_ce, + .num_configs = (sizeof(ulog_ces)/sizeof(struct config_entry)), + .configs = &ulog_ces, }; void _init(void) diff --git a/output/mysql/ulogd_MYSQL.c b/output/mysql/ulogd_MYSQL.c index 894098f..78c799d 100644 --- a/output/mysql/ulogd_MYSQL.c +++ b/output/mysql/ulogd_MYSQL.c @@ -65,39 +65,45 @@ static char *stmt_val; static char *stmt_ins; /* our configuration directives */ -static config_entry_t db_ce = { - .key = "db", - .type = CONFIG_TYPE_STRING, - .options = CONFIG_OPT_MANDATORY, +static struct config_entry mysql_ces[] = { + { + .key = "db", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_MANDATORY, + }, + { + .key = "host", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_MANDATORY, + }, + { + .key = "user", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_MANDATORY, + }, + { + .key = "pass", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_MANDATORY, + }, + { + .key = "table", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_MANDATORY, + }, }; -static config_entry_t host_ce = { - .next = &db_ce, - .key = "host", - .type = CONFIG_TYPE_STRING, - .options = CONFIG_OPT_MANDATORY, +static struct config_keyset mysql_keyset = { + .num_ces = sizeof(mysql_ces)/sizeof(struct config_entry), + .ces = &mysql_ces, }; -static config_entry_t user_ce = { - .next = &host_ce, - .key = "user", - .type = CONFIG_TYPE_STRING, - .options = CONFIG_OPT_MANDATORY, -}; - -static config_entry_t pass_ce = { - .next = &user_ce, - .key = "pass", - .type = CONFIG_TYPE_STRING, - .options = CONFIG_OPT_MANDATORY, -}; -static config_entry_t table_ce = { - .next = &pass_ce, - .key = "table", - .type = CONFIG_TYPE_STRING, - .options = CONFIG_OPT_MANDATORY, -}; +#define db_ce(x) x[0] +#define host_ce(x) x[1] +#define user_ce(x) x[2] +#define pass_ce(x) x[3] +#define table_ce(x) x[4] /* our main output function, called by ulogd */ static int mysql_output(ulog_iret_t *result) @@ -357,6 +363,7 @@ static ulog_output_t mysql_plugin = { .output = &mysql_output, .init = &mysql_init, .fini = &mysql_fini, + .config_kset = &mysql_keyset, }; void _init(void) diff --git a/output/ulogd_output_OPRINT.c b/output/ulogd_output_OPRINT.c index ea5ff6a..dfcad05 100644 --- a/output/ulogd_output_OPRINT.c +++ b/output/ulogd_output_OPRINT.c @@ -81,9 +81,12 @@ static int oprint_interp(struct ulogd_pluginstance *instance) return 0; } -static config_entry_t outf_ce = { NULL, "file", CONFIG_TYPE_STRING, - CONFIG_OPT_NONE, 0, - { string: ULOGD_OPRINT_DEFAULT } }; +static struct config_entry outf_ce = { + .key = "file", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + .u.string = ULOGD_OPRINT_DEFAULT +}; static void sighup_handler_print(int signal) { @@ -155,6 +158,7 @@ static struct ulogd_plugin oprint_plugin = { .destructor = &oprint_fini, .signal = &sighup_handler_print, .configs = &outf_ce, + .num_configs = 1, }; void _init(void) diff --git a/ulogd.c b/ulogd.c index 50ac6b4..be8804c 100644 --- a/ulogd.c +++ b/ulogd.c @@ -87,10 +87,10 @@ static int loglevel = 1; /* current loglevel */ static char *ulogd_configfile = ULOGD_CONFIGFILE; /* linked list for all registered interpreters */ -//static ulog_interpreter_t *ulogd_interpreters; +//static struct ulog_interpreter *ulogd_interpreters; /* linked list for all registered plugins */ -static ulog_output_t *ulogd_plugins; +static struct ulogd_plugin *ulogd_plugins; LIST_HEAD(ulogd_pi_stacks); /*********************************************************************** @@ -108,7 +108,7 @@ LIST_HEAD(ulogd_pi_stacks); #define INTERH_ALLOC_GRAN 5 /* hashtable for all registered interpreters */ -static ulog_interpreter_t **ulogd_interh; +static struct ulogd_interpreter **ulogd_interh; /* current hashtable size */ static unsigned int ulogd_interh_ids_alloc; @@ -117,7 +117,7 @@ static unsigned int ulogd_interh_ids_alloc; static unsigned int ulogd_interh_ids; /* allocate a new interpreter id and write it into the interpreter struct */ -static unsigned int interh_allocid(ulog_interpreter_t *ip) +static unsigned int interh_allocid(struct ulogd_interpreter *ip) { unsigned int id; @@ -125,15 +125,15 @@ static unsigned int interh_allocid(ulog_interpreter_t *ip) if (id >= ulogd_interh_ids_alloc) { if (!ulogd_interh) - ulogd_interh = (ulog_interpreter_t **) + ulogd_interh = (struct ulogd_interpreter **) malloc(INTERH_ALLOC_GRAN * - sizeof(ulog_interpreter_t)); + sizeof(struct ulogd_interpreter)); else - ulogd_interh = (ulog_interpreter_t **) + ulogd_interh = (struct ulogd_interpreter **) realloc(ulogd_interh, (INTERH_ALLOC_GRAN + ulogd_interh_ids_alloc) * - sizeof(ulog_interpreter_t)); + sizeof(struct ulogd_interpreter)); ulogd_interh_ids_alloc += INTERH_ALLOC_GRAN; } @@ -180,7 +180,7 @@ static unsigned int ulogd_keyh_ids_alloc; static unsigned int ulogd_keyh_ids; /* allocate a new key_id */ -static unsigned int keyh_allocid(ulog_interpreter_t *ip, unsigned int offset, +static unsigned int keyh_allocid(struct ulogd_interpreter *ip, unsigned int offset, const char *name) { unsigned int id; @@ -255,9 +255,9 @@ char *keyh_getname(unsigned int id) } /* get result for given key id. does not check if result valid */ -ulog_iret_t *keyh_getres(unsigned int id) +struct ulogd_iret *keyh_getres(unsigned int id) { - ulog_iret_t *ret; + struct ulogd_iret *ret; if (id > ulogd_keyh_ids) { ulogd_log(ULOGD_NOTICE, @@ -275,7 +275,7 @@ ulog_iret_t *keyh_getres(unsigned int id) ***********************************************************************/ /* try to lookup a registered interpreter for a given name */ -static ulog_interpreter_t *find_interpreter(const char *name) +static struct ulogd_interpreter *find_interpreter(const char *name) { unsigned int id; @@ -288,7 +288,7 @@ static ulog_interpreter_t *find_interpreter(const char *name) /* the function called by all interpreter plugins for registering their * target. */ -void register_interpreter(ulog_interpreter_t *me) +void register_interpreter(struct ulogd_interpreter *me) { unsigned int i; @@ -334,9 +334,9 @@ void register_interpreter(ulog_interpreter_t *me) ***********************************************************************/ /* try to lookup a registered plugin for a given name */ -static ulog_plugin_t *find_plugin(const char *name) +static struct ulogd_plugin *find_plugin(const char *name) { - ulog_output_t *ptr; + struct ulogd_plugin *ptr; for (ptr = ulogd_outputs; ptr; ptr = ptr->next) { if (strcmp(name, ptr->name) == 0) @@ -347,7 +347,7 @@ static ulog_plugin_t *find_plugin(const char *name) } /* the function called by all plugins for registering themselves */ -void register_plugin(ulog_plugin_t *me) +void register_plugin(struct ulogd_plugin *me) { if (find_plugin(me->name)) { ulogd_log(ULOGD_NOTICE, "output `%s' already registered\n", @@ -395,9 +395,9 @@ void __ulogd_log(int level, char *file, int line, const char *format, ...) } /* propagate results to all registered output plugins */ -static void propagate_results(ulog_iret_t *ret) +static void propagate_results(struct ulogd_iret *ret) { - ulog_output_t *p; + struct ulogd_plugin *p; for (p = ulogd_outputs; p; p = p->next) { (*p->output)(ret); @@ -405,9 +405,9 @@ static void propagate_results(ulog_iret_t *ret) } /* clean results (set all values to 0 and free pointers) */ -static void clean_results(ulog_iret_t *ret) +static void clean_results(struct ulogd_iret *ret) { - ulog_iret_t *r; + struct ulogd_iret *r; for (r = ret; r; r = r->next) { if (r->flags & ULOGD_RETF_FREE) { @@ -421,17 +421,37 @@ static void clean_results(ulog_iret_t *ret) -static int ulogd_pluginstance_t *ulogd_pluginsance_alloc(int len) +static struct ulogd_pluginstance * +pluginstance_alloc_init(struct ulogd_plugin *pl, char *pi_id, + struct ulogd_pluginstance *stack) { - ulogd_pluginstance_t *pi = malloc(sizeof(ulogd_pluginstance_t)+len); + unsigned int ce_size; + struct ulogd_pluginstance *pi = malloc(sizeof(struct ulogd_pluginstance)+len); if (!pi) return NULL; - memset(pi, 0, sizeof(ulogd_pluginstance_t)+len); + + /* initialize */ + memset(pi, 0, sizeof(struct ulogd_pluginstance)+len); INIT_LIST_HEAD(&pi->list); + pi->plugin = pl; + memcpy(pi->id, pi_id, sizeof(pi->id)); + + /* copy config keys */ + pi->config_kset.num_ces = pl->config_kset.num_ces; + ce_size = pl->config_kset.num_ces*sizeof(struct config_entry); + pi->config_kset.ces = malloc(ce_size); + if (!pi->configs) { + free(pi); + return NULL; + } + memcpy(pi->config_kset.ces, pl->config_kset.ces, ce_size); + /* FIXME: allocate input and output keys ?*/ + return pi; } + /* plugin loader to dlopen() a plugins */ static int load_plugin(char *file) { @@ -446,7 +466,7 @@ static int load_plugin(char *file) /* create a new stack of plugins */ static int create_stack(char *option) { - ulogd_pluginstance_t *stack = NULL; + struct ulogd_pluginstance *stack = NULL; char *buf = strdup(option); char *tok; @@ -457,19 +477,43 @@ static int create_stack(char *option) ulogd_log(ULOGD_DEBUG, "building new pluginstance stack:\n"); - for (tok = strtok(buf, ":\n"); tok; tok = strtok(NULL, ":\n")) { - ulogd_pluginstance_t *pi = ulogd_pluginstance_alloc(0); - ulogd_plugin_t *pl = find_plugin(tok); + for (tok = strtok(buf, ",\n"); tok; tok = strtok(NULL, ",\n")) { + char *plname, *equals; + char pi_id[ULOGD_MAX_KEYLEN]; + struct ulogd_pluginstance *pi; + struct ulogd_plugin *pl; + + /* parse token into sub-tokens */ + equals = strchr(tok, '='); + if (!equals || (equals - tok >= ULOGD_MAX_KEYLEN)) { + ulogd_log(ULOGD_ERROR, "syntax error while parsing `%s'" + "of line `%s'\n", tok, buf); + } + strncpy(pi_id, tok, ULOGD_MAX_KEYLEN-1); + pi_id[equals-tok] = '\0'; + plname = equals+1; + + /* find matching plugin */ + pl = find_plugin(plname); if (!pl) { ulogd_log(ULOGD_ERROR, "can't find requested plugin " "%s\n", ); return 1; } - pi->plugin = pl; - ulogd_log(ULOGD_DEBUG, "pushing `%s' on stack\n", pl->name); - /* FIXME: allocate input and output keys */ + /* allocate */ + pi = ulogd_pluginstance_alloc_init(pl. pi_id, stack); + if (!pi) { + ulogd_log(ULOGD_ERROR, + "unable to allocate pluginstance for %s\n", + pi_id); + return 1; + } + /* FIXME: call constructor routine from end to beginning, + * fix up input/output keys */ + + ulogd_log(ULOGD_DEBUG, "pushing `%s' on stack\n", pl->name); if (!stack) stack = pi; else @@ -498,7 +542,7 @@ static int logfile_open(const char *name) } /* wrapper to handle conffile error codes */ -static int parse_conffile(const char *section, config_entry_t *ce) +static int parse_conffile(const char *section, struct config_keyset *ce) { int err; @@ -538,42 +582,47 @@ static int parse_conffile(const char *section, config_entry_t *ce) } /* configuration directives of the main program */ -static config_entry_t logf_ce = { - .next = NULL, - .key = "logfile", - .type = CONFIG_TYPE_STRING, - .options = CONFIG_OPT_NONE, - .u.string = ULOGD_LOGFILE_DEFAULT, -}; - -static config_entry_t plugin_ce = { - .next = &logf_ce, - .key = "plugin", - .type = CONFIG_TYPE_CALLBACK, - .options = CONFIG_OPT_MULTI, - .u.parser: &load_plugin, +static struct config_entry ulogd_ces[] = { + { + .key = "logfile", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + .u.string = ULOGD_LOGFILE_DEFAULT, + }, + { + .key = "plugin", + .type = CONFIG_TYPE_CALLBACK, + .options = CONFIG_OPT_MULTI, + .u.parser = &load_plugin, + }, + { + .key = "loglevel", + .type = CONFIG_TYPE_INT, + .options = CONFIG_OPT_NONE, + .u.value = 1, + }, + { + .key = "stack", + .type = CONFIG_TYPE_CALLBACK, + .options = CONFIG_OPT_NONE, + .u.parser = &create_stack, + }, }; -static config_entry_t loglevel_ce = { - .next = &logf_ce, - .key = "loglevel", - .type = CONFIG_TYPE_INT, - .options = CONFIG_OPT_NONE, - .u.value = 1, +static struct config_keyset ulogd_kset = { + .ces = &ulogd_ces, + .num_ces = sizeof(ulogd_ces)/sizeof(struct config_entry), }; -static config_entry_t stack_ce = { - .next = &loglevel_ce, - .key = "stack", - .type = CONFIG_TYPE_CALLBACK, - .options = CONFIG_OPT_NONE, - .u.parser = &create_stack, -}; +#define logfile_ce ulogd_ces[0] +#define plugin_ce ulogd_ces[1] +#define loglevel_ce ulogd_ces[2] +#define stack_ce ulogd_ces[3] static void sigterm_handler(int signal) { - ulog_output_t *p; + struct ulogd_plugin *p; ulogd_log(ULOGD_NOTICE, "sigterm received, exiting\n"); @@ -592,7 +641,7 @@ static void sigterm_handler(int signal) static void sighup_handler(int signal) { - ulog_output_t *p; + struct ulogd_plugin *p; if (logfile != stdout) { fclose(logfile); @@ -697,7 +746,7 @@ int main(int argc, char* argv[]) } /* parse config file */ - if (parse_conffile("global", &logf_ce)) { + if (parse_conffile("global", &ulogd_kset)) { ulogd_log(ULOGD_FATAL, "parse_conffile\n"); exit(1); } @@ -705,12 +754,13 @@ int main(int argc, char* argv[]) if (change_uid) { ulogd_log(ULOGD_NOTICE, "Changing UID / GID\n"); if (setgid(gid)) { - ulogd_log(ULOGD_FATAL, "can't set GID\n"); + ulogd_log(ULOGD_FATAL, "can't set GID %u\n", gid); ipulog_perror(NULL); exit(1); } if (setegid(gid)) { - ulogd_log(ULOGD_FATAL, "can't sett effective GID\n"); + ulogd_log(ULOGD_FATAL, "can't sett effective GID %u\n", + gid); ipulog_perror(NULL); exit(1); } @@ -720,12 +770,13 @@ int main(int argc, char* argv[]) exit(1); } if (setuid(uid)) { - ulogd_log(ULOGD_FATAL, "can't set UID\n"); + ulogd_log(ULOGD_FATAL, "can't set UID %u\n", uid); ipulog_perror(NULL); exit(1); } if (seteuid(uid)) { - ulogd_log(ULOGD_FATAL, "can't set effective UID\n"); + ulogd_log(ULOGD_FATAL, "can't set effective UID %u\n", + uid); ipulog_perror(NULL); exit(1); } -- cgit v1.2.3