]> git.ipfire.org Git - thirdparty/xtables-addons.git/commitdiff
Add xt_LOGMARK (nfmark, ctmark, secmark logger)
authorJan Engelhardt <jengelh@computergmbh.de>
Wed, 30 Jan 2008 12:54:57 +0000 (13:54 +0100)
committerJan Engelhardt <jengelh@computergmbh.de>
Wed, 30 Jan 2008 12:54:57 +0000 (13:54 +0100)
xt_LOGMARK dumps the nfmark (packet mark), ctmark (connection mark)
and/or secmark to syslog.

Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
extensions/Kbuild
extensions/Makefile.am
extensions/libxt_LOGMARK.c [new file with mode: 0644]
extensions/libxt_LOGMARK.man [new file with mode: 0644]
extensions/xt_LOGMARK.Kconfig [new file with mode: 0644]
extensions/xt_LOGMARK.c [new file with mode: 0644]
extensions/xt_LOGMARK.h [new file with mode: 0644]

index 73c477f27991833d45b8ee165edb05c45ff0d87d..8662717166cac36a5e8fce35cdff68430ba1eefa 100644 (file)
@@ -1,5 +1,6 @@
 # -*- Makefile -*-
 
+obj-m += xt_LOGMARK.o
 obj-m += xt_TARPIT.o
 obj-m += xt_TEE.o
 obj-m += compat_xtables.o
index 92403d16057d9151d9f448690518296b369eeaba..d838aacc82e7a2859b58c584ab10e5946557d00d 100644 (file)
@@ -10,6 +10,7 @@ AM_CFLAGS        = ${regular_CFLAGS} ${iptables_CFLAGS} ${kinclude_CFLAGS} \
                    -D_INIT=$*_init
 AM_LDFLAGS       = -module -avoid-version
 ipt_LTLIBRARIES  = \
+       libxt_LOGMARK.la \
        libxt_TARPIT.la \
        libxt_TEE.la
 
