[PATCH 1/2 nftables] src: introduce passive OS fingerprint matching

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add support for "osf" expression. Example:

table ip foo {
	chain bar {
		type filter hook input priority 0; policy accept;
		osf "Linux" counter packets 3 bytes 132
	}
}

Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
---
 include/expression.h                |  6 +++++
 include/linux/netfilter/nf_tables.h | 12 ++++++++++
 include/osf.h                       |  6 +++++
 src/Makefile.am                     |  1 +
 src/evaluate.c                      |  9 ++++++++
 src/netlink_delinearize.c           | 15 +++++++++++++
 src/netlink_linearize.c             | 13 +++++++++++
 src/osf.c                           | 35 +++++++++++++++++++++++++++++
 src/parser_bison.y                  | 12 ++++++++++
 src/scanner.l                       |  2 ++
 10 files changed, 111 insertions(+)
 create mode 100644 include/osf.h
 create mode 100644 src/osf.c

diff --git a/include/expression.h b/include/expression.h
index 2bb51e5..b898698 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -25,6 +25,7 @@
  * @EXPR_EXTHDR:	exthdr expression
  * @EXPR_META:		meta expression
  * @EXPR_SOCKET:	socket expression
+ * @EXPR_OSF:		osf expression
  * @EXPR_CT:		conntrack expression
  * @EXPR_CONCAT:	concatenation
  * @EXPR_LIST:		list of expressions
