* [ebtables PATCH] Add filter for matching on a string
@ 2017-12-21 0:03 Bernie Harris
0 siblings, 0 replies; only message in thread
From: Bernie Harris @ 2017-12-21 0:03 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo, kadlec, fw, Bernie Harris
This is a proposal to add a new filter type that matches on an
arbitrary string within the network-layer packet.
This would allow filtering packets on bridge interfaces based on
certain fields of uncommon protocols (e.g. BACnet).
Two new rule options are added:
--string-offset <offset in decimal>
--string-hex <sequence of octets in hex>
The offset is relative to the start of the network layer packet.
A corresponding kernel patch will also be proposed.
Signed-off-by: Bernie Harris <bernie.harris@alliedtelesis.co.nz>
---
extensions/Makefile | 2 +-
extensions/ebt_string.c | 154 ++++++++++++++++++++++++++++
include/linux/netfilter_bridge/ebt_string.h | 15 +++
3 files changed, 170 insertions(+), 1 deletion(-)
create mode 100644 extensions/ebt_string.c
create mode 100644 include/linux/netfilter_bridge/ebt_string.h
diff --git a/extensions/Makefile b/extensions/Makefile
index b3548e8..60a70a2 100644
--- a/extensions/Makefile
+++ b/extensions/Makefile
@@ -1,7 +1,7 @@
#! /usr/bin/make
EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan mark_m mark \
- pkttype stp among limit ulog nflog
+ pkttype stp among limit ulog nflog string
EXT_TABLES+=filter nat broute
EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o)
EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o)
diff --git a/extensions/ebt_string.c b/extensions/ebt_string.c
new file mode 100644
index 0000000..0596035
--- /dev/null
+++ b/extensions/ebt_string.c
@@ -0,0 +1,154 @@
+/* ebt_string
+ *
+ * Author:
+ * Bernie Harris <bernie.harris@alliedtelesis.co.nz>
+ *
+ * October, 2017
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <ctype.h>
+#include "../include/ebtables_u.h"
+#include <linux/if_packet.h>
+#include <linux/netfilter_bridge/ebt_string.h>
+
+#define STRING_OFFSET '1'
+#define STRING_HEX '2'
+#define OPT_STRING_OFFSET 0x01
+#define OPT_STRING_HEX 0x02
+
+static const struct option opts[] =
+{
+ { "string-offset" , required_argument, 0, STRING_OFFSET },
+ { "string-hex" , required_argument, 0, STRING_HEX },
+ { 0 }
+};
+
+static void print_help()
+{
+ printf(
+"string options:\n"
+"--string-offset offset : offset relative to start of network packet to match from\n"
+"--string-hex string : string to match, in hex format (e.g. 6578616d706c65)\n"
+"The maximum allowable number of octets to match for are %d\n", MAX_STRING_OCTETS);
+}
+
+static void init(struct ebt_entry_match *match)
+{
+ struct ebt_string_info *info = (struct ebt_string_info *)match->data;
+
+ info->offset = 0;
+ info->length = 0;
+}
+
+static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
+ unsigned int *flags, struct ebt_entry_match **match)
+{
+ struct ebt_string_info *info = (struct ebt_string_info *)(*match)->data;
+ int i;
+ int input_string_length = 0;
+ char buf[3] = { 0 };
+
+ switch (c) {
+ case STRING_OFFSET:
+ ebt_check_option2(flags, OPT_STRING_OFFSET);
+ if (ebt_check_inverse2(optarg))
+ ebt_print_error2("Unexpected `!' after --string-offset");
+ info->offset = (__u16)strtoul(optarg, NULL, 10);
+ break;
+ case STRING_HEX:
+ ebt_check_option2(flags, OPT_STRING_HEX);
+
+ /* Don't support inversion */
+ if (ebt_check_inverse2(optarg))
+ ebt_print_error2("Unexpected `!' after --string-hex");
+
+ /* Check match string length */
+ input_string_length = strlen(optarg);
+ if (input_string_length == 0)
+ ebt_print_error2("Match string must contain at least one character");
+ if (input_string_length > MAX_STRING_OCTETS * 2)
+ ebt_print_error2("Match string exceeds %d octets", MAX_STRING_OCTETS);
+ if (input_string_length % 2 != 0)
+ ebt_print_error2("Invalid match string");
+
+ for (i = 0; i < input_string_length / 2; i++) {
+ strncpy(buf, optarg + 2 * i, 2);
+
+ /* String must be in hex format */
+ if (!isxdigit(buf[0]) || !isxdigit(buf[1]))
+ ebt_print_error2("Invalid match string");
+
+ info->string[i] = (unsigned char)strtoul(buf, NULL, 16);
+ }
+
+ info->length = i;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static void final_check(const struct ebt_u_entry *entry,
+ const struct ebt_entry_match *match, const char *name,
+ unsigned int hookmask, unsigned int time)
+{
+}
+
+static void print(const struct ebt_u_entry *entry,
+ const struct ebt_entry_match *match)
+{
+ struct ebt_string_info *info = (struct ebt_string_info *)match->data;
+ char print_string[MAX_STRING_OCTETS * 2 + 1] = { 0 };
+ int i;
+
+ for (i = 0; i < info->length; i++)
+ sprintf(print_string + i * 2, "%02x", info->string[i]);
+
+ printf("--string-offset %u --string-hex %s ", info->offset, print_string);
+}
+
+static int compare(const struct ebt_entry_match *m1,
+ const struct ebt_entry_match *m2)
+{
+ struct ebt_string_info *info1 = (struct ebt_string_info *)m1->data;
+ struct ebt_string_info *info2 = (struct ebt_string_info *)m2->data;
+ int i = 0;
+
+ if (info1->offset != info2->offset)
+ return 0;
+
+ if (info1->length != info2->length)
+ return 0;
+
+ for (i = 0; i < info1->length; i++)
+ {
+ if (info1->string[i] != info2->string[i])
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct ebt_u_match string_match =
+{
+ .name = "string",
+ .size = sizeof(struct ebt_string_info),
+ .help = print_help,
+ .init = init,
+ .parse = parse,
+ .final_check = final_check,
+ .print = print,
+ .compare = compare,
+ .extra_ops = opts,
+};
+
+void _init(void)
+{
+ ebt_register_match(&string_match);
+}
diff --git a/include/linux/netfilter_bridge/ebt_string.h b/include/linux/netfilter_bridge/ebt_string.h
new file mode 100644
index 0000000..ce56b30
--- /dev/null
+++ b/include/linux/netfilter_bridge/ebt_string.h
@@ -0,0 +1,15 @@
+#ifndef __LINUX_BRIDGE_EBT_STRING_H
+#define __LINUX_BRIDGE_EBT_STRING_H
+
+#include <linux/types.h>
+
+#define EBT_STRING_MATCH "string"
+#define MAX_STRING_OCTETS 64
+
+struct ebt_string_info {
+ __u16 offset;
+ __u16 length;
+ unsigned char string[MAX_STRING_OCTETS + 1];
+};
+
+#endif
--
2.15.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2017-12-21 0:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-21 0:03 [ebtables PATCH] Add filter for matching on a string Bernie Harris
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).