]> git.ipfire.org Git - thirdparty/ulogd2.git/commitdiff
Add a printflow plugin is similar to the PRINTPKT plugin, but for flows. It's
author/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org>
Tue, 23 May 2006 09:00:01 +0000 (09:00 +0000)
committer/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org>
Tue, 23 May 2006 09:00:01 +0000 (09:00 +0000)
output is compatible with the SYSLOG and LOGEMU plugins. (Philip Craig)

filter/Makefile.am
filter/ulogd_filter_PRINTFLOW.c [new file with mode: 0644]
include/ulogd/Makefile.am
include/ulogd/printflow.h [new file with mode: 0644]
input/flow/ulogd_inpflow_NFCT.c
output/ulogd_output_LOGEMU.c
output/ulogd_output_SYSLOG.c
ulogd.conf.in
util/printflow.c [new file with mode: 0644]

index 8c2a37d26d8c665dd7be1a5ba3fa2d709e210662..b3207f979dc7aa7357b33ce130d266e504e277a1 100644 (file)
@@ -5,7 +5,7 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include
 noinst_HEADERS = rtnl.h iftable.h
 
 pkglib_LTLIBRARIES = ulogd_filter_IFINDEX.la ulogd_filter_PWSNIFF.la \
-                    ulogd_filter_PRINTPKT.la
+                    ulogd_filter_PRINTPKT.la ulogd_filter_PRINTFLOW.la
 
 ulogd_filter_IFINDEX_la_SOURCES = ulogd_filter_IFINDEX.c rtnl.c iftable.c
 ulogd_filter_IFINDEX_la_LDFLAGS = -module
@@ -15,3 +15,6 @@ ulogd_filter_PWSNIFF_la_LDFLAGS = -module
 
 ulogd_filter_PRINTPKT_la_SOURCES = ulogd_filter_PRINTPKT.c ../util/printpkt.c
 ulogd_filter_PRINTPKT_la_LDFLAGS = -module