@@ -52,6 +53,7 @@ enum expr_types {
 	EXPR_EXTHDR,
 	EXPR_META,
 	EXPR_SOCKET,
+	EXPR_OSF,
 	EXPR_CT,
 	EXPR_CONCAT,
 	EXPR_LIST,
@@ -191,6 +193,7 @@ enum expr_flags {
 #include <hash.h>
 #include <ct.h>
 #include <socket.h>
+#include <osf.h>
 
 /**
  * struct expr
@@ -303,6 +306,9 @@ struct expr {
 			/* SOCKET */
 			enum nft_socket_keys	key;
 		} socket;
+		struct {
+			/* OSF */
+		} osf;
 		struct {
 			/* EXPR_RT */
 			enum nft_rt_keys	key;
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 88e0ca1..c54a1a0 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -932,6 +932,18 @@ enum nft_socket_keys {
 };
 #define NFT_SOCKET_MAX	(__NFT_SOCKET_MAX - 1)
 
+/**
+ * enum nft_osf_attributes - nf_tables osf expression netlink attributes
+ *
+ * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ */
+enum nft_osf_attributes {
+	NFTA_OSF_UNSPEC,
+	NFTA_OSF_DREG,
+	__NFTA_OSF_MAX
+};
+#define NFT_OSF_MAX		(__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_ct_keys - nf_tables ct expression keys
  *
diff --git a/include/osf.h b/include/osf.h
new file mode 100644
index 0000000..715b04e
--- /dev/null
+++ b/include/osf.h
@@ -0,0 +1,6 @@
+#ifndef NFTABLES_OSF_H
+#define NFTABLES_OSF_H
+
+struct expr *osf_expr_alloc(const struct location *loc);
+
+#endif /* NFTABLES_OSF_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index bd6fe07..db8f4a3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,6 +58,7 @@ libnftables_la_SOURCES =			\
 		mergesort.c			\
 		tcpopt.c			\
 		socket.c			\
+		osf.c				\
 		libnftables.c
 
 # yacc and lex generate dirty code
diff --git a/src/evaluate.c b/src/evaluate.c
index ae881cc..839866e 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1720,6 +1720,13 @@ static int expr_evaluate_socket(struct eval_ctx *ctx, struct expr **expr)
 	return 0;
 }
 
+static int expr_evaluate_osf(struct eval_ctx *ctx, struct expr **expr)
+{
+	__expr_set_context(&ctx->ectx, (*expr)->dtype, (*expr)->byteorder,
+			   (*expr)->len, 1);
+	return 0;
+}
+
 static int expr_evaluate_variable(struct eval_ctx *ctx, struct expr **exprp)
 {
 	struct expr *new = expr_clone((*exprp)->sym->expr);
@@ -1759,6 +1766,8 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
 		return expr_evaluate_meta(ctx, expr);
 	case EXPR_SOCKET:
 		return expr_evaluate_socket(ctx, expr);
+	case EXPR_OSF:
+		return expr_evaluate_osf(ctx, expr);
 	case EXPR_FIB:
 		return expr_evaluate_fib(ctx, expr);
 	case EXPR_PAYLOAD:
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 7e9765c..557da5e 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -630,6 +630,19 @@ static void netlink_parse_socket(struct netlink_parse_ctx *ctx,
 	netlink_set_register(ctx, dreg, expr);
 }
 
+static void netlink_parse_osf(struct netlink_parse_ctx *ctx,
+			      const struct location *loc,
+			      const struct nftnl_expr *nle)
+{
+	enum nft_registers dreg;
+	struct expr *expr;
+
+	expr = osf_expr_alloc(loc);
+	printf("%u", NFTNL_EXPR_OSF_DREG);
+	dreg = netlink_parse_register(nle, NFTNL_EXPR_OSF_DREG);
+	netlink_set_register(ctx, dreg, expr);
+}
+
 static void netlink_parse_meta_stmt(struct netlink_parse_ctx *ctx,
 				    const struct location *loc,
 				    const struct nftnl_expr *nle)
@@ -1353,6 +1366,7 @@ static const struct {
 	{ .name = "exthdr",	.parse = netlink_parse_exthdr },
 	{ .name = "meta",	.parse = netlink_parse_meta },
 	{ .name = "socket",	.parse = netlink_parse_socket },
+	{ .name = "osf",	.parse = netlink_parse_osf },
 	{ .name = "rt",		.parse = netlink_parse_rt },
 	{ .name = "ct",		.parse = netlink_parse_ct },
 	{ .name = "connlimit",	.parse = netlink_parse_connlimit },
@@ -2042,6 +2056,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
 	case EXPR_NUMGEN:
 	case EXPR_FIB:
 	case EXPR_SOCKET:
+	case EXPR_OSF:
 		break;
 	case EXPR_HASH:
 		if (expr->hash.expr)
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 8471e83..3021d85 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -219,6 +219,17 @@ static void netlink_gen_socket(struct netlink_linearize_ctx *ctx,
 	nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
+static void netlink_gen_osf(struct netlink_linearize_ctx *ctx,
+			    const struct expr *expr,
+			    enum nft_registers dreg)
+{
+	struct nftnl_expr *nle;
+
+	nle = alloc_nft_expr("osf");
+	netlink_put_register(nle, NFTNL_EXPR_OSF_DREG, dreg);
+	nftnl_rule_add_expr(ctx->nlr, nle);
+}
+
 static void netlink_gen_numgen(struct netlink_linearize_ctx *ctx,
 			    const struct expr *expr,
 			    enum nft_registers dreg)
@@ -708,6 +719,8 @@ static void netlink_gen_expr(struct netlink_linearize_ctx *ctx,
 		return netlink_gen_fib(ctx, expr, dreg);
 	case EXPR_SOCKET:
 		return netlink_gen_socket(ctx, expr, dreg);
+	case EXPR_OSF:
+		return netlink_gen_osf(ctx, expr, dreg);
 	default:
 		BUG("unknown expression type %s\n", expr->ops->name);
 	}
diff --git a/src/osf.c b/src/osf.c
new file mode 100644
index 0000000..783ead1
--- /dev/null
+++ b/src/osf.c
@@ -0,0 +1,35 @@
+#include <nftables.h>
+#include <expression.h>
+#include <utils.h>
+#include <string.h>
+#include <osf.h>
+
+#include <net/if.h>
+
+static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
+{
+	nft_print(octx, "osf");
+}
+
+static void osf_expr_clone(struct expr *new, const struct expr *expr)
+{
+}
+
+static const struct expr_ops osf_expr_ops = {
+	.type		= EXPR_OSF,
+	.name		= "osf",
+	.print		= osf_expr_print,
+	.clone		= osf_expr_clone,
+};
+
+struct expr *osf_expr_alloc(const struct location *loc)
+{
+	unsigned int len = IFNAMSIZ * BITS_PER_BYTE;
+	const struct datatype *type = &string_type;
+	struct expr *expr;
+
+	expr = expr_alloc(loc, &osf_expr_ops, type,
+			  BYTEORDER_HOST_ENDIAN, len);
+
+	return expr;
+}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 98bfeba..557569a 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -192,6 +192,8 @@ int nft_lex(void *, void *, void *);
 %token SOCKET			"socket"
 %token TRANSPARENT		"transparent"
 
+%token OSF			"osf"
+
 %token HOOK			"hook"
 %token DEVICE			"device"
 %token DEVICES			"devices"
@@ -716,6 +718,9 @@ int nft_lex(void *, void *, void *);
 %destructor { expr_free($$); }	fib_expr
 %type <val>			fib_tuple	fib_result	fib_flag
 
+%type <expr>			osf_expr
+%destructor { expr_free($$); }	osf_expr
+
 %type <val>			markup_format
 %type <string>			monitor_event
 %destructor { xfree($$); }	monitor_event
@@ -2907,6 +2912,7 @@ primary_expr		:	symbol_expr			{ $$ = $1; }
 			|	numgen_expr			{ $$ = $1; }
 			|	hash_expr			{ $$ = $1; }
 			|	fib_expr			{ $$ = $1; }
+			|	osf_expr			{ $$ = $1; }
 			|	'('	basic_expr	')'	{ $$ = $2; }
 			;
 
@@ -3577,6 +3583,12 @@ socket_expr		:	SOCKET	socket_key
 socket_key 		: TRANSPARENT { $$ = NFT_SOCKET_TRANSPARENT; }
 			;
 
+osf_expr		:	OSF	NAME
+			{
+				$$ = osf_expr_alloc(&@$);
+			}
+			;
+
 offset_opt		:	/* empty */	{ $$ = 0; }
 			|	OFFSET	NUM	{ $$ = $2; }
 			;
diff --git a/src/scanner.l b/src/scanner.l
index ed01b5e..468ea9f 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -534,6 +534,8 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 
 "fib"			{ return FIB; }
 
+"osf"			{ return OSF; }
+
 "notrack"		{ return NOTRACK; }
 
 "options"		{ return OPTIONS; }
-- 
2.18.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux