]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
output: add GPRINT plugin
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 22 Feb 2012 11:33:51 +0000 (12:33 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 22 Feb 2012 12:15:53 +0000 (13:15 +0100)
This patch adds GPRINT which is a generalization of OPRINT.

It display the set of key-values separated by commas. This is
the generic print that you can attach to whatever kind of
input plugin.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
output/Makefile.am
output/ulogd_output_GPRINT.c [new file with mode: 0644]
ulogd.conf.in

index 2ec6e8dd47b642feb77864b86db3603cc9d09730..bb93b28f56ced8f3a8f7b0d3bd68fe5961f9ffa3 100644 (file)
@@ -5,9 +5,12 @@ AM_CFLAGS = ${regular_CFLAGS} ${LIBNETFILTER_LOG_CFLAGS} \
 SUBDIRS= pcap mysql pgsql sqlite3 dbi
 
 pkglibexec_LTLIBRARIES = ulogd_output_LOGEMU.la ulogd_output_SYSLOG.la \
-                        ulogd_output_OPRINT.la \
+                        ulogd_output_OPRINT.la ulogd_output_GPRINT.la \
                         ulogd_output_NACCT.la ulogd_output_XML.la
 
+ulogd_output_GPRINT_la_SOURCES = ulogd_output_GPRINT.c
+ulogd_output_GPRINT_la_LDFLAGS = -avoid-version -module
+
 ulogd_output_LOGEMU_la_SOURCES = ulogd_output_LOGEMU.c
 ulogd_output_LOGEMU_la_LDFLAGS = -avoid-version -module
 
diff --git a/output/ulogd_output_GPRINT.c b/output/ulogd_output_GPRINT.c
new file mode 100644 (file)
index 0000000..759a0ca
--- /dev/null
@@ -0,0 +1,270 @@
+/* ulogd_GPRINT.c
+ *
+ * ulogd output target for logging to a file in comma-separated key-value.
+ * This is a generalization of ulogd_GPRINT.c
+ *
+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2012 by Intra2net AG <http://www.intra2net.com>
+ *
+ *  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 <time.h>
+#include <errno.h>
+#include <ulogd/ulogd.h>
+#include <ulogd/conffile.h>
+
+#ifndef ULOGD_GPRINT_DEFAULT
+#define ULOGD_GPRINT_DEFAULT   "/var/log/ulogd.gprint"
+#endif
+
+struct gprint_priv {
+       FILE *of;
+};
+
+enum gprint_conf {
+       GPRINT_CONF_FILENAME = 0,
+       GPRINT_CONF_SYNC,
+       GPRINT_CONF_TIMESTAMP,
+       GPRINT_CONF_MAX
+};
+
+static struct config_keyset gprint_kset = {
+       .num_ces = GPRINT_CONF_MAX,
+       .ces = {
+               [GPRINT_CONF_FILENAME] = {
+                       .key = "file",
+                       .type = CONFIG_TYPE_STRING,
+                       .options = CONFIG_OPT_NONE,
+                       .u = {.string = ULOGD_GPRINT_DEFAULT },
+               },
+               [GPRINT_CONF_SYNC] = {
+                       .key = "sync",
+                       .type = CONFIG_TYPE_INT,
+                       .options = CONFIG_OPT_NONE,
+                       .u = { .value = 0 },
+               },
+               [GPRINT_CONF_TIMESTAMP] = {
+                       .key = "timestamp",
+                       .type = CONFIG_TYPE_INT,
+                       .options = CONFIG_OPT_NONE,
+                       .u = { .value = 0 },
+               },
+       },
+};
+
+#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;
+       unsigned int i;
+       char buf[4096];
+       int rem = sizeof(buf), size = 0, ret;
+
+       if (upi->config_kset->ces[GPRINT_CONF_TIMESTAMP].u.value != 0) {
+               struct tm tm;
+               time_t now;
+
+               now = time(NULL);
+               localtime_r(&now, &tm);
+
+               ret = snprintf(buf+size, rem,
+                               "timestamp=%.4u/%.2u/%.2u-%.2u:%.2u:%.2u,",
+                               1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
+                               tm.tm_hour, tm.tm_min, tm.tm_sec);
+               if (ret < 0)
+                       return ULOGD_IRET_OK;
+               rem -= ret;
+               size += ret;
+       }
+
+       for (i = 0; i < upi->input.num_keys; i++) {
+               struct ulogd_key *key = upi->input.keys[i].u.source;
+
+               if (!key)
+                       continue;
+
+               if (!IS_VALID(*key))
+                       continue;
+
+               switch (key->type) {
+               case ULOGD_RET_STRING:
+                       ret = snprintf(buf+size, rem, "%s=", key->name);
+                       if (ret < 0)
+                               break;
+                       rem -= ret;
+                       size += ret;
+
+                       ret = snprintf(buf+size, rem, "%s,",
+                                       (char *) key->u.value.ptr);
+                       if (ret < 0)
+                               break;
+                       rem -= ret;
+                       size += ret;
+                       break;
+               case ULOGD_RET_BOOL:
+               case ULOGD_RET_INT8:
+               case ULOGD_RET_INT16:
+               case ULOGD_RET_INT32:
+                       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);
+                       if (ret < 0)
+                               break;
+                       rem -= ret;
+                       size += ret;
+                       break;
+               case ULOGD_RET_UINT8:
+               case ULOGD_RET_UINT16:
+               case ULOGD_RET_UINT32:
+               case ULOGD_RET_UINT64:
+                       ret = snprintf(buf+size, rem, "%s=", key->name);
+                       if (ret < 0)
+                               break;
+                       rem -= ret;
+                       size += ret;
+
+                       ret = snprintf(buf+size, rem, "%lu,",
+                                       key->u.value.ui64);
+                       if (ret < 0)
+                               break;
+                       rem -= ret;
+                       size += ret;
+                       break;
+               case ULOGD_RET_IPADDR:
+                       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)
+                               break;
+                       rem -= ret;
+                       size += ret;
+                       break;
+               default:
+                       /* don't know how to interpret this key. */
+                       break;
+               }
+       }
+       buf[size-1]='\0';
+       fprintf(opi->of, "%s\n", buf);
+
+       if (upi->config_kset->ces[GPRINT_CONF_SYNC].u.value != 0)
+               fflush(opi->of);
+
+       return ULOGD_IRET_OK;
+}
+
+static void sighup_handler_print(struct ulogd_pluginstance *upi, int signal)
+{
+       struct gprint_priv *oi = (struct gprint_priv *) &upi->private;
+       FILE *old = oi->of;
+
+       switch (signal) {
+       case SIGHUP:
+               ulogd_log(ULOGD_NOTICE, "GPRINT: reopening logfile\n");
+               oi->of = fopen(upi->config_kset->ces[0].u.string, "a");
+               if (!oi->of) {
+                       ulogd_log(ULOGD_ERROR, "can't open GPRINT "
+                                              "log file: %s\n",
+                                 strerror(errno));
+                       oi->of = old;
+               } else {
+                       fclose(old);
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+static int gprint_configure(struct ulogd_pluginstance *upi,
+                           struct ulogd_pluginstance_stack *stack)
+{
+       int ret;
+
+       ret = ulogd_wildcard_inputkeys(upi);
+       if (ret < 0)
+               return ret;
+
+       ret = config_parse_file(upi->id, upi->config_kset);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int gprint_init(struct ulogd_pluginstance *upi)
+{
+       struct gprint_priv *op = (struct gprint_priv *) &upi->private;
+
+       op->of = fopen(upi->config_kset->ces[0].u.string, "a");
+       if (!op->of) {
+               ulogd_log(ULOGD_FATAL, "can't open GPRINT log file: %s\n", 
+                       strerror(errno));
+               return -1;
+       }
+       return 0;
+}
+
+static int gprint_fini(struct ulogd_pluginstance *pi)
+{
+       struct gprint_priv *op = (struct gprint_priv *) &pi->private;
+
+       if (op->of != stdout)
+               fclose(op->of);
+
+       return 0;
+}
+
+static struct ulogd_plugin gprint_plugin = {
+       .name = "GPRINT",
+       .input = {
+               .type = ULOGD_DTYPE_PACKET | ULOGD_DTYPE_FLOW,
+       },
+       .output = {
+               .type = ULOGD_DTYPE_SINK,
+       },
+       .configure = &gprint_configure,
+       .interp = &gprint_interp,
+       .start  = &gprint_init,
+       .stop   = &gprint_fini,
+       .signal = &sighup_handler_print,
+       .config_kset = &gprint_kset,
+       .version = ULOGD_VERSION,
+};
+
+void __attribute__ ((constructor)) init(void);
+
+void init(void)
+{
+       ulogd_register_plugin(&gprint_plugin);
+}
index ac7bcae17a11f1cc31570df968b2ef64ce720d83..c0c8559b44b63399dd024841dd1f0a0c423e086f 100644 (file)
@@ -42,6 +42,7 @@ plugin="@pkglibexecdir@/ulogd_output_SYSLOG.so"
 plugin="@pkglibexecdir@/ulogd_output_XML.so"
 #plugin="@pkglibexecdir@/ulogd_output_SQLITE3.so"
 #plugin="@pkglibexecdir@/ulogd_output_OPRINT.so"
+plugin="@pkglibexecdir@/ulogd_output_GPRINT.so"
 #plugin="@pkglibexecdir@/ulogd_output_NACCT.so"
 #plugin="@pkglibexecdir@/ulogd_output_PCAP.so"
 #plugin="@pkglibexecdir@/ulogd_output_PGSQL.so"
@@ -167,6 +168,11 @@ sync=1
 file="/var/log/ulogd_oprint.log"
 sync=1
 
+[gp1]
+file="/var/log/ulogd_gprint.log"
+sync=1
+timestamp=1
+
 [xml1]
 directory="/var/log/"
 sync=1