+
+ulogd_filter_PRINTFLOW_la_SOURCES = ulogd_filter_PRINTFLOW.c ../util/printflow.c
+ulogd_filter_PRINTFLOW_la_LDFLAGS = -module
diff --git a/filter/ulogd_filter_PRINTFLOW.c b/filter/ulogd_filter_PRINTFLOW.c
new file mode 100644 (file)
index 0000000..181c09e
--- /dev/null
@@ -0,0 +1,66 @@
+/* ulogd_filter_PRINTFLOW.c, Version $Revision: 1.1 $
+ *
+ * This target produces entries similar to the LOG target, but for flows.
+ *
+ * (C) 2006 by Philip Craig <philipc@snapgear.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 <ulogd/ulogd.h>
+#include <ulogd/printflow.h>
+
+static struct ulogd_key printflow_outp[] = {
+       {
+               .type = ULOGD_RET_STRING,
+               .flags = ULOGD_RETF_NONE,
+               .name = "print",
+       },
+};
+
+static int printflow_interp(struct ulogd_pluginstance *upi)
+{
+       struct ulogd_key *inp = upi->input.keys;
+       struct ulogd_key *ret = upi->output.keys;
+       static char buf[4096];
+
+       printflow_print(inp, buf);
+       ret[0].u.value.ptr = buf;
+       ret[0].flags |= ULOGD_RETF_VALID;
+       return 0;
+}
+
+static struct ulogd_plugin printflow_plugin = {
+       .name = "PRINTFLOW",
+       .input = {
+               .keys = printflow_keys,
+               .num_keys = ARRAY_SIZE(printflow_keys),
+               .type = ULOGD_DTYPE_FLOW,
+       },
+       .output = {
+               .keys = printflow_outp,
+               .num_keys = ARRAY_SIZE(printflow_outp),
+               .type = ULOGD_DTYPE_FLOW,
+       },
+       .interp = &printflow_interp,
+       .version = ULOGD_VERSION,
+};
+
+void __attribute__ ((constructor)) init(void);
+
+void init(void)
+{
+       ulogd_register_plugin(&printflow_plugin);
+}
index 09333900953e1a172f5f746f8ab60ce25ac9a670..2a3a03d791f97b2e569ee12d22ae25da4a14c55c 100644 (file)
@@ -1,2 +1,2 @@
 
-noinst_HEADERS = conffile.h db.h ipfix_protocol.h linuxlist.h ulogd.h printpkt.h
+noinst_HEADERS = conffile.h db.h ipfix_protocol.h linuxlist.h ulogd.h printpkt.h printflow.h
diff --git a/include/ulogd/printflow.h b/include/ulogd/printflow.h
new file mode 100644 (file)
index 0000000..7343a23
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _PRINTFLOW_H
+#define _PRINTFLOW_H
+
+#define FLOW_IDS       10
+extern struct ulogd_key printflow_keys[FLOW_IDS];
+
+int printflow_print(struct ulogd_key *res, char *buf);
+
+#endif
index c97c7bc8398277704dbacee9fbc076abe93951ac..34b49bedf1978cb32d25748ed253080670cc9893 100644 (file)
@@ -244,6 +244,11 @@ static struct ulogd_key nfct_okeys[] = {
                        .field_id       = IPFIX_flowEndSeconds,
                },
        },
+       {
+               .type = ULOGD_RET_BOOL,
+               .flags = ULOGD_RETF_NONE,
+               .name = "dir",
+       },
 };
 
 static struct ct_htable *htable_alloc(int htable_size, int prealloc)
@@ -424,6 +429,9 @@ static int propagate_ct_flow(struct ulogd_pluginstance *upi,
                ret[14].flags |= ULOGD_RETF_VALID;
        }
 
+       ret[15].u.value.b = (dir == NFCT_DIR_ORIGINAL) ? 0 : 1;
+       ret[15].flags |= ULOGD_RETF_VALID;
+
        ulogd_propagate_results(upi);
 
        return 0;
index a224d7b3b3b88729a5f50fa7e828aa66c936ff7c..c18aad7a5d26ee1ff70b1ce9767027d51f496f38 100644 (file)
@@ -55,6 +55,7 @@ static struct ulogd_key logemu_inp[] = {
        },
        {
                .type = ULOGD_RET_UINT32,
+               .flags = ULOGD_KEYF_OPTIONAL,
                .name = "oob.time.sec",
        },
 };
@@ -91,7 +92,7 @@ static int _output_logemu(struct ulogd_pluginstance *upi)
                char *tmp;
                time_t now;
 
-               if (res[1].u.source->flags & ULOGD_RETF_VALID)
+               if (res[1].u.source && (res[1].u.source->flags & ULOGD_RETF_VALID))
                        now = (time_t) res[1].u.source->u.value.ui32;
                else
                        now = time(NULL);
@@ -187,7 +188,7 @@ static struct ulogd_plugin logemu_plugin = {
        .input = {
                .keys = logemu_inp,
                .num_keys = ARRAY_SIZE(logemu_inp),
-               .type = ULOGD_DTYPE_PACKET,
+               .type = ULOGD_DTYPE_PACKET | ULOGD_DTYPE_FLOW,
        },
        .output = {
                .type = ULOGD_DTYPE_SINK,
index 8b8929565ca397737d4eb383daa516fe7c4ed3f7..2959a29b981508ba9d31fd5d02a5aea89a2dc431 100644 (file)
@@ -163,7 +163,7 @@ static struct ulogd_plugin syslog_plugin = {
        .input = {
                .keys = syslog_inp,
                .num_keys = ARRAY_SIZE(syslog_inp),
-               .type = ULOGD_DTYPE_PACKET,
+               .type = ULOGD_DTYPE_PACKET | ULOGD_DTYPE_FLOW,
        },
        .output = {
                .type = ULOGD_DTYPE_SINK,
index 6bd61e4aa5a5af4d52dddba329a022f813fb37cf..0a3e791c6f3b04897d23a00c52028f1d29477cbd 100644 (file)
@@ -36,6 +36,7 @@ plugin="@libdir@/ulogd/ulogd_inppkt_NFLOG.so"
 plugin="@libdir@/ulogd/ulogd_inpflow_NFCT.so"
 plugin="@libdir@/ulogd/ulogd_filter_IFINDEX.so"
 plugin="@libdir@/ulogd/ulogd_filter_PRINTPKT.so"
+plugin="@libdir@/ulogd/ulogd_filter_PRINTFLOW.so"
 plugin="@libdir@/ulogd/ulogd_output_LOGEMU.so"
 plugin="@libdir@/ulogd/ulogd_output_OPRINT.so"
 plugin="@libdir@/ulogd/ulogd_raw2packet_BASE.so"
@@ -43,6 +44,9 @@ plugin="@libdir@/ulogd/ulogd_raw2packet_BASE.so"
 # this is a stack for packet-based logging via LOGEMU
 #stack=log1:NFLOG,base1:BASE,ifi1:IFINDEX,print1:PRINTPKT,emu1:LOGEMU
 
+# this is a stack for flow-based logging via LOGEMU
+#stack=ct1:NFCT,print1:PRINTFLOW,emu1:LOGEMU
+
 # this is a stack for flow-based logging via OPRINT
 #stack=ct1:NFCT,op1:OPRINT
 
diff --git a/util/printflow.c b/util/printflow.c
new file mode 100644 (file)
index 0000000..aa354d4
--- /dev/null
@@ -0,0 +1,150 @@
+/* printflow.c
+ *
+ * build something looking like an iptables LOG message, but for flows
+ *
+ * (C) 2006 by Philip Craig <philipc@snapgear.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
+ *
+ * $Id: printflow.c,v 1.1 2006/05/16 01:57:31 philipc Exp $
+ *
+ */
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <ulogd/ulogd.h>
+#include <ulogd/printflow.h>
+
+struct ulogd_key printflow_keys[] = {
+       {
+               .type = ULOGD_RET_IPADDR,
+               .flags = ULOGD_RETF_NONE,
+               .name = "ip.saddr",
+       },
+       {
+               .type = ULOGD_RET_IPADDR,
+               .flags = ULOGD_RETF_NONE,
+               .name = "ip.daddr",
+       },
+       {
+               .type = ULOGD_RET_UINT8,
+               .flags = ULOGD_RETF_NONE,
+               .name = "ip.protocol",
+       },
+       {
+               .type = ULOGD_RET_UINT16,
+               .flags = ULOGD_RETF_NONE,
+               .name = "l4.sport",
+       },
+       {
+               .type = ULOGD_RET_UINT16,
+               .flags = ULOGD_RETF_NONE,
+               .name = "l4.dport",
+       },
+       {
+               .type = ULOGD_RET_UINT32,
+               .flags = ULOGD_RETF_NONE,
+               .name = "raw.pktlen",
+       },
+       {
+               .type = ULOGD_RET_UINT32,
+               .flags = ULOGD_RETF_NONE,
+               .name = "raw.pktcount",
+       },
+       {
+               .type = ULOGD_RET_UINT8,
+               .flags = ULOGD_RETF_NONE,
+               .name = "icmp.code",
+       },
+       {
+               .type = ULOGD_RET_UINT8,
+               .flags = ULOGD_RETF_NONE,
+               .name = "icmp.type",
+       },
+       {
+               .type = ULOGD_RET_BOOL,
+               .flags = ULOGD_RETF_NONE,
+               .name = "dir",
+       },
+};
+int printflow_keys_num = sizeof(printflow_keys)/sizeof(*printflow_keys);
+
+#define GET_VALUE(res, x)      (res[x].u.source->u.value)
+#define GET_FLAGS(res, x)      (res[x].u.source->flags)
+#define pp_is_valid(res, x)    (GET_FLAGS(res, x) & ULOGD_RETF_VALID)
+
+#define pp_print(buf_cur, label, res, x, type) \
+       if (pp_is_valid(res, x)) \
+               buf_cur += sprintf(buf_cur, label"=%u ", GET_VALUE(res, x).type);
+
+int printflow_print(struct ulogd_key *res, char *buf)
+{
+       char *buf_cur = buf;
+
+       if (pp_is_valid(res, 9))
+               buf_cur += sprintf(buf_cur, "DIR=%s ",
+                               GET_VALUE(res, 9).b ? "REPLY" : "ORIG ");
+
+       if (pp_is_valid(res, 0))
+               buf_cur += sprintf(buf_cur, "SRC=%s ", inet_ntoa(
+                               (struct in_addr) {htonl(GET_VALUE(res, 0).ui32)}));
+
+       if (pp_is_valid(res, 1))
+               buf_cur += sprintf(buf_cur, "DST=%s ", inet_ntoa(
+                               (struct in_addr) {htonl(GET_VALUE(res, 1).ui32)}));
+
+       if (!pp_is_valid(res, 2))
+               goto out;
+
+       switch (GET_VALUE(res, 2).ui8) {
+       case IPPROTO_TCP:
+               buf_cur += sprintf(buf_cur, "PROTO=TCP ");
+               pp_print(buf_cur, "SPT", res, 3, ui16);
+               pp_print(buf_cur, "DPT", res, 4, ui16);
+               break;
+
+       case IPPROTO_UDP:
+               buf_cur += sprintf(buf_cur, "PROTO=UDP ");
+               pp_print(buf_cur, "SPT", res, 3, ui16);
+               pp_print(buf_cur, "DPT", res, 4, ui16);
+               break;
+
+       case IPPROTO_ICMP:
+               buf_cur += sprintf(buf_cur, "PROTO=ICMP ");
+               pp_print(buf_cur, "TYPE", res, 7, ui8);
+               pp_print(buf_cur, "CODE", res, 8, ui8);
+               break;
+
+       case IPPROTO_ESP:
+               buf_cur += sprintf(buf_cur, "PROTO=ESP ");
+               break;
+
+       case IPPROTO_AH:
+               buf_cur += sprintf(buf_cur, "PROTO=AH ");
+               break;
+
+       default:
+               pp_print(buf_cur, "PROTO", res, 2, ui8);
+               break;
+       }
+
+out:
+       pp_print(buf_cur, "PKTS", res, 6, ui32);
+       pp_print(buf_cur, "BYTES", res, 5, ui32);
+       strcat(buf_cur, "\n");
+
+       return 0;
+}