]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: introduce passive OS fingerprint matching
authorFernando Fernandez Mancera <ffmancera@riseup.net>
Fri, 3 Aug 2018 21:47:11 +0000 (23:47 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 3 Aug 2018 22:21:19 +0000 (00:21 +0200)
Add support for "osf" expression. Example:

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

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/expression.h
include/linux/netfilter/nf_tables.h
src/Makefile.am
src/evaluate.c
src/netlink_delinearize.c
src/netlink_linearize.c
src/osf.c [new file with mode: 0644]
src/parser_bison.y
src/scanner.l

index 2bb51e531ecbeb550d8bf6be42ffdffb34ca6087..f2c5c1ad7a04a25effe00b3de1b046e00aa98a13 100644 (file)
@@ -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
index ea374ae6755681e1eb016d67afbdd637aa18d9e9..63b90546fcd893436d8b5c1a77b861957cc35589 100644 (file)
@@ -933,6 +933,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
  *
index bd6fe07beb8a4faa8dd1799c3f50a7330c7f1e9f..ed3640e4f6372dbb015467d0f8b81b4ae18c2596 100644 (file)
@@ -56,6 +56,7 @@ libnftables_la_SOURCES =                      \
                iface.c                         \
                services.c                      \
                mergesort.c                     \
+               osf.c                           \
                tcpopt.c                        \
                socket.c                        \
                libnftables.c
index b793c125a5ca95a0e42d404081e5a13b8916c705..1fc861f600b4d068b589b886113be5e853f3dff5 100644 (file)
@@ -1724,6 +1724,11 @@ 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)
+{
+       return expr_evaluate_primary(ctx, expr);
+}
+
 static int expr_evaluate_variable(struct eval_ctx *ctx, struct expr **exprp)
 {
        struct expr *new = expr_clone((*exprp)->sym->expr);
@@ -1763,6 +1768,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:
index c886ff98b7116dbf50936fee75c072d0e4032cdd..dbf1f6186a3d57e519a36bc0aacace3ea3413b2d 100644 (file)
@@ -630,6 +630,18 @@ 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);
+       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)
@@ -1397,6 +1409,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 },
@@ -2087,6 +2100,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)
index aa00564aa81b1829275a7537a1acc7bbed4b7590..442c5a940bc3f7c485a945520a46f7582fb0632b 100644 (file)
@@ -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 (file)
index 0000000..f07a725
--- /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 name");
+}
+
+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;
+}
index 827b0580899b73bc34bf71a53585fdea86129b25..9a75120a4dc758361a294111cc9e6672e4564f0e 100644 (file)
@@ -194,6 +194,8 @@ int nft_lex(void *, void *, void *);
 
 %token TPROXY                  "tproxy"
 
+%token OSF                     "osf"
+
 %token HOOK                    "hook"
 %token DEVICE                  "device"
 %token DEVICES                 "devices"
@@ -721,6 +723,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
@@ -2952,6 +2957,7 @@ primary_expr              :       symbol_expr                     { $$ = $1; }
                        |       numgen_expr                     { $$ = $1; }
                        |       hash_expr                       { $$ = $1; }
                        |       fib_expr                        { $$ = $1; }
+                       |       osf_expr                        { $$ = $1; }
                        |       '('     basic_expr      ')'     { $$ = $2; }
                        ;
 
@@ -2997,6 +3003,12 @@ fib_tuple                :       fib_flag        DOT     fib_tuple
                        |       fib_flag
                        ;
 
+osf_expr               :       OSF     NAME
+                       {
+                               $$ = osf_expr_alloc(&@$);
+                       }
+                       ;
+
 shift_expr             :       primary_expr
                        |       shift_expr              LSHIFT          primary_expr
                        {
index 703700fe6fde94437e1b33428a279cd04da7f0d0..bce691529058b58838ac76c031adf18241e6710e 100644 (file)
@@ -536,6 +536,8 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 
 "fib"                  { return FIB; }
 
+"osf"                  { return OSF; }
+
 "notrack"              { return NOTRACK; }
 
 "options"              { return OPTIONS; }