diff options
Diffstat (limited to 'output')
-rw-r--r-- | output/Makefile.am | 35 | ||||
-rw-r--r-- | output/dbi/Makefile.am | 10 | ||||
-rw-r--r-- | output/dbi/ulogd_output_DBI.c | 82 | ||||
-rw-r--r-- | output/ipfix/Makefile.am | 5 | ||||
-rw-r--r-- | output/ipfix/ipfix.c | 6 | ||||
-rw-r--r-- | output/ipfix/ipfix.h | 8 | ||||
-rw-r--r-- | output/ipfix/ulogd_output_IPFIX.c | 12 | ||||
-rw-r--r-- | output/mysql/Makefile.am | 9 | ||||
-rw-r--r-- | output/mysql/ulogd_output_MYSQL.c | 20 | ||||
-rw-r--r-- | output/pcap/Makefile.am | 8 | ||||
-rw-r--r-- | output/pcap/ulogd_output_PCAP.c | 50 | ||||
-rw-r--r-- | output/pgsql/Makefile.am | 10 | ||||
-rw-r--r-- | output/pgsql/ulogd_output_PGSQL.c | 64 | ||||
-rw-r--r-- | output/sqlite3/Makefile.am | 7 | ||||
-rw-r--r-- | output/sqlite3/ulogd_output_SQLITE3.c | 97 | ||||
-rw-r--r-- | output/ulogd_output_GPRINT.c | 38 | ||||
-rw-r--r-- | output/ulogd_output_JSON.c | 86 | ||||
-rw-r--r-- | output/ulogd_output_OPRINT.c | 89 | ||||
-rw-r--r-- | output/ulogd_output_XML.c | 33 |
19 files changed, 357 insertions, 312 deletions
diff --git a/output/Makefile.am b/output/Makefile.am index 7ba8217..cdb49df 100644 --- a/output/Makefile.am +++ b/output/Makefile.am @@ -1,8 +1,35 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include ${LIBNETFILTER_ACCT_CFLAGS} \ - ${LIBNETFILTER_CONNTRACK_CFLAGS} ${LIBNETFILTER_LOG_CFLAGS} -AM_CFLAGS = ${regular_CFLAGS} +if HAVE_PCAP + OPT_SUBDIR_PCAP = pcap +endif + +if HAVE_MYSQL + OPT_SUBDIR_MYSQL = mysql +endif + +if HAVE_PGSQL + OPT_SUBDIR_PGSQL = pgsql +endif + +if HAVE_SQLITE3 + OPT_SUBDIR_SQLITE3 = sqlite3 +endif + +if HAVE_DBI + OPT_SUBDIR_DBI = dbi +endif + +SUBDIRS = $(OPT_SUBDIR_PCAP) \ + $(OPT_SUBDIR_MYSQL) \ + $(OPT_SUBDIR_PGSQL) \ + $(OPT_SUBDIR_SQLITE3) \ + $(OPT_SUBDIR_DBI) \ + ipfix + +include $(top_srcdir)/Make_global.am -SUBDIRS= pcap mysql pgsql sqlite3 dbi ipfix +AM_CPPFLAGS += ${LIBNETFILTER_ACCT_CFLAGS} \ + ${LIBNETFILTER_CONNTRACK_CFLAGS} \ + ${LIBNETFILTER_LOG_CFLAGS} pkglib_LTLIBRARIES = ulogd_output_LOGEMU.la ulogd_output_SYSLOG.la \ ulogd_output_OPRINT.la ulogd_output_GPRINT.la \ diff --git a/output/dbi/Makefile.am b/output/dbi/Makefile.am index f413cab..9a618b1 100644 --- a/output/dbi/Makefile.am +++ b/output/dbi/Makefile.am @@ -1,13 +1,9 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include $(DBI_INC) -AM_CFLAGS = ${regular_CFLAGS} - -if HAVE_DBI +AM_CPPFLAGS += $(libdbi_CFLAGS) pkglib_LTLIBRARIES = ulogd_output_DBI.la ulogd_output_DBI_la_SOURCES = ulogd_output_DBI.c ../../util/db.c -ulogd_output_DBI_la_LIBADD = ${DBI_LIB} +ulogd_output_DBI_la_LIBADD = $(libdbi_LIBS) ulogd_output_DBI_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/dbi/ulogd_output_DBI.c b/output/dbi/ulogd_output_DBI.c index d2a9682..88af7a1 100644 --- a/output/dbi/ulogd_output_DBI.c +++ b/output/dbi/ulogd_output_DBI.c @@ -29,6 +29,8 @@ #define DEBUGP(x, args...) #endif +static dbi_inst libdbi_instance; + struct dbi_instance { struct db_instance db_inst; @@ -89,15 +91,6 @@ static struct config_keyset dbi_kset = { #define dbtype_ce(x) (x->ces[DB_CE_NUM+6]) -/* lower-cases s in place */ -static void str_tolower(char *s) -{ - while(*s) { - *s = tolower(*s); - s++; - } -} - /* find out which columns the table has */ static int get_columns_dbi(struct ulogd_pluginstance *upi) { @@ -129,8 +122,7 @@ static int get_columns_dbi(struct ulogd_pluginstance *upi) upi->input.num_keys = dbi_result_get_numfields(pi->result); ulogd_log(ULOGD_DEBUG, "%u fields in table\n", upi->input.num_keys); - upi->input.keys = malloc(sizeof(struct ulogd_key) * - upi->input.num_keys); + upi->input.keys = calloc(upi->input.num_keys, sizeof(*upi->input.keys)); if (!upi->input.keys) { upi->input.num_keys = 0; ulogd_log(ULOGD_ERROR, "ENOMEM\n"); @@ -138,28 +130,26 @@ static int get_columns_dbi(struct ulogd_pluginstance *upi) return -ENOMEM; } - memset(upi->input.keys, 0, sizeof(struct ulogd_key) * - upi->input.num_keys); - for (ui=1; ui<=upi->input.num_keys; ui++) { - char buf[ULOGD_MAX_KEYLEN+1]; - char *underscore; - const char* field_name = dbi_result_get_field_name(pi->result, ui); + const char *field_name = dbi_result_get_field_name(pi->result, ui); + char *cp; if (!field_name) break; - /* replace all underscores with dots */ - strncpy(buf, field_name, ULOGD_MAX_KEYLEN); - while ((underscore = strchr(buf, '_'))) - *underscore = '.'; - - str_tolower(buf); + snprintf(upi->input.keys[ui - 1].name, + sizeof(upi->input.keys[ui - 1].name), + "%s", field_name); - DEBUGP("field '%s' found: ", buf); + /* down-case and replace all underscores with dots */ + for (cp = upi->input.keys[ui - 1].name; *cp; cp++) { + if (*cp == '_') + *cp = '.'; + else + *cp = tolower(*cp); + } - /* add it to list of input keys */ - strncpy(upi->input.keys[ui-1].name, buf, ULOGD_MAX_KEYLEN); + DEBUGP("field '%s' found: ", upi->input.keys[ui - 1].name); } /* ID is a sequence */ @@ -177,7 +167,6 @@ static int close_db_dbi(struct ulogd_pluginstance *upi) ulogd_log(ULOGD_DEBUG, "dbi: closing connection\n"); dbi_conn_close(pi->dbh); pi->dbh = NULL; - //dbi_shutdown(); return 0; } @@ -187,9 +176,9 @@ static int open_db_dbi(struct ulogd_pluginstance *upi) { struct dbi_instance *pi = (struct dbi_instance *) upi->private; char *server = host_ce(upi->config_kset).u.string; - char *user = user_ce(upi->config_kset).u.string; - char *pass = pass_ce(upi->config_kset).u.string; - char *db = db_ce(upi->config_kset).u.string; + char *user = user_ce(upi->config_kset).u.string; + char *pass = pass_ce(upi->config_kset).u.string; + char *db = db_ce(upi->config_kset).u.string; char *dbtype = dbtype_ce(upi->config_kset).u.string; dbi_driver driver; int ret; @@ -199,14 +188,14 @@ static int open_db_dbi(struct ulogd_pluginstance *upi) ulogd_log(ULOGD_ERROR, "Opening connection for db type %s\n", dbtype); - driver = dbi_driver_open(dbtype); + driver = dbi_driver_open_r(dbtype, libdbi_instance); if (driver == NULL) { ulogd_log(ULOGD_ERROR, "unable to load driver for db type %s\n", dbtype); close_db_dbi(upi); return -1; } - pi->dbh = dbi_conn_new(dbtype); + pi->dbh = dbi_conn_new_r(dbtype, libdbi_instance); if (pi->dbh == NULL) { ulogd_log(ULOGD_ERROR, "unable to initialize db type %s\n", dbtype); @@ -214,13 +203,13 @@ static int open_db_dbi(struct ulogd_pluginstance *upi) return -1; } - if (server) + if (server[0]) dbi_conn_set_option(pi->dbh, "host", server); - if (user) + if (user[0]) dbi_conn_set_option(pi->dbh, "username", user); - if (pass) + if (pass[0]) dbi_conn_set_option(pi->dbh, "password", pass); - if (db) + if (db[0]) dbi_conn_set_option(pi->dbh, "dbname", db); ret = dbi_conn_connect(pi->dbh); @@ -247,18 +236,20 @@ static int escape_string_dbi(struct ulogd_pluginstance *upi, } ret = dbi_conn_quote_string_copy(pi->dbh, src, &newstr); - if (ret <= 2) + if (ret == 0) { + *dst = '\0'; return 0; + } /* dbi_conn_quote_string_copy returns a quoted string, * but __interp_db already quotes the string * So we return a string without the quotes */ - strncpy(dst,newstr+1,ret-2); - dst[ret-2] = '\0'; + memcpy(dst, newstr + 1, ret - 2); + dst[ret - 2] = '\0'; free(newstr); - return (ret-2); + return ret - 2; } static int execute_dbi(struct ulogd_pluginstance *upi, @@ -320,11 +311,14 @@ static struct ulogd_plugin dbi_plugin = { .version = VERSION, }; -void __attribute__ ((constructor)) init(void); - -void init(void) +void __attribute__ ((constructor)) init(void) { - dbi_initialize(NULL); + dbi_initialize_r(NULL, &libdbi_instance); ulogd_register_plugin(&dbi_plugin); } + +void __attribute__ ((destructor)) fini(void) +{ + dbi_shutdown_r(libdbi_instance); +} diff --git a/output/ipfix/Makefile.am b/output/ipfix/Makefile.am index cacda26..882de85 100644 --- a/output/ipfix/Makefile.am +++ b/output/ipfix/Makefile.am @@ -1,5 +1,6 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = $(regular_CFLAGS) +include $(top_srcdir)/Make_global.am + +noinst_HEADERS = ipfix.h pkglib_LTLIBRARIES = ulogd_output_IPFIX.la diff --git a/output/ipfix/ipfix.c b/output/ipfix/ipfix.c index 4bb432a..e0b3440 100644 --- a/output/ipfix/ipfix.c +++ b/output/ipfix/ipfix.c @@ -8,8 +8,6 @@ /* These forward declarations are needed since ulogd.h doesn't like to be the first */ #include <ulogd/linuxlist.h> -#define __packed __attribute__((packed)) - #include "ipfix.h" #include <ulogd/ulogd.h> @@ -85,8 +83,7 @@ struct ipfix_msg *ipfix_msg_alloc(size_t len, uint32_t oid, int tid) (len < IPFIX_HDRLEN + IPFIX_SET_HDRLEN)) return NULL; - msg = malloc(sizeof(struct ipfix_msg) + len); - memset(msg, 0, sizeof(struct ipfix_msg)); + msg = calloc(1, sizeof(struct ipfix_msg) + len); msg->tid = tid; msg->end = msg->data + len; msg->tail = msg->data + IPFIX_HDRLEN; @@ -95,7 +92,6 @@ struct ipfix_msg *ipfix_msg_alloc(size_t len, uint32_t oid, int tid) /* Initialize message header */ hdr = ipfix_msg_hdr(msg); - memset(hdr, 0, IPFIX_HDRLEN); hdr->version = htons(IPFIX_VERSION); hdr->oid = htonl(oid); diff --git a/output/ipfix/ipfix.h b/output/ipfix/ipfix.h index 93945fb..b0f3ae6 100644 --- a/output/ipfix/ipfix.h +++ b/output/ipfix/ipfix.h @@ -19,7 +19,7 @@ struct ipfix_hdr { uint32_t seqno; uint32_t oid; /* Observation Domain ID */ uint8_t data[]; -} __packed; +} __attribute__((packed)); #define IPFIX_HDRLEN sizeof(struct ipfix_hdr) @@ -32,7 +32,7 @@ struct ipfix_templ_hdr { uint16_t tid; uint16_t cnt; uint8_t data[]; -} __packed; +} __attribute__((packed)); #define IPFIX_TEMPL_HDRLEN(nfields) sizeof(struct ipfix_templ_hdr) + (sizeof(uint16_t) * 2 * nfields) @@ -42,7 +42,7 @@ struct ipfix_set_hdr { uint16_t id; uint16_t len; uint8_t data[]; -} __packed; +} __attribute__((packed)); #define IPFIX_SET_HDRLEN sizeof(struct ipfix_set_hdr) @@ -67,7 +67,7 @@ struct vy_ipfix_data { uint16_t dport; uint8_t l4_proto; uint32_t aid; /* Application ID */ -} __packed; +} __attribute__((packed)); #define VY_IPFIX_SID 256 diff --git a/output/ipfix/ulogd_output_IPFIX.c b/output/ipfix/ulogd_output_IPFIX.c index 5b59003..1c0f730 100644 --- a/output/ipfix/ulogd_output_IPFIX.c +++ b/output/ipfix/ulogd_output_IPFIX.c @@ -198,7 +198,8 @@ static int send_msgs(struct ulogd_pluginstance *pi) struct ipfix_priv *priv = (struct ipfix_priv *) &pi->private; struct llist_head *curr, *tmp; struct ipfix_msg *msg; - int ret = ULOGD_IRET_OK, sent; + int ret = ULOGD_IRET_OK; + ssize_t sent; llist_for_each_prev(curr, &priv->list) { msg = llist_entry(curr, struct ipfix_msg, link); @@ -212,8 +213,8 @@ static int send_msgs(struct ulogd_pluginstance *pi) /* TODO handle short send() for other protocols */ if ((size_t) sent < ipfix_msg_len(msg)) - ulogd_log(ULOGD_ERROR, "short send: %d < %d\n", - sent, ipfix_msg_len(msg)); + ulogd_log(ULOGD_ERROR, "short send: %zd < %zu\n", + sent, ipfix_msg_len(msg)); } llist_for_each_safe(curr, tmp, &priv->list) { @@ -242,7 +243,7 @@ static int ipfix_ufd_cb(int fd, unsigned what, void *arg) ulogd_log(ULOGD_INFO, "connection reset by peer\n"); ulogd_unregister_fd(&priv->ufd); } else - ulogd_log(ULOGD_INFO, "unexpected data (%d bytes)\n", nread); + ulogd_log(ULOGD_INFO, "unexpected data (%zd bytes)\n", nread); } return 0; @@ -425,6 +426,9 @@ static int ipfix_interp(struct ulogd_pluginstance *pi) if (!(GET_FLAGS(pi->input.keys, InIpSaddr) & ULOGD_RETF_VALID)) return ULOGD_IRET_OK; + if (GET_LENGTH(pi->input.keys, InIpSaddr) != sizeof(data->saddr)) + return ULOGD_IRET_OK; + oid = oid_ce(pi->config_kset).u.value; mtu = mtu_ce(pi->config_kset).u.value; send_template = send_template_ce(pi->config_kset).u.string; diff --git a/output/mysql/Makefile.am b/output/mysql/Makefile.am index c24208c..69d9839 100644 --- a/output/mysql/Makefile.am +++ b/output/mysql/Makefile.am @@ -1,12 +1,9 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include $(MYSQL_INC) -AM_CFLAGS = ${regular_CFLAGS} +include $(top_srcdir)/Make_global.am -if HAVE_MYSQL +AM_CPPFLAGS += $(libmysqlclient_CFLAGS) pkglib_LTLIBRARIES = ulogd_output_MYSQL.la ulogd_output_MYSQL_la_SOURCES = ulogd_output_MYSQL.c ../../util/db.c -ulogd_output_MYSQL_la_LIBADD = ${MYSQL_LIB} +ulogd_output_MYSQL_la_LIBADD = $(libmysqlclient_LIBS) ulogd_output_MYSQL_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/mysql/ulogd_output_MYSQL.c b/output/mysql/ulogd_output_MYSQL.c index 643320c..9727e30 100644 --- a/output/mysql/ulogd_output_MYSQL.c +++ b/output/mysql/ulogd_output_MYSQL.c @@ -127,30 +127,26 @@ static int get_columns_mysql(struct ulogd_pluginstance *upi) upi->input.num_keys = mysql_num_fields(result); ulogd_log(ULOGD_DEBUG, "%u fields in table\n", upi->input.num_keys); - upi->input.keys = malloc(sizeof(struct ulogd_key) * - upi->input.num_keys); + upi->input.keys = calloc(upi->input.num_keys, sizeof(*upi->input.keys)); if (!upi->input.keys) { upi->input.num_keys = 0; ulogd_log(ULOGD_ERROR, "ENOMEM\n"); return -ENOMEM; } - - memset(upi->input.keys, 0, sizeof(struct ulogd_key) * - upi->input.num_keys); for (i = 0; (field = mysql_fetch_field(result)); i++) { - char buf[ULOGD_MAX_KEYLEN+1]; char *underscore; + snprintf(upi->input.keys[i].name, + sizeof(upi->input.keys[i].name), + "%s", field->name); + /* replace all underscores with dots */ - strncpy(buf, field->name, ULOGD_MAX_KEYLEN); - while ((underscore = strchr(buf, '_'))) + for (underscore = upi->input.keys[i].name; + (underscore = strchr(underscore, '_')); ) *underscore = '.'; - DEBUGP("field '%s' found\n", buf); - - /* add it to list of input keys */ - strncpy(upi->input.keys[i].name, buf, ULOGD_MAX_KEYLEN); + DEBUGP("field '%s' found\n", upi->input.keys[i].name); } /* MySQL Auto increment ... ID :) */ upi->input.keys[0].flags |= ULOGD_KEYF_INACTIVE; diff --git a/output/pcap/Makefile.am b/output/pcap/Makefile.am index c1723a6..b5064ea 100644 --- a/output/pcap/Makefile.am +++ b/output/pcap/Makefile.am @@ -1,13 +1,9 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = ${regular_CFLAGS} - -if HAVE_PCAP +AM_CPPFLAGS += $(libpcap_CFLAGS) pkglib_LTLIBRARIES = ulogd_output_PCAP.la ulogd_output_PCAP_la_SOURCES = ulogd_output_PCAP.c ulogd_output_PCAP_la_LIBADD = ${libpcap_LIBS} ulogd_output_PCAP_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/pcap/ulogd_output_PCAP.c b/output/pcap/ulogd_output_PCAP.c index e7798f2..19ce47f 100644 --- a/output/pcap/ulogd_output_PCAP.c +++ b/output/pcap/ulogd_output_PCAP.c @@ -220,33 +220,26 @@ 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) { - pi->of = fopen(filename, "w"); - if (!pi->of) { - ulogd_log(ULOGD_ERROR, "can't open pcap file %s: %s\n", - filename, - strerror(errno)); - return -EPERM; - } - if (!write_pcap_header(pi)) { - ulogd_log(ULOGD_ERROR, "can't write pcap header: %s\n", - strerror(errno)); - return -ENOSPC; - } - } else { - pi->of = fopen(filename, "a"); - if (!pi->of) { - ulogd_log(ULOGD_ERROR, "can't open pcap file %s: %s\n", - filename, - strerror(errno)); - return -EPERM; - } + struct stat st_of; + FILE *of; + + of = fopen(filename, "a"); + if (!of) { + ulogd_log(ULOGD_ERROR, "can't open pcap file %s: %s\n", + filename, + strerror(errno)); + return -EPERM; + } + + if (pi->of) + fclose(pi->of); + pi->of = of; + + if (fstat(fileno(pi->of), &st_of) == 0 && st_of.st_size == 0 && + !write_pcap_header(pi)) { + ulogd_log(ULOGD_ERROR, "can't write pcap header: %s\n", + strerror(errno)); + return -ENOSPC; } return 0; @@ -254,12 +247,9 @@ static int append_create_outfile(struct ulogd_pluginstance *upi) static void signal_pcap(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: diff --git a/output/pgsql/Makefile.am b/output/pgsql/Makefile.am index bdaf1d2..c78a773 100644 --- a/output/pgsql/Makefile.am +++ b/output/pgsql/Makefile.am @@ -1,13 +1,9 @@ +include $(top_srcdir)/Make_global.am -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(PQINCPATH) -AM_CFLAGS = ${regular_CFLAGS} - -if HAVE_PGSQL +AM_CPPFLAGS += $(libpq_CFLAGS) pkglib_LTLIBRARIES = ulogd_output_PGSQL.la ulogd_output_PGSQL_la_SOURCES = ulogd_output_PGSQL.c ../../util/db.c -ulogd_output_PGSQL_la_LIBADD = ${PQLIBS} +ulogd_output_PGSQL_la_LIBADD = $(libpq_LIBS) ulogd_output_PGSQL_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/pgsql/ulogd_output_PGSQL.c b/output/pgsql/ulogd_output_PGSQL.c index fda289e..04c2665 100644 --- a/output/pgsql/ulogd_output_PGSQL.c +++ b/output/pgsql/ulogd_output_PGSQL.c @@ -181,8 +181,7 @@ static int get_columns_pgsql(struct ulogd_pluginstance *upi) upi->input.num_keys = PQntuples(pi->pgres); ulogd_log(ULOGD_DEBUG, "%u fields in table\n", upi->input.num_keys); - upi->input.keys = malloc(sizeof(struct ulogd_key) * - upi->input.num_keys); + upi->input.keys = calloc(upi->input.num_keys, sizeof(*upi->input.keys)); if (!upi->input.keys) { upi->input.num_keys = 0; ulogd_log(ULOGD_ERROR, "ENOMEM\n"); @@ -190,22 +189,19 @@ static int get_columns_pgsql(struct ulogd_pluginstance *upi) return -ENOMEM; } - memset(upi->input.keys, 0, sizeof(struct ulogd_key) * - upi->input.num_keys); - for (i = 0; i < PQntuples(pi->pgres); i++) { - char buf[ULOGD_MAX_KEYLEN+1]; char *underscore; + snprintf(upi->input.keys[i].name, + sizeof(upi->input.keys[i].name), + "%s", PQgetvalue(pi->pgres, i, 0)); + /* replace all underscores with dots */ - strncpy(buf, PQgetvalue(pi->pgres, i, 0), ULOGD_MAX_KEYLEN); - while ((underscore = strchr(buf, '_'))) + for (underscore = upi->input.keys[i].name; + (underscore = strchr(underscore, '_')); ) *underscore = '.'; - DEBUGP("field '%s' found: ", buf); - - /* add it to list of input keys */ - strncpy(upi->input.keys[i].name, buf, ULOGD_MAX_KEYLEN); + DEBUGP("field '%s' found\n", upi->input.keys[i].name); } /* ID (starting by '.') is a sequence */ @@ -236,48 +232,38 @@ static int open_db_pgsql(struct ulogd_pluginstance *upi) char *schema = NULL; char pgbuf[128]; - if (!connstr) { - char *server = host_ce(upi->config_kset).u.string; - unsigned int port = port_ce(upi->config_kset).u.value; - char *user = user_ce(upi->config_kset).u.string; - char *pass = pass_ce(upi->config_kset).u.string; - char *db = db_ce(upi->config_kset).u.string; + if (!connstr[0]) { + char *server = host_ce(upi->config_kset).u.string; + unsigned int port = port_ce(upi->config_kset).u.value; + char *user = user_ce(upi->config_kset).u.string; + char *pass = pass_ce(upi->config_kset).u.string; + char *db = db_ce(upi->config_kset).u.string; + char *cp; /* 80 is more than what we need for the fixed parts below */ len = 80 + strlen(user) + strlen(db); /* hostname and and password are the only optionals */ - if (server) + if (server[0]) len += strlen(server); - if (pass) + if (pass[0]) len += strlen(pass); if (port) len += 20; - connstr = (char *) malloc(len); + cp = connstr = malloc(len); if (!connstr) return -ENOMEM; - connstr[0] = '\0'; - if (server && strlen(server) > 0) { - strcpy(connstr, " host="); - strcat(connstr, server); - } + if (server[0]) + cp += sprintf(cp, "host=%s ", server); - if (port) { - char portbuf[20]; - snprintf(portbuf, sizeof(portbuf), " port=%u", port); - strcat(connstr, portbuf); - } + if (port) + cp += sprintf(cp, "port=%u ", port); - strcat(connstr, " dbname="); - strcat(connstr, db); - strcat(connstr, " user="); - strcat(connstr, user); + cp += sprintf(cp, "dbname=%s user=%s", db, user); - if (pass) { - strcat(connstr, " password="); - strcat(connstr, pass); - } + if (pass[0]) + cp += sprintf(cp, " password=%s", pass); } pi->dbh = PQconnectdb(connstr); if (PQstatus(pi->dbh) != CONNECTION_OK) { diff --git a/output/sqlite3/Makefile.am b/output/sqlite3/Makefile.am index 62af267..72fd1a6 100644 --- a/output/sqlite3/Makefile.am +++ b/output/sqlite3/Makefile.am @@ -1,12 +1,9 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include ${libsqlite3_CFLAGS} -AM_CFLAGS = ${regular_CFLAGS} +include $(top_srcdir)/Make_global.am -if HAVE_SQLITE3 +AM_CPPFLAGS += ${libsqlite3_CFLAGS} pkglib_LTLIBRARIES = ulogd_output_SQLITE3.la ulogd_output_SQLITE3_la_SOURCES = ulogd_output_SQLITE3.c ../../util/db.c ulogd_output_SQLITE3_la_LIBADD = ${libsqlite3_LIBS} ulogd_output_SQLITE3_la_LDFLAGS = -avoid-version -module - -endif diff --git a/output/sqlite3/ulogd_output_SQLITE3.c b/output/sqlite3/ulogd_output_SQLITE3.c index 20ceb3b..6aeb7a3 100644 --- a/output/sqlite3/ulogd_output_SQLITE3.c +++ b/output/sqlite3/ulogd_output_SQLITE3.c @@ -33,6 +33,7 @@ #include <stdlib.h> #include <string.h> #include <arpa/inet.h> +#include <netinet/in.h> #include <ulogd/ulogd.h> #include <ulogd/conffile.h> #include <sqlite3.h> @@ -48,7 +49,7 @@ struct field { TAILQ_ENTRY(field) link; - char name[ULOGD_MAX_KEYLEN]; + char name[ULOGD_MAX_KEYLEN + 1]; struct ulogd_key *key; }; @@ -104,11 +105,14 @@ add_row(struct ulogd_pluginstance *pi) ret = sqlite3_finalize(priv->p_stmt); priv->p_stmt = NULL; - if (ret == SQLITE_SCHEMA) - sqlite3_createstmt(pi); - else { + if (ret != SQLITE_SCHEMA) { ulogd_log(ULOGD_ERROR, "SQLITE3: step: %s\n", - sqlite3_errmsg(priv->dbh)); + sqlite3_errmsg(priv->dbh)); + goto err_reset; + } + if (sqlite3_createstmt(pi) < 0) { + ulogd_log(ULOGD_ERROR, + "SQLITE3: Could not create statement.\n"); goto err_reset; } } @@ -142,6 +146,10 @@ sqlite3_interp(struct ulogd_pluginstance *pi) } switch (f->key->type) { + case ULOGD_RET_BOOL: + ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.b); + break; + case ULOGD_RET_INT8: ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.i8); break; @@ -155,7 +163,7 @@ sqlite3_interp(struct ulogd_pluginstance *pi) break; case ULOGD_RET_INT64: - ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.i64); + ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.i64); break; case ULOGD_RET_UINT8: @@ -171,17 +179,20 @@ sqlite3_interp(struct ulogd_pluginstance *pi) break; case ULOGD_RET_IPADDR: - case ULOGD_RET_UINT64: - ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.ui64); + if (k_ret->len == sizeof(struct in_addr)) + ret = sqlite3_bind_int(priv->p_stmt, i, + k_ret->u.value.ui32); + else + ret = sqlite3_bind_null(priv->p_stmt, i); break; - case ULOGD_RET_BOOL: - ret = sqlite3_bind_int(priv->p_stmt, i, k_ret->u.value.b); + case ULOGD_RET_UINT64: + ret = sqlite3_bind_int64(priv->p_stmt, i, k_ret->u.value.ui64); break; case ULOGD_RET_STRING: ret = sqlite3_bind_text(priv->p_stmt, i, k_ret->u.value.ptr, - strlen(k_ret->u.value.ptr), SQLITE_STATIC); + strlen(k_ret->u.value.ptr), SQLITE_STATIC); break; default: @@ -214,10 +225,8 @@ sqlite3_createstmt(struct ulogd_pluginstance *pi) { struct sqlite3_priv *priv = (void *)pi->private; struct field *f; - char buf[ULOGD_MAX_KEYLEN]; - char *underscore; - char *stmt_pos; int i, cols = 0; + char *stmt_pos; if (priv->stmt != NULL) free(priv->stmt); @@ -226,31 +235,21 @@ sqlite3_createstmt(struct ulogd_pluginstance *pi) ulogd_log(ULOGD_ERROR, "SQLITE3: out of memory\n"); return -1; } + stmt_pos = priv->stmt; - sprintf(priv->stmt, "insert into %s (", table_ce(pi)); - stmt_pos = priv->stmt + strlen(priv->stmt); + stmt_pos += sprintf(stmt_pos, "insert into %s (", table_ce(pi)); tailq_for_each(f, priv->fields, link) { - strncpy(buf, f->name, ULOGD_MAX_KEYLEN); - - while ((underscore = strchr(buf, '.'))) - *underscore = '_'; - - sprintf(stmt_pos, "%s,", buf); - stmt_pos = priv->stmt + strlen(priv->stmt); - + stmt_pos += sprintf(stmt_pos, "%s,", f->name); cols++; } *(stmt_pos - 1) = ')'; - sprintf(stmt_pos, " values ("); - stmt_pos = priv->stmt + strlen(priv->stmt); + stmt_pos += sprintf(stmt_pos, " values ("); - for (i = 0; i < cols - 1; i++) { - sprintf(stmt_pos,"?,"); - stmt_pos += 2; - } + for (i = 0; i < cols - 1; i++) + stmt_pos += sprintf(stmt_pos, "?,"); sprintf(stmt_pos, "?)"); ulogd_log(ULOGD_DEBUG, "%s: stmt='%s'\n", pi->id, priv->stmt); @@ -260,8 +259,8 @@ sqlite3_createstmt(struct ulogd_pluginstance *pi) sqlite3_prepare(priv->dbh, priv->stmt, -1, &priv->p_stmt, 0); if (priv->p_stmt == NULL) { ulogd_log(ULOGD_ERROR, "SQLITE3: prepare: %s\n", - sqlite3_errmsg(priv->dbh)); - return 1; + sqlite3_errmsg(priv->dbh)); + return -1; } DEBUGP("statement prepared.\n"); @@ -273,10 +272,15 @@ sqlite3_createstmt(struct ulogd_pluginstance *pi) static struct ulogd_key * ulogd_find_key(struct ulogd_pluginstance *pi, const char *name) { + char buf[ULOGD_MAX_KEYLEN + 1] = ""; unsigned int i; + /* replace all underscores with dots */ + for (i = 0; i < sizeof(buf) - 1 && name[i]; ++i) + buf[i] = name[i] != '_' ? name[i] : '.'; + for (i = 0; i < pi->input.num_keys; i++) { - if (strcmp(pi->input.keys[i].name, name) == 0) + if (strcmp(pi->input.keys[i].name, buf) == 0) return &pi->input.keys[i]; } @@ -305,9 +309,6 @@ static int sqlite3_init_db(struct ulogd_pluginstance *pi) { struct sqlite3_priv *priv = (void *)pi->private; - char buf[ULOGD_MAX_KEYLEN]; - char *underscore; - struct field *f; sqlite3_stmt *schema_stmt; int col, num_cols; @@ -327,23 +328,24 @@ sqlite3_init_db(struct ulogd_pluginstance *pi) } for (col = 0; col < num_cols; col++) { - strncpy(buf, sqlite3_column_name(schema_stmt, col), ULOGD_MAX_KEYLEN); - - /* replace all underscores with dots */ - while ((underscore = strchr(buf, '_')) != NULL) - *underscore = '.'; - - DEBUGP("field '%s' found\n", buf); + struct field *f; /* prepend it to the linked list */ if ((f = calloc(1, sizeof(struct field))) == NULL) { ulogd_log(ULOGD_ERROR, "SQLITE3: out of memory\n"); return -1; } - strncpy(f->name, buf, ULOGD_MAX_KEYLEN); + snprintf(f->name, sizeof(f->name), + "%s", sqlite3_column_name(schema_stmt, col)); + + DEBUGP("field '%s' found\n", f->name); - if ((f->key = ulogd_find_key(pi, buf)) == NULL) + if ((f->key = ulogd_find_key(pi, f->name)) == NULL) { + ulogd_log(ULOGD_ERROR, + "SQLITE3: unknown input key: %s\n", f->name); + free(f); return -1; + } TAILQ_INSERT_TAIL(&priv->fields, f, link); } @@ -394,7 +396,10 @@ sqlite3_start(struct ulogd_pluginstance *pi) } /* create and prepare the actual insert statement */ - sqlite3_createstmt(pi); + if (sqlite3_createstmt(pi) < 0) { + ulogd_log(ULOGD_ERROR, "SQLITE3: Could not create statement.\n"); + return -1; + } return 0; } diff --git a/output/ulogd_output_GPRINT.c b/output/ulogd_output_GPRINT.c index bc7aa34..37829fa 100644 --- a/output/ulogd_output_GPRINT.c +++ b/output/ulogd_output_GPRINT.c @@ -27,6 +27,8 @@ #include <time.h> #include <errno.h> #include <inttypes.h> +#include <arpa/inet.h> +#include <netinet/in.h> #include <ulogd/ulogd.h> #include <ulogd/conffile.h> @@ -69,12 +71,6 @@ static struct config_keyset gprint_kset = { }, }; -#define NIPQUAD(addr) \ - ((unsigned char *)&addr)[0], \ - ((unsigned char *)&addr)[1], \ - ((unsigned char *)&addr)[2], \ - ((unsigned char *)&addr)[3] - static int gprint_interp(struct ulogd_pluginstance *upi) { struct gprint_priv *opi = (struct gprint_priv *) &upi->private; @@ -127,13 +123,15 @@ static int gprint_interp(struct ulogd_pluginstance *upi) case ULOGD_RET_INT8: case ULOGD_RET_INT16: case ULOGD_RET_INT32: + case ULOGD_RET_INT64: ret = snprintf(buf+size, rem, "%s=", key->name); if (ret < 0) break; rem -= ret; size += ret; - ret = snprintf(buf+size, rem, "%d,", key->u.value.i32); + ret = snprintf(buf+size, rem, "%" PRId64 ",", + key->u.value.i64); if (ret < 0) break; rem -= ret; @@ -156,20 +154,36 @@ static int gprint_interp(struct ulogd_pluginstance *upi) rem -= ret; size += ret; break; - case ULOGD_RET_IPADDR: + case ULOGD_RET_IPADDR: { + struct in6_addr ipv6addr; + struct in_addr ipv4addr; + int family; + void *addr; + ret = snprintf(buf+size, rem, "%s=", key->name); if (ret < 0) break; rem -= ret; size += ret; - ret = snprintf(buf+size, rem, "%u.%u.%u.%u,", - NIPQUAD(key->u.value.ui32)); - if (ret < 0) + if (key->len == sizeof(ipv6addr)) { + memcpy(ipv6addr.s6_addr, key->u.value.ui128, + sizeof(ipv6addr.s6_addr)); + addr = &ipv6addr; + family = AF_INET6; + } else { + ipv4addr.s_addr = key->u.value.ui32; + addr = &ipv4addr; + family = AF_INET; + } + if (!inet_ntop(family, addr, buf + size, rem)) break; + ret = strlen(buf + size); + rem -= ret; size += ret; break; + } default: /* don't know how to interpret this key. */ break; @@ -249,7 +263,7 @@ static int gprint_fini(struct ulogd_pluginstance *pi) static struct ulogd_plugin gprint_plugin = { .name = "GPRINT", .input = { - .type = ULOGD_DTYPE_PACKET | ULOGD_DTYPE_FLOW | ULOGD_DTYPE_SUM, + .type = ULOGD_DTYPE_RAW | ULOGD_DTYPE_PACKET | ULOGD_DTYPE_FLOW | ULOGD_DTYPE_SUM, }, .output = { .type = ULOGD_DTYPE_SINK, diff --git a/output/ulogd_output_JSON.c b/output/ulogd_output_JSON.c index 6edfa90..f80d0e2 100644 --- a/output/ulogd_output_JSON.c +++ b/output/ulogd_output_JSON.c @@ -33,6 +33,10 @@ #include <ulogd/conffile.h> #include <jansson.h> +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX 108 +#endif + #ifndef ULOGD_JSON_DEFAULT #define ULOGD_JSON_DEFAULT "/var/log/ulogd.json" #endif @@ -146,23 +150,21 @@ static void close_socket(struct json_priv *op) { static int _connect_socket_unix(struct ulogd_pluginstance *pi) { + const char *socket_path = file_ce(pi->config_kset).u.string; struct json_priv *op = (struct json_priv *) &pi->private; - struct sockaddr_un u_addr; + struct sockaddr_un u_addr = { .sun_family = AF_UNIX }; int sfd; close_socket(op); - ulogd_log(ULOGD_DEBUG, "connecting to unix:%s\n", - file_ce(pi->config_kset).u.string); + ulogd_log(ULOGD_DEBUG, "connecting to unix:%s\n", socket_path); + strcpy(u_addr.sun_path, socket_path); sfd = socket(AF_UNIX, SOCK_STREAM, 0); - if (sfd == -1) { + if (sfd == -1) return -1; - } - u_addr.sun_family = AF_UNIX; - strncpy(u_addr.sun_path, file_ce(pi->config_kset).u.string, - sizeof(u_addr.sun_path) - 1); - if (connect(sfd, (struct sockaddr *) &u_addr, sizeof(struct sockaddr_un)) == -1) { + + if (connect(sfd, (struct sockaddr *) &u_addr, sizeof(u_addr)) == -1) { close(sfd); return -1; } @@ -269,14 +271,14 @@ static int json_interp_file(struct ulogd_pluginstance *upi, char *buf) return ULOGD_IRET_OK; } -#define MAX_LOCAL_TIME_STRING 38 +#define MAX_LOCAL_TIME_STRING 80 static int json_interp(struct ulogd_pluginstance *upi) { struct json_priv *opi = (struct json_priv *) &upi->private; + char *dvc, *buf, *tmp; unsigned int i; - char *buf; - int buflen; + size_t buflen; json_t *msg; msg = json_object(); @@ -302,11 +304,12 @@ static int json_interp(struct ulogd_pluginstance *upi) now = time(NULL); t = localtime_r(&now, &result); if (unlikely(*opi->cached_tz = '\0' || t->tm_gmtoff != opi->cached_gmtoff)) { + int gmtoff = t->tm_gmtoff % 86400; + int gmtoff_hours = gmtoff / 3600; + int gmtoff_minutes = abs(gmtoff) / 60 % 60; + snprintf(opi->cached_tz, sizeof(opi->cached_tz), - "%c%02d%02d", - t->tm_gmtoff > 0 ? '+' : '-', - abs(t->tm_gmtoff) / 60 / 60, - abs(t->tm_gmtoff) / 60 % 60); + "%+03d%02d", gmtoff_hours, gmtoff_minutes); } if (pp_is_valid(inp, opi->usec_idx)) { @@ -332,12 +335,8 @@ static int json_interp(struct ulogd_pluginstance *upi) json_object_set_new(msg, "timestamp", json_string(timestr)); } - if (upi->config_kset->ces[JSON_CONF_DEVICE].u.string) { - char *dvc = upi->config_kset->ces[JSON_CONF_DEVICE].u.string; - json_object_set_new(msg, "dvc", json_string(dvc)); - } - - + dvc = upi->config_kset->ces[JSON_CONF_DEVICE].u.string; + json_object_set_new(msg, "dvc", json_string(dvc)); for (i = 0; i < upi->input.num_keys; i++) { struct ulogd_key *key = upi->input.keys[i].u.source; @@ -365,6 +364,9 @@ static int json_interp(struct ulogd_pluginstance *upi) case ULOGD_RET_INT32: json_object_set_new(msg, field_name, json_integer(key->u.value.i32)); break; + case ULOGD_RET_INT64: + json_object_set_new(msg, field_name, json_integer(key->u.value.i64)); + break; case ULOGD_RET_UINT8: if ((upi->config_kset->ces[JSON_CONF_BOOLEAN_LABEL].u.value != 0) && (!strcmp(key->name, "raw.label"))) { @@ -391,7 +393,6 @@ static int json_interp(struct ulogd_pluginstance *upi) } } - buf = json_dumps(msg, 0); json_decref(msg); if (buf == NULL) { @@ -399,13 +400,15 @@ static int json_interp(struct ulogd_pluginstance *upi) return ULOGD_IRET_ERR; } buflen = strlen(buf); - buf = realloc(buf, sizeof(char)*(buflen+2)); - if (buf == NULL) { + tmp = realloc(buf, buflen + sizeof("\n")); + if (tmp == NULL) { + free(buf); ulogd_log(ULOGD_ERROR, "Could not create message\n"); return ULOGD_IRET_ERR; } - strncat(buf, "\n", 1); - buflen++; + buf = tmp; + buf[buflen++] = '\n'; + buf[buflen] = '\0'; if (opi->mode == JSON_MODE_FILE) return json_interp_file(upi, buf); @@ -430,9 +433,33 @@ static void reopen_file(struct ulogd_pluginstance *upi) } } +static int validate_unix_socket(struct ulogd_pluginstance *upi) +{ + const char *socket_path = file_ce(upi->config_kset).u.string; + + if (!socket_path[0]) { + ulogd_log(ULOGD_ERROR, "missing unix socket path"); + return -1; + } + if (strlen(socket_path) >= UNIX_PATH_MAX) { + ulogd_log(ULOGD_ERROR, "unix socket path `%s' is longer than %u\n", + file_ce(upi->config_kset).u.string, UNIX_PATH_MAX); + return -1; + } + + return 0; +} + static void reopen_socket(struct ulogd_pluginstance *upi) { + struct json_priv *op = (struct json_priv *) &upi->private; + ulogd_log(ULOGD_NOTICE, "JSON: reopening socket\n"); + + if (op->mode == JSON_MODE_UNIX && + validate_unix_socket(upi) < 0) + return; + if (_connect_socket(upi) < 0) { ulogd_log(ULOGD_ERROR, "can't open JSON " "socket: %s\n", @@ -505,9 +532,8 @@ static int json_init_socket(struct ulogd_pluginstance *upi) { struct json_priv *op = (struct json_priv *) &upi->private; - if (host_ce(upi->config_kset).u.string == NULL) - return -1; - if (port_ce(upi->config_kset).u.string == NULL) + if (op->mode == JSON_MODE_UNIX && + validate_unix_socket(upi) < 0) return -1; op->sock = -1; diff --git a/output/ulogd_output_OPRINT.c b/output/ulogd_output_OPRINT.c index 6fde445..13934ff 100644 --- a/output/ulogd_output_OPRINT.c +++ b/output/ulogd_output_OPRINT.c @@ -24,6 +24,8 @@ #include <string.h> #include <errno.h> #include <inttypes.h> +#include <arpa/inet.h> +#include <netinet/in.h> #include <ulogd/ulogd.h> #include <ulogd/conffile.h> @@ -31,18 +33,6 @@ #define ULOGD_OPRINT_DEFAULT "/var/log/ulogd_oprint.log" #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] - struct oprint_priv { FILE *of; }; @@ -59,38 +49,61 @@ static int oprint_interp(struct ulogd_pluginstance *upi) if (!ret) ulogd_log(ULOGD_NOTICE, "no result for %s ?!?\n", upi->input.keys[i].name); - + if (!IS_VALID(*ret)) continue; fprintf(opi->of,"%s=", ret->name); switch (ret->type) { - case ULOGD_RET_STRING: - fprintf(opi->of, "%s\n", - (char *) ret->u.value.ptr); - break; - case ULOGD_RET_BOOL: - case ULOGD_RET_INT8: - case ULOGD_RET_INT16: - case ULOGD_RET_INT32: - fprintf(opi->of, "%d\n", ret->u.value.i32); - break; - case ULOGD_RET_UINT8: - case ULOGD_RET_UINT16: - case ULOGD_RET_UINT32: - fprintf(opi->of, "%u\n", ret->u.value.ui32); + case ULOGD_RET_STRING: + fprintf(opi->of, "%s\n", (char *) ret->u.value.ptr); + break; + case ULOGD_RET_BOOL: + case ULOGD_RET_INT8: + case ULOGD_RET_INT16: + case ULOGD_RET_INT32: + fprintf(opi->of, "%d\n", ret->u.value.i32); + break; + case ULOGD_RET_INT64: + fprintf(opi->of, "%" PRId64 "\n", ret->u.value.i64); + break; + case ULOGD_RET_UINT8: + case ULOGD_RET_UINT16: + case ULOGD_RET_UINT32: + fprintf(opi->of, "%u\n", ret->u.value.ui32); + break; + case ULOGD_RET_UINT64: + fprintf(opi->of, "%" PRIu64 "\n", ret->u.value.ui64); + break; + case ULOGD_RET_IPADDR: { + char addrbuf[INET6_ADDRSTRLEN + 1] = ""; + struct in6_addr ipv6addr; + struct in_addr ipv4addr; + int family; + void *addr; + + if (ret->len == sizeof(ipv6addr)) { + memcpy(ipv6addr.s6_addr, ret->u.value.ui128, + sizeof(ipv6addr.s6_addr)); + addr = &ipv6addr; + family = AF_INET6; + } else { + ipv4addr.s_addr = ret->u.value.ui32; + addr = &ipv4addr; + family = AF_INET; + } + if (!inet_ntop(family, addr, addrbuf, sizeof(addrbuf))) break; - case ULOGD_RET_UINT64: - fprintf(opi->of, "%" PRIu64 "\n", ret->u.value.ui64); - break; - case ULOGD_RET_IPADDR: - fprintf(opi->of, "%u.%u.%u.%u\n", - HIPQUAD(ret->u.value.ui32)); - break; - case ULOGD_RET_NONE: - fprintf(opi->of, "<none>\n"); - break; - default: fprintf(opi->of, "default\n"); + + fprintf(opi->of, "%s\n", addrbuf); + break; + } + case ULOGD_RET_NONE: + fprintf(opi->of, "<none>\n"); + break; + default: + fprintf(opi->of, "default\n"); + break; } } if (upi->config_kset->ces[1].u.value != 0) diff --git a/output/ulogd_output_XML.c b/output/ulogd_output_XML.c index ba33739..44af596 100644 --- a/output/ulogd_output_XML.c +++ b/output/ulogd_output_XML.c @@ -109,7 +109,7 @@ xml_output_flow(struct ulogd_key *inp, char *buf, ssize_t size) if (tmp < 0 || tmp >= size) return -1; - return 0; + return tmp; #else return -1; #endif @@ -126,7 +126,7 @@ xml_output_packet(struct ulogd_key *inp, char *buf, ssize_t size) if (tmp < 0 || tmp >= size) return -1; - return 0; + return tmp; #else return -1; #endif @@ -143,7 +143,7 @@ xml_output_sum(struct ulogd_key *inp, char *buf, ssize_t size) NFACCT_SNPRINTF_F_TIME); if (tmp < 0 || tmp >= size) return -1; - return 0; + return tmp; #else return -1; #endif @@ -155,14 +155,25 @@ static int xml_output(struct ulogd_pluginstance *upi) struct ulogd_key *inp = upi->input.keys; struct xml_priv *opi = (struct xml_priv *) &upi->private; static char buf[4096]; - int ret = -1; + int ret = -1, tmp = 0; - if (pp_is_valid(inp, KEY_CT)) - ret = xml_output_flow(inp, buf, sizeof(buf)); - else if (pp_is_valid(inp, KEY_PCKT)) - ret = xml_output_packet(inp, buf, sizeof(buf)); - else if (pp_is_valid(inp, KEY_SUM)) - ret = xml_output_sum(inp, buf, sizeof(buf)); + if (pp_is_valid(inp, KEY_PCKT)) { + ret = xml_output_packet(inp, buf + tmp, sizeof(buf) - tmp); + if (ret < 0) + return ULOGD_IRET_ERR; + tmp += ret; + } + if (pp_is_valid(inp, KEY_CT)) { + ret = xml_output_flow(inp, buf + tmp, sizeof(buf) - tmp); + if (ret < 0) + return ULOGD_IRET_ERR; + tmp += ret; + } + if (pp_is_valid(inp, KEY_SUM)) { + ret = xml_output_sum(inp, buf + tmp, sizeof(buf) - tmp); + if (ret < 0) + return ULOGD_IRET_ERR; + } if (ret < 0) return ULOGD_IRET_ERR; @@ -314,7 +325,7 @@ static struct ulogd_plugin xml_plugin = { .input = { .keys = xml_inp, .num_keys = ARRAY_SIZE(xml_inp), - .type = ULOGD_DTYPE_FLOW | ULOGD_DTYPE_SUM, + .type = ULOGD_DTYPE_FLOW | ULOGD_DTYPE_SUM | ULOGD_DTYPE_RAW, }, .output = { .type = ULOGD_DTYPE_SINK, |