diff --git a/extensions/libxt_LOGMARK.c b/extensions/libxt_LOGMARK.c
new file mode 100644 (file)
index 0000000..b074c59
--- /dev/null
@@ -0,0 +1,168 @@
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <xtables.h>
+#include "xt_LOGMARK.h"
+
+enum {
+       F_LEVEL   = 1 << 0,
+       F_PREFIX  = 1 << 1,
+       F_NFMARK  = 1 << 2,
+       F_CTMARK  = 1 << 3,
+       F_SECMARK = 1 << 4,
+};
+
+static const struct option logmark_tg_opts[] = {
+       {.name = "log-level",   .has_arg = true,  .val = 'l'},
+       {.name = "log-prefix",  .has_arg = true,  .val = 'p'},
+       {.name = "log-nfmark",  .has_arg = false, .val = 'n'},
+       {.name = "log-ctmark",  .has_arg = false, .val = 'c'},
+       {.name = "log-secmark", .has_arg = false, .val = 's'},
+       {},
+};
+
+static void logmark_tg_help(void)
+{
+       printf(
+"LOGMARK target options:\n"
+"  --log-level level      Level of logging (numeric, 0-8)\n"
+"  --log-prefix prefix    Prefix log messages with this string\n"
+"  --log-nfmark           Log the packet mark\n"
+"  --log-ctmark           Log the connection mark\n"
+"  --log-secmark          Log the security mark of the packet\n"
+);
+}
+
+static void logmark_tg_init(struct xt_entry_target *target)
+{
+       struct xt_logmark_tginfo *info = (void *)target->data;
+
+       info->level   = 4;
+       *info->prefix = '\0';
+}
+
+static int
+logmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
+                 const void *entry, struct xt_entry_target **target)
+{
+       struct xt_logmark_tginfo *info = (void *)(*target)->data;
+       unsigned int x;
+
+       switch (c) {
+       case 'l': /* --log-level */
+               param_act(P_ONLY_ONCE, "LOGMARK", "--log-level", *flags & F_LEVEL);
+               param_act(P_NO_INVERT, "LOGMARK", "--log-level", invert);
+               if (!strtonum(optarg, NULL, &x, 0, 8))
+                       param_act(P_BAD_VALUE, "LOGMARK", "--log-level", optarg);
+               info->level = x;
+               *flags |= F_LEVEL;
+               return true;
+
+       case 'p': /* --log-prefix */
+               param_act(P_ONLY_ONCE, "LOGMARK", "--log-prefix", *flags & F_PREFIX);
+               param_act(P_NO_INVERT, "LOGMARK", "--log-prefix", invert);
+               if (strlen(optarg) > sizeof(info->prefix))
+                       exit_error(PARAMETER_PROBLEM, "LOGMARK: Maximum "
+                                  "prefix length is %zu",
+                                  sizeof(info->prefix));
+               if (strchr(optarg, '\n'))
+                       exit_error(PARAMETER_PROBLEM, "LOGMARK: Newlines not "
+                                  "allowed in log prefix");
+               strncpy(info->prefix, optarg, sizeof(info->prefix));
+               *flags |= F_PREFIX;
+               return true;
+
+       case 'n': /* --log-nfmark */
+               param_act(P_ONLY_ONCE, "LOGMARK", "--log-nfmark", *flags & F_NFMARK);
+               param_act(P_NO_INVERT, "LOGMARK", "--log-nfmark", invert);
+               info->flags |= XT_LOGMARK_NFMARK;
+               *flags |= F_NFMARK;
+               return true;
+
+       case 'c': /* --log-ctmark */
+               param_act(P_ONLY_ONCE, "LOGMARK", "--log-ctmark", *flags & F_CTMARK);
+               param_act(P_NO_INVERT, "LOGMARK", "--log-ctmark", invert);
+               info->flags |= XT_LOGMARK_CTMARK;
+               *flags |= F_CTMARK;
+               return true;
+
+       case 's': /* --log-secmark */
+               param_act(P_ONLY_ONCE, "LOGMARK", "--log-secmark", *flags & F_SECMARK);
+               param_act(P_NO_INVERT, "LOGMARK", "--log-secmark", invert);
+               info->flags |= XT_LOGMARK_SECMARK;
+               *flags |= F_SECMARK;
+               return true;
+       }
+       return false;
+}
+
+static void
+logmark_tg_print(const void *ip, const struct xt_entry_target *target,
+                 int numeric)
+{
+       const struct xt_logmark_tginfo *info = (void *)target->data;
+
+       printf("LOGMARK level %u prefix \"%s\"", info->level, info->prefix);
+       if (info->flags & XT_LOGMARK_NFMARK)
+               printf(" nfmark");
+       if (info->flags & XT_LOGMARK_CTMARK)
+               printf(" ctmark");
+       if (info->flags & XT_LOGMARK_SECMARK)
+               printf(" secmark");
+       printf("; ");
+}
+
+static void
+logmark_tg_save(const void *ip, const struct xt_entry_target *target)
+{
+       const struct xt_logmark_tginfo *info = (void *)target->data;
+
+       if (info->level != 4)
+               printf("--log-level %u ", info->level);
+       if (*info->prefix != '\0')
+               printf("--log-prefix \"%s\" ", info->prefix);
+       if (info->flags & XT_LOGMARK_NFMARK)
+               printf("--log-nfmark ");
+       if (info->flags & XT_LOGMARK_CTMARK)
+               printf("--log-ctmark ");
+       if (info->flags & XT_LOGMARK_SECMARK)
+               printf("--log-secmark ");
+}
+
+static struct xtables_target logmark_tg_reg = {
+       .version       = IPTABLES_VERSION,
+       .name          = "LOGMARK",
+       .revision      = 0,
+       .family        = AF_INET,
+       .size          = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
+       .userspacesize = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
+       .help          = logmark_tg_help,
+       .init          = logmark_tg_init,
+       .parse         = logmark_tg_parse,
+       .print         = logmark_tg_print,
+       .save          = logmark_tg_save,
+       .extra_opts    = logmark_tg_opts,
+};
+
+static struct xtables_target logmark_tg6_reg = {
+       .version       = IPTABLES_VERSION,
+       .name          = "LOGMARK",
+       .revision      = 0,
+       .family        = AF_INET6,
+       .size          = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
+       .userspacesize = XT_ALIGN(sizeof(struct xt_logmark_tginfo)),
+       .help          = logmark_tg_help,
+       .init          = logmark_tg_init,
+       .parse         = logmark_tg_parse,
+       .print         = logmark_tg_print,
+       .save          = logmark_tg_save,
+       .extra_opts    = logmark_tg_opts,
+};
+
+void _init(void);
+void _init(void)
+{
+       xtables_register_target(&logmark_tg_reg);
+       xtables_register_target(&logmark_tg6_reg);
+}
diff --git a/extensions/libxt_LOGMARK.man b/extensions/libxt_LOGMARK.man
new file mode 100644 (file)
index 0000000..e954aa4
--- /dev/null
@@ -0,0 +1,17 @@
+The LOGMARK target will log packet and connection marks to syslog.
+.TP
+\fB--log-level\fR \fIlevel\fR
+A logging level between 0 and 8 (inclusive).
+.TP
+\fB--log-prefix\fR \fIstring\fR
+Prefix log messages with the specified prefix; up to 29 bytes long, and useful
+for distinguishing messages in the logs.
+.TP
+\fB--log-nfmark\fR
+Include the packet mark in the log.
+.TP
+\fB--log-ctmark\fR
+Include the connection mark in the log.
+.TP
+\fB--log-secmark\fR
+Include the packet secmark in the log.
diff --git a/extensions/xt_LOGMARK.Kconfig b/extensions/xt_LOGMARK.Kconfig
new file mode 100644 (file)
index 0000000..3743010
--- /dev/null
@@ -0,0 +1,6 @@
+config NETFILTER_XT_TARGET_LOGMARK
+       tristate '"LOGMARK" target support'
+       depends on NETFILTER_XTABLES
+       ---help---
+       This option adds a "LOGMARK" target which allows you to look at the
+       netfilter marks and secmark of the packet and connection.
diff --git a/extensions/xt_LOGMARK.c b/extensions/xt_LOGMARK.c
new file mode 100644 (file)
index 0000000..d6c05c7
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *     xt_LOGMARK - netfilter mark logging
+ *     useful for debugging
+ *
+ *     Copyright © CC Computer Consultants, 2007 - 2008
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 or 3 as published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter/x_tables.h>
+#include <net/netfilter/nf_conntrack.h>
+#include "compat_xtables.h"
+#include "xt_LOGMARK.h"
+
+static unsigned int
+logmark_tg(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
+{
+       const struct xt_logmark_tginfo *info = targinfo;
+
+       printk("<%u>%.*s", info->level, sizeof(info->prefix), info->prefix);
+
+       if (info->flags & XT_LOGMARK_NFMARK)
+               printk(" nfmark=0x%x", skb->mark);
+       if (info->flags & XT_LOGMARK_CTMARK) {
+               const struct nf_conn *ct;
+               enum ip_conntrack_info ctinfo;
+
+               ct = nf_ct_get(skb, &ctinfo);
+               if (ct == NULL)
+                       printk(" ctmark=X");
+               else
+                       printk(" ctmark=0x%x", ct->mark);
+       }
+       if (info->flags & XT_LOGMARK_SECMARK)
+               printk(" secmark=0x%x", skb->secmark);
+       printk("\n");
+
+       return XT_CONTINUE;
+}
+
+static bool
+logmark_tg_check(const char *tablename, const void *e,
+                 const struct xt_target *target, void *targinfo,
+                 unsigned int hook_mask)
+{
+       const struct xt_logmark_tginfo *info = targinfo;
+
+       if (info->level >= 8) {
+               pr_debug("LOGMARK: level %u >= 8\n", info->level);
+               return false;
+       }
+
+       return true;
+}
+
+static struct xt_target logmark_tg_reg[] __read_mostly = {
+       {
+               .name       = "LOGMARK",
+               .revision   = 0,
+               .family     = AF_INET,
+               .checkentry = logmark_tg_check,
+               .target     = logmark_tg,
+               .targetsize = sizeof(struct xt_logmark_tginfo),
+               .me         = THIS_MODULE,
+       },
+       {
+               .name       = "LOGMARK",
+               .revision   = 0,
+               .family     = AF_INET6,
+               .checkentry = logmark_tg_check,
+               .target     = logmark_tg,
+               .targetsize = sizeof(struct xt_logmark_tginfo),
+               .me         = THIS_MODULE,
+       },
+};
+
+static int __init logmark_tg_init(void)
+{
+       return xt_register_targets(logmark_tg_reg, ARRAY_SIZE(logmark_tg_reg));
+}
+
+static void __exit logmark_tg_exit(void)
+{
+       xt_unregister_targets(logmark_tg_reg, ARRAY_SIZE(logmark_tg_reg));
+}
+
+module_init(logmark_tg_init);
+module_exit(logmark_tg_exit);
+MODULE_DESCRIPTION("Xtables: netfilter mark logging to syslog");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_LOGMARK");
+MODULE_ALIAS("ip6t_LOGMARK");
diff --git a/extensions/xt_LOGMARK.h b/extensions/xt_LOGMARK.h
new file mode 100644 (file)
index 0000000..0f1ed52
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _LINUX_NETFILTER_XT_LOGMARK_TARGET_H
+#define _LINUX_NETFILTER_XT_LOGMARK_TARGET_H 1
+
+enum {
+       XT_LOGMARK_NFMARK  = 1 << 0,
+       XT_LOGMARK_CTMARK  = 1 << 1,
+       XT_LOGMARK_SECMARK = 1 << 2,
+};
+
+struct xt_logmark_tginfo {
+       char prefix[14];
+       u_int8_t level;
+       u_int8_t flags;
+};
+
+#endif /* _LINUX_NETFILTER_XT_LOGMARK_TARGET_H */