Re: [nft PATCH 2/3] json: Fix osf ttl support

2018-10-24 Thread Fernando Fernandez Mancera

Thanks Phil, I will keep this in mind for the next time.

On 10/24/18 12:35 PM, Phil Sutter wrote:

Having to use numerical values for ttl property in JSON is not
practical as these values are arbitrary and meaningful only in
netfilter. Instead align JSON output/input with standard API, accepting
names for TTL matching strategy.

Also add missing documentation in libnftables-json man page and fix JSON
equivalent in tests/py.

Fixes: 03eafe098d5ee ("osf: add ttl option support")
Signed-off-by: Phil Sutter 
---
  doc/libnftables-json.adoc | 24 
  src/json.c| 13 -
  src/parser_json.c | 19 +++
  tests/py/inet/osf.t.json  | 35 ---
  4 files changed, 83 insertions(+), 8 deletions(-)

diff --git a/doc/libnftables-json.adoc b/doc/libnftables-json.adoc
index 98303b357f10c..ea5fbe818302f 100644
--- a/doc/libnftables-json.adoc
+++ b/doc/libnftables-json.adoc
@@ -1288,3 +1288,27 @@ 
  
  
  Construct a reference to packet's socket.

+
+=== OSF
+[verse]
+
+*{ "osf": {
+   "key":* 'OSF_KEY'*,
+   "ttl":* 'OSF_TTL'
+*}}*
+
+'OSF_KEY' := *"name"*
+'OSF_TTL' := *"loose"* | *"skip"*
+
+
+Perform OS fingerprinting. This expression is typically used in LHS of a 
*match*
+statement.
+
+*key*::
+   What part of the fingerprint info to match against. At this point, only
+   the OS name is supported.
+*ttl*::
+   Define how packet's TTL value is to be matched. This property is
+   optional. If omitted, TTL value has to match exactly. A value of *loose*
+   accepts TTL values less than the fingerprint one. A value of *skip*
+   omits TTL value comparison entirely.
diff --git a/src/json.c b/src/json.c
index cea9f19cd9982..d21536afd714e 100644
--- a/src/json.c
+++ b/src/json.c
@@ -857,7 +857,18 @@ json_t *socket_expr_json(const struct expr *expr, struct 
output_ctx *octx)
  
  json_t *osf_expr_json(const struct expr *expr, struct output_ctx *octx)

  {
-   return json_pack("{s:{s:i, s:s}}", "osf", "ttl", expr->osf.ttl, "key", 
"name");
+   json_t *root = json_pack("{s:s}", "key", "name");
+
+   switch (expr->osf.ttl) {
+   case 1:
+   json_object_set_new(root, "ttl", json_string("loose"));
+   break;
+   case 2:
+   json_object_set_new(root, "ttl", json_string("skip"));
+   break;
+   }
+
+   return json_pack("{s:o}", "osf", root);
  }
  
  json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)

diff --git a/src/parser_json.c b/src/parser_json.c
index fc0dc9a9e4046..46a02fe14de03 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -375,14 +375,25 @@ static struct expr *json_parse_meta_expr(struct json_ctx 
*ctx,
  static struct expr *json_parse_osf_expr(struct json_ctx *ctx,
const char *type, json_t *root)
  {
-   const char *key;
-   uint8_t ttl;
+   const char *key, *ttl;
+   uint8_t ttlval = 0;
  
-	if (json_unpack_err(ctx, root, "{s:i, s:s}", "ttl", ttl,"key", ))

+   if (json_unpack_err(ctx, root, "{s:s}", "key", ))
return NULL;
  
+	if (!json_unpack(root, "{s:s}", "ttl", )) {

+   if (!strcmp(ttl, "loose")) {
+   ttlval = 1;
+   } else if (!strcmp(ttl, "skip")) {
+   ttlval = 2;
+   } else {
+   json_error(ctx, "Invalid osf ttl option '%s'.", ttl);
+   return NULL;
+   }
+   }
+
if (!strcmp(key, "name"))
-   return osf_expr_alloc(int_loc, ttl);
+   return osf_expr_alloc(int_loc, ttlval);
  
  	json_error(ctx, "Invalid osf key value.");

return NULL;
diff --git a/tests/py/inet/osf.t.json b/tests/py/inet/osf.t.json
index 45335cab30c0b..452f3023585b3 100644
--- a/tests/py/inet/osf.t.json
+++ b/tests/py/inet/osf.t.json
@@ -4,7 +4,6 @@
  "match": {
  "left": {
  "osf": {
-"ttl": 0,
  "key": "name"
  }
  },
@@ -14,13 +13,44 @@
  }
  ]
  
+# osf ttl loose name "Linux"

+[
+{
+"match": {
+"left": {
+"osf": {
+"key": "name",
+"ttl": "loose"
+}
+},
+"op": "==",
+"right": "Linux"
+}
+}
+]
+
+# osf ttl skip name "Linux"
+[
+{
+"match": {
+"left": {
+"osf": {
+"key": "name",
+"ttl": "skip"
+}
+},
+"op": "==",
+"right": "Linux"
+}
+}
+]
+
  # osf name { "Windows", "MacOs" }
  [
  {
  "match": {
  "left": {
  "osf": {
-"ttl": 0,
  "key": "name"
  }
  

[PATCH nft v3] src: osf: add ttl option support

2018-10-23 Thread Fernando Fernandez Mancera
Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl skip name "Linux"
}
}

Signed-off-by: Fernando Fernandez Mancera 
---
v1:initial patch
v2:use "ttl-global, ttl-nocheck.." instead of "1, 2.."
v3:better names for ttl options, add json and tests/py support
All is working properly.
---
 include/expression.h|  4 ++
 include/linux/netfilter/nf_tables.h |  2 +
 include/osf.h   |  2 +-
 src/json.c  |  2 +-
 src/netlink_delinearize.c   |  5 ++-
 src/netlink_linearize.c |  1 +
 src/osf.c   | 26 ++-
 src/parser_bison.y  | 19 +++-
 src/parser_json.c   |  5 ++-
 tests/py/inet/osf.t |  3 ++
 tests/py/inet/osf.t.json|  3 ++
 tests/py/inet/osf.t.payload | 68 -
 12 files changed, 129 insertions(+), 11 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index d6977c3..f018c95 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -345,6 +345,10 @@ struct expr {
uint8_t direction;
uint8_t spnum;
} xfrm;
+   struct {
+   /* EXPR_OSF */
+   uint8_t ttl;
+   } osf;
};
 };
 
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 4e28598..1d13ad3 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -939,10 +939,12 @@ enum nft_socket_keys {
  * enum nft_osf_attributes - nf_tables osf expression netlink attributes
  *
  * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
  */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX
 };
 #define NFT_OSF_MAX(__NFTA_OSF_MAX - 1)
diff --git a/include/osf.h b/include/osf.h
index 54cdd4a..23ea34d 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,7 +1,7 @@
 #ifndef NFTABLES_OSF_H
 #define NFTABLES_OSF_H
 
-struct expr *osf_expr_alloc(const struct location *loc);
+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl);
 
 extern int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
 
diff --git a/src/json.c b/src/json.c
index 1cde270..cea9f19 100644
--- a/src/json.c
+++ b/src/json.c
@@ -857,7 +857,7 @@ json_t *socket_expr_json(const struct expr *expr, struct 
output_ctx *octx)
 
 json_t *osf_expr_json(const struct expr *expr, struct output_ctx *octx)
 {
-   return json_pack("{s:{s:s}}", "osf", "key", "name");
+   return json_pack("{s:{s:i, s:s}}", "osf", "ttl", expr->osf.ttl, "key", 
"name");
 }
 
 json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index cd05885..84948db 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -655,8 +655,11 @@ static void netlink_parse_osf(struct netlink_parse_ctx 
*ctx,
 {
enum nft_registers dreg;
struct expr *expr;
+   uint8_t ttl;
+
+   ttl = nftnl_expr_get_u8(nle, NFTNL_EXPR_OSF_TTL);
+   expr = osf_expr_alloc(loc, ttl);
 
-   expr = osf_expr_alloc(loc);
dreg = netlink_parse_register(nle, NFTNL_EXPR_OSF_DREG);
netlink_set_register(ctx, dreg, expr);
 }
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 0ac51bd..0c8f5fe 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -227,6 +227,7 @@ static void netlink_gen_osf(struct netlink_linearize_ctx 
*ctx,
 
nle = alloc_nft_expr("osf");
netlink_put_register(nle, NFTNL_EXPR_OSF_DREG, dreg);
+   nftnl_expr_set_u8(nle, NFTNL_EXPR_OSF_TTL, expr->osf.ttl);
nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
diff --git a/src/osf.c b/src/osf.c
index 85c9573..436f34b 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -5,13 +5,32 @@
 #include 
 #include 
 
+static const char *osf_ttl_int_to_str(const uint8_t ttl)
+{
+   if (ttl == 1)
+   return "ttl loose ";
+   else if (ttl == 2)
+   return "ttl skip ";
+
+   return "";
+}
+
 static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
-   nft_print(octx, "osf name");
+   const char *ttl_str;
+
+   ttl_str = osf_ttl_int_to_str(expr->osf.ttl);
+   nft_print(octx, "osf %sname", ttl_str);
 }
 
 static void osf_expr_clone(struct expr *new, const struct expr *expr)
 {
+   new->osf.ttl = e

[PATCH 1/2 nft v3 preview] src: osf: add ttl option support

2018-10-22 Thread Fernando Fernandez Mancera
Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf skip name "Linux"
}
}

Signed-off-by: Fernando Fernandez Mancera 
---
v1:initial patch
v2:use "ttl-global, ttl-nocheck.." instead of "1, 2.."
v3:better names for ttl options, add json and tests/py support
---
 include/expression.h|  4 +++
 include/linux/netfilter/nf_tables.h |  2 ++
 include/osf.h   |  2 +-
 src/json.c  |  2 +-
 src/netlink_delinearize.c   |  5 +++-
 src/netlink_linearize.c |  1 +
 src/osf.c   | 26 --
 src/parser_bison.y  | 19 +++--
 src/parser_json.c   |  5 ++--
 tests/py/inet/osf.t |  3 +++
 tests/py/inet/osf.t.json|  3 +++
 tests/py/inet/osf.t.payload | 41 +++--
 12 files changed, 90 insertions(+), 23 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index d6977c3..f018c95 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -345,6 +345,10 @@ struct expr {
uint8_t direction;
uint8_t spnum;
} xfrm;
+   struct {
+   /* EXPR_OSF */
+   uint8_t ttl;
+   } osf;
};
 };
 
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 4e28598..1d13ad3 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -939,10 +939,12 @@ enum nft_socket_keys {
  * enum nft_osf_attributes - nf_tables osf expression netlink attributes
  *
  * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
  */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX
 };
 #define NFT_OSF_MAX(__NFTA_OSF_MAX - 1)
diff --git a/include/osf.h b/include/osf.h
index 54cdd4a..23ea34d 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,7 +1,7 @@
 #ifndef NFTABLES_OSF_H
 #define NFTABLES_OSF_H
 
-struct expr *osf_expr_alloc(const struct location *loc);
+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl);
 
 extern int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
 
diff --git a/src/json.c b/src/json.c
index 1cde270..cea9f19 100644
--- a/src/json.c
+++ b/src/json.c
@@ -857,7 +857,7 @@ json_t *socket_expr_json(const struct expr *expr, struct 
output_ctx *octx)
 
 json_t *osf_expr_json(const struct expr *expr, struct output_ctx *octx)
 {
-   return json_pack("{s:{s:s}}", "osf", "key", "name");
+   return json_pack("{s:{s:i, s:s}}", "osf", "ttl", expr->osf.ttl, "key", 
"name");
 }
 
 json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index cd05885..84948db 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -655,8 +655,11 @@ static void netlink_parse_osf(struct netlink_parse_ctx 
*ctx,
 {
enum nft_registers dreg;
struct expr *expr;
+   uint8_t ttl;
+
+   ttl = nftnl_expr_get_u8(nle, NFTNL_EXPR_OSF_TTL);
+   expr = osf_expr_alloc(loc, ttl);
 
-   expr = osf_expr_alloc(loc);
dreg = netlink_parse_register(nle, NFTNL_EXPR_OSF_DREG);
netlink_set_register(ctx, dreg, expr);
 }
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 0ac51bd..0c8f5fe 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -227,6 +227,7 @@ static void netlink_gen_osf(struct netlink_linearize_ctx 
*ctx,
 
nle = alloc_nft_expr("osf");
netlink_put_register(nle, NFTNL_EXPR_OSF_DREG, dreg);
+   nftnl_expr_set_u8(nle, NFTNL_EXPR_OSF_TTL, expr->osf.ttl);
nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
diff --git a/src/osf.c b/src/osf.c
index 85c9573..1a224fd 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -5,13 +5,32 @@
 #include 
 #include 
 
+static const char *osf_ttl_int_to_str(const uint8_t ttl)
+{
+   if (ttl == 1)
+   return "loose ";
+   else if (ttl == 2)
+   return "skip ";
+
+   return "";
+}
+
 static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
-   nft_print(octx, "osf name");
+   const char *ttl_str;
+
+   ttl_str = osf_ttl_int_to_str(expr->osf.ttl);
+   nft_print(octx, "osf %sname", ttl_str);
 }
 
 static void osf_expr_clone(struct expr *new, const struct expr *expr)
 {
+   new->osf.ttl = expr->osf.ttl;
+}
+
+

[PATCH 2/2 nft v3] doc: osf: add ttl option to man page

2018-10-22 Thread Fernando Fernandez Mancera
---
 doc/primary-expression.txt | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt
index 0fda76d..0c02d9d 100644
--- a/doc/primary-expression.txt
+++ b/doc/primary-expression.txt
@@ -187,18 +187,30 @@ and others) from packets with the SYN bit set.
 [options="header"]
 |==
 |Name |Description| Type
+|ttl|
+Do TTL checks on the packet to determine the operating system.|
+string
 |name|
-Name of the OS signature to match. All signatures can be found at pf.os file.|
-Use "unknown" for OS signatures that the expression could not detect.
+Name of the OS signature to match. All signatures can be found at pf.os file.
+Use "unknown" for OS signatures that the expression could not detect.|
+string
 |==
 
+.Available ttl values
+-
+If no TTL attribute is passed, make a true IP header and fingerprint TTL true 
comparison. This generally works for LANs.
+
+* loose: Check if the IP header's TTL is less than the fingerprint one. Works 
for globally-routable addresses.
+* skip: Do not compare the TTL at all.
+-
+
 .Using osf expression
 -
-# Accept packets that match the "Linux" OS signature.
+# Accept packets that match the "Linux" OS genre signature without comparing 
TTL.
 table inet x {
 chain y {
type filter hook input priority 0; policy accept;
-osf "Linux"
+osf skip name "Linux"
 }
 }
 ---
-- 
2.19.1



Re: [PATCH 1/2 nft v2] src: osf: add ttl option support

2018-10-22 Thread Fernando Fernandez Mancera
El 22 de octubre de 2018 20:38:13 CEST, Pablo Neira Ayuso  
escribió:
>On Mon, Oct 22, 2018 at 05:35:42PM +0200, Fernando Fernandez Mancera
>wrote:
>> I am going to add the necessary NFT_OSF_* definitions in the
>nf_tables.h
>
>Just add a copy of nf_osf.h to nftables tree. We cannot mangle
>nf_tables.h, it's a copy from the original header to ensure sources
>compile with any kernel version.
>
>> header. The options format is "ttl-*" because "global" or "loose"
>could be
>> confusing. Do you prefer the option without "ttl-"?
>
>Yes, the ttl- is not needed.
>
>Make sure what you list via 'nft list ruleset > file' can be loaded
>via 'nft -f file'

The patch is already done but tests/py is giving me errors when using ct mark 
and maps with osf. Should I send it?

I am trying to solve this anyway.

Thanks :-)


Re: [PATCH 1/2 nft v2] src: osf: add ttl option support

2018-10-22 Thread Fernando Fernandez Mancera

Comments below.

On 10/15/18 2:47 PM, Pablo Neira Ayuso wrote:

Please send a v3 including tests/py. More comments below.

On Sat, Sep 29, 2018 at 12:15:17PM +0200, Fernando Fernandez Mancera wrote:

Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl nocheck name "Linux"


Listing and output should match, ie. what you list should work with
nft -f, see below.


diff --git a/src/parser_bison.y b/src/parser_bison.y
index 831090b..a7ec858 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -739,6 +739,7 @@ int nft_lex(void *, void *, void *);
  %type  fib_tuple   fib_result  fib_flag
  
  %type 			osf_expr

+%type   osf_ttl
  %destructor { expr_free($$); }osf_expr
  
  %type 			markup_format

@@ -3112,9 +3113,21 @@ fib_tuple:   fib_flagDOT 
fib_tuple
|   fib_flag
;
  
-osf_expr		:	OSF	NAME

+osf_expr   :   OSF osf_ttl NAME
{
-   $$ = osf_expr_alloc(&@$);
+   $$ = osf_expr_alloc(&@$, $2);
+   }
+   ;
+
+osf_ttl:   /* empty */ { $$ = 0; }
+   |   STRING
+   {
+   if (!strcmp($1, "ttl-global"))


This should be "global". But I would suggest you rename this to "loose".


+   $$ = 1;


Can we use NFT_OSF_* definitions, instead of magic number?


+   else if (!strcmp($1, "ttl-nocheck"))


This should be "nocheck". But I'd suggest you rename this to "skip"


+   $$ = 2;


Same here, avoid magic number, use definition.


+   else
+   $$ = 3;


Same thing.



I am going to add the necessary NFT_OSF_* definitions in the nf_tables.h 
header. The options format is "ttl-*" because "global" or "loose" could 
be confusing. Do you prefer the option without "ttl-"?


Thanks.


Re: [PATCH 1/2 nft v2] src: osf: add ttl option support

2018-10-17 Thread Fernando Fernandez Mancera




On 10/15/18 2:47 PM, Pablo Neira Ayuso wrote:

Please send a v3 including tests/py. More comments below.

On Sat, Sep 29, 2018 at 12:15:17PM +0200, Fernando Fernandez Mancera wrote:

Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl nocheck name "Linux"


Listing and output should match, ie. what you list should work with
nft -f, see below.


diff --git a/src/parser_bison.y b/src/parser_bison.y
index 831090b..a7ec858 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -739,6 +739,7 @@ int nft_lex(void *, void *, void *);
  %type  fib_tuple   fib_result  fib_flag
  
  %type 			osf_expr

+%type   osf_ttl
  %destructor { expr_free($$); }osf_expr
  
  %type 			markup_format

@@ -3112,9 +3113,21 @@ fib_tuple:   fib_flagDOT 
fib_tuple
|   fib_flag
;
  
-osf_expr		:	OSF	NAME

+osf_expr   :   OSF osf_ttl NAME
{
-   $$ = osf_expr_alloc(&@$);
+   $$ = osf_expr_alloc(&@$, $2);
+   }
+   ;
+
+osf_ttl:   /* empty */ { $$ = 0; }
+   |   STRING
+   {
+   if (!strcmp($1, "ttl-global"))


This should be "global". But I would suggest you rename this to "loose".


+   $$ = 1;


Can we use NFT_OSF_* definitions, instead of magic number?


+   else if (!strcmp($1, "ttl-nocheck"))


This should be "nocheck". But I'd suggest you rename this to "skip"


+   $$ = 2;


Same here, avoid magic number, use definition.


+   else
+   $$ = 3;


Same thing.


}
;
diff --git a/src/osf.c b/src/osf.c
index 85c9573..c7dd25f 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -5,13 +5,32 @@
  #include 
  #include 
  
+static const char *osf_ttl_int_to_str(const uint8_t ttl)

+{
+   if (ttl == 1)
+   return "ttl global";
+   else if (ttl == 2)
+   return "ttl nocheck";
+
+   return "";
+}
+
  static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
  {
-   nft_print(octx, "osf name");
+   const char *ttl_str;
+
+   ttl_str = osf_ttl_int_to_str(expr->osf.ttl);
+   nft_print(octx, "osf %s name", ttl_str);
  }
  
  static void osf_expr_clone(struct expr *new, const struct expr *expr)

  {
+   new->osf.ttl = expr->osf.ttl;
+}
+
+static bool osf_expr_cmp(const struct expr *e1, const struct expr *e2)
+{
+   return e1->osf.ttl == e2->osf.ttl;
  }
  
  static const struct expr_ops osf_expr_ops = {

@@ -19,10 +38,11 @@ static const struct expr_ops osf_expr_ops = {
.name   = "osf",
.print  = osf_expr_print,
.clone  = osf_expr_clone,
+   .cmp= osf_expr_cmp,
.json   = osf_expr_json,


BTW, could you extend json to support 'ttl' too?



Hi Pablo, thanks for this review.

All changes seem fine to me :-)


[PATCH nf-next v4] nft_osf: Add ttl option support

2018-10-10 Thread Fernando Fernandez Mancera
Add ttl option support to the nftables "osf" expression.

Signed-off-by: Fernando Fernandez Mancera 
---
v1:initial patch
v2:v2: code correctness and fix the "~" typo.
v3:make priv->ttl = ttl; optional and priv->ttl default value is now 0.
v4:delete "if (ttl_check != -1)" branch
---
 include/linux/netfilter/nfnetlink_osf.h  |  3 +-
 include/uapi/linux/netfilter/nf_tables.h |  7 
 net/netfilter/nfnetlink_osf.c| 46 +++-
 net/netfilter/nft_osf.c  | 15 +++-
 4 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
index ecf7dab81e9e..c646c966 100644
--- a/include/linux/netfilter/nfnetlink_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -27,6 +27,7 @@ bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  const struct list_head *nf_osf_fingers);
 
 const char *nf_osf_find(const struct sk_buff *skb,
-const struct list_head *nf_osf_fingers);
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check);
 
 #endif /* _NFOSF_H */
diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 5444e76870bb..579974b0bf0d 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1511,9 +1511,16 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+/**
+ * enum nft_osf_attributes - nftables osf expression netlink attributes
+ *
+ * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
+ */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX,
 };
 #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index 00db27dfd2ff..6f41dd74729d 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -30,32 +30,27 @@ EXPORT_SYMBOL_GPL(nf_osf_fingers);
 static inline int nf_osf_ttl(const struct sk_buff *skb,
 int ttl_check, unsigned char f_ttl)
 {
+   struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
const struct iphdr *ip = ip_hdr(skb);
-
-   if (ttl_check != -1) {
-   if (ttl_check == NF_OSF_TTL_TRUE)
-   return ip->ttl == f_ttl;
-   if (ttl_check == NF_OSF_TTL_NOCHECK)
-   return 1;
-   else if (ip->ttl <= f_ttl)
-   return 1;
-   else {
-   struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
-   int ret = 0;
-
-   for_ifa(in_dev) {
-   if (inet_ifa_match(ip->saddr, ifa)) {
-   ret = (ip->ttl == f_ttl);
-   break;
-   }
-   }
-   endfor_ifa(in_dev);
-
-   return ret;
+   int ret = 0;
+
+   if (ttl_check == NF_OSF_TTL_TRUE)
+   return ip->ttl == f_ttl;
+   if (ttl_check == NF_OSF_TTL_NOCHECK)
+   return 1;
+   else if (ip->ttl <= f_ttl)
+   return 1;
+
+   for_ifa(in_dev) {
+   if (inet_ifa_match(ip->saddr, ifa)) {
+   ret = (ip->ttl == f_ttl);
+   break;
}
}
 
-   return ip->ttl == f_ttl;
+   endfor_ifa(in_dev);
+
+   return ret;
 }
 
 struct nf_osf_hdr_ctx {
@@ -213,7 +208,7 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
if (!tcp)
return false;
 
-   ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : -1;
+   ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : 0;
 
list_for_each_entry_rcu(kf, _osf_fingers[ctx.df], finger_entry) {
 
@@ -257,7 +252,8 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
 EXPORT_SYMBOL_GPL(nf_osf_match);
 
 const char *nf_osf_find(const struct sk_buff *skb,
-   const struct list_head *nf_osf_fingers)
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check)
 {
const struct iphdr *ip = ip_hdr(skb);
const struct nf_osf_user_finger *f;
@@ -275,7 +271,7 @@ const char *nf_osf_find(const struct sk_buff *skb,
 
list_for_each_entry_rcu(kf, _osf_fingers[ctx.df], finger_entry) {
f = >finger;
-   if (!nf_osf_match_one(skb, f, -1, ))
+   if (!nf_osf_match_one(skb, f, ttl_check, ))
continue;
 
genre = f->genre;
diff --git 

[PATCH nf] netfilter: nft_osf: output hook is not valid anymore

2018-10-10 Thread Fernando Fernandez Mancera
nft_osf no longer supports "output" hook as xt_osf doesn't either.

Fixes: b96af92d6eaf ("netfilter: nf_tables: implement Passive OS fingerprint 
module in nft_osf")
Signed-off-by: Fernando Fernandez Mancera 
---
 net/netfilter/nft_osf.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index a35fb59ace73..bce6617ca514 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -69,6 +69,15 @@ static int nft_osf_dump(struct sk_buff *skb, const struct 
nft_expr *expr)
return -1;
 }
 
+static int nft_osf_validate(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nft_data **data)
+{
+return nft_chain_validate_hooks(ctx->chain, (1 << NF_INET_LOCAL_IN) |
+   (1 << NF_INET_PRE_ROUTING) |
+   (1 << NF_INET_FORWARD));
+}
+
 static struct nft_expr_type nft_osf_type;
 static const struct nft_expr_ops nft_osf_op = {
.eval   = nft_osf_eval,
@@ -76,6 +85,7 @@ static const struct nft_expr_ops nft_osf_op = {
.init   = nft_osf_init,
.dump   = nft_osf_dump,
.type   = _osf_type,
+   .validate   = nft_osf_validate,
 };
 
 static struct nft_expr_type nft_osf_type __read_mostly = {
-- 
2.19.1



Re: [PATCH nf-next v3] nft_osf: Add ttl option support

2018-10-04 Thread Fernando Fernandez Mancera

On 10/4/18 2:03 PM, Pablo Neira Ayuso wrote:

On Thu, Oct 04, 2018 at 01:57:17PM +0200, Fernando Fernandez Mancera wrote:
[...]

diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index 00db27dfd2ff..e0fe1b8429ac 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -32,9 +32,7 @@ static inline int nf_osf_ttl(const struct sk_buff *skb,
  {
const struct iphdr *ip = ip_hdr(skb);
  
-	if (ttl_check != -1) {

-   if (ttl_check == NF_OSF_TTL_TRUE)
-   return ip->ttl == f_ttl;
+   if (ttl_check != 0) {


May ttl_check now ever be -1 now that we do not need it in nft_osf?

If xt_osf never does it, we can probably remove this branch, ie.

-   if (ttl_check != -1) {

and save one level of indentation.

This would need a careful look at current xt_osf.c - as well as its
previous one code - to make sure we do not break anything if we remove
this ttl_check != -1 branch.



Currently in xt_osf.c if the option "--ttl" is not found by default, 
after the v3 iteration, it sets ttl_check to 0 as you can see here:


@@ -213,7 +211,7 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
if (!tcp)
return false;

-   ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : -1;
+   ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : 0;

I think we can remove the "ttl_check != -1" branch and keep the if 
statement that checks "ttl_check == NF_OSF_TTL_TRUE". I can do it and 
test if it breaks something in xt_osf.c but I think this change should 
break nothing.


[PATCH nf-next v3] nft_osf: Add ttl option support

2018-10-04 Thread Fernando Fernandez Mancera
Add ttl option support to the nftables "osf" expression.

Signed-off-by: Fernando Fernandez Mancera 
---
v1:initial patch
v2:v2: code correctness and fix the "~" typo.
v3:make priv->ttl = ttl; optional and priv->ttl default value is now 0.
---
 include/linux/netfilter/nfnetlink_osf.h  |  3 ++-
 include/uapi/linux/netfilter/nf_tables.h |  7 +++
 net/netfilter/nfnetlink_osf.c| 11 +--
 net/netfilter/nft_osf.c  | 15 ++-
 4 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
index ecf7dab81e9e..c646c966 100644
--- a/include/linux/netfilter/nfnetlink_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -27,6 +27,7 @@ bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  const struct list_head *nf_osf_fingers);
 
 const char *nf_osf_find(const struct sk_buff *skb,
-const struct list_head *nf_osf_fingers);
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check);
 
 #endif /* _NFOSF_H */
diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 5444e76870bb..579974b0bf0d 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1511,9 +1511,16 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+/**
+ * enum nft_osf_attributes - nftables osf expression netlink attributes
+ *
+ * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
+ */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX,
 };
 #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index 00db27dfd2ff..e0fe1b8429ac 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -32,9 +32,7 @@ static inline int nf_osf_ttl(const struct sk_buff *skb,
 {
const struct iphdr *ip = ip_hdr(skb);
 
-   if (ttl_check != -1) {
-   if (ttl_check == NF_OSF_TTL_TRUE)
-   return ip->ttl == f_ttl;
+   if (ttl_check != 0) {
if (ttl_check == NF_OSF_TTL_NOCHECK)
return 1;
else if (ip->ttl <= f_ttl)
@@ -213,7 +211,7 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
if (!tcp)
return false;
 
-   ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : -1;
+   ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : 0;
 
list_for_each_entry_rcu(kf, _osf_fingers[ctx.df], finger_entry) {
 
@@ -257,7 +255,8 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
 EXPORT_SYMBOL_GPL(nf_osf_match);
 
 const char *nf_osf_find(const struct sk_buff *skb,
-   const struct list_head *nf_osf_fingers)
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check)
 {
const struct iphdr *ip = ip_hdr(skb);
const struct nf_osf_user_finger *f;
@@ -275,7 +274,7 @@ const char *nf_osf_find(const struct sk_buff *skb,
 
list_for_each_entry_rcu(kf, _osf_fingers[ctx.df], finger_entry) {
f = >finger;
-   if (!nf_osf_match_one(skb, f, -1, ))
+   if (!nf_osf_match_one(skb, f, ttl_check, ))
continue;
 
genre = f->genre;
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index 5af74b37f423..63c7199a441d 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -6,10 +6,12 @@
 
 struct nft_osf {
enum nft_registers  dreg:8;
+   u8  ttl;
 };
 
 static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
[NFTA_OSF_DREG] = { .type = NLA_U32 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U8 },
 };
 
 static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
@@ -33,7 +35,7 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
return;
}
 
-   os_name = nf_osf_find(skb, nf_osf_fingers);
+   os_name = nf_osf_find(skb, nf_osf_fingers, priv->ttl);
if (!os_name)
strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN);
else
@@ -46,6 +48,14 @@ static int nft_osf_init(const struct nft_ctx *ctx,
 {
struct nft_osf *priv = nft_expr_priv(expr);
int err;
+   u8 ttl;
+
+   if (nla_get_u8(tb[NFTA_OSF_TTL])) {
+   ttl = nla_get_u8(tb[NFTA_OSF_TTL]);
+   if (ttl > 2)
+   return -EINVAL;
+   priv->ttl = ttl;
+   }
 
priv->dreg = n

Re: [PATCH nf-next v2] nft_osf: Add ttl option support

2018-10-04 Thread Fernando Fernandez Mancera




On 10/3/18 5:36 PM, Pablo Neira Ayuso wrote:

Hi Fernando,

A few comments.

On Sat, Sep 29, 2018 at 12:18:51PM +0200, Fernando Fernandez Mancera wrote:

Add ttl option support to the nftables "osf" expression.


[..]

if (!os_name)
strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN);
else
@@ -46,6 +50,15 @@ static int nft_osf_init(const struct nft_ctx *ctx,
  {
struct nft_osf *priv = nft_expr_priv(expr);
int err;
+   u8 ttl;
+
+   if (!tb[NFTA_OSF_TTL])
+   return -EINVAL;
+
+   ttl = nla_get_u8(tb[NFTA_OSF_TTL]);
+   if (ttl > 2)
+   return -EOPNOTSUPP;
+   priv->ttl = nla_get_u8(tb[NFTA_OSF_TTL]);


Better make this optional, ie.

 if (tb[NFTA_OSF_TTL]) {
 ttl = nla_get_u8(tb[NFTA_OSF_TTL]);
 if (ttl > 2)
 return -EINVAL;

 priv->ttl = ttl;
 }



Seems fine to me, I am going to do it.


What is the good default value for priv->ttl? We were using -1 before
this patch, but now ttl is u8, while nf_osf_ttl() takes a signed
value. Better make this s8 instead of u8?

Thanks.



About the default value for priv->ttl, I think we can use 0 instead of 
-1. Right now, if priv->ttl is -1 the behaviour established is "-m osf 
--ttl 0". What do you think about that?


Thanks.


[PATCH nft] include: add missing xfrm.h to Makefile.am

2018-09-30 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/Makefile.am | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/Makefile.am b/include/Makefile.am
index d3a677d..c103f48 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -31,4 +31,5 @@ noinst_HEADERS =  cli.h   \
rule.h  \
rt.h\
utils.h \
+   xfrm.h  \
xt.h
-- 
2.19.0



Re: [PATCH 2/2 nft] doc: osf: add ttl option to man page

2018-09-30 Thread Fernando Fernandez Mancera
Sorry, I have forgotten to add "Signed-off-by: Fernando Fernandez 
Mancera ". Thanks.


On 9/29/18 12:15 PM, Fernando Fernandez Mancera wrote:

---
  doc/primary-expression.txt | 20 
  1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt
index 0fda76d..92dd89a 100644
--- a/doc/primary-expression.txt
+++ b/doc/primary-expression.txt
@@ -187,18 +187,30 @@ and others) from packets with the SYN bit set.
  [options="header"]
  |==
  |Name |Description| Type
+|ttl|
+Do TTL checks on the packet to determine the operating system.|
+string
  |name|
-Name of the OS signature to match. All signatures can be found at pf.os file.|
-Use "unknown" for OS signatures that the expression could not detect.
+Name of the OS signature to match. All signatures can be found at pf.os file.
+Use "unknown" for OS signatures that the expression could not detect.|
+string
  |==
  
+.Available ttl values

+-
+If no TTL attribute is passed, make a true IP header and fingerprint TTL true 
comparison. This generally works for LANs.
+
+* ttl-global: Check if the IP header's TTL is less than the fingerprint one. 
Works for globally-routable addresses.
+* ttl-nocheck: Do not compare the TTL at all.
+-
+
  .Using osf expression
  -
-# Accept packets that match the "Linux" OS signature.
+# Accept packets that match the "Linux" OS genre signature without comparing 
TTL.
  table inet x {
  chain y {
type filter hook input priority 0; policy accept;
-osf "Linux"
+osf ttl-nocheck name "Linux"
  }
  }
  ---



[PATCH nf-next v2] nft_osf: Add ttl option support

2018-09-29 Thread Fernando Fernandez Mancera
Add ttl option support to the nftables "osf" expression.

Signed-off-by: Fernando Fernandez Mancera 
---
v1: initial patch
v2: code correctness and fix the "~" typo.
---
 include/linux/netfilter/nfnetlink_osf.h  |  3 ++-
 include/uapi/linux/netfilter/nf_tables.h |  7 +++
 net/netfilter/nfnetlink_osf.c|  5 +++--
 net/netfilter/nft_osf.c  | 18 +-
 4 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
index ecf7dab81e9e..c646c966 100644
--- a/include/linux/netfilter/nfnetlink_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -27,6 +27,7 @@ bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  const struct list_head *nf_osf_fingers);
 
 const char *nf_osf_find(const struct sk_buff *skb,
-const struct list_head *nf_osf_fingers);
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check);
 
 #endif /* _NFOSF_H */
diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 5444e76870bb..579974b0bf0d 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1511,9 +1511,16 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+/**
+ * enum nft_osf_attributes - nftables osf expression netlink attributes
+ *
+ * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
+ */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX,
 };
 #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index 00db27dfd2ff..ec8fa9661538 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -257,7 +257,8 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
 EXPORT_SYMBOL_GPL(nf_osf_match);
 
 const char *nf_osf_find(const struct sk_buff *skb,
-   const struct list_head *nf_osf_fingers)
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check)
 {
const struct iphdr *ip = ip_hdr(skb);
const struct nf_osf_user_finger *f;
@@ -275,7 +276,7 @@ const char *nf_osf_find(const struct sk_buff *skb,
 
list_for_each_entry_rcu(kf, _osf_fingers[ctx.df], finger_entry) {
f = >finger;
-   if (!nf_osf_match_one(skb, f, -1, ))
+   if (!nf_osf_match_one(skb, f, ttl_check, ))
continue;
 
genre = f->genre;
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index 5af74b37f423..0fbaaafff8d8 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -6,10 +6,12 @@
 
 struct nft_osf {
enum nft_registers  dreg:8;
+   u8  ttl;
 };
 
 static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
[NFTA_OSF_DREG] = { .type = NLA_U32 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U8 },
 };
 
 static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
@@ -21,6 +23,7 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
const struct tcphdr *tcp;
struct tcphdr _tcph;
const char *os_name;
+   int ttl_check;
 
tcp = skb_header_pointer(skb, ip_hdrlen(skb),
 sizeof(struct tcphdr), &_tcph);
@@ -33,7 +36,8 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
return;
}
 
-   os_name = nf_osf_find(skb, nf_osf_fingers);
+   ttl_check = priv->ttl;
+   os_name = nf_osf_find(skb, nf_osf_fingers, ttl_check);
if (!os_name)
strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN);
else
@@ -46,6 +50,15 @@ static int nft_osf_init(const struct nft_ctx *ctx,
 {
struct nft_osf *priv = nft_expr_priv(expr);
int err;
+   u8 ttl;
+
+   if (!tb[NFTA_OSF_TTL])
+   return -EINVAL;
+
+   ttl = nla_get_u8(tb[NFTA_OSF_TTL]);
+   if (ttl > 2)
+   return -EOPNOTSUPP;
+   priv->ttl = nla_get_u8(tb[NFTA_OSF_TTL]);
 
priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
err = nft_validate_register_store(ctx, priv->dreg, NULL,
@@ -60,6 +73,9 @@ static int nft_osf_dump(struct sk_buff *skb, const struct 
nft_expr *expr)
 {
const struct nft_osf *priv = nft_expr_priv(expr);
 
+   if (nla_put_u8(skb, NFTA_OSF_TTL, priv->ttl))
+   goto nla_put_failure;
+
if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg))
goto nla_put_failure;
 
-- 
2.19.0



[PATCH libnftnl] expr: osf: add ttl option support

2018-09-29 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/libnftnl/expr.h |  1 +
 include/linux/netfilter/nf_tables.h |  4 +++-
 src/expr/osf.c  | 26 +-
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 6285c6f..6988c62 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -281,6 +281,7 @@ enum {
 
 enum {
NFTNL_EXPR_OSF_DREG = NFTNL_EXPR_BASE,
+   NFTNL_EXPR_OSF_TTL,
 };
 
 enum {
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index da2c291..936687d 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -936,11 +936,13 @@ enum nft_socket_keys {
 /**
  * enum nft_osf_attributes - nf_tables osf expression netlink attributes
  *
- * @NFTA_OSF_DREG: OS to match
+ * @NFTA_OSF_DREG: destination register (NLA_U32)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
  */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX,
 };
 #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
diff --git a/src/expr/osf.c b/src/expr/osf.c
index 6fd62e5..39d7e0c 100644
--- a/src/expr/osf.c
+++ b/src/expr/osf.c
@@ -14,6 +14,7 @@
 
 struct nftnl_expr_osf {
enum nft_registers  dreg;
+   uint8_t ttl;
 };
 
 static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
@@ -25,6 +26,9 @@ static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t 
type,
case NFTNL_EXPR_OSF_DREG:
osf->dreg = *((uint32_t *)data);
break;
+   case NFTNL_EXPR_OSF_TTL:
+   osf->ttl = *((uint8_t *)data);
+   break;
}
return 0;
 }
@@ -39,6 +43,9 @@ nftnl_expr_osf_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_OSF_DREG:
*data_len = sizeof(osf->dreg);
return >dreg;
+   case NFTNL_EXPR_OSF_TTL:
+   *data_len = sizeof(osf->ttl);
+   return >ttl;
}
return NULL;
 }
@@ -56,6 +63,11 @@ static int nftnl_expr_osf_cb(const struct nlattr *attr, void 
*data)
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
+
+   case NFTNL_EXPR_OSF_TTL:
+   if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
+   abi_breakage();
+   break;
}
 
tb[type] = attr;
@@ -69,6 +81,8 @@ nftnl_expr_osf_build(struct nlmsghdr *nlh, const struct 
nftnl_expr *e)
 
if (e->flags & (1 << NFTNL_EXPR_OSF_DREG))
mnl_attr_put_u32(nlh, NFTNL_EXPR_OSF_DREG, htonl(osf->dreg));
+   if (e->flags & (1 << NFTNL_EXPR_OSF_TTL))
+   mnl_attr_put_u8(nlh, NFTNL_EXPR_OSF_TTL, osf->ttl);
 }
 
 static int
@@ -85,6 +99,11 @@ nftnl_expr_osf_parse(struct nftnl_expr *e, struct nlattr 
*attr)
e->flags |= (1 << NFTNL_EXPR_OSF_DREG);
}
 
+   if (tb[NFTA_OSF_TTL]) {
+   osf->ttl = mnl_attr_get_u8(tb[NFTA_OSF_TTL]);
+   e->flags |= (1 << NFTNL_EXPR_OSF_TTL);
+   }
+
return 0;
 }
 
@@ -95,7 +114,7 @@ static int nftnl_expr_osf_snprintf_default(char *buf, size_t 
size,
int ret, offset = 0, len = size;
 
if (e->flags & (1 << NFTNL_EXPR_OSF_DREG)) {
-   ret = snprintf(buf, len, "dreg %u ", osf->dreg);
+   ret = snprintf(buf, len, "dreg %u ttl %u", osf->dreg, osf->ttl);
SNPRINTF_BUFFER_SIZE(ret, len, offset);
}
 
@@ -110,6 +129,8 @@ static int nftnl_expr_osf_export(char *buf, size_t size,
 
if (e->flags & (1 << NFTNL_EXPR_OSF_DREG))
nftnl_buf_u32(, type, osf->dreg, "dreg");
+   if (e->flags & (1 << NFTNL_EXPR_OSF_TTL))
+   nftnl_buf_u32(, type, osf->ttl, "ttl");
 
return nftnl_buf_done();
 }
@@ -140,6 +161,9 @@ static bool nftnl_expr_osf_cmp(const struct nftnl_expr *e1,
if (e1->flags & (1 << NFTNL_EXPR_OSF_DREG))
eq &= (l1->dreg == l2->dreg);
 
+   if (e1->flags & (1 << NFTNL_EXPR_OSF_TTL))
+   eq &= (l1->ttl == l2->ttl);
+
return eq;
 }
 
-- 
2.19.0



[PATCH 2/2 nft] doc: osf: add ttl option to man page

2018-09-29 Thread Fernando Fernandez Mancera
---
 doc/primary-expression.txt | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt
index 0fda76d..92dd89a 100644
--- a/doc/primary-expression.txt
+++ b/doc/primary-expression.txt
@@ -187,18 +187,30 @@ and others) from packets with the SYN bit set.
 [options="header"]
 |==
 |Name |Description| Type
+|ttl|
+Do TTL checks on the packet to determine the operating system.|
+string
 |name|
-Name of the OS signature to match. All signatures can be found at pf.os file.|
-Use "unknown" for OS signatures that the expression could not detect.
+Name of the OS signature to match. All signatures can be found at pf.os file.
+Use "unknown" for OS signatures that the expression could not detect.|
+string
 |==
 
+.Available ttl values
+-
+If no TTL attribute is passed, make a true IP header and fingerprint TTL true 
comparison. This generally works for LANs.
+
+* ttl-global: Check if the IP header's TTL is less than the fingerprint one. 
Works for globally-routable addresses.
+* ttl-nocheck: Do not compare the TTL at all.
+-
+
 .Using osf expression
 -
-# Accept packets that match the "Linux" OS signature.
+# Accept packets that match the "Linux" OS genre signature without comparing 
TTL.
 table inet x {
 chain y {
type filter hook input priority 0; policy accept;
-osf "Linux"
+osf ttl-nocheck name "Linux"
 }
 }
 ---
-- 
2.19.0



[PATCH 1/2 nft v2] src: osf: add ttl option support

2018-09-29 Thread Fernando Fernandez Mancera
Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl nocheck name "Linux"
}
}

Signed-off-by: Fernando Fernandez Mancera 
---
v1: initial patch
v2: use "ttl-global" or "ttl-nocheck" instead of "1" or "2"
---
 include/expression.h|  4 
 include/linux/netfilter/nf_tables.h |  2 ++
 include/osf.h   |  2 +-
 src/netlink_delinearize.c   |  5 -
 src/netlink_linearize.c |  1 +
 src/osf.c   | 26 --
 src/parser_bison.y  | 17 +++--
 7 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index fb52abf..a794128 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -345,6 +345,10 @@ struct expr {
uint8_t direction;
uint8_t spnum;
} xfrm;
+   struct {
+   /* EXPR_OSF */
+   uint8_t ttl;
+   } osf;
};
 };
 
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 169c2ab..1003942 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -939,10 +939,12 @@ enum nft_socket_keys {
  * enum nft_osf_attributes - nf_tables osf expression netlink attributes
  *
  * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
  */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX
 };
 #define NFT_OSF_MAX(__NFTA_OSF_MAX - 1)
diff --git a/include/osf.h b/include/osf.h
index 54cdd4a..23ea34d 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,7 +1,7 @@
 #ifndef NFTABLES_OSF_H
 #define NFTABLES_OSF_H
 
-struct expr *osf_expr_alloc(const struct location *loc);
+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl);
 
 extern int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
 
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 0a6ebe0..d474893 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -655,8 +655,11 @@ static void netlink_parse_osf(struct netlink_parse_ctx 
*ctx,
 {
enum nft_registers dreg;
struct expr *expr;
+   uint8_t ttl;
+
+   ttl = nftnl_expr_get_u8(nle, NFTNL_EXPR_OSF_TTL);
+   expr = osf_expr_alloc(loc, ttl);
 
-   expr = osf_expr_alloc(loc);
dreg = netlink_parse_register(nle, NFTNL_EXPR_OSF_DREG);
netlink_set_register(ctx, dreg, expr);
 }
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 0ac51bd..0c8f5fe 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -227,6 +227,7 @@ static void netlink_gen_osf(struct netlink_linearize_ctx 
*ctx,
 
nle = alloc_nft_expr("osf");
netlink_put_register(nle, NFTNL_EXPR_OSF_DREG, dreg);
+   nftnl_expr_set_u8(nle, NFTNL_EXPR_OSF_TTL, expr->osf.ttl);
nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
diff --git a/src/osf.c b/src/osf.c
index 85c9573..c7dd25f 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -5,13 +5,32 @@
 #include 
 #include 
 
+static const char *osf_ttl_int_to_str(const uint8_t ttl)
+{
+   if (ttl == 1)
+   return "ttl global";
+   else if (ttl == 2)
+   return "ttl nocheck";
+
+   return "";
+}
+
 static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
-   nft_print(octx, "osf name");
+   const char *ttl_str;
+
+   ttl_str = osf_ttl_int_to_str(expr->osf.ttl);
+   nft_print(octx, "osf %s name", ttl_str);
 }
 
 static void osf_expr_clone(struct expr *new, const struct expr *expr)
 {
+   new->osf.ttl = expr->osf.ttl;
+}
+
+static bool osf_expr_cmp(const struct expr *e1, const struct expr *e2)
+{
+   return e1->osf.ttl == e2->osf.ttl;
 }
 
 static const struct expr_ops osf_expr_ops = {
@@ -19,10 +38,11 @@ static const struct expr_ops osf_expr_ops = {
.name   = "osf",
.print  = osf_expr_print,
.clone  = osf_expr_clone,
+   .cmp= osf_expr_cmp,
.json   = osf_expr_json,
 };
 
-struct expr *osf_expr_alloc(const struct location *loc)
+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl)
 {
unsigned int len = NFT_OSF_MAXGENRELEN * BITS_PER_BYTE;
const struct datatype *type = _type;
@@ -31,5 +51,7 @@ struct expr *osf_expr_alloc(const struct location *loc)
expr = expr_alloc(loc, _expr_ops, type,
  BYTEORDER_HOST_EN

Re: [PATCH nft] src: osf: add ttl option support

2018-09-26 Thread Fernando Fernandez Mancera

On 9/18/18 1:16 AM, Pablo Neira Ayuso wrote:
On Sun, Sep 16, 2018 at 09:11:12PM +0200, Fernando Fernandez Mancera 
wrote:

Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
    type filter hook input priority filter; policy accept;
    osf ttl 0 name "Linux"


Looking at nf_osf_ttl()

* Currently, default behaviour is "check for exact TTL" if no ttl option
   is specified, which is -m osf --ttl 0, which works for local area
   network.

Therefore:

* We need an option to skip TTL checking, eg. 'ttl nocheck', which is
   mapping -m osf --ttl 2.
* We need an option to check for globally-routable address, eg. 'ttl
   global', which is mapping -m osf --ttl 1.

You could also add 'ttl local', but that seems to be the default
behaviour anyway, so you could just document this.



I am not sure how to modify the json support, so the version of tests 
that I have at this moment doesn't include json support. Any 
recommendations to start with? Thanks :-)


Re: [PATCH nft] src: osf: add ttl option support

2018-09-26 Thread Fernando Fernandez Mancera
Sorry if I have misunderstood you but right now, the function implements 
'ttl nocheck' and 'ttl global' behaviours. Yes I am going to document 
that the default behaviour is 'ttl local'.


So if I am not wrong this doesn't require changes. Did you mean 
something different or it is fine? Thanks!


On 9/18/18 1:16 AM, Pablo Neira Ayuso wrote:

On Sun, Sep 16, 2018 at 09:11:12PM +0200, Fernando Fernandez Mancera wrote:

Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl 0 name "Linux"


Looking at nf_osf_ttl()

* Currently, default behaviour is "check for exact TTL" if no ttl option
   is specified, which is -m osf --ttl 0, which works for local area
   network.

Therefore:

* We need an option to skip TTL checking, eg. 'ttl nocheck', which is
   mapping -m osf --ttl 2.
* We need an option to check for globally-routable address, eg. 'ttl
   global', which is mapping -m osf --ttl 1.

You could also add 'ttl local', but that seems to be the default
behaviour anyway, so you could just document this.



Re: [PATCH nft] src: osf: add ttl option support

2018-09-18 Thread Fernando Fernandez Mancera




On 9/18/18 1:16 AM, Pablo Neira Ayuso wrote:

On Sun, Sep 16, 2018 at 09:11:12PM +0200, Fernando Fernandez Mancera wrote:

Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl 0 name "Linux"


Looking at nf_osf_ttl()

* Currently, default behaviour is "check for exact TTL" if no ttl option
   is specified, which is -m osf --ttl 0, which works for local area
   network.

Therefore:

* We need an option to skip TTL checking, eg. 'ttl nocheck', which is
   mapping -m osf --ttl 2.
* We need an option to check for globally-routable address, eg. 'ttl
   global', which is mapping -m osf --ttl 1.

You could also add 'ttl local', but that seems to be the default
behaviour anyway, so you could just document this.



Okay, I am going to work on this. Thanks for the review.


Re: [PATCH nf-next] nft_osf: Add ttl option support

2018-09-18 Thread Fernando Fernandez Mancera




On 9/18/18 1:15 AM, Pablo Neira Ayuso wrote:

On Sun, Sep 16, 2018 at 09:10:16PM +0200, Fernando Fernandez Mancera wrote:

Add ttl option support to the nftables "osf" expression.

Signed-off-by: Fernando Fernandez Mancera 
---
  include/linux/netfilter/nfnetlink_osf.h  |  3 ++-
  include/uapi/linux/netfilter/nf_tables.h |  7 +++
  include/uapi/linux/netfilter/nfnetlink_osf.h |  1 +
  net/netfilter/nfnetlink_osf.c|  5 +++--
  net/netfilter/nft_osf.c  | 14 +-
  5 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
index ecf7dab81e9e..c646c966 100644
--- a/include/linux/netfilter/nfnetlink_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -27,6 +27,7 @@ bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  const struct list_head *nf_osf_fingers);
  
  const char *nf_osf_find(const struct sk_buff *skb,

-const struct list_head *nf_osf_fingers);
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check);
  
  #endif /* _NFOSF_H */

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index e23290ffdc77..85df36521153 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1493,9 +1493,16 @@ enum nft_flowtable_hook_attributes {
  };
  #define NFTA_FLOWTABLE_HOOK_MAX   (__NFTA_FLOWTABLE_HOOK_MAX - 1)
  
+/**

+ * enum nft_osf_attributes - nftables osf expression netlink attributes
+ *
+ * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
+ */
  enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX,
  };
  #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
diff --git a/include/uapi/linux/netfilter/nfnetlink_osf.h 
b/include/uapi/linux/netfilter/nfnetlink_osf.h
index 272bc3195f2d..7e0c00658bf8 100644
--- a/include/uapi/linux/netfilter/nfnetlink_osf.h
+++ b/include/uapi/linux/netfilter/nfnetlink_osf.h
@@ -26,6 +26,7 @@
  
  #define NF_OSF_FLAGMASK		(NF_OSF_GENRE | NF_OSF_TTL | \

 NF_OSF_LOG | NF_OSF_INVERT)
+


You can remove this entire patch chunk. This newline is not needed >

  /* Wildcard MSS (kind of).
   * It is used to implement a state machine for the different wildcard values
   * of the MSS and window sizes.
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index 00db27dfd2ff..ec8fa9661538 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -257,7 +257,8 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  EXPORT_SYMBOL_GPL(nf_osf_match);
  
  const char *nf_osf_find(const struct sk_buff *skb,

-   const struct list_head *nf_osf_fingers)
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check)
  {
const struct iphdr *ip = ip_hdr(skb);
const struct nf_osf_user_finger *f;
@@ -275,7 +276,7 @@ const char *nf_osf_find(const struct sk_buff *skb,
  
  	list_for_each_entry_rcu(kf, _osf_fingers[ctx.df], finger_entry) {

f = >finger;
-   if (!nf_osf_match_one(skb, f, -1, ))
+   if (!nf_osf_match_one(skb, f, ttl_check, ))
continue;
  
  		genre = f->genre;

diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index 5af74b37f423..b63c5f5c716b 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -6,10 +6,12 @@
  
  struct nft_osf {

enum nft_registers  dreg:8;
+   u8  ttl;
  };
  
  static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {

[NFTA_OSF_DREG] = { .type = NLA_U32 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U8 },
  };
  
  static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,

@@ -21,6 +23,7 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
const struct tcphdr *tcp;
struct tcphdr _tcph;
const char *os_name;
+   int ttl_check;
  
  	tcp = skb_header_pointer(skb, ip_hdrlen(skb),

 sizeof(struct tcphdr), &_tcph);
@@ -33,7 +36,8 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
return;
}
  
-	os_name = nf_osf_find(skb, nf_osf_fingers);

+   ttl_check = priv->ttl;
+   os_name = nf_osf_find(skb, nf_osf_fingers, ttl_check);
if (!os_name)
strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN);
else
@@ -47,6 +51,11 @@ static int nft_osf_init(const struct nft_ctx *ctx,
struct nft_osf *priv = nft_expr_priv(expr);
int err;
  
+	if (!tb[NFTA_OS

Re: [PATCH nft] src: osf: add ttl option support

2018-09-16 Thread Fernando Fernandez Mancera
I have not implemented tests and json support yet because I prefer to do 
it after the review of this patchset. Thanks!


On 9/16/18 9:11 PM, Fernando Fernandez Mancera wrote:

Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl 0 name "Linux"
}
}

Signed-off-by: Fernando Fernandez Mancera 
---
  include/expression.h|  4 
  include/linux/netfilter/nf_tables.h |  2 ++
  include/osf.h   |  2 +-
  src/netlink_delinearize.c   |  5 -
  src/netlink_linearize.c |  1 +
  src/osf.c   | 13 +++--
  src/parser_bison.y  |  4 ++--
  7 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index f2c5c1a..d3cca1c 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -337,6 +337,10 @@ struct expr {
uint32_tflags;
uint32_tresult;
} fib;
+   struct {
+   /* EXPR_OSF */
+   uint8_t ttl;
+   } osf;
};
  };
  
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h

index 143ebe2..6c3f08c 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -938,10 +938,12 @@ enum nft_socket_keys {
   * enum nft_osf_attributes - nf_tables osf expression netlink attributes
   *
   * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
   */
  enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX
  };
  #define NFT_OSF_MAX   (__NFTA_OSF_MAX - 1)
diff --git a/include/osf.h b/include/osf.h
index 54cdd4a..23ea34d 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,7 +1,7 @@
  #ifndef NFTABLES_OSF_H
  #define NFTABLES_OSF_H
  
-struct expr *osf_expr_alloc(const struct location *loc);

+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl);
  
  extern int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
  
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c

index 6c5188c..021ff7b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -636,8 +636,11 @@ static void netlink_parse_osf(struct netlink_parse_ctx 
*ctx,
  {
enum nft_registers dreg;
struct expr *expr;
+   uint8_t ttl;
+
+   ttl = nftnl_expr_get_u8(nle, NFTNL_EXPR_OSF_TTL);
+   expr = osf_expr_alloc(loc, ttl);
  
-	expr = osf_expr_alloc(loc);

dreg = netlink_parse_register(nle, NFTNL_EXPR_OSF_DREG);
netlink_set_register(ctx, dreg, expr);
  }
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 0bd946a..28f23da 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -227,6 +227,7 @@ static void netlink_gen_osf(struct netlink_linearize_ctx 
*ctx,
  
  	nle = alloc_nft_expr("osf");

netlink_put_register(nle, NFTNL_EXPR_OSF_DREG, dreg);
+   nftnl_expr_set_u8(nle, NFTNL_EXPR_OSF_TTL, expr->osf.ttl);
nftnl_rule_add_expr(ctx->nlr, nle);
  }
  
diff --git a/src/osf.c b/src/osf.c

index 85c9573..2341dfb 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -7,11 +7,17 @@
  
  static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)

  {
-   nft_print(octx, "osf name");
+   nft_print(octx, "osf ttl %u name", expr->osf.ttl);
  }
  
  static void osf_expr_clone(struct expr *new, const struct expr *expr)

  {
+   new->osf.ttl = expr->osf.ttl;
+}
+
+static bool osf_expr_cmp(const struct expr *e1, const struct expr *e2)
+{
+   return e1->osf.ttl == e2->osf.ttl;
  }
  
  static const struct expr_ops osf_expr_ops = {

@@ -19,10 +25,11 @@ static const struct expr_ops osf_expr_ops = {
.name   = "osf",
.print  = osf_expr_print,
.clone  = osf_expr_clone,
+   .cmp= osf_expr_cmp,
.json   = osf_expr_json,
  };
  
-struct expr *osf_expr_alloc(const struct location *loc)

+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl)
  {
unsigned int len = NFT_OSF_MAXGENRELEN * BITS_PER_BYTE;
const struct datatype *type = _type;
@@ -31,5 +38,7 @@ struct expr *osf_expr_alloc(const struct location *loc)
expr = expr_alloc(loc, _expr_ops, type,
  BYTEORDER_HOST_ENDIAN, len);
  
+	expr->osf.ttl = ttl;

+
return expr;
  }
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 85830d8..11f8ad5 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -3087,9 +3087,9 @@ fib_tuple

[PATCH nft] src: osf: add ttl option support

2018-09-16 Thread Fernando Fernandez Mancera
Add support for ttl option in "osf" expression. Example:

table ip foo {
chain bar {
type filter hook input priority filter; policy accept;
osf ttl 0 name "Linux"
}
}

Signed-off-by: Fernando Fernandez Mancera 
---
 include/expression.h|  4 
 include/linux/netfilter/nf_tables.h |  2 ++
 include/osf.h   |  2 +-
 src/netlink_delinearize.c   |  5 -
 src/netlink_linearize.c |  1 +
 src/osf.c   | 13 +++--
 src/parser_bison.y  |  4 ++--
 7 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index f2c5c1a..d3cca1c 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -337,6 +337,10 @@ struct expr {
uint32_tflags;
uint32_tresult;
} fib;
+   struct {
+   /* EXPR_OSF */
+   uint8_t ttl;
+   } osf;
};
 };
 
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 143ebe2..6c3f08c 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -938,10 +938,12 @@ enum nft_socket_keys {
  * enum nft_osf_attributes - nf_tables osf expression netlink attributes
  *
  * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
  */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX
 };
 #define NFT_OSF_MAX(__NFTA_OSF_MAX - 1)
diff --git a/include/osf.h b/include/osf.h
index 54cdd4a..23ea34d 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,7 +1,7 @@
 #ifndef NFTABLES_OSF_H
 #define NFTABLES_OSF_H
 
-struct expr *osf_expr_alloc(const struct location *loc);
+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl);
 
 extern int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
 
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 6c5188c..021ff7b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -636,8 +636,11 @@ static void netlink_parse_osf(struct netlink_parse_ctx 
*ctx,
 {
enum nft_registers dreg;
struct expr *expr;
+   uint8_t ttl;
+
+   ttl = nftnl_expr_get_u8(nle, NFTNL_EXPR_OSF_TTL);
+   expr = osf_expr_alloc(loc, ttl);
 
-   expr = osf_expr_alloc(loc);
dreg = netlink_parse_register(nle, NFTNL_EXPR_OSF_DREG);
netlink_set_register(ctx, dreg, expr);
 }
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 0bd946a..28f23da 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -227,6 +227,7 @@ static void netlink_gen_osf(struct netlink_linearize_ctx 
*ctx,
 
nle = alloc_nft_expr("osf");
netlink_put_register(nle, NFTNL_EXPR_OSF_DREG, dreg);
+   nftnl_expr_set_u8(nle, NFTNL_EXPR_OSF_TTL, expr->osf.ttl);
nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
diff --git a/src/osf.c b/src/osf.c
index 85c9573..2341dfb 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -7,11 +7,17 @@
 
 static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
-   nft_print(octx, "osf name");
+   nft_print(octx, "osf ttl %u name", expr->osf.ttl);
 }
 
 static void osf_expr_clone(struct expr *new, const struct expr *expr)
 {
+   new->osf.ttl = expr->osf.ttl;
+}
+
+static bool osf_expr_cmp(const struct expr *e1, const struct expr *e2)
+{
+   return e1->osf.ttl == e2->osf.ttl;
 }
 
 static const struct expr_ops osf_expr_ops = {
@@ -19,10 +25,11 @@ static const struct expr_ops osf_expr_ops = {
.name   = "osf",
.print  = osf_expr_print,
.clone  = osf_expr_clone,
+   .cmp= osf_expr_cmp,
.json   = osf_expr_json,
 };
 
-struct expr *osf_expr_alloc(const struct location *loc)
+struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl)
 {
unsigned int len = NFT_OSF_MAXGENRELEN * BITS_PER_BYTE;
const struct datatype *type = _type;
@@ -31,5 +38,7 @@ struct expr *osf_expr_alloc(const struct location *loc)
expr = expr_alloc(loc, _expr_ops, type,
  BYTEORDER_HOST_ENDIAN, len);
 
+   expr->osf.ttl = ttl;
+
return expr;
 }
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 85830d8..11f8ad5 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -3087,9 +3087,9 @@ fib_tuple :   fib_flagDOT 
fib_tuple
|   fib_flag
;
 
-osf_expr   :   OSF NAME
+osf_expr   :   OSF NUM   

[PATCH nf-next] nft_osf: Add ttl option support

2018-09-16 Thread Fernando Fernandez Mancera
Add ttl option support to the nftables "osf" expression.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nfnetlink_osf.h  |  3 ++-
 include/uapi/linux/netfilter/nf_tables.h |  7 +++
 include/uapi/linux/netfilter/nfnetlink_osf.h |  1 +
 net/netfilter/nfnetlink_osf.c|  5 +++--
 net/netfilter/nft_osf.c  | 14 +-
 5 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
index ecf7dab81e9e..c646c966 100644
--- a/include/linux/netfilter/nfnetlink_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -27,6 +27,7 @@ bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  const struct list_head *nf_osf_fingers);
 
 const char *nf_osf_find(const struct sk_buff *skb,
-const struct list_head *nf_osf_fingers);
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check);
 
 #endif /* _NFOSF_H */
diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index e23290ffdc77..85df36521153 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1493,9 +1493,16 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+/**
+ * enum nft_osf_attributes - nftables osf expression netlink attributes
+ *
+ * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
+ */
 enum nft_osf_attributes {
NFTA_OSF_UNSPEC,
NFTA_OSF_DREG,
+   NFTA_OSF_TTL,
__NFTA_OSF_MAX,
 };
 #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
diff --git a/include/uapi/linux/netfilter/nfnetlink_osf.h 
b/include/uapi/linux/netfilter/nfnetlink_osf.h
index 272bc3195f2d..7e0c00658bf8 100644
--- a/include/uapi/linux/netfilter/nfnetlink_osf.h
+++ b/include/uapi/linux/netfilter/nfnetlink_osf.h
@@ -26,6 +26,7 @@
 
 #define NF_OSF_FLAGMASK(NF_OSF_GENRE | NF_OSF_TTL | \
 NF_OSF_LOG | NF_OSF_INVERT)
+
 /* Wildcard MSS (kind of).
  * It is used to implement a state machine for the different wildcard values
  * of the MSS and window sizes.
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index 00db27dfd2ff..ec8fa9661538 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -257,7 +257,8 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
 EXPORT_SYMBOL_GPL(nf_osf_match);
 
 const char *nf_osf_find(const struct sk_buff *skb,
-   const struct list_head *nf_osf_fingers)
+   const struct list_head *nf_osf_fingers,
+   const int ttl_check)
 {
const struct iphdr *ip = ip_hdr(skb);
const struct nf_osf_user_finger *f;
@@ -275,7 +276,7 @@ const char *nf_osf_find(const struct sk_buff *skb,
 
list_for_each_entry_rcu(kf, _osf_fingers[ctx.df], finger_entry) {
f = >finger;
-   if (!nf_osf_match_one(skb, f, -1, ))
+   if (!nf_osf_match_one(skb, f, ttl_check, ))
continue;
 
genre = f->genre;
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index 5af74b37f423..b63c5f5c716b 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -6,10 +6,12 @@
 
 struct nft_osf {
enum nft_registers  dreg:8;
+   u8  ttl;
 };
 
 static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
[NFTA_OSF_DREG] = { .type = NLA_U32 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U8 },
 };
 
 static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
@@ -21,6 +23,7 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
const struct tcphdr *tcp;
struct tcphdr _tcph;
const char *os_name;
+   int ttl_check;
 
tcp = skb_header_pointer(skb, ip_hdrlen(skb),
 sizeof(struct tcphdr), &_tcph);
@@ -33,7 +36,8 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
return;
}
 
-   os_name = nf_osf_find(skb, nf_osf_fingers);
+   ttl_check = priv->ttl;
+   os_name = nf_osf_find(skb, nf_osf_fingers, ttl_check);
if (!os_name)
strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN);
else
@@ -47,6 +51,11 @@ static int nft_osf_init(const struct nft_ctx *ctx,
struct nft_osf *priv = nft_expr_priv(expr);
int err;
 
+   if (!tb[NFTA_OSF_TTL] || nla_get_u8(tb[NFTA_OSF_TTL]) < 0 ||
+   nla_get_u8(tb[NFTA_OSF_TTL]) > 2)
+   return ~EINVAL;
+   priv->ttl = nla_get_u8(tb[NFTA_OSF_TTL]);
+
priv-&

Re: [PATCH nft] src: osf: load pf.os from expr_evaluate_osf()

2018-08-31 Thread Fernando Fernandez Mancera

On 8/31/18 7:19 PM, Pablo Neira Ayuso wrote:

On Thu, Aug 30, 2018 at 07:18:42PM +0200, Fernando Fernandez Mancera wrote:

Remove osf_init variable and call nfnl_osf_load_fingerprints() from
expr_evaluate_osf() instead of doing that from do_command_add() path.


Applied, thanks Fernando.

BTW, I have applied a patch to use --debug=mnl to display the
debugging for osf's pf.os file loading, I overlook this was breaking
tests/py/.



Sorry about this, I didn't know that tests/py use --debug=netlink. 
Thanks Pablo.


[PATCH nft] src: osf: load pf.os from expr_evaluate_osf()

2018-08-30 Thread Fernando Fernandez Mancera
Remove osf_init variable and call nfnl_osf_load_fingerprints() from
expr_evaluate_osf() instead of doing that from do_command_add() path.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/osf.h  |  1 -
 src/evaluate.c | 11 +++
 src/nfnl_osf.c |  2 --
 src/osf.c  |  1 -
 src/rule.c |  6 +-
 5 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/include/osf.h b/include/osf.h
index 074ba9a..54cdd4a 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -3,7 +3,6 @@
 
 struct expr *osf_expr_alloc(const struct location *loc);
 
-extern bool osf_init;
 extern int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
 
 #endif /* NFTABLES_OSF_H */
diff --git a/src/evaluate.c b/src/evaluate.c
index a3a7874..d4d121c 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -26,6 +26,8 @@
 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1727,6 +1729,15 @@ static int expr_evaluate_socket(struct eval_ctx *ctx, 
struct expr **expr)
 
 static int expr_evaluate_osf(struct eval_ctx *ctx, struct expr **expr)
 {
+   struct netlink_ctx nl_ctx = {
+   .nf_sock= ctx->nf_sock,
+   .debug_mask = ctx->debug_mask,
+   .octx   = ctx->octx,
+   .seqnum = time(NULL),
+   };
+
+   nfnl_osf_load_fingerprints(_ctx, 0);
+
return expr_evaluate_primary(ctx, expr);
 }
 
diff --git a/src/nfnl_osf.c b/src/nfnl_osf.c
index e37510b..fb76fb0 100644
--- a/src/nfnl_osf.c
+++ b/src/nfnl_osf.c
@@ -43,8 +43,6 @@
 #define OSFPDEL':'
 #define MAXOPTSTRLEN   128
 
-bool osf_init;
-
 static struct nf_osf_opt IANA_opts[] = {
{ .kind = 0, .length = 1,},
{ .kind=1, .length=1,},
diff --git a/src/osf.c b/src/osf.c
index fc09e15..85c9573 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -28,7 +28,6 @@ struct expr *osf_expr_alloc(const struct location *loc)
const struct datatype *type = _type;
struct expr *expr;
 
-   osf_init = true;
expr = expr_alloc(loc, _expr_ops, type,
  BYTEORDER_HOST_ENDIAN, len);
 
diff --git a/src/rule.c b/src/rule.c
index 470b112..f24624f 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1329,7 +1329,6 @@ static int do_add_set(struct netlink_ctx *ctx, const 
struct cmd *cmd,
 static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl)
 {
uint32_t flags = excl ? NLM_F_EXCL : 0;
-   int err;
 
if (ctx->octx->echo) {
int ret;
@@ -1348,10 +1347,7 @@ static int do_command_add(struct netlink_ctx *ctx, 
struct cmd *cmd, bool excl)
case CMD_OBJ_CHAIN:
return netlink_add_chain_batch(ctx, cmd, flags);
case CMD_OBJ_RULE:
-   err = netlink_add_rule_batch(ctx, cmd, flags | NLM_F_APPEND);
-   if (osf_init)
-   nfnl_osf_load_fingerprints(ctx, 0);
-   return err;
+   return netlink_add_rule_batch(ctx, cmd, flags | NLM_F_APPEND);
case CMD_OBJ_SET:
return do_add_set(ctx, cmd, flags);
case CMD_OBJ_SETELEM:
-- 
2.18.0



[PATCH 1/3 nft v4] files: osf: copy iptables/utils/pf.os into nftables tree

2018-08-22 Thread Fernando Fernandez Mancera
As we are going to need pf.os file to load OS fingerprints from the incoming
nfnl_osf.c, we copy it into the nftables tree directory "files/osf/".

Signed-off-by: Fernando Fernandez Mancera 
---
 configure.ac   |   1 +
 files/Makefile.am  |   3 +-
 files/nftables/Makefile.am |   2 +-
 files/osf/Makefile.am  |   2 +
 files/osf/pf.os| 709 +
 5 files changed, 715 insertions(+), 2 deletions(-)
 create mode 100644 files/osf/Makefile.am
 create mode 100644 files/osf/pf.os

diff --git a/configure.ac b/configure.ac
index c6536a3..9bbd9d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,6 +130,7 @@ AC_CONFIG_FILES([   \
include/linux/netfilter_ipv6/Makefile   \
files/Makefile  \
files/nftables/Makefile \
+   files/osf/Makefile  \
doc/Makefile\
py/Makefile \
])
diff --git a/files/Makefile.am b/files/Makefile.am
index a8394c0..4f41b66 100644
--- a/files/Makefile.am
+++ b/files/Makefile.am
@@ -1 +1,2 @@
-SUBDIRS = nftables
+SUBDIRS =  nftables \
+   osf
diff --git a/files/nftables/Makefile.am b/files/nftables/Makefile.am
index 43e3028..f18156d 100644
--- a/files/nftables/Makefile.am
+++ b/files/nftables/Makefile.am
@@ -13,4 +13,4 @@ dist_pkgsysconf_DATA =all-in-one.nft  \
ipv6-raw.nft
 
 install-data-hook:
-   ${SED} -i 's|@sbindir[@]|${sbindir}/|g' ${DESTDIR}${pkgsysconfdir}/*
+   ${SED} -i 's|@sbindir[@]|${sbindir}/|g' ${DESTDIR}${pkgsysconfdir}/*.nft
diff --git a/files/osf/Makefile.am b/files/osf/Makefile.am
new file mode 100644
index 000..d80196d
--- /dev/null
+++ b/files/osf/Makefile.am
@@ -0,0 +1,2 @@
+pkgsysconfdir = ${sysconfdir}/nftables/osf
+dist_pkgsysconf_DATA = pf.os
diff --git a/files/osf/pf.os b/files/osf/pf.os
new file mode 100644
index 000..e285851
--- /dev/null
+++ b/files/osf/pf.os
@@ -0,0 +1,709 @@
+# $FreeBSD: head/etc/pf.os 258865 2013-12-03 04:32:02Z eadler $
+# $OpenBSD: pf.os,v 1.27 2016/09/03 17:08:57 sthen Exp $
+# passive OS fingerprinting
+# -
+#
+# SYN signatures. Those signatures work for SYN packets only (duh!).
+#
+# (C) Copyright 2000-2003 by Michal Zalewski 
+# (C) Copyright 2003 by Mike Frantzen 
+#
+#  Permission to use, copy, modify, and distribute this software for any
+#  purpose with or without fee is hereby granted, provided that the above
+#  copyright notice and this permission notice appear in all copies.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#
+# This fingerprint database is adapted from Michal Zalewski's p0f passive
+# operating system package.  The last database sync was from a Nov 3 2003
+# p0f.fp.
+#
+#
+# Each line in this file specifies a single fingerprint. Please read the
+# information below carefully before attempting to append any signatures
+# reported as UNKNOWN to this file to avoid mistakes.
+#
+# We use the following set metrics for fingerprinting:
+#
+# - Window size (WSS) - a highly OS dependent setting used for TCP/IP
+#   performance control (max. amount of data to be sent without ACK).
+#   Some systems use a fixed value for initial packets. On other
+#   systems, it is a multiple of MSS or MTU (MSS+40). In some rare
+#   cases, the value is just arbitrary.
+#
+#   NEW SIGNATURE: if p0f reported a special value of 'Snn', the number
+#   appears to be a multiple of MSS (MSS*nn); a special value of 'Tnn'
+#   means it is a multiple of MTU ((MSS+40)*nn). Unless you notice the
+#   value of nn is not fixed (unlikely), just copy the Snn or Tnn token
+#   literally. If you know this device has a simple stack and a fixed
+#   MTU, you can however multiply S value by MSS, or T value by MSS+40,
+#   and put it instead of Snn or Tnn.
+#
+#   If WSS otherwise looks like a fixed value (for example a multiple
+#   of two), or if you can confirm the value is fixed, please quote
+#   it literally. If there's no apparent pattern in WSS chosen, you
+#   should consider wildcarding this value.
+#
+# - Overall packet size - a function of all IP and TCP options and bugs.
+#
+#   NEW SIGNATURE: Copy this value literally.
+#
+# - Initial TTL - We check the actual TTL of a received packet. It can't
+#   be higher than the initial TTL, and also shouldn't be dra

[PATCH 3/3 nft v4] src: osf: import nfnl_osf.c to load osf fingerprints

2018-08-22 Thread Fernando Fernandez Mancera
Import iptables/utils/nfnl_osf.c into nftables tree with some changes in order
to load OS fingerprints automatically from pf.os file.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/Makefile.am |   1 +
 include/linux/netfilter/nfnetlink_osf.h | 119 +++
 include/osf.h   |   5 +
 src/Makefile.am |   1 +
 src/nfnl_osf.c  | 401 
 src/osf.c   |   1 +
 src/rule.c  |  29 +-
 7 files changed, 549 insertions(+), 8 deletions(-)
 create mode 100644 include/linux/netfilter/nfnetlink_osf.h
 create mode 100644 src/nfnl_osf.c

diff --git a/include/linux/netfilter/Makefile.am 
b/include/linux/netfilter/Makefile.am
index f6a8aa2..2c1de18 100644
--- a/include/linux/netfilter/Makefile.am
+++ b/include/linux/netfilter/Makefile.am
@@ -3,4 +3,5 @@ noinst_HEADERS =nf_conntrack_common.h   \
nf_log.h\
nf_nat.h\
nf_tables.h \
+   nfnetlink_osf.h \
nfnetlink.h
diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
new file mode 100644
index 000..15a39d2
--- /dev/null
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -0,0 +1,119 @@
+#ifndef _NF_OSF_H
+#define _NF_OSF_H
+
+#include 
+
+#define MAXGENRELEN32
+
+#define NF_OSF_GENRE   (1 << 0)
+#define NF_OSF_TTL (1 << 1)
+#define NF_OSF_LOG (1 << 2)
+#define NF_OSF_INVERT  (1 << 3)
+
+#define NF_OSF_LOGLEVEL_ALL0   /* log all matched fingerprints 
*/
+#define NF_OSF_LOGLEVEL_FIRST  1   /* log only the first matced 
fingerprint */
+#define NF_OSF_LOGLEVEL_ALL_KNOWN  2   /* do not log unknown packets */
+
+#define NF_OSF_TTL_TRUE0   /* True ip and 
fingerprint TTL comparison */
+
+/* Check if ip TTL is less than fingerprint one */
+#define NF_OSF_TTL_LESS1
+
+/* Do not compare ip and fingerprint TTL at all */
+#define NF_OSF_TTL_NOCHECK 2
+
+#define NF_OSF_FLAGMASK(NF_OSF_GENRE | NF_OSF_TTL | \
+NF_OSF_LOG | NF_OSF_INVERT)
+/* Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct nf_osf_wc {
+   __u32   wc;
+   __u32   val;
+};
+
+/* This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct nf_osf_opt {
+   __u16   kind, length;
+   struct nf_osf_wcwc;
+};
+
+struct nf_osf_info {
+   chargenre[MAXGENRELEN];
+   __u32   len;
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+};
+
+struct nf_osf_user_finger {
+   struct nf_osf_wcwss;
+
+   __u8ttl, df;
+   __u16   ss, mss;
+   __u16   opt_num;
+
+   chargenre[MAXGENRELEN];
+   charversion[MAXGENRELEN];
+   charsubtype[MAXGENRELEN];
+
+   /* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+   struct nf_osf_opt   opt[MAX_IPOPTLEN];
+};
+
+struct nf_osf_nlmsg {
+   struct nf_osf_user_finger   f;
+   struct iphdrip;
+   struct tcphdr   tcp;
+};
+
+/* Defines for IANA option kinds */
+enum iana_options {
+   OSFOPT_EOL = 0, /* End of options */
+   OSFOPT_NOP, /* NOP */
+   OSFOPT_MSS, /* Maximum segment size */
+   OSFOPT_WSO, /* Window scale option */
+   OSFOPT_SACKP,   /* SACK permitted */
+   OSFOPT_SACK,/* SACK */
+   OSFOPT_ECHO,
+   OSFOPT_ECHOREPLY,
+   OSFOPT_TS,  /* Timestamp option */
+   OSFOPT_POCP,/* Partial Order Connection Permitted */
+   OSFOPT_POSP,/* Partial Order Service Profile */
+
+   /* Others are not used in the current OSF */
+   OSFOPT_EMPTY = 255,
+};
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum nf_osf_window_size_options {
+   OSF_WSS_PLAIN   = 0,
+   OSF_WSS_MSS,
+   OSF_WSS_MTU,
+   OSF_WSS_MODULO,
+   OSF_WSS_MAX,
+};
+
+enum nf_osf_attr_type {
+   OSF_ATTR_UNSPEC,
+   OSF_ATTR_FINGER,
+   OSF_ATTR_MAX,
+};
+
+/*
+ * Add/remove fingerprint from the kernel.
+ */
+enum nf_osf_msg_types {
+   OSF_MSG_ADD,
+   OSF_MSG_REMOVE,
+   OSF_MSG_MAX,
+};
+
+#endif /* _NF_OSF_H */
diff --git a/include/osf.h b/include/osf.h
index 715b04e..7f52169 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,6 +1,11 @@
 #ifndef NFTABLES_OSF_H

[PATCH 2/3 nft v4] src: mnl: make nft_mnl_talk() public

2018-08-22 Thread Fernando Fernandez Mancera
As we are going to use the function nft_mnl_talk() from the incoming
nftnl_osf.c, we make it public.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/mnl.h | 4 
 src/mnl.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/mnl.h b/include/mnl.h
index cb131bb..36109c7 100644
--- a/include/mnl.h
+++ b/include/mnl.h
@@ -92,4 +92,8 @@ int mnl_nft_event_listener(struct mnl_socket *nf_sock, 
unsigned int debug_mask,
   int (*cb)(const struct nlmsghdr *nlh, void *data),
   void *cb_data);
 
+int nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len,
+int (*cb)(const struct nlmsghdr *nlh, void *data),
+void *cb_data);
+
 #endif /* _NFTABLES_MNL_H_ */
diff --git a/src/mnl.c b/src/mnl.c
index 42eacab..6a6d45c 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -66,7 +66,7 @@ out:
return ret;
 }
 
-static int
+int
 nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len,
 int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data)
 {
-- 
2.18.0



[PATCH 2/3 nft v3] src: mnl: make nft_mnl_talk() public

2018-08-21 Thread Fernando Fernandez Mancera
As we are going to use the function nft_mnl_talk() from the incoming
nftnl_osf.c, we make it public.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/mnl.h | 4 
 src/mnl.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/mnl.h b/include/mnl.h
index cb131bb..36109c7 100644
--- a/include/mnl.h
+++ b/include/mnl.h
@@ -92,4 +92,8 @@ int mnl_nft_event_listener(struct mnl_socket *nf_sock, 
unsigned int debug_mask,
   int (*cb)(const struct nlmsghdr *nlh, void *data),
   void *cb_data);
 
+int nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len,
+int (*cb)(const struct nlmsghdr *nlh, void *data),
+void *cb_data);
+
 #endif /* _NFTABLES_MNL_H_ */
diff --git a/src/mnl.c b/src/mnl.c
index 42eacab..6a6d45c 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -66,7 +66,7 @@ out:
return ret;
 }
 
-static int
+int
 nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len,
 int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data)
 {
-- 
2.18.0



[PATCH 3/3 nft v3] src: osf: import nfnl_osf.c to load osf fingerprints

2018-08-21 Thread Fernando Fernandez Mancera
Import iptables/utils/nfnl_osf.c into nftables tree with some changes in order
to load OS fingerprints automatically from pf.os file.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/Makefile.am |   1 +
 include/linux/netfilter/nfnetlink_osf.h | 119 +++
 include/osf.h   |   5 +
 src/Makefile.am |   1 +
 src/nfnl_osf.c  | 401 
 src/osf.c   |   1 +
 src/rule.c  |  29 +-
 7 files changed, 549 insertions(+), 8 deletions(-)
 create mode 100644 include/linux/netfilter/nfnetlink_osf.h
 create mode 100644 src/nfnl_osf.c

diff --git a/include/linux/netfilter/Makefile.am 
b/include/linux/netfilter/Makefile.am
index f6a8aa2..2c1de18 100644
--- a/include/linux/netfilter/Makefile.am
+++ b/include/linux/netfilter/Makefile.am
@@ -3,4 +3,5 @@ noinst_HEADERS =nf_conntrack_common.h   \
nf_log.h\
nf_nat.h\
nf_tables.h \
+   nfnetlink_osf.h \
nfnetlink.h
diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
new file mode 100644
index 000..15a39d2
--- /dev/null
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -0,0 +1,119 @@
+#ifndef _NF_OSF_H
+#define _NF_OSF_H
+
+#include 
+
+#define MAXGENRELEN32
+
+#define NF_OSF_GENRE   (1 << 0)
+#define NF_OSF_TTL (1 << 1)
+#define NF_OSF_LOG (1 << 2)
+#define NF_OSF_INVERT  (1 << 3)
+
+#define NF_OSF_LOGLEVEL_ALL0   /* log all matched fingerprints 
*/
+#define NF_OSF_LOGLEVEL_FIRST  1   /* log only the first matced 
fingerprint */
+#define NF_OSF_LOGLEVEL_ALL_KNOWN  2   /* do not log unknown packets */
+
+#define NF_OSF_TTL_TRUE0   /* True ip and 
fingerprint TTL comparison */
+
+/* Check if ip TTL is less than fingerprint one */
+#define NF_OSF_TTL_LESS1
+
+/* Do not compare ip and fingerprint TTL at all */
+#define NF_OSF_TTL_NOCHECK 2
+
+#define NF_OSF_FLAGMASK(NF_OSF_GENRE | NF_OSF_TTL | \
+NF_OSF_LOG | NF_OSF_INVERT)
+/* Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct nf_osf_wc {
+   __u32   wc;
+   __u32   val;
+};
+
+/* This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct nf_osf_opt {
+   __u16   kind, length;
+   struct nf_osf_wcwc;
+};
+
+struct nf_osf_info {
+   chargenre[MAXGENRELEN];
+   __u32   len;
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+};
+
+struct nf_osf_user_finger {
+   struct nf_osf_wcwss;
+
+   __u8ttl, df;
+   __u16   ss, mss;
+   __u16   opt_num;
+
+   chargenre[MAXGENRELEN];
+   charversion[MAXGENRELEN];
+   charsubtype[MAXGENRELEN];
+
+   /* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+   struct nf_osf_opt   opt[MAX_IPOPTLEN];
+};
+
+struct nf_osf_nlmsg {
+   struct nf_osf_user_finger   f;
+   struct iphdrip;
+   struct tcphdr   tcp;
+};
+
+/* Defines for IANA option kinds */
+enum iana_options {
+   OSFOPT_EOL = 0, /* End of options */
+   OSFOPT_NOP, /* NOP */
+   OSFOPT_MSS, /* Maximum segment size */
+   OSFOPT_WSO, /* Window scale option */
+   OSFOPT_SACKP,   /* SACK permitted */
+   OSFOPT_SACK,/* SACK */
+   OSFOPT_ECHO,
+   OSFOPT_ECHOREPLY,
+   OSFOPT_TS,  /* Timestamp option */
+   OSFOPT_POCP,/* Partial Order Connection Permitted */
+   OSFOPT_POSP,/* Partial Order Service Profile */
+
+   /* Others are not used in the current OSF */
+   OSFOPT_EMPTY = 255,
+};
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum nf_osf_window_size_options {
+   OSF_WSS_PLAIN   = 0,
+   OSF_WSS_MSS,
+   OSF_WSS_MTU,
+   OSF_WSS_MODULO,
+   OSF_WSS_MAX,
+};
+
+enum nf_osf_attr_type {
+   OSF_ATTR_UNSPEC,
+   OSF_ATTR_FINGER,
+   OSF_ATTR_MAX,
+};
+
+/*
+ * Add/remove fingerprint from the kernel.
+ */
+enum nf_osf_msg_types {
+   OSF_MSG_ADD,
+   OSF_MSG_REMOVE,
+   OSF_MSG_MAX,
+};
+
+#endif /* _NF_OSF_H */
diff --git a/include/osf.h b/include/osf.h
index 715b04e..7f52169 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,6 +1,11 @@
 #ifndef NFTABLES_OSF_H

[PATCH 1/3 nft v3] files: osf: copy iptables/utils/pf.os into nftables tree

2018-08-21 Thread Fernando Fernandez Mancera
As we are going to need pf.os file to load OS fingerprints from the incoming
nfnl_osf.c, we copy it into the nftables tree directory "files/osf/".

Signed-off-by: Fernando Fernandez Mancera 
---
 configure.ac   |   1 +
 files/Makefile.am  |   3 +-
 files/nftables/Makefile.am |   2 +-
 files/osf/Makefile.am  |   2 +
 files/osf/pf.os| 709 +
 5 files changed, 715 insertions(+), 2 deletions(-)
 create mode 100644 files/osf/Makefile.am
 create mode 100644 files/osf/pf.os

diff --git a/configure.ac b/configure.ac
index c6536a3..9bbd9d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,6 +130,7 @@ AC_CONFIG_FILES([   \
include/linux/netfilter_ipv6/Makefile   \
files/Makefile  \
files/nftables/Makefile \
+   files/osf/Makefile  \
doc/Makefile\
py/Makefile \
])
diff --git a/files/Makefile.am b/files/Makefile.am
index a8394c0..4f41b66 100644
--- a/files/Makefile.am
+++ b/files/Makefile.am
@@ -1 +1,2 @@
-SUBDIRS = nftables
+SUBDIRS =  nftables \
+   osf
diff --git a/files/nftables/Makefile.am b/files/nftables/Makefile.am
index 43e3028..f18156d 100644
--- a/files/nftables/Makefile.am
+++ b/files/nftables/Makefile.am
@@ -13,4 +13,4 @@ dist_pkgsysconf_DATA =all-in-one.nft  \
ipv6-raw.nft
 
 install-data-hook:
-   ${SED} -i 's|@sbindir[@]|${sbindir}/|g' ${DESTDIR}${pkgsysconfdir}/*
+   ${SED} -i 's|@sbindir[@]|${sbindir}/|g' ${DESTDIR}${pkgsysconfdir}/*.nft
diff --git a/files/osf/Makefile.am b/files/osf/Makefile.am
new file mode 100644
index 000..d80196d
--- /dev/null
+++ b/files/osf/Makefile.am
@@ -0,0 +1,2 @@
+pkgsysconfdir = ${sysconfdir}/nftables/osf
+dist_pkgsysconf_DATA = pf.os
diff --git a/files/osf/pf.os b/files/osf/pf.os
new file mode 100644
index 000..e285851
--- /dev/null
+++ b/files/osf/pf.os
@@ -0,0 +1,709 @@
+# $FreeBSD: head/etc/pf.os 258865 2013-12-03 04:32:02Z eadler $
+# $OpenBSD: pf.os,v 1.27 2016/09/03 17:08:57 sthen Exp $
+# passive OS fingerprinting
+# -
+#
+# SYN signatures. Those signatures work for SYN packets only (duh!).
+#
+# (C) Copyright 2000-2003 by Michal Zalewski 
+# (C) Copyright 2003 by Mike Frantzen 
+#
+#  Permission to use, copy, modify, and distribute this software for any
+#  purpose with or without fee is hereby granted, provided that the above
+#  copyright notice and this permission notice appear in all copies.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#
+# This fingerprint database is adapted from Michal Zalewski's p0f passive
+# operating system package.  The last database sync was from a Nov 3 2003
+# p0f.fp.
+#
+#
+# Each line in this file specifies a single fingerprint. Please read the
+# information below carefully before attempting to append any signatures
+# reported as UNKNOWN to this file to avoid mistakes.
+#
+# We use the following set metrics for fingerprinting:
+#
+# - Window size (WSS) - a highly OS dependent setting used for TCP/IP
+#   performance control (max. amount of data to be sent without ACK).
+#   Some systems use a fixed value for initial packets. On other
+#   systems, it is a multiple of MSS or MTU (MSS+40). In some rare
+#   cases, the value is just arbitrary.
+#
+#   NEW SIGNATURE: if p0f reported a special value of 'Snn', the number
+#   appears to be a multiple of MSS (MSS*nn); a special value of 'Tnn'
+#   means it is a multiple of MTU ((MSS+40)*nn). Unless you notice the
+#   value of nn is not fixed (unlikely), just copy the Snn or Tnn token
+#   literally. If you know this device has a simple stack and a fixed
+#   MTU, you can however multiply S value by MSS, or T value by MSS+40,
+#   and put it instead of Snn or Tnn.
+#
+#   If WSS otherwise looks like a fixed value (for example a multiple
+#   of two), or if you can confirm the value is fixed, please quote
+#   it literally. If there's no apparent pattern in WSS chosen, you
+#   should consider wildcarding this value.
+#
+# - Overall packet size - a function of all IP and TCP options and bugs.
+#
+#   NEW SIGNATURE: Copy this value literally.
+#
+# - Initial TTL - We check the actual TTL of a received packet. It can't
+#   be higher than the initial TTL, and also shouldn't be dra

Re: [PATCH 3/3 nft v2] src: osf: import nfnl_osf.c to load osf fingerprints

2018-08-14 Thread Fernando Fernandez Mancera
Thanks you for this review, I am going to send a v3 iteration with the changes 
done and tested.

El 14 de agosto de 2018 16:10:33 CEST, Pablo Neira Ayuso  
escribió:
>On Mon, Aug 13, 2018 at 06:57:08PM +0200, Fernando Fernandez Mancera
>wrote:
>[...]
>> diff --git a/include/nfnl_osf.h b/include/nfnl_osf.h
>> new file mode 100644
>> index 000..b676045
>> --- /dev/null
>> +++ b/include/nfnl_osf.h
>
>No need for a new nfnl_osf.h file, please use the existing
>include/osf.h.
>
>> @@ -0,0 +1,10 @@
>> +#ifndef _NFNL_OSF_H
>> +#define _NFNL_OSF_H
>> +
>> +#define OS_SIGNATURES DEFAULT_INCLUDE_PATH "/pf.os"
>> +
>> +bool osf_init;
>
>This needs to be:
>
>extern bool osf_init;
>
>Then, define 'bool osf_init' from the nfnl_osf.c file.
>
>Make sure you update include/Makefile.am so `make distcheck' doesn't
>break.
>
>> +
>> +int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
>> +
>> +#endif  /* _NFNL_OSF_H */
>> diff --git a/src/Makefile.am b/src/Makefile.am
>> index ed3640e..e569029 100644
>> --- a/src/Makefile.am
>> +++ b/src/Makefile.am
>> @@ -57,6 +57,7 @@ libnftables_la_SOURCES =   \
>>  services.c  \
>>  mergesort.c \
>>  osf.c   \
>> +nfnl_osf.c  \
>>  tcpopt.c\
>>  socket.c\
>>  libnftables.c
>> diff --git a/src/nfnl_osf.c b/src/nfnl_osf.c
>> new file mode 100644
>> index 000..53e4ec6
>> --- /dev/null
>> +++ b/src/nfnl_osf.c
>> @@ -0,0 +1,424 @@
>> +/*
>> + * Copyright (c) 2005 Evgeniy Polyakov 
>> + *
>> + *
>> + * This program is free software; you can redistribute it and/or
>modify
>> + * it under the terms of the GNU General Public License as published
>by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 
>02110-1301, USA.
>> + */
>> +
>> +#include 
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +#include 
>> +
>> +#include 
>> +
>> +#include 
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define OPTDEL  ','
>> +#define OSFPDEL ':'
>> +#define MAXOPTSTRLEN128
>> +
>> +static struct nf_osf_opt IANA_opts[] = {
>> +{ .kind = 0, .length = 1,},
>> +{ .kind=1, .length=1,},
>> +{ .kind=2, .length=4,},
>> +{ .kind=3, .length=3,},
>> +{ .kind=4, .length=2,},
>> +{ .kind=5, .length=1,}, /* SACK length is not defined */
>> +{ .kind=6, .length=6,},
>> +{ .kind=7, .length=6,},
>> +{ .kind=8, .length=10,},
>> +{ .kind=9, .length=2,},
>> +{ .kind=10, .length=3,},
>> +{ .kind=11, .length=1,},/* CC: Suppose 1 */
>> +{ .kind=12, .length=1,},/* the same */
>> +{ .kind=13, .length=1,},/* and here too */
>> +{ .kind=14, .length=3,},
>> +{ .kind=15, .length=1,},/* TCP Alternate Checksum Data. 
>> Length is
>not defined */
>> +{ .kind=16, .length=1,},
>> +{ .kind=17, .length=1,},
>> +{ .kind=18, .length=3,},
>> +{ .kind=19, .length=18,},
>> +{ .kind=20, .length=1,},
>> +{ .kind=21, .length=1,},
>> +{ .kind=22, .length=1,},
>> +{ .kind=23, .length=1,},
>> +{ .kind=24, .length=1,},
>> +{ .kind=25, .length=1,},
>> +{ .kind=26, .length=1,},
>> +};
>> +
>> +static void uloga(const char *f, struct netlink_ctx *ctx, ...)
>> +{
>> +if (!(ctx->debug_mask & NFT_DEBUG_NETLINK))
>> +return;
>> +
>> +nft_print(ctx->octx, "%s", f);
>> +}
&g

[PATCH 3/3 nft v2] src: osf: import nfnl_osf.c to load osf fingerprints

2018-08-13 Thread Fernando Fernandez Mancera
Import iptables/utils/nfnl_osf.c into nftables tree with some changes in order
to load OS fingerprints automatically from pf.os file.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nfnetlink_osf.h | 119 +++
 include/nfnl_osf.h  |  10 +
 src/Makefile.am |   1 +
 src/nfnl_osf.c  | 424 
 src/osf.c   |   2 +
 src/rule.c  |   4 +
 6 files changed, 560 insertions(+)
 create mode 100644 include/linux/netfilter/nfnetlink_osf.h
 create mode 100644 include/nfnl_osf.h
 create mode 100644 src/nfnl_osf.c

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
new file mode 100644
index 000..15a39d2
--- /dev/null
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -0,0 +1,119 @@
+#ifndef _NF_OSF_H
+#define _NF_OSF_H
+
+#include 
+
+#define MAXGENRELEN32
+
+#define NF_OSF_GENRE   (1 << 0)
+#define NF_OSF_TTL (1 << 1)
+#define NF_OSF_LOG (1 << 2)
+#define NF_OSF_INVERT  (1 << 3)
+
+#define NF_OSF_LOGLEVEL_ALL0   /* log all matched fingerprints 
*/
+#define NF_OSF_LOGLEVEL_FIRST  1   /* log only the first matced 
fingerprint */
+#define NF_OSF_LOGLEVEL_ALL_KNOWN  2   /* do not log unknown packets */
+
+#define NF_OSF_TTL_TRUE0   /* True ip and 
fingerprint TTL comparison */
+
+/* Check if ip TTL is less than fingerprint one */
+#define NF_OSF_TTL_LESS1
+
+/* Do not compare ip and fingerprint TTL at all */
+#define NF_OSF_TTL_NOCHECK 2
+
+#define NF_OSF_FLAGMASK(NF_OSF_GENRE | NF_OSF_TTL | \
+NF_OSF_LOG | NF_OSF_INVERT)
+/* Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct nf_osf_wc {
+   __u32   wc;
+   __u32   val;
+};
+
+/* This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct nf_osf_opt {
+   __u16   kind, length;
+   struct nf_osf_wcwc;
+};
+
+struct nf_osf_info {
+   chargenre[MAXGENRELEN];
+   __u32   len;
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+};
+
+struct nf_osf_user_finger {
+   struct nf_osf_wcwss;
+
+   __u8ttl, df;
+   __u16   ss, mss;
+   __u16   opt_num;
+
+   chargenre[MAXGENRELEN];
+   charversion[MAXGENRELEN];
+   charsubtype[MAXGENRELEN];
+
+   /* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+   struct nf_osf_opt   opt[MAX_IPOPTLEN];
+};
+
+struct nf_osf_nlmsg {
+   struct nf_osf_user_finger   f;
+   struct iphdrip;
+   struct tcphdr   tcp;
+};
+
+/* Defines for IANA option kinds */
+enum iana_options {
+   OSFOPT_EOL = 0, /* End of options */
+   OSFOPT_NOP, /* NOP */
+   OSFOPT_MSS, /* Maximum segment size */
+   OSFOPT_WSO, /* Window scale option */
+   OSFOPT_SACKP,   /* SACK permitted */
+   OSFOPT_SACK,/* SACK */
+   OSFOPT_ECHO,
+   OSFOPT_ECHOREPLY,
+   OSFOPT_TS,  /* Timestamp option */
+   OSFOPT_POCP,/* Partial Order Connection Permitted */
+   OSFOPT_POSP,/* Partial Order Service Profile */
+
+   /* Others are not used in the current OSF */
+   OSFOPT_EMPTY = 255,
+};
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum nf_osf_window_size_options {
+   OSF_WSS_PLAIN   = 0,
+   OSF_WSS_MSS,
+   OSF_WSS_MTU,
+   OSF_WSS_MODULO,
+   OSF_WSS_MAX,
+};
+
+enum nf_osf_attr_type {
+   OSF_ATTR_UNSPEC,
+   OSF_ATTR_FINGER,
+   OSF_ATTR_MAX,
+};
+
+/*
+ * Add/remove fingerprint from the kernel.
+ */
+enum nf_osf_msg_types {
+   OSF_MSG_ADD,
+   OSF_MSG_REMOVE,
+   OSF_MSG_MAX,
+};
+
+#endif /* _NF_OSF_H */
diff --git a/include/nfnl_osf.h b/include/nfnl_osf.h
new file mode 100644
index 000..b676045
--- /dev/null
+++ b/include/nfnl_osf.h
@@ -0,0 +1,10 @@
+#ifndef _NFNL_OSF_H
+#define _NFNL_OSF_H
+
+#define OS_SIGNATURES DEFAULT_INCLUDE_PATH "/pf.os"
+
+bool osf_init;
+
+int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
+
+#endif /* _NFNL_OSF_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index ed3640e..e569029 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -57,6 +57,7 @@ libnftables_la_SOURCES =  \
services.c  \
mergesort.c \
osf.c 

[PATCH 2/3 nft v2] src: mnl: make nft_mnl_talk() public

2018-08-13 Thread Fernando Fernandez Mancera
As we are going to use the function nft_mnl_talk() from the incoming
nftnl_osf.c, we make it public.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/mnl.h | 4 
 src/mnl.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/mnl.h b/include/mnl.h
index cb131bb..36109c7 100644
--- a/include/mnl.h
+++ b/include/mnl.h
@@ -92,4 +92,8 @@ int mnl_nft_event_listener(struct mnl_socket *nf_sock, 
unsigned int debug_mask,
   int (*cb)(const struct nlmsghdr *nlh, void *data),
   void *cb_data);
 
+int nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len,
+int (*cb)(const struct nlmsghdr *nlh, void *data),
+void *cb_data);
+
 #endif /* _NFTABLES_MNL_H_ */
diff --git a/src/mnl.c b/src/mnl.c
index 42eacab..6a6d45c 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -66,7 +66,7 @@ out:
return ret;
 }
 
-static int
+int
 nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len,
 int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data)
 {
-- 
2.18.0



Re: [PATCH 3/3 nft] src: osf: import nfnl_osf.c to load osf fingerprints

2018-08-11 Thread Fernando Fernandez Mancera




On 08/11/2018 12:03 PM, Pablo Neira Ayuso wrote:

+#endif /* _NF_OSF_H */
diff --git a/include/nfnl_osf.h b/include/nfnl_osf.h
new file mode 100644
index 000..d9287e9
--- /dev/null
+++ b/include/nfnl_osf.h
@@ -0,0 +1,6 @@
+#ifndef _NFNL_OSF_H
+#define _NFNL_OSF_H
+
+int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
+
+#endif /* _NFNL_OSF_H */
diff --git a/include/osf.h b/include/osf.h
index 715b04e..0a35b07 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,6 +1,8 @@
  #ifndef NFTABLES_OSF_H
  #define NFTABLES_OSF_H
  
+bool osf_init;


I think you can probably place osf_init in struct netlink_ctx?



If we place osf_init in struct netlink_ctx we will need to modify 
osf_expr_alloc() and I am not sure if we can get access to netlink_ctx 
from netlink_parse_osf() in netlink_delinearize.c. Also we will need 
access to netlink_ctx from parser_bison.y.


So I propose to add osf_init in nfnl_osf.h in order to have only one 
extra include in rule.c. Thanks.



  struct expr *osf_expr_alloc(const struct location *loc);
  
  #endif /* NFTABLES_OSF_H */

diff --git a/src/Makefile.am b/src/Makefile.am
index ed3640e..e569029 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -57,6 +57,7 @@ libnftables_la_SOURCES =  \
services.c  \
mergesort.c \
osf.c   \
+   nfnl_osf.c  \
tcpopt.c\
socket.c\
libnftables.c
diff --git a/src/nfnl_osf.c b/src/nfnl_osf.c
new file mode 100644
index 000..07bf682
--- /dev/null
+++ b/src/nfnl_osf.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2005 Evgeniy Polyakov 
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#define OPTDEL ','
+#define OSFPDEL':'
+#define MAXOPTSTRLEN   128
+
+static struct nf_osf_opt IANA_opts[] = {
+   { .kind = 0, .length = 1,},
+   { .kind=1, .length=1,},
+   { .kind=2, .length=4,},
+   { .kind=3, .length=3,},
+   { .kind=4, .length=2,},
+   { .kind=5, .length=1,}, /* SACK length is not defined */
+   { .kind=6, .length=6,},
+   { .kind=7, .length=6,},
+   { .kind=8, .length=10,},
+   { .kind=9, .length=2,},
+   { .kind=10, .length=3,},
+   { .kind=11, .length=1,},/* CC: Suppose 1 */
+   { .kind=12, .length=1,},/* the same */
+   { .kind=13, .length=1,},/* and here too */
+   { .kind=14, .length=3,},
+   { .kind=15, .length=1,},/* TCP Alternate Checksum Data. 
Length is not defined */
+   { .kind=16, .length=1,},
+   { .kind=17, .length=1,},
+   { .kind=18, .length=3,},
+   { .kind=19, .length=18,},
+   { .kind=20, .length=1,},
+   { .kind=21, .length=1,},
+   { .kind=22, .length=1,},
+   { .kind=23, .length=1,},
+   { .kind=24, .length=1,},
+   { .kind=25, .length=1,},
+   { .kind=26, .length=1,},
+};
+
+static void uloga(const char *f, struct netlink_ctx *ctx, ...)
+{
+   if (!(ctx->debug_mask & NFT_DEBUG_NETLINK))
+   return;
+
+   nft_print(ctx->octx, "%s", f);
+}


I think you can use uloga() all the time, so you can remove ulog()
function.



I agree. Changes done.


+static void ulog(const char *f, struct netlink_ctx *ctx, ...)
+{
+   char str[64];
+   struct tm tm;
+   struct timeval tv;
+
+   gettimeofday(, NULL);
+   localtime_r((time_t *)_sec, );
+   strftime(str, sizeof(str), "%F %R:%S", );
+
+   if (!(ctx->debug_mask & NFT_DEBUG_NETLINK))
+   return;
+
+   nft_print(ctx->octx, "%s.%lu %ld %s", str, tv.tv_usec,
+ syscall(__NR_gettid), f);
+}
+
+#define ulog_err(f, ctx, a...) uloga(f ": %s [%d].\n", ctx, ##a, 
strerror(errno), errno)


And this macro too.

Other than that, this looks good to me, thanks.



Re: [PATCH 3/3 nft] src: osf: import nfnl_osf.c to load osf fingerprints

2018-08-10 Thread Fernando Fernandez Mancera
I think we should place osf_init in nfnl_osf.h so this way we don't need to 
include osf.h in rule.c. If you agree I will send another patchset iteration. 
Thanks.

El 10 de agosto de 2018 15:02:00 CEST, Fernando Fernandez Mancera 
 escribió:
>Import iptables/utils/nfnl_osf.c into nftables tree with some changes
>in order
>to load OS fingerprints automatically from pf.os file.
>
>Signed-off-by: Fernando Fernandez Mancera 
>---
> include/linux/netfilter/nfnetlink_osf.h | 119 +++
> include/nfnl_osf.h  |   6 +
> include/osf.h   |   2 +
> src/Makefile.am |   1 +
> src/nfnl_osf.c  | 449 
> src/osf.c   |   2 +
> src/rule.c  |   5 +
> 7 files changed, 584 insertions(+)
> create mode 100644 include/linux/netfilter/nfnetlink_osf.h
> create mode 100644 include/nfnl_osf.h
> create mode 100644 src/nfnl_osf.c
>
>diff --git a/include/linux/netfilter/nfnetlink_osf.h
>b/include/linux/netfilter/nfnetlink_osf.h
>new file mode 100644
>index 000..15a39d2
>--- /dev/null
>+++ b/include/linux/netfilter/nfnetlink_osf.h
>@@ -0,0 +1,119 @@
>+#ifndef _NF_OSF_H
>+#define _NF_OSF_H
>+
>+#include 
>+
>+#define MAXGENRELEN   32
>+
>+#define NF_OSF_GENRE  (1 << 0)
>+#define NF_OSF_TTL(1 << 1)
>+#define NF_OSF_LOG(1 << 2)
>+#define NF_OSF_INVERT (1 << 3)
>+
>+#define NF_OSF_LOGLEVEL_ALL   0   /* log all matched fingerprints 
>*/
>+#define NF_OSF_LOGLEVEL_FIRST 1   /* log only the first matced
>fingerprint */
>+#define NF_OSF_LOGLEVEL_ALL_KNOWN 2   /* do not log unknown packets */
>+
>+#define NF_OSF_TTL_TRUE   0   /* True ip and 
>fingerprint TTL comparison
>*/
>+
>+/* Check if ip TTL is less than fingerprint one */
>+#define NF_OSF_TTL_LESS   1
>+
>+/* Do not compare ip and fingerprint TTL at all */
>+#define NF_OSF_TTL_NOCHECK2
>+
>+#define NF_OSF_FLAGMASK   (NF_OSF_GENRE | NF_OSF_TTL | \
>+   NF_OSF_LOG | NF_OSF_INVERT)
>+/* Wildcard MSS (kind of).
>+ * It is used to implement a state machine for the different wildcard
>values
>+ * of the MSS and window sizes.
>+ */
>+struct nf_osf_wc {
>+  __u32   wc;
>+  __u32   val;
>+};
>+
>+/* This struct represents IANA options
>+ * http://www.iana.org/assignments/tcp-parameters
>+ */
>+struct nf_osf_opt {
>+  __u16   kind, length;
>+  struct nf_osf_wcwc;
>+};
>+
>+struct nf_osf_info {
>+  chargenre[MAXGENRELEN];
>+  __u32   len;
>+  __u32   flags;
>+  __u32   loglevel;
>+  __u32   ttl;
>+};
>+
>+struct nf_osf_user_finger {
>+  struct nf_osf_wcwss;
>+
>+  __u8ttl, df;
>+  __u16   ss, mss;
>+  __u16   opt_num;
>+
>+  chargenre[MAXGENRELEN];
>+  charversion[MAXGENRELEN];
>+  charsubtype[MAXGENRELEN];
>+
>+  /* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
>+  struct nf_osf_opt   opt[MAX_IPOPTLEN];
>+};
>+
>+struct nf_osf_nlmsg {
>+  struct nf_osf_user_finger   f;
>+  struct iphdrip;
>+  struct tcphdr   tcp;
>+};
>+
>+/* Defines for IANA option kinds */
>+enum iana_options {
>+  OSFOPT_EOL = 0, /* End of options */
>+  OSFOPT_NOP, /* NOP */
>+  OSFOPT_MSS, /* Maximum segment size */
>+  OSFOPT_WSO, /* Window scale option */
>+  OSFOPT_SACKP,   /* SACK permitted */
>+  OSFOPT_SACK,/* SACK */
>+  OSFOPT_ECHO,
>+  OSFOPT_ECHOREPLY,
>+  OSFOPT_TS,  /* Timestamp option */
>+  OSFOPT_POCP,/* Partial Order Connection Permitted */
>+  OSFOPT_POSP,/* Partial Order Service Profile */
>+
>+  /* Others are not used in the current OSF */
>+  OSFOPT_EMPTY = 255,
>+};
>+
>+/*
>+ * Initial window size option state machine: multiple of mss, mtu or
>+ * plain numeric value. Can also be made as plain numeric value which
>+ * is not a multiple of specified value.
>+ */
>+enum nf_osf_window_size_options {
>+  OSF_WSS_PLAIN   = 0,
>+  OSF_WSS_MSS,
>+  OSF_WSS_MTU,
>+  OSF_WSS_MODULO,
>+  OSF_WSS_MAX,
>+};
>+
>+enum nf_osf_attr_type {
>+  OSF_ATTR_UNSPEC,
>+  OSF_ATTR_FINGER,
>+  OSF_ATTR_MAX,
>+};
>+
>+/*
>+ * Add/remove fingerprint from the kernel.
>+ */
>+enum nf_osf_msg_types {
>+  OSF

[PATCH 3/3 nft] src: osf: import nfnl_osf.c to load osf fingerprints

2018-08-10 Thread Fernando Fernandez Mancera
Import iptables/utils/nfnl_osf.c into nftables tree with some changes in order
to load OS fingerprints automatically from pf.os file.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nfnetlink_osf.h | 119 +++
 include/nfnl_osf.h  |   6 +
 include/osf.h   |   2 +
 src/Makefile.am |   1 +
 src/nfnl_osf.c  | 449 
 src/osf.c   |   2 +
 src/rule.c  |   5 +
 7 files changed, 584 insertions(+)
 create mode 100644 include/linux/netfilter/nfnetlink_osf.h
 create mode 100644 include/nfnl_osf.h
 create mode 100644 src/nfnl_osf.c

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
new file mode 100644
index 000..15a39d2
--- /dev/null
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -0,0 +1,119 @@
+#ifndef _NF_OSF_H
+#define _NF_OSF_H
+
+#include 
+
+#define MAXGENRELEN32
+
+#define NF_OSF_GENRE   (1 << 0)
+#define NF_OSF_TTL (1 << 1)
+#define NF_OSF_LOG (1 << 2)
+#define NF_OSF_INVERT  (1 << 3)
+
+#define NF_OSF_LOGLEVEL_ALL0   /* log all matched fingerprints 
*/
+#define NF_OSF_LOGLEVEL_FIRST  1   /* log only the first matced 
fingerprint */
+#define NF_OSF_LOGLEVEL_ALL_KNOWN  2   /* do not log unknown packets */
+
+#define NF_OSF_TTL_TRUE0   /* True ip and 
fingerprint TTL comparison */
+
+/* Check if ip TTL is less than fingerprint one */
+#define NF_OSF_TTL_LESS1
+
+/* Do not compare ip and fingerprint TTL at all */
+#define NF_OSF_TTL_NOCHECK 2
+
+#define NF_OSF_FLAGMASK(NF_OSF_GENRE | NF_OSF_TTL | \
+NF_OSF_LOG | NF_OSF_INVERT)
+/* Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct nf_osf_wc {
+   __u32   wc;
+   __u32   val;
+};
+
+/* This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct nf_osf_opt {
+   __u16   kind, length;
+   struct nf_osf_wcwc;
+};
+
+struct nf_osf_info {
+   chargenre[MAXGENRELEN];
+   __u32   len;
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+};
+
+struct nf_osf_user_finger {
+   struct nf_osf_wcwss;
+
+   __u8ttl, df;
+   __u16   ss, mss;
+   __u16   opt_num;
+
+   chargenre[MAXGENRELEN];
+   charversion[MAXGENRELEN];
+   charsubtype[MAXGENRELEN];
+
+   /* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+   struct nf_osf_opt   opt[MAX_IPOPTLEN];
+};
+
+struct nf_osf_nlmsg {
+   struct nf_osf_user_finger   f;
+   struct iphdrip;
+   struct tcphdr   tcp;
+};
+
+/* Defines for IANA option kinds */
+enum iana_options {
+   OSFOPT_EOL = 0, /* End of options */
+   OSFOPT_NOP, /* NOP */
+   OSFOPT_MSS, /* Maximum segment size */
+   OSFOPT_WSO, /* Window scale option */
+   OSFOPT_SACKP,   /* SACK permitted */
+   OSFOPT_SACK,/* SACK */
+   OSFOPT_ECHO,
+   OSFOPT_ECHOREPLY,
+   OSFOPT_TS,  /* Timestamp option */
+   OSFOPT_POCP,/* Partial Order Connection Permitted */
+   OSFOPT_POSP,/* Partial Order Service Profile */
+
+   /* Others are not used in the current OSF */
+   OSFOPT_EMPTY = 255,
+};
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum nf_osf_window_size_options {
+   OSF_WSS_PLAIN   = 0,
+   OSF_WSS_MSS,
+   OSF_WSS_MTU,
+   OSF_WSS_MODULO,
+   OSF_WSS_MAX,
+};
+
+enum nf_osf_attr_type {
+   OSF_ATTR_UNSPEC,
+   OSF_ATTR_FINGER,
+   OSF_ATTR_MAX,
+};
+
+/*
+ * Add/remove fingerprint from the kernel.
+ */
+enum nf_osf_msg_types {
+   OSF_MSG_ADD,
+   OSF_MSG_REMOVE,
+   OSF_MSG_MAX,
+};
+
+#endif /* _NF_OSF_H */
diff --git a/include/nfnl_osf.h b/include/nfnl_osf.h
new file mode 100644
index 000..d9287e9
--- /dev/null
+++ b/include/nfnl_osf.h
@@ -0,0 +1,6 @@
+#ifndef _NFNL_OSF_H
+#define _NFNL_OSF_H
+
+int nfnl_osf_load_fingerprints(struct netlink_ctx *ctx, int del);
+
+#endif /* _NFNL_OSF_H */
diff --git a/include/osf.h b/include/osf.h
index 715b04e..0a35b07 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,6 +1,8 @@
 #ifndef NFTABLES_OSF_H
 #define NFTABLES_OSF_H
 
+bool osf_init;
+
 struct expr *osf_expr_alloc(const struct location *loc);
 
 #endif /* NFTABLES_OSF_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index ed3640e..e569029 100644
--- a/src/Makefile.

[PATCH 1/3 nft] files: osf: copy iptables/utils/pf.os into nftables tree

2018-08-10 Thread Fernando Fernandez Mancera
As we are going to need pf.os file to load OS fingerprints from the incoming
nfnl_osf.c, we copy it into the nftables tree directory "files/osf/".

Signed-off-by: Fernando Fernandez Mancera 
---
 files/osf/pf.os | 709 
 1 file changed, 709 insertions(+)
 create mode 100644 files/osf/pf.os

diff --git a/files/osf/pf.os b/files/osf/pf.os
new file mode 100644
index 000..e285851
--- /dev/null
+++ b/files/osf/pf.os
@@ -0,0 +1,709 @@
+# $FreeBSD: head/etc/pf.os 258865 2013-12-03 04:32:02Z eadler $
+# $OpenBSD: pf.os,v 1.27 2016/09/03 17:08:57 sthen Exp $
+# passive OS fingerprinting
+# -
+#
+# SYN signatures. Those signatures work for SYN packets only (duh!).
+#
+# (C) Copyright 2000-2003 by Michal Zalewski 
+# (C) Copyright 2003 by Mike Frantzen 
+#
+#  Permission to use, copy, modify, and distribute this software for any
+#  purpose with or without fee is hereby granted, provided that the above
+#  copyright notice and this permission notice appear in all copies.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+#  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+#  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+#  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+#  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+#  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+#  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#
+# This fingerprint database is adapted from Michal Zalewski's p0f passive
+# operating system package.  The last database sync was from a Nov 3 2003
+# p0f.fp.
+#
+#
+# Each line in this file specifies a single fingerprint. Please read the
+# information below carefully before attempting to append any signatures
+# reported as UNKNOWN to this file to avoid mistakes.
+#
+# We use the following set metrics for fingerprinting:
+#
+# - Window size (WSS) - a highly OS dependent setting used for TCP/IP
+#   performance control (max. amount of data to be sent without ACK).
+#   Some systems use a fixed value for initial packets. On other
+#   systems, it is a multiple of MSS or MTU (MSS+40). In some rare
+#   cases, the value is just arbitrary.
+#
+#   NEW SIGNATURE: if p0f reported a special value of 'Snn', the number
+#   appears to be a multiple of MSS (MSS*nn); a special value of 'Tnn'
+#   means it is a multiple of MTU ((MSS+40)*nn). Unless you notice the
+#   value of nn is not fixed (unlikely), just copy the Snn or Tnn token
+#   literally. If you know this device has a simple stack and a fixed
+#   MTU, you can however multiply S value by MSS, or T value by MSS+40,
+#   and put it instead of Snn or Tnn.
+#
+#   If WSS otherwise looks like a fixed value (for example a multiple
+#   of two), or if you can confirm the value is fixed, please quote
+#   it literally. If there's no apparent pattern in WSS chosen, you
+#   should consider wildcarding this value.
+#
+# - Overall packet size - a function of all IP and TCP options and bugs.
+#
+#   NEW SIGNATURE: Copy this value literally.
+#
+# - Initial TTL - We check the actual TTL of a received packet. It can't
+#   be higher than the initial TTL, and also shouldn't be dramatically
+#   lower (maximum distance is defined as 40 hops).
+#
+#   NEW SIGNATURE: *Never* copy TTL from a p0f-reported signature literally.
+#   You need to determine the initial TTL. The best way to do it is to
+#   check the documentation for a remote system, or check its settings.
+#   A fairly good method is to simply round the observed TTL up to
+#   32, 64, 128, or 255, but it should be noted that some obscure devices
+#   might not use round TTLs (in particular, some shoddy appliances use
+#   "original" initial TTL settings). If not sure, you can see how many
+#   hops you're away from the remote party with traceroute or mtr.
+#
+# - Don't fragment flag (DF) - some modern OSes set this to implement PMTU
+#   discovery. Others do not bother.
+#
+#   NEW SIGNATURE: Copy this value literally.
+#
+# - Maximum segment size (MSS) - this setting is usually link-dependent. P0f
+#   uses it to determine link type of the remote host.
+#
+#   NEW SIGNATURE: Always wildcard this value, except for rare cases when
+#   you have an appliance with a fixed value, know the system supports only
+#   a very limited number of network interface types, or know the system
+#   is using a value it pulled out of nowhere.  Specific unique MSS
+#   can be used to tell Google crawlbots from the rest of the population.
+#
+# - Window scaling (WSCALE) - this feature is used to scale WSS.
+#   It extends the size of a TCP/IP window to 32 bits. Some modern
+#   systems implement this feature.
+#
+#   NEW SIGNATURE: Observe several signatures. Initial WSCALE is often set
+#   to zero or other low value. There's usually no need t

[PATCH 2/3 nft] src: mnl: make nft_mnl_talk() public

2018-08-10 Thread Fernando Fernandez Mancera
As we are going to use the function nft_mnl_talk() from the incoming
nftnl_osf.c, we make it public.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/mnl.h | 4 
 src/mnl.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/mnl.h b/include/mnl.h
index cb131bb..36109c7 100644
--- a/include/mnl.h
+++ b/include/mnl.h
@@ -92,4 +92,8 @@ int mnl_nft_event_listener(struct mnl_socket *nf_sock, 
unsigned int debug_mask,
   int (*cb)(const struct nlmsghdr *nlh, void *data),
   void *cb_data);
 
+int nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len,
+int (*cb)(const struct nlmsghdr *nlh, void *data),
+void *cb_data);
+
 #endif /* _NFTABLES_MNL_H_ */
diff --git a/src/mnl.c b/src/mnl.c
index 42eacab..6a6d45c 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -66,7 +66,7 @@ out:
return ret;
 }
 
-static int
+int
 nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len,
 int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data)
 {
-- 
2.18.0



[PATCH nf-next] netfilter: nfnetlink_osf: add missing enum in nfnetlink_osf uapi header

2018-08-07 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nfnetlink_osf.h  | 12 
 include/uapi/linux/netfilter/nfnetlink_osf.h | 13 +
 include/uapi/linux/netfilter/xt_osf.h|  1 +
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
index a7311bc03d3a..ecf7dab81e9e 100644
--- a/include/linux/netfilter/nfnetlink_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -4,18 +4,6 @@
 
 #include 
 
-/* Initial window size option state machine: multiple of mss, mtu or
- * plain numeric value. Can also be made as plain numeric value which
- * is not a multiple of specified value.
- */
-enum nf_osf_window_size_options {
-   OSF_WSS_PLAIN   = 0,
-   OSF_WSS_MSS,
-   OSF_WSS_MTU,
-   OSF_WSS_MODULO,
-   OSF_WSS_MAX,
-};
-
 enum osf_fmatch_states {
/* Packet does not match the fingerprint */
FMATCH_WRONG = 0,
diff --git a/include/uapi/linux/netfilter/nfnetlink_osf.h 
b/include/uapi/linux/netfilter/nfnetlink_osf.h
index 3b93fbb9fc24..15a39d292ef9 100644
--- a/include/uapi/linux/netfilter/nfnetlink_osf.h
+++ b/include/uapi/linux/netfilter/nfnetlink_osf.h
@@ -88,6 +88,19 @@ enum iana_options {
OSFOPT_EMPTY = 255,
 };
 
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum nf_osf_window_size_options {
+   OSF_WSS_PLAIN   = 0,
+   OSF_WSS_MSS,
+   OSF_WSS_MTU,
+   OSF_WSS_MODULO,
+   OSF_WSS_MAX,
+};
+
 enum nf_osf_attr_type {
OSF_ATTR_UNSPEC,
OSF_ATTR_FINGER,
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index c56c59605c2b..24102b5286ec 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -46,6 +46,7 @@
 #define xt_osf_finger  nf_osf_finger
 #define xt_osf_nlmsg   nf_osf_nlmsg
 
+#define xt_osf_window_size_options nf_osf_window_size_options
 #define xt_osf_attr_type   nf_osf_attr_type
 #define xt_osf_msg_types   nf_osf_msg_types
 
-- 
2.18.0

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


[PATCH 2/2 nft v2] tests: improve test cases for osf

2018-08-07 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 tests/py/inet/osf.t |  5 -
 tests/py/inet/osf.t.payload | 12 +++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/tests/py/inet/osf.t b/tests/py/inet/osf.t
index 4db20b7..6533b84 100644
--- a/tests/py/inet/osf.t
+++ b/tests/py/inet/osf.t
@@ -1,6 +1,9 @@
 :osfchain;type filter hook input priority 0
 
 *ip;osfip;osfchain
+*ip6;osfip6;osfchain
+*inet;osfinet;osfchain
 
-osf name "Linux";ok;osf "Linux"
+osf name "Linux";ok
+osf name "morethansixteenbytes";fail
 osf name ;fail
diff --git a/tests/py/inet/osf.t.payload b/tests/py/inet/osf.t.payload
index 70eedb5..9f3da48 100644
--- a/tests/py/inet/osf.t.payload
+++ b/tests/py/inet/osf.t.payload
@@ -1,4 +1,14 @@
 # osf name "Linux"
 ip osfip osfchain
-  [ osf 1]
+  [ osf  ]
+  [ cmp eq reg 1 0x756e694c 0x0078 0x 0x ]
+
+# osf name "Linux"
+ip6 osfip6 osfchain
+  [ osf  ]
+  [ cmp eq reg 1 0x756e694c 0x0078 0x 0x ]
+
+# osf name "Linux"
+inet osfinet osfchain
+  [ osf  ]
   [ cmp eq reg 1 0x756e694c 0x0078 0x 0x ]
-- 
2.18.0

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


[PATCH 1/2 nft v2] src: use NFT_OSF_MAXGENRELEN instead of IFNAMSIZ in osf.c

2018-08-07 Thread Fernando Fernandez Mancera
As no "genre" in pf.os exceed 16 bytes of length, we reduce
NFT_OSF_MAXGENRELEN parameter to 16 bytes and use it instead of IFNAMSIZ.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nf_tables.h | 1 +
 src/osf.c   | 4 +---
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 63b9054..fe65652 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -8,6 +8,7 @@
 #define NFT_SET_MAXNAMELEN NFT_NAME_MAXLEN
 #define NFT_OBJ_MAXNAMELEN NFT_NAME_MAXLEN
 #define NFT_USERDATA_MAXLEN256
+#define NFT_OSF_MAXGENRELEN16
 
 /**
  * enum nft_registers - nf_tables registers
diff --git a/src/osf.c b/src/osf.c
index f07a725..131d54e 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -4,8 +4,6 @@
 #include 
 #include 
 
-#include 
-
 static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
nft_print(octx, "osf name");
@@ -24,7 +22,7 @@ static const struct expr_ops osf_expr_ops = {
 
 struct expr *osf_expr_alloc(const struct location *loc)
 {
-   unsigned int len = IFNAMSIZ * BITS_PER_BYTE;
+   unsigned int len = NFT_OSF_MAXGENRELEN * BITS_PER_BYTE;
const struct datatype *type = _type;
struct expr *expr;
 
-- 
2.18.0

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


[PATCH nf-next v2] netfilter: nft_osf: use NFT_OSF_MAXGENRELEN instead of IFNAMSIZ

2018-08-07 Thread Fernando Fernandez Mancera
As no "genre" on pf.os exceed 16 bytes of length, we reduce
NFT_OSF_MAXGENRELEN parameter to 16 bytes and use it instead of IFNAMSIZ.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/uapi/linux/netfilter/nf_tables.h | 1 +
 net/netfilter/nft_osf.c  | 8 +++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 357862d948de..94657c701f22 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -8,6 +8,7 @@
 #define NFT_SET_MAXNAMELEN NFT_NAME_MAXLEN
 #define NFT_OBJ_MAXNAMELEN NFT_NAME_MAXLEN
 #define NFT_USERDATA_MAXLEN256
+#define NFT_OSF_MAXGENRELEN16
 
 /**
  * enum nft_registers - nf_tables registers
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index 9b2f3de7be4f..5af74b37f423 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -4,8 +4,6 @@
 #include 
 #include 
 
-#define OSF_GENRE_SIZE 32
-
 struct nft_osf {
enum nft_registers  dreg:8;
 };
@@ -37,9 +35,9 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
 
os_name = nf_osf_find(skb, nf_osf_fingers);
if (!os_name)
-   strncpy((char *)dest, "unknown", IFNAMSIZ);
+   strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN);
else
-   strncpy((char *)dest, os_name, IFNAMSIZ);
+   strncpy((char *)dest, os_name, NFT_OSF_MAXGENRELEN);
 }
 
 static int nft_osf_init(const struct nft_ctx *ctx,
@@ -51,7 +49,7 @@ static int nft_osf_init(const struct nft_ctx *ctx,
 
priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
err = nft_validate_register_store(ctx, priv->dreg, NULL,
- NFTA_DATA_VALUE, OSF_GENRE_SIZE);
+ NFTA_DATA_VALUE, NFT_OSF_MAXGENRELEN);
if (err < 0)
return err;
 
-- 
2.18.0

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


[PATCH libnftnl] expr: osf: modify _snprintf_default function

2018-08-07 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 src/expr/osf.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/expr/osf.c b/src/expr/osf.c
index 1541390..ac7a6f3 100644
--- a/src/expr/osf.c
+++ b/src/expr/osf.c
@@ -91,11 +91,10 @@ nftnl_expr_osf_parse(struct nftnl_expr *e, struct nlattr 
*attr)
 static int nftnl_expr_osf_snprintf_default(char *buf, size_t size,
   const struct nftnl_expr *e)
 {
-   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
int ret, offset = 0, len = size;
 
if (e->flags & (1 << NFTNL_EXPR_OSF_DREG)) {
-   ret = snprintf(buf, len, "%u", osf->dreg);
+   ret = snprintf(buf, len, " ");
SNPRINTF_BUFFER_SIZE(ret, len, offset);
}
 
-- 
2.18.0

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


Re: [PATCH nf-next] netfilter: nft_osf: use OSF_GENRE_SIZE instead of IFNAMSIZ

2018-08-06 Thread Fernando Fernandez Mancera

On 08/06/2018 01:30 PM, Pablo Neira Ayuso wrote:

On Mon, Aug 06, 2018 at 01:24:17PM +0200, Fernando Fernandez Mancera wrote:

Right now, we have "MAXGENRELEN" defined in UAPI, so I am going to use it
instead of define OSF_GENRE_SIZE.


Oh I see.

This is 32 bytes long and we cannot change it because original xt_osf
structure relies on that. Changes would break the binary interface
which is a no-go.

We can probably place this in netfilter/nf_tables.h uapi file instead
so this is only used by nft_osf.

If we ever need more than 16 bytes, we can extend it to be 32 bytes.

OK?



OK, seems fine to me. Thanks

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


[PATCH 1/2 nft] src: use OSF_GENRE_SIZE instead of IFNAMSIZ in osf.c

2018-08-06 Thread Fernando Fernandez Mancera
As no "genre" in pf.os exceed 16 bytes of length, we reduce OSF_GENRE_SIZE
parameter to 16 bytes and use it instead of IFNAMSIZ.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/osf.h | 2 ++
 src/osf.c | 4 +---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/osf.h b/include/osf.h
index 715b04e..d4d0c19 100644
--- a/include/osf.h
+++ b/include/osf.h
@@ -1,6 +1,8 @@
 #ifndef NFTABLES_OSF_H
 #define NFTABLES_OSF_H
 
+#define OSF_GENRE_SIZE 16
+
 struct expr *osf_expr_alloc(const struct location *loc);
 
 #endif /* NFTABLES_OSF_H */
diff --git a/src/osf.c b/src/osf.c
index f07a725..e7aae89 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -4,8 +4,6 @@
 #include 
 #include 
 
-#include 
-
 static void osf_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
nft_print(octx, "osf name");
@@ -24,7 +22,7 @@ static const struct expr_ops osf_expr_ops = {
 
 struct expr *osf_expr_alloc(const struct location *loc)
 {
-   unsigned int len = IFNAMSIZ * BITS_PER_BYTE;
+   unsigned int len = OSF_GENRE_SIZE * BITS_PER_BYTE;
const struct datatype *type = _type;
struct expr *expr;
 
-- 
2.18.0

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


[PATCH 2/2 nft] tests: improve test cases for osf

2018-08-06 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 tests/py/inet/osf.t |  5 -
 tests/py/inet/osf.t.payload | 10 ++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/tests/py/inet/osf.t b/tests/py/inet/osf.t
index 4db20b7..6533b84 100644
--- a/tests/py/inet/osf.t
+++ b/tests/py/inet/osf.t
@@ -1,6 +1,9 @@
 :osfchain;type filter hook input priority 0
 
 *ip;osfip;osfchain
+*ip6;osfip6;osfchain
+*inet;osfinet;osfchain
 
-osf name "Linux";ok;osf "Linux"
+osf name "Linux";ok
+osf name "morethansixteenbytes";fail
 osf name ;fail
diff --git a/tests/py/inet/osf.t.payload b/tests/py/inet/osf.t.payload
index 70eedb5..91ff369 100644
--- a/tests/py/inet/osf.t.payload
+++ b/tests/py/inet/osf.t.payload
@@ -2,3 +2,13 @@
 ip osfip osfchain
   [ osf 1]
   [ cmp eq reg 1 0x756e694c 0x0078 0x 0x ]
+
+# osf name "Linux"
+ip6 osfip6 osfchain
+  [ osf 1]
+  [ cmp eq reg 1 0x756e694c 0x0078 0x 0x ]
+
+# osf name "Linux"
+inet osfinet osfchain
+  [ osf 1]
+  [ cmp eq reg 1 0x756e694c 0x0078 0x 0x ]
-- 
2.18.0

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


[PATCH nf-next] netfilter: nft_osf: use OSF_GENRE_SIZE instead of IFNAMSIZ

2018-08-06 Thread Fernando Fernandez Mancera
As no "genre" on pf.os exceed 16 bytes of length, we reduce OSF_GENRE_SIZE
parameter to 16 bytes and use it instead of IFNAMSIZ.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nfnetlink_osf.h | 2 ++
 net/netfilter/nft_osf.c | 6 ++
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
index a7311bc03d3a..6215dbf4f122 100644
--- a/include/linux/netfilter/nfnetlink_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -4,6 +4,8 @@
 
 #include 
 
+#define OSF_GENRE_SIZE 16
+
 /* Initial window size option state machine: multiple of mss, mtu or
  * plain numeric value. Can also be made as plain numeric value which
  * is not a multiple of specified value.
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index 9b2f3de7be4f..6564adfe5c6f 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -4,8 +4,6 @@
 #include 
 #include 
 
-#define OSF_GENRE_SIZE 32
-
 struct nft_osf {
enum nft_registers  dreg:8;
 };
@@ -37,9 +35,9 @@ static void nft_osf_eval(const struct nft_expr *expr, struct 
nft_regs *regs,
 
os_name = nf_osf_find(skb, nf_osf_fingers);
if (!os_name)
-   strncpy((char *)dest, "unknown", IFNAMSIZ);
+   strncpy((char *)dest, "unknown", OSF_GENRE_SIZE);
else
-   strncpy((char *)dest, os_name, IFNAMSIZ);
+   strncpy((char *)dest, os_name, OSF_GENRE_SIZE);
 }
 
 static int nft_osf_init(const struct nft_ctx *ctx,
-- 
2.18.0

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


[PATCH nftables] test: py: fix osf testcases warning

2018-08-03 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 tests/py/inet/osf.t | 4 ++--
 tests/py/inet/osf.t.payload | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/py/inet/osf.t b/tests/py/inet/osf.t
index 743049a..4db20b7 100644
--- a/tests/py/inet/osf.t
+++ b/tests/py/inet/osf.t
@@ -2,5 +2,5 @@
 
 *ip;osfip;osfchain
 
-osf name Linux;ok
-osf name;fail
+osf name "Linux";ok;osf "Linux"
+osf name ;fail
diff --git a/tests/py/inet/osf.t.payload b/tests/py/inet/osf.t.payload
index bb11051..70eedb5 100644
--- a/tests/py/inet/osf.t.payload
+++ b/tests/py/inet/osf.t.payload
@@ -1,4 +1,4 @@
-# osf name Linux
+# osf name "Linux"
 ip osfip osfchain
   [ osf 1]
   [ cmp eq reg 1 0x756e694c 0x0078 0x 0x ]
-- 
2.18.0

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


Re: [PATCH nftables] doc: add osf expression to man page

2018-08-03 Thread Fernando Fernandez Mancera

Please, apply v2 instead this one. I have fixed a typo.

On 08/04/2018 12:15 AM, Fernando Fernandez Mancera wrote:

Signed-off-by: Fernando Fernandez Mancera 
---
  doc/primary-expression.txt | 29 +
  1 file changed, 29 insertions(+)

diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt
index 50093b4..1445288 100644
--- a/doc/primary-expression.txt
+++ b/doc/primary-expression.txt
@@ -156,6 +156,35 @@ table inet x {
  }
  --
  
+OSF EXPRESSION

+~~
+[verse]
+osf {name}
+
+The osf expression does passive operating system fingerprinting. This
+expression compares some data (Window Size, MSS, options and their order, DF,
+and others) from packets with the SYN bit set.
+
+.Available osf attributes
+[options="header"]
+|==
+|Name |Description| Type
+|name|
+Name os the OS signature to match. All signatures can be found at pf.os file.|
+Use "unknown" for OS signatures that the expression could not detect.
+|==
+
+.Using osf expression
+-
+# Accept packets that match the "Linux" OS signature.
+table inet x {
+chain y {
+   type filter hook input priority 0; policy accept;
+osf "Linux"
+}
+}
+---
+
  FIB EXPRESSIONS
  ~~~
  [verse]


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


[PATCH nftables v2] doc: add osf expression to man page

2018-08-03 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 doc/primary-expression.txt | 29 +
 1 file changed, 29 insertions(+)

diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt
index 50093b4..86f3e52 100644
--- a/doc/primary-expression.txt
+++ b/doc/primary-expression.txt
@@ -156,6 +156,35 @@ table inet x {
 }
 --
 
+OSF EXPRESSION
+~~
+[verse]
+osf {name}
+
+The osf expression does passive operating system fingerprinting. This
+expression compares some data (Window Size, MSS, options and their order, DF,
+and others) from packets with the SYN bit set.
+
+.Available osf attributes
+[options="header"]
+|==
+|Name |Description| Type
+|name|
+Name of the OS signature to match. All signatures can be found at pf.os file.|
+Use "unknown" for OS signatures that the expression could not detect.
+|==
+
+.Using osf expression
+-
+# Accept packets that match the "Linux" OS signature.
+table inet x {
+chain y {
+   type filter hook input priority 0; policy accept;
+osf "Linux"
+}
+}
+---
+
 FIB EXPRESSIONS
 ~~~
 [verse]
-- 
2.18.0

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


[PATCH nftables] doc: add osf expression to man page

2018-08-03 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 doc/primary-expression.txt | 29 +
 1 file changed, 29 insertions(+)

diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt
index 50093b4..1445288 100644
--- a/doc/primary-expression.txt
+++ b/doc/primary-expression.txt
@@ -156,6 +156,35 @@ table inet x {
 }
 --
 
+OSF EXPRESSION
+~~
+[verse]
+osf {name}
+
+The osf expression does passive operating system fingerprinting. This
+expression compares some data (Window Size, MSS, options and their order, DF,
+and others) from packets with the SYN bit set.
+
+.Available osf attributes
+[options="header"]
+|==
+|Name |Description| Type
+|name|
+Name os the OS signature to match. All signatures can be found at pf.os file.|
+Use "unknown" for OS signatures that the expression could not detect.
+|==
+
+.Using osf expression
+-
+# Accept packets that match the "Linux" OS signature.
+table inet x {
+chain y {
+   type filter hook input priority 0; policy accept;
+osf "Linux"
+}
+}
+---
+
 FIB EXPRESSIONS
 ~~~
 [verse]
-- 
2.18.0

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


[PATCH 2/2 nftables] test: py: add test cases for "osf" matching

2018-08-03 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 tests/py/inet/osf.t | 6 ++
 tests/py/inet/osf.t.payload | 4 
 2 files changed, 10 insertions(+)
 create mode 100644 tests/py/inet/osf.t
 create mode 100644 tests/py/inet/osf.t.payload

diff --git a/tests/py/inet/osf.t b/tests/py/inet/osf.t
new file mode 100644
index 000..743049a
--- /dev/null
+++ b/tests/py/inet/osf.t
@@ -0,0 +1,6 @@
+:osfchain;type filter hook input priority 0
+
+*ip;osfip;osfchain
+
+osf name Linux;ok
+osf name;fail
diff --git a/tests/py/inet/osf.t.payload b/tests/py/inet/osf.t.payload
new file mode 100644
index 000..bb11051
--- /dev/null
+++ b/tests/py/inet/osf.t.payload
@@ -0,0 +1,4 @@
+# osf name Linux
+ip osfip osfchain
+  [ osf 1]
+  [ cmp eq reg 1 0x756e694c 0x0078 0x 0x ]
-- 
2.18.0

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


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

2018-08-03 Thread Fernando Fernandez Mancera
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 
---
 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 
 #include 
 #include 
+#include 
 
 /**
  * struct expr
@@ -303,6 +306,9 @@ struct expr {
/* SOCKET */
enum nft_socket_keyskey;
} socket;
+   struct {
+   /* OSF */
+   } osf;
struct {
/* EXPR_RT */
enum nft_rt_keyskey;
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 000..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(>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(&q

[PATCH 2/2 nf-next] nfnetlink_osf: rename nf_osf header file to nfnetlink_osf

2018-07-31 Thread Fernando Fernandez Mancera
As the first client of nf_osf userspace header is nft_osf and xt_osf, we
rename it to nfnetlink_osf.h

Suggested-by: Jan Engelhardt 
Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/{nf_osf.h => nfnetlink_osf.h}  | 2 +-
 include/uapi/linux/netfilter/{nf_osf.h => nfnetlink_osf.h} | 0
 include/uapi/linux/netfilter/xt_osf.h  | 2 +-
 net/netfilter/nfnetlink_osf.c  | 2 +-
 net/netfilter/nft_osf.c| 2 +-
 5 files changed, 4 insertions(+), 4 deletions(-)
 rename include/linux/netfilter/{nf_osf.h => nfnetlink_osf.h} (95%)
 rename include/uapi/linux/netfilter/{nf_osf.h => nfnetlink_osf.h} (100%)

diff --git a/include/linux/netfilter/nf_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
similarity index 95%
rename from include/linux/netfilter/nf_osf.h
rename to include/linux/netfilter/nfnetlink_osf.h
index 3e455d6f94d5..a7311bc03d3a 100644
--- a/include/linux/netfilter/nf_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -2,7 +2,7 @@
 #ifndef _NFOSF_H
 #define _NFOSF_H
 
-#include 
+#include 
 
 /* Initial window size option state machine: multiple of mss, mtu or
  * plain numeric value. Can also be made as plain numeric value which
diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nfnetlink_osf.h
similarity index 100%
rename from include/uapi/linux/netfilter/nf_osf.h
rename to include/uapi/linux/netfilter/nfnetlink_osf.h
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index a90e90c27cef..c56c59605c2b 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -23,7 +23,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #define XT_OSF_GENRE   NF_OSF_GENRE
 #define XT_OSF_INVERT  NF_OSF_INVERT
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index ba0fa11869ce..f9dba62c450f 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -18,7 +18,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 /*
  * Indexed by dont-fragment bit.
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index bdacc4cffba4..9b2f3de7be4f 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -2,7 +2,7 @@
 #include 
 
 #include 
-#include 
+#include 
 
 #define OSF_GENRE_SIZE 32
 
-- 
2.18.0

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


[PATCH nf-next 1/2] fixup: nf_osf: move nf_osf_fingers to non-uapi nf_osf header file

2018-07-31 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nf_osf.h  | 2 ++
 include/uapi/linux/netfilter/nf_osf.h | 2 --
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h
index aee460fcbd31..3e455d6f94d5 100644
--- a/include/linux/netfilter/nf_osf.h
+++ b/include/linux/netfilter/nf_osf.h
@@ -25,6 +25,8 @@ enum osf_fmatch_states {
FMATCH_OPT_WRONG,
 };
 
+extern struct list_head nf_osf_fingers[2];
+
 struct nf_osf_finger {
struct rcu_head rcu_head;
struct list_headfinger_entry;
diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
index cc2487ff74f6..3b93fbb9fc24 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -70,8 +70,6 @@ struct nf_osf_nlmsg {
struct tcphdr   tcp;
 };
 
-extern struct list_head nf_osf_fingers[2];
-
 /* Defines for IANA option kinds */
 enum iana_options {
OSFOPT_EOL = 0, /* End of options */
-- 
2.18.0

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


Re: [netfilter-core] [nf-next:master 5/7] ./usr/include/linux/netfilter/nf_osf.h:73: userspace cannot reference function or variable defined in the kernel

2018-07-31 Thread Fernando Fernandez Mancera
El 31 de julio de 2018 7:52:26 CEST, Florian Westphal  escribió:
>kbuild test robot  wrote:
>> tree:  
>https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
>master
>> head:   4ed8eb6570a49931c705512060acd50058d61616
>> commit: f9324952088f1cd62ea4addf9ff532f1e6452a22 [5/7] netfilter:
>nfnetlink_osf: extract nfnetlink_subsystem code from xt_osf.c
>> config: i386-randconfig-a1-07310851 (attached as .config)
>> compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
>> reproduce:
>> git checkout f9324952088f1cd62ea4addf9ff532f1e6452a22
>> # save the attached .config to linux build tree
>> make ARCH=i386 
>> 
>> All warnings (new ones prefixed by >>):
>> 
>> >> ./usr/include/linux/netfilter/nf_osf.h:73: userspace cannot
>reference function or variable defined in the kernel
>
>Fernando, this is because of
>
>+extern struct list_head nf_osf_fingers[2];
>
>You either need to find another (non UAPI) header to place this in, or,
>alternatively, consider wrapping it in
>#ifdef __KERNEL__
>
>Can you make a patch?
>Thanks.
>--
>To unsubscribe from this list: send the line "unsubscribe
>netfilter-devel" in
>the body of a message to majord...@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

Thanks Florian, I am going to write a patch for this. Maybe a good option is to 
place it on the non-UAPI header of nfnetlink_osf.

[PATCH libnftnl v3] expr: add osf support

2018-07-24 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/libnftnl/expr.h |   4 +
 include/linux/netfilter/nf_tables.h |  12 ++
 src/Makefile.am |   1 +
 src/expr/osf.c  | 174 
 src/expr_ops.c  |   2 +
 5 files changed, 193 insertions(+)
 create mode 100644 src/expr/osf.c

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 219104e..6ec63ee 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -268,6 +268,10 @@ enum {
NFTNL_EXPR_OBJREF_SET_ID,
 };
 
+enum {
+   NFTNL_EXPR_OSF_DREG = NFTNL_EXPR_BASE,
+};
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 91449ef..51f9056 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -929,6 +929,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: OS to match
+ */
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_DREG,
+   __NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_ct_keys - nf_tables ct expression keys
  *
diff --git a/src/Makefile.am b/src/Makefile.am
index c66a257..bdc10f7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,6 +56,7 @@ libnftnl_la_SOURCES = utils.c \
  expr/redir.c  \
  expr/hash.c   \
  expr/socket.c \
+ expr/osf.c\
  obj/counter.c \
  obj/ct_helper.c   \
  obj/quota.c   \
diff --git a/src/expr/osf.c b/src/expr/osf.c
new file mode 100644
index 000..a005af8
--- /dev/null
+++ b/src/expr/osf.c
@@ -0,0 +1,174 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include 
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nftnl_expr_osf {
+   enum nft_registers  dreg;
+};
+
+static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_DREG:
+   osf->dreg = *((uint32_t *)data);
+   break;
+   }
+   return 0;
+}
+
+static const void *
+nftnl_expr_osf_get(const struct nftnl_expr *e, uint16_t type,
+  uint32_t *data_len)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_DREG:
+   *data_len = sizeof(osf->dreg);
+   return >dreg;
+   }
+   return NULL;
+}
+
+static int nftnl_expr_osf_cb(const struct nlattr *attr, void *data)
+{
+   const struct nlattr **tb = data;
+   int type = mnl_attr_get_type(attr);
+
+   if (mnl_attr_type_valid(attr, NFTA_OSF_MAX) < 0)
+   return MNL_CB_OK;
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_DREG:
+   if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+   abi_breakage();
+   break;
+   }
+
+   tb[type] = attr;
+   return MNL_CB_OK;
+}
+
+static void
+nftnl_expr_osf_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   if (e->flags & (1 << NFTNL_EXPR_OSF_DREG))
+   mnl_attr_put_u32(nlh, NFTNL_EXPR_OSF_DREG, htonl(osf->dreg));
+}
+
+static int
+nftnl_expr_osf_parse(struct nftnl_expr *e, struct nlattr *attr)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+   struct nlattr *tb[NFTA_OSF_MAX + 1] = {};
+
+   if (mnl_attr_parse_nested(attr, nftnl_expr_osf_cb, tb) < 0)
+   return -1;
+
+   if (tb[NFTA_OSF_DREG]) {
+   osf->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_OSF_DREG]));
+   e->flags |= (1 << NFTNL_EXPR_OSF_DREG);
+   }
+
+   return 0;
+}
+
+static int nftnl_expr_osf_json_parse(struct nftnl_expr *e, json_t *root,
+struct nftnl_parse_err *err)
+{
+#ifdef JSON_PARSING
+   __u32 dreg;
+
+   genre = nftnl_jansson_parse_u32(root, "dreg", err);
+   if (genre != NULL)
+   nftnl_expr_set_u32(e, NFTNL_EXPR_OSF_DREG, );
+
+   return 0;
+#else
+   errno = EOPNOTSUPP;
+   return -1;
+#endif
+}
+
+static int nftnl_expr_osf_snprintf_default(char *buf, size_t size,
+  const struct nftnl_expr *e)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+   int ret, offset = 0, len = size;
+
+   if (e->flags & (1 << NFTNL_EXPR_OSF_DREG)) {
+   ret = s

[PATCH 3/3 nf-next v3] netfilter: nft_osf: implement Passive OS fingerprint module in nft_osf

2018-07-24 Thread Fernando Fernandez Mancera
Add basic module functions into nft_osf.[ch] in order to implement OSF
module in nf_tables.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/uapi/linux/netfilter/nf_tables.h |   7 ++
 net/netfilter/Kconfig|   7 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_osf.c  | 107 +++
 4 files changed, 122 insertions(+)
 create mode 100644 net/netfilter/nft_osf.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index f466860bcf75..382c32d630e9 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1463,6 +1463,13 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_DREG,
+   __NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_device_attributes - nf_tables device netlink attributes
  *
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3e5334997062..1ce88b5bb54f 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -638,6 +638,13 @@ config NFT_SOCKET
  This option allows matching for the presence or absence of a
  corresponding socket and its attributes.
 
+config NFT_OSF
+   tristate "Netfilter nf_tables passive OS fingerprint support"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK_OSF
+   help
+ This option allows matching packets from an specific OS.
+
 if NF_TABLES_NETDEV
 
 config NF_DUP_NETDEV
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 150a4eb2373a..dfbadee341f7 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_NFT_FIB)   += nft_fib.o
 obj-$(CONFIG_NFT_FIB_INET) += nft_fib_inet.o
 obj-$(CONFIG_NFT_FIB_NETDEV)   += nft_fib_netdev.o
 obj-$(CONFIG_NFT_SOCKET)   += nft_socket.o
+obj-$(CONFIG_NFT_OSF)  += nft_osf.o
 
 # nf_tables netdev
 obj-$(CONFIG_NFT_DUP_NETDEV)   += nft_dup_netdev.o
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
new file mode 100644
index ..ec36039b09ec
--- /dev/null
+++ b/net/netfilter/nft_osf.c
@@ -0,0 +1,107 @@
+#include 
+#include 
+
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nft_osf {
+   enum nft_registers  dreg:8;
+};
+
+static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
+   [NFTA_OSF_DREG] = { .type = NLA_U32 },
+};
+
+static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   u32 *dest = >data[priv->dreg];
+   struct sk_buff *skb = pkt->skb;
+   const struct tcphdr *tcp;
+   struct tcphdr _tcph;
+   const char *os_name;
+
+   tcp = skb_header_pointer(skb, ip_hdrlen(skb),
+sizeof(struct tcphdr), &_tcph);
+   if (!tcp) {
+   regs->verdict.code = NFT_BREAK;
+   return;
+   }
+   if (!tcp->syn) {
+   regs->verdict.code = NFT_BREAK;
+   return;
+   }
+
+   os_name = nf_osf_find(skb, nf_osf_fingers);
+   if (!os_name)
+   strncpy((char *)dest, "unknown", IFNAMSIZ);
+   else
+   strncpy((char *)dest, os_name, IFNAMSIZ);
+}
+
+static int nft_osf_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   int err;
+
+   priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
+   err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFTA_DATA_VALUE, OSF_GENRE_SIZE);
+   if (err < 0)
+   return err;
+
+   return 0;
+}
+
+static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr)
+{
+   const struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg))
+   goto nla_put_failure;
+
+   return 0;
+
+nla_put_failure:
+   return -1;
+}
+
+static struct nft_expr_type nft_osf_type;
+
+static const struct nft_expr_ops nft_osf_op = {
+   .eval = nft_osf_eval,
+   .size = NFT_EXPR_SIZE(sizeof(struct nft_osf)),
+   .init = nft_osf_init,
+   .dump = nft_osf_dump,
+   .type = _osf_type,
+};
+
+static struct nft_expr_type nft_osf_type __read_mostly = {
+   .ops= _osf_op,
+   .name   = "osf",
+   .owner  = THIS_MODULE,
+   .policy = nft_osf_policy,
+   .maxattr= NFTA_OSF_MAX,
+};
+
+static int __init nft_osf_module_init(void)
+{
+   return nft_register_ex

[PATCH 2/3 nf-next v3] netfilter: nfnetlink_osf: extract nfnetlink_subsystem code from xt_osf.c

2018-07-24 Thread Fernando Fernandez Mancera
Move nfnetlink osf subsystem from xt_osf.c to standalone module so we can
reuse it from the new nft_ost extension.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/uapi/linux/netfilter/nf_osf.h |  11 ++
 include/uapi/linux/netfilter/xt_osf.h |   9 +-
 net/netfilter/nfnetlink_osf.c | 154 ++
 net/netfilter/xt_osf.c| 147 +---
 4 files changed, 168 insertions(+), 153 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
index 3738116b2bbe..cc2487ff74f6 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -70,6 +70,8 @@ struct nf_osf_nlmsg {
struct tcphdr   tcp;
 };
 
+extern struct list_head nf_osf_fingers[2];
+
 /* Defines for IANA option kinds */
 enum iana_options {
OSFOPT_EOL = 0, /* End of options */
@@ -94,4 +96,13 @@ enum nf_osf_attr_type {
OSF_ATTR_MAX,
 };
 
+/*
+ * Add/remove fingerprint from the kernel.
+ */
+enum nf_osf_msg_types {
+   OSF_MSG_ADD,
+   OSF_MSG_REMOVE,
+   OSF_MSG_MAX,
+};
+
 #endif /* _NF_OSF_H */
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index b189007f4f28..a90e90c27cef 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -47,13 +47,6 @@
 #define xt_osf_nlmsg   nf_osf_nlmsg
 
 #define xt_osf_attr_type   nf_osf_attr_type
-/*
- * Add/remove fingerprint from the kernel.
- */
-enum xt_osf_msg_types {
-   OSF_MSG_ADD,
-   OSF_MSG_REMOVE,
-   OSF_MSG_MAX,
-};
+#define xt_osf_msg_types   nf_osf_msg_types
 
 #endif /* _XT_OSF_H */
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index f4c75e982902..ba0fa11869ce 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -20,6 +20,13 @@
 #include 
 #include 
 
+/*
+ * Indexed by dont-fragment bit.
+ * It is the only constant value in the fingerprint.
+ */
+struct list_head nf_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nf_osf_fingers);
+
 static inline int nf_osf_ttl(const struct sk_buff *skb,
 int ttl_check, unsigned char f_ttl)
 {
@@ -279,4 +286,151 @@ const char *nf_osf_find(const struct sk_buff *skb,
 }
 EXPORT_SYMBOL_GPL(nf_osf_find);
 
+static const struct nla_policy nfnl_osf_policy[OSF_ATTR_MAX + 1] = {
+   [OSF_ATTR_FINGER]   = { .len = sizeof(struct nf_osf_user_finger) },
+};
+
+static int nfnl_osf_add_callback(struct net *net, struct sock *ctnl,
+struct sk_buff *skb, const struct nlmsghdr 
*nlh,
+const struct nlattr * const osf_attrs[],
+struct netlink_ext_ack *extack)
+{
+   struct nf_osf_user_finger *f;
+   struct nf_osf_finger *kf = NULL, *sf;
+   int err = 0;
+
+   if (!capable(CAP_NET_ADMIN))
+   return -EPERM;
+
+   if (!osf_attrs[OSF_ATTR_FINGER])
+   return -EINVAL;
+
+   if (!(nlh->nlmsg_flags & NLM_F_CREATE))
+   return -EINVAL;
+
+   f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+   kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL);
+   if (!kf)
+   return -ENOMEM;
+
+   memcpy(>finger, f, sizeof(struct nf_osf_user_finger));
+
+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;
+
+   kfree(kf);
+   kf = NULL;
+
+   if (nlh->nlmsg_flags & NLM_F_EXCL)
+   err = -EEXIST;
+   break;
+   }
+
+   /*
+* We are protected by nfnl mutex.
+*/
+   if (kf)
+   list_add_tail_rcu(>finger_entry, _osf_fingers[!!f->df]);
+
+   return err;
+}
+
+static int nfnl_osf_remove_callback(struct net *net, struct sock *ctnl,
+   struct sk_buff *skb,
+   const struct nlmsghdr *nlh,
+   const struct nlattr * const osf_attrs[],
+   struct netlink_ext_ack *extack)
+{
+   struct nf_osf_user_finger *f;
+   struct nf_osf_finger *sf;
+   int err = -ENOENT;
+
+   if (!capable(CAP_NET_ADMIN))
+   return -EPERM;
+
+   if (!osf_attrs[OSF_ATTR_FINGER])
+   return -EINVAL;
+
+   f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;
+
+   /*
+* We are protected by nfnl mutex.
+*/
+   list_del_rcu(>finger_entry);
+   kfree_rcu(sf, rcu_head);
+
+   

[PATCH 1/3 nf-next v3] netfilter: nf_osf: rename nf_osf.c to nfnetlink_osf.c

2018-07-24 Thread Fernando Fernandez Mancera
Rename nf_osf.c to nfnetlink_osf.c as we introduce nfnetlink_osf which is
the OSF infraestructure.

Signed-off-by: Fernando Fernandez Mancera 
---
 net/netfilter/Kconfig   | 15 ++-
 net/netfilter/Makefile  |  2 +-
 net/netfilter/{nf_osf.c => nfnetlink_osf.c} |  0
 3 files changed, 11 insertions(+), 6 deletions(-)
 rename net/netfilter/{nf_osf.c => nfnetlink_osf.c} (100%)

diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index e0ab50c58dc4..3e5334997062 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG
  and is also scheduled to replace the old syslog-based ipt_LOG
  and ip6t_LOG modules.
 
+config NETFILTER_NETLINK_OSF
+   tristate "Netfilter OSF over NFNETLINK interface"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK
+   help
+ If this option is enabled, the kernel will include support
+ for passive OS fingerprint via NFNETLINK.
+
 config NF_CONNTRACK
tristate "Netfilter connection tracking support"
default m if NETFILTER_ADVANCED=n
@@ -442,9 +450,6 @@ config NETFILTER_SYNPROXY
 
 endif # NF_CONNTRACK
 
-config NF_OSF
-   tristate
-
 config NF_TABLES
select NETFILTER_NETLINK
tristate "Netfilter nf_tables support"
@@ -1379,8 +1384,8 @@ config NETFILTER_XT_MATCH_NFACCT
 
 config NETFILTER_XT_MATCH_OSF
tristate '"osf" Passive OS fingerprint match'
-   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
-   select NF_OSF
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK_OSF
help
  This option selects the Passive OS Fingerprinting match module
  that allows to passively match the remote operating system by
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 53bd1ed1228a..150a4eb2373a 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
 obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
 obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
+obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o
 
 # connection tracking
 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
@@ -107,7 +108,6 @@ obj-$(CONFIG_NFT_HASH)  += nft_hash.o
 obj-$(CONFIG_NFT_FIB)  += nft_fib.o
 obj-$(CONFIG_NFT_FIB_INET) += nft_fib_inet.o
 obj-$(CONFIG_NFT_FIB_NETDEV)   += nft_fib_netdev.o
-obj-$(CONFIG_NF_OSF)   += nf_osf.o
 obj-$(CONFIG_NFT_SOCKET)   += nft_socket.o
 
 # nf_tables netdev
diff --git a/net/netfilter/nf_osf.c b/net/netfilter/nfnetlink_osf.c
similarity index 100%
rename from net/netfilter/nf_osf.c
rename to net/netfilter/nfnetlink_osf.c
-- 
2.18.0

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


Re: [PATCH 2/3 nf-next v2] netfilter: nfnetlink_osf: extract nfnetlink_subsystem code from xt_osf.c

2018-07-24 Thread Fernando Fernandez Mancera

  static struct xt_match xt_osf_match = {
@@ -178,51 +66,23 @@ static struct xt_match xt_osf_match = {
  static int __init xt_osf_init(void)
  {
int err = -EINVAL;
-   int i;
-
-   for (i=0; i  
  	err = xt_register_match(_osf_match);


You can just simplify this and so:

 return xt_register_match(...);



I think I cannot do "return xt_register_match(...);" because if it fails 
we need to print the error as it is already done. We can do "return 
err;" instead of "goto err_out;".



if (err) {
pr_err("Failed to register OS fingerprint "
   "matching module (%d)\n", err);
-   goto err_out_remove;
+   goto err_out;
}
  
  	return 0;
  
-err_out_remove:

-   nfnetlink_subsys_unregister(_osf_nfnetlink);
-err_out_exit:
+err_out:
return err;
  }

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


typo found in socket.h at nftables repository

2018-07-21 Thread Fernando Fernandez Mancera

Hi,

I think I found a typo in socket.h at nftables repository. It is just a 
small fix so I propose this patch.


---

From c788837976b674878d8ea819e97e9b4a762db91d Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera 
Date: Sat, 21 Jul 2018 21:39:09 +0200
Subject: [PATCH nftables] src: fix a typo in socket.h

Fix a typo in socket_template struct description.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/socket.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/socket.h b/include/socket.h
index 1814974..d99526b 100644
--- a/include/socket.h
+++ b/include/socket.h
@@ -1,10 +1,8 @@
 #ifndef NFTABLES_SOCKET_H
 #define NFTABLES_SOCKET_H

-//#include 
-
 /**
- * struct rt_template - template for routing expressions
+ * struct socket_template - template for socket expressions
  *
  * @token: parser token for the expression
  * @dtype: data type of the expression
--
2.18.0
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libnftnl v2] expr: add osf support

2018-07-20 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/libnftnl/expr.h |   7 +
 include/linux/netfilter/nf_tables.h |  18 +++
 src/Makefile.am |   1 +
 src/expr/osf.c  | 242 
 src/expr_ops.c  |   2 +
 5 files changed, 270 insertions(+)
 create mode 100644 src/expr/osf.c

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 219104e..af3d6b2 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -268,6 +268,13 @@ enum {
NFTNL_EXPR_OBJREF_SET_ID,
 };
 
+enum {
+   NFTNL_EXPR_OSF_DREG = NFTNL_EXPR_BASE,
+   NFTNL_EXPR_OSF_FLAGS,
+   NFTNL_EXPR_OSF_LOGLEVEL,
+   NFTNL_EXPR_OSF_TTL,
+};
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 91449ef..4577c2d 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -929,6 +929,24 @@ 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: OS to match
+ * @NFTA_OSF_FLAGS: Valid flags
+ * @NFTA_OSF_LOGLEVEL: different log levels
+ * @NFTA_OSF_TTL: different checks on TTL
+ */
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_DREG,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_ct_keys - nf_tables ct expression keys
  *
diff --git a/src/Makefile.am b/src/Makefile.am
index c66a257..bdc10f7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,6 +56,7 @@ libnftnl_la_SOURCES = utils.c \
  expr/redir.c  \
  expr/hash.c   \
  expr/socket.c \
+ expr/osf.c\
  obj/counter.c \
  obj/ct_helper.c   \
  obj/quota.c   \
diff --git a/src/expr/osf.c b/src/expr/osf.c
new file mode 100644
index 000..bcde9ae
--- /dev/null
+++ b/src/expr/osf.c
@@ -0,0 +1,242 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include 
+#include 
+#include 
+
+struct nftnl_expr_osf {
+   enum nft_registers  dreg;
+   __u8flags;
+   __u8loglevel;
+   __u8ttl;
+};
+
+static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_DREG:
+   osf->dreg = *((uint32_t *)data);
+   break;
+   case NFTNL_EXPR_OSF_FLAGS:
+   osf->flags = *((uint8_t *)data);
+   break;
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   osf->loglevel = *((uint8_t *)data);
+   break;
+   case NFTNL_EXPR_OSF_TTL:
+   osf->ttl = *((uint8_t *)data);
+   break;
+   }
+   return 0;
+}
+
+static const void *
+nftnl_expr_osf_get(const struct nftnl_expr *e, uint16_t type,
+  uint32_t *data_len)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_DREG:
+   *data_len = sizeof(osf->dreg);
+   return >dreg;
+   case NFTNL_EXPR_OSF_FLAGS:
+   *data_len = sizeof(osf->flags);
+   return >flags;
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   *data_len = sizeof(osf->loglevel);
+   return >loglevel;
+   case NFTNL_EXPR_OSF_TTL:
+   *data_len = sizeof(osf->ttl);
+   return >ttl;
+   }
+   return NULL;
+}
+
+static int nftnl_expr_osf_cb(const struct nlattr *attr, void *data)
+{
+   const struct nlattr **tb = data;
+   int type = mnl_attr_get_type(attr);
+
+   if (mnl_attr_type_valid(attr, NFTA_OSF_MAX) < 0)
+   return MNL_CB_OK;
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_DREG:
+   if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+   abi_breakage();
+   break;
+   case NFTNL_EXPR_OSF_FLAGS:
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   case NFTNL_EXPR_OSF_TTL:
+   if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
+   abi_breakage();
+   break;
+   }
+
+   tb[type] = attr;
+   return MNL_CB_OK;
+}
+
+static void
+nftnl_expr_osf_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   if (e->flags & (1 << NFTNL_EXPR_OSF_DREG))
+   mnl_attr_put_u32(nlh, NFTNL_EXPR_OSF_DREG, htonl(osf->dreg));
+ 

[PATCH 1/3 nf-next v2] netfilter: nf_osf: rename nf_osf.c to nfnetlink_osf.c

2018-07-20 Thread Fernando Fernandez Mancera
Rename nf_osf.c to nfnetlink_osf.c as we introduce nfnetlink_osf which is
the OSF infraestructure.

Signed-off-by: Fernando Fernandez Mancera 
---
 .../linux/netfilter/{nf_osf.h => nfnetlink_osf.h} |  2 +-
 .../linux/netfilter/{nf_osf.h => nfnetlink_osf.h} |  6 +++---
 include/uapi/linux/netfilter/xt_osf.h |  2 +-
 net/netfilter/Kconfig | 15 ++-
 net/netfilter/Makefile|  2 +-
 net/netfilter/{nf_osf.c => nfnetlink_osf.c}   |  2 +-
 6 files changed, 17 insertions(+), 12 deletions(-)
 rename include/linux/netfilter/{nf_osf.h => nfnetlink_osf.h} (95%)
 rename include/uapi/linux/netfilter/{nf_osf.h => nfnetlink_osf.h} (96%)
 rename net/netfilter/{nf_osf.c => nfnetlink_osf.c} (99%)

diff --git a/include/linux/netfilter/nf_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
similarity index 95%
rename from include/linux/netfilter/nf_osf.h
rename to include/linux/netfilter/nfnetlink_osf.h
index 7d0947d6ef16..53c3397fd608 100644
--- a/include/linux/netfilter/nf_osf.h
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -1,4 +1,4 @@
-#include 
+#include 
 
 /* Initial window size option state machine: multiple of mss, mtu or
  * plain numeric value. Can also be made as plain numeric value which
diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nfnetlink_osf.h
similarity index 96%
rename from include/uapi/linux/netfilter/nf_osf.h
rename to include/uapi/linux/netfilter/nfnetlink_osf.h
index 3738116b2bbe..7c3c79d48289 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nfnetlink_osf.h
@@ -1,5 +1,5 @@
-#ifndef _NF_OSF_H
-#define _NF_OSF_H
+#ifndef _NFNETLINK_OSF_H
+#define _NFNETLINK_OSF_H
 
 #include 
 
@@ -94,4 +94,4 @@ enum nf_osf_attr_type {
OSF_ATTR_MAX,
 };
 
-#endif /* _NF_OSF_H */
+#endif /* _NFNETLINK_OSF_H */
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index b189007f4f28..5d2e3cae6201 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -23,7 +23,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #define XT_OSF_GENRE   NF_OSF_GENRE
 #define XT_OSF_INVERT  NF_OSF_INVERT
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index e0ab50c58dc4..3e5334997062 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG
  and is also scheduled to replace the old syslog-based ipt_LOG
  and ip6t_LOG modules.
 
+config NETFILTER_NETLINK_OSF
+   tristate "Netfilter OSF over NFNETLINK interface"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK
+   help
+ If this option is enabled, the kernel will include support
+ for passive OS fingerprint via NFNETLINK.
+
 config NF_CONNTRACK
tristate "Netfilter connection tracking support"
default m if NETFILTER_ADVANCED=n
@@ -442,9 +450,6 @@ config NETFILTER_SYNPROXY
 
 endif # NF_CONNTRACK
 
-config NF_OSF
-   tristate
-
 config NF_TABLES
select NETFILTER_NETLINK
tristate "Netfilter nf_tables support"
@@ -1379,8 +1384,8 @@ config NETFILTER_XT_MATCH_NFACCT
 
 config NETFILTER_XT_MATCH_OSF
tristate '"osf" Passive OS fingerprint match'
-   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
-   select NF_OSF
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK_OSF
help
  This option selects the Passive OS Fingerprinting match module
  that allows to passively match the remote operating system by
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 53bd1ed1228a..150a4eb2373a 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
 obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
 obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
+obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o
 
 # connection tracking
 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
@@ -107,7 +108,6 @@ obj-$(CONFIG_NFT_HASH)  += nft_hash.o
 obj-$(CONFIG_NFT_FIB)  += nft_fib.o
 obj-$(CONFIG_NFT_FIB_INET) += nft_fib_inet.o
 obj-$(CONFIG_NFT_FIB_NETDEV)   += nft_fib_netdev.o
-obj-$(CONFIG_NF_OSF)   += nf_osf.o
 obj-$(CONFIG_NFT_SOCKET)   += nft_socket.o
 
 # nf_tables netdev
diff --git a/net/netfilter/nf_osf.c b/net/netfilter/nfnetlink_osf.c
similarity index 99%
rename from net/netfilter/nf_osf.c
rename to net/netfilter/nfnetlink_osf.c
index f4c75e982902..7a8cc8bae714 100644
--- a/net/netfilter/nf_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -18,7 +18,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 static inline int nf_osf_ttl(const struct sk_buff *skb,
 

[PATCH 3/3 nf-next v2] netfilter: nft_osf: implement Passive OS fingerprint module in nft_osf

2018-07-20 Thread Fernando Fernandez Mancera
Add basic module functions into nft_osf.[ch] in order to implement OSF
module in nf_tables.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/uapi/linux/netfilter/nf_tables.h |  10 ++
 net/netfilter/Kconfig|   7 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_osf.c  | 123 +++
 4 files changed, 141 insertions(+)
 create mode 100644 net/netfilter/nft_osf.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index f466860bcf75..eab5d83a73b0 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1463,6 +1463,16 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_DREG,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_device_attributes - nf_tables device netlink attributes
  *
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3e5334997062..1ce88b5bb54f 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -638,6 +638,13 @@ config NFT_SOCKET
  This option allows matching for the presence or absence of a
  corresponding socket and its attributes.
 
+config NFT_OSF
+   tristate "Netfilter nf_tables passive OS fingerprint support"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK_OSF
+   help
+ This option allows matching packets from an specific OS.
+
 if NF_TABLES_NETDEV
 
 config NF_DUP_NETDEV
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 150a4eb2373a..dfbadee341f7 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_NFT_FIB)   += nft_fib.o
 obj-$(CONFIG_NFT_FIB_INET) += nft_fib_inet.o
 obj-$(CONFIG_NFT_FIB_NETDEV)   += nft_fib_netdev.o
 obj-$(CONFIG_NFT_SOCKET)   += nft_socket.o
+obj-$(CONFIG_NFT_OSF)  += nft_osf.o
 
 # nf_tables netdev
 obj-$(CONFIG_NFT_DUP_NETDEV)   += nft_dup_netdev.o
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
new file mode 100644
index ..b42a205c5262
--- /dev/null
+++ b/net/netfilter/nft_osf.c
@@ -0,0 +1,123 @@
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nft_osf {
+   enum nft_registers  dreg:8;
+   __u8flags;
+   __u8loglevel;
+   __u8ttl;
+};
+
+static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
+   [NFTA_OSF_DREG] = { .type = NLA_U32 },
+   [NFTA_OSF_FLAGS]= { .type = NLA_U8 },
+   [NFTA_OSF_LOGLEVEL] = { .type = NLA_U8 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U8 },
+};
+
+static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   u32 *dest = >data[priv->dreg];
+   struct sk_buff *skb = pkt->skb;
+   const struct tcphdr *tcp;
+   struct tcphdr _tcph;
+   const char *os_name;
+
+   tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), 
&_tcph);
+   if (!tcp)
+   regs->verdict.code = NFT_BREAK;
+   if (!tcp->syn)
+   regs->verdict.code = NFT_BREAK;
+
+   os_name = nf_osf_find(skb, nf_osf_fingers);
+   if (!os_name)
+   strncpy((char *)dest, "unknown", IFNAMSIZ);
+   else
+   strncpy((char *)dest, os_name, IFNAMSIZ);
+}
+
+static int nft_osf_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   __u8 flags, loglevel, ttl;
+   int err;
+
+   priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
+   err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFTA_DATA_VALUE, OSF_GENRE_SIZE);
+   if (err < 0)
+   return err;
+
+   flags = ntohl(nla_get_u8(tb[NFTA_OSF_FLAGS]));
+   if (flags & ~NF_OSF_FLAGMASK)
+   return -EINVAL;
+   priv->flags = flags;
+
+   loglevel = ntohl(nla_get_u8(tb[NFTA_OSF_LOGLEVEL]));
+   if (loglevel >= NF_OSF_LOGLEVEL_ALL_KNOWN)
+   return -EINVAL;
+   priv->loglevel  = loglevel;
+
+   ttl = ntohl(nla_get_u8(tb[NFTA_OSF_TTL]));
+   if (ttl >= NF_OSF_TTL_NOCHECK)
+   return -EINVAL;
+   priv->ttl   = ttl;
+
+   return 0;
+}
+
+static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr)
+{
+   const struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (nft_dump_register(skb, NFTA_OSF_DREG, priv-&

[PATCH 2/3 nf-next v2] netfilter: nfnetlink_osf: extract nfnetlink_subsystem code from xt_osf.c

2018-07-20 Thread Fernando Fernandez Mancera
Move nfnetlink osf subsystem from xt_osf.c to standalone module so we can
reuse it from the new nft_ost extension.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/uapi/linux/netfilter/nfnetlink_osf.h |  12 ++
 include/uapi/linux/netfilter/xt_osf.h|   9 +-
 net/netfilter/nfnetlink_osf.c| 154 +++
 net/netfilter/xt_osf.c   | 146 +-
 4 files changed, 170 insertions(+), 151 deletions(-)

diff --git a/include/uapi/linux/netfilter/nfnetlink_osf.h 
b/include/uapi/linux/netfilter/nfnetlink_osf.h
index 7c3c79d48289..f419259ec367 100644
--- a/include/uapi/linux/netfilter/nfnetlink_osf.h
+++ b/include/uapi/linux/netfilter/nfnetlink_osf.h
@@ -2,6 +2,8 @@
 #define _NFNETLINK_OSF_H
 
 #include 
+#include 
+#include 
 
 #define MAXGENRELEN32
 
@@ -70,6 +72,8 @@ struct nf_osf_nlmsg {
struct tcphdr   tcp;
 };
 
+extern struct list_head nf_osf_fingers[2];
+
 /* Defines for IANA option kinds */
 enum iana_options {
OSFOPT_EOL = 0, /* End of options */
@@ -94,4 +98,12 @@ enum nf_osf_attr_type {
OSF_ATTR_MAX,
 };
 
+/*
+ * Add/remove fingerprint from the kernel.
+ */
+enum nf_osf_msg_types {
+   OSF_MSG_ADD,
+   OSF_MSG_REMOVE,
+   OSF_MSG_MAX,
+};
 #endif /* _NFNETLINK_OSF_H */
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index 5d2e3cae6201..c56c59605c2b 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -47,13 +47,6 @@
 #define xt_osf_nlmsg   nf_osf_nlmsg
 
 #define xt_osf_attr_type   nf_osf_attr_type
-/*
- * Add/remove fingerprint from the kernel.
- */
-enum xt_osf_msg_types {
-   OSF_MSG_ADD,
-   OSF_MSG_REMOVE,
-   OSF_MSG_MAX,
-};
+#define xt_osf_msg_types   nf_osf_msg_types
 
 #endif /* _XT_OSF_H */
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
index 7a8cc8bae714..f9dba62c450f 100644
--- a/net/netfilter/nfnetlink_osf.c
+++ b/net/netfilter/nfnetlink_osf.c
@@ -20,6 +20,13 @@
 #include 
 #include 
 
+/*
+ * Indexed by dont-fragment bit.
+ * It is the only constant value in the fingerprint.
+ */
+struct list_head nf_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nf_osf_fingers);
+
 static inline int nf_osf_ttl(const struct sk_buff *skb,
 int ttl_check, unsigned char f_ttl)
 {
@@ -279,4 +286,151 @@ const char *nf_osf_find(const struct sk_buff *skb,
 }
 EXPORT_SYMBOL_GPL(nf_osf_find);
 
+static const struct nla_policy nfnl_osf_policy[OSF_ATTR_MAX + 1] = {
+   [OSF_ATTR_FINGER]   = { .len = sizeof(struct nf_osf_user_finger) },
+};
+
+static int nfnl_osf_add_callback(struct net *net, struct sock *ctnl,
+struct sk_buff *skb, const struct nlmsghdr 
*nlh,
+const struct nlattr * const osf_attrs[],
+struct netlink_ext_ack *extack)
+{
+   struct nf_osf_user_finger *f;
+   struct nf_osf_finger *kf = NULL, *sf;
+   int err = 0;
+
+   if (!capable(CAP_NET_ADMIN))
+   return -EPERM;
+
+   if (!osf_attrs[OSF_ATTR_FINGER])
+   return -EINVAL;
+
+   if (!(nlh->nlmsg_flags & NLM_F_CREATE))
+   return -EINVAL;
+
+   f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+   kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL);
+   if (!kf)
+   return -ENOMEM;
+
+   memcpy(>finger, f, sizeof(struct nf_osf_user_finger));
+
+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;
+
+   kfree(kf);
+   kf = NULL;
+
+   if (nlh->nlmsg_flags & NLM_F_EXCL)
+   err = -EEXIST;
+   break;
+   }
+
+   /*
+* We are protected by nfnl mutex.
+*/
+   if (kf)
+   list_add_tail_rcu(>finger_entry, _osf_fingers[!!f->df]);
+
+   return err;
+}
+
+static int nfnl_osf_remove_callback(struct net *net, struct sock *ctnl,
+   struct sk_buff *skb,
+   const struct nlmsghdr *nlh,
+   const struct nlattr * const osf_attrs[],
+   struct netlink_ext_ack *extack)
+{
+   struct nf_osf_user_finger *f;
+   struct nf_osf_finger *sf;
+   int err = -ENOENT;
+
+   if (!capable(CAP_NET_ADMIN))
+   return -EPERM;
+
+   if (!osf_attrs[OSF_ATTR_FINGER])
+   return -EINVAL;
+
+   f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;
+
+   /*
+ 

Re: [PATCH nf-next v2] netfilter: nfnetlink_osf: add netlink support for osf module

2018-07-17 Thread Fernando Fernandez Mancera

It has been testing by adding the following rules:

#iptables -I INPUT -p tcp -j ACCEPT -m osf --genre Linux --log 0 --ttl 2

#iptables -I INPUT -p tcp -j REJECT -m osf --genre Linux --log 0 --ttl 1

#iptables -I INPUT -p tcp -j ACCEPT -m osf --genre Linux --log 0 --ttl 0

Also

$ lsmod | grep -i osf

xt_osf 16384  1
nf_osf 16384  1 xt_osf
x_tables   40960  3 iptable_filter,xt_osf,ip_tables

Is this enough? Thanks.


On 07/17/2018 07:25 PM, Fernando Fernandez Mancera wrote:

Signed-off-by: Fernando Fernandez Mancera 
---
  include/linux/netfilter/nf_osf.h  |   2 +
  include/uapi/linux/netfilter/nf_osf.h |   5 +
  include/uapi/linux/netfilter/xt_osf.h |   8 --
  net/netfilter/Kconfig |  10 +-
  net/netfilter/Makefile|   1 +
  net/netfilter/nf_osf.c|   7 ++
  net/netfilter/nfnetlink_osf.c | 134 ++
  net/netfilter/xt_osf.c| 133 ++---
  8 files changed, 164 insertions(+), 136 deletions(-)
  create mode 100644 net/netfilter/nfnetlink_osf.c

diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h
index 7d0947d6ef16..3411c87152d7 100644
--- a/include/linux/netfilter/nf_osf.h
+++ b/include/linux/netfilter/nf_osf.h
@@ -27,6 +27,8 @@ struct nf_osf_finger {
struct nf_osf_user_finger   finger;
  };
  
+extern struct list_head nf_osf_fingers[2];

+
  bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  int hooknum, struct net_device *in, struct net_device *out,
  const struct nf_osf_info *info, struct net *net,
diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
index a89583099b2a..18516829fce1 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -96,4 +96,9 @@ enum nf_osf_attr_type {
OSF_ATTR_MAX,
  };
  
+enum nf_osf_msg_types {

+   OSF_MSG_ADD,
+   OSF_MSG_REMOVE,
+   OSF_MSG_MAX,
+};
  #endif /* _NF_OSF_H */
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index b189007f4f28..6fe4d75b1f11 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -47,13 +47,5 @@
  #define xt_osf_nlmsg  nf_osf_nlmsg
  
  #define xt_osf_attr_type	nf_osf_attr_type

-/*
- * Add/remove fingerprint from the kernel.
- */
-enum xt_osf_msg_types {
-   OSF_MSG_ADD,
-   OSF_MSG_REMOVE,
-   OSF_MSG_MAX,
-};
  
  #endif/* _XT_OSF_H */

diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 6c65d756e603..06abc3bc05d3 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG
  and is also scheduled to replace the old syslog-based ipt_LOG
  and ip6t_LOG modules.
  
+config NETFILTER_NETLINK_OSF

+   tristate "Netfilter OSF over NFNETLINK interface"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK
+   help
+ If this option is enabled, the kernel will include support
+ for passive OS fingerprint via NFNETLINK.
+
  config NF_CONNTRACK
tristate "Netfilter connection tracking support"
default m if NETFILTER_ADVANCED=n
@@ -1379,8 +1387,8 @@ config NETFILTER_XT_MATCH_NFACCT
  
  config NETFILTER_XT_MATCH_OSF

tristate '"osf" Passive OS fingerprint match'
-   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
select NF_OSF
+   select NETFILTER_NETLINK_OSF
help
  This option selects the Passive OS Fingerprinting match module
  that allows to passively match the remote operating system by
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0b3851e825fa..ab144e65edf1 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
  obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
  obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
  obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
+obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o
  
  # connection tracking

  obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
diff --git a/net/netfilter/nf_osf.c b/net/netfilter/nf_osf.c
index f4c75e982902..b5c3af060d62 100644
--- a/net/netfilter/nf_osf.c
+++ b/net/netfilter/nf_osf.c
@@ -20,6 +20,13 @@
  #include 
  #include 
  
+/*

+ * Indexed by dont-fragment bit.
+ * It is the only constant value in the fingerprint.
+ */
+struct list_head nf_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nf_osf_fingers);
+
  static inline int nf_osf_ttl(const struct sk_buff *skb,
 int ttl_check, unsigned char f_ttl)
  {
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
new file mode 100644
index ..ba71f04a4004
--- /dev/null
+++ b/net/netfilter/nfnetlink_osf.c

[PATCH nf-next v2] netfilter: nfnetlink_osf: add netlink support for osf module

2018-07-17 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nf_osf.h  |   2 +
 include/uapi/linux/netfilter/nf_osf.h |   5 +
 include/uapi/linux/netfilter/xt_osf.h |   8 --
 net/netfilter/Kconfig |  10 +-
 net/netfilter/Makefile|   1 +
 net/netfilter/nf_osf.c|   7 ++
 net/netfilter/nfnetlink_osf.c | 134 ++
 net/netfilter/xt_osf.c| 133 ++---
 8 files changed, 164 insertions(+), 136 deletions(-)
 create mode 100644 net/netfilter/nfnetlink_osf.c

diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h
index 7d0947d6ef16..3411c87152d7 100644
--- a/include/linux/netfilter/nf_osf.h
+++ b/include/linux/netfilter/nf_osf.h
@@ -27,6 +27,8 @@ struct nf_osf_finger {
struct nf_osf_user_finger   finger;
 };
 
+extern struct list_head nf_osf_fingers[2];
+
 bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  int hooknum, struct net_device *in, struct net_device *out,
  const struct nf_osf_info *info, struct net *net,
diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
index a89583099b2a..18516829fce1 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -96,4 +96,9 @@ enum nf_osf_attr_type {
OSF_ATTR_MAX,
 };
 
+enum nf_osf_msg_types {
+   OSF_MSG_ADD,
+   OSF_MSG_REMOVE,
+   OSF_MSG_MAX,
+};
 #endif /* _NF_OSF_H */
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index b189007f4f28..6fe4d75b1f11 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -47,13 +47,5 @@
 #define xt_osf_nlmsg   nf_osf_nlmsg
 
 #define xt_osf_attr_type   nf_osf_attr_type
-/*
- * Add/remove fingerprint from the kernel.
- */
-enum xt_osf_msg_types {
-   OSF_MSG_ADD,
-   OSF_MSG_REMOVE,
-   OSF_MSG_MAX,
-};
 
 #endif /* _XT_OSF_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 6c65d756e603..06abc3bc05d3 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG
  and is also scheduled to replace the old syslog-based ipt_LOG
  and ip6t_LOG modules.
 
+config NETFILTER_NETLINK_OSF
+   tristate "Netfilter OSF over NFNETLINK interface"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK
+   help
+ If this option is enabled, the kernel will include support
+ for passive OS fingerprint via NFNETLINK.
+
 config NF_CONNTRACK
tristate "Netfilter connection tracking support"
default m if NETFILTER_ADVANCED=n
@@ -1379,8 +1387,8 @@ config NETFILTER_XT_MATCH_NFACCT
 
 config NETFILTER_XT_MATCH_OSF
tristate '"osf" Passive OS fingerprint match'
-   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
select NF_OSF
+   select NETFILTER_NETLINK_OSF
help
  This option selects the Passive OS Fingerprinting match module
  that allows to passively match the remote operating system by
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0b3851e825fa..ab144e65edf1 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
 obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
 obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
+obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o
 
 # connection tracking
 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
diff --git a/net/netfilter/nf_osf.c b/net/netfilter/nf_osf.c
index f4c75e982902..b5c3af060d62 100644
--- a/net/netfilter/nf_osf.c
+++ b/net/netfilter/nf_osf.c
@@ -20,6 +20,13 @@
 #include 
 #include 
 
+/*
+ * Indexed by dont-fragment bit.
+ * It is the only constant value in the fingerprint.
+ */
+struct list_head nf_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nf_osf_fingers);
+
 static inline int nf_osf_ttl(const struct sk_buff *skb,
 int ttl_check, unsigned char f_ttl)
 {
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
new file mode 100644
index ..ba71f04a4004
--- /dev/null
+++ b/net/netfilter/nfnetlink_osf.c
@@ -0,0 +1,134 @@
+#include 
+#include 
+
+static const struct nla_policy nfnl_osf_policy[OSF_ATTR_MAX + 1] = {
+   [OSF_ATTR_FINGER]   = { .len = sizeof(struct nf_osf_user_finger) },
+};
+
+static int nfnl_osf_add_callback(struct net *net, struct sock *ctnl,
+struct sk_buff *skb, const struct nlmsghdr 
*nlh,
+const struct nlattr * const osf_attrs[],
+struct netlink_ext_ack *extack)
+{
+   struct nf_osf_user_finger *f;
+ 

Re: [PATCH nf-next 3/3] netfilter: nf_osf: add nf_osf_find()

2018-07-17 Thread Fernando Fernandez Mancera

Tested-by: Fernando Fernandez Mancera 

On 07/13/2018 02:54 PM, Pablo Neira Ayuso wrote:

This new function returns the OS genre as a string. Plan is to use to
from the new nft_osf extension.

Note that this doesn't yet support ttl options, but it could be easily
extended to do so.

Signed-off-by: Pablo Neira Ayuso 
---
Compile tested only.

  include/linux/netfilter/nf_osf.h |  3 +++
  net/netfilter/nf_osf.c   | 30 ++
  2 files changed, 33 insertions(+)

diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h
index 0e114c492fb8..7d0947d6ef16 100644
--- a/include/linux/netfilter/nf_osf.h
+++ b/include/linux/netfilter/nf_osf.h
@@ -31,3 +31,6 @@ bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  int hooknum, struct net_device *in, struct net_device *out,
  const struct nf_osf_info *info, struct net *net,
  const struct list_head *nf_osf_fingers);
+
+const char *nf_osf_find(const struct sk_buff *skb,
+const struct list_head *nf_osf_fingers);
diff --git a/net/netfilter/nf_osf.c b/net/netfilter/nf_osf.c
index b44d62d5d9a9..f4c75e982902 100644
--- a/net/netfilter/nf_osf.c
+++ b/net/netfilter/nf_osf.c
@@ -249,4 +249,34 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
  }
  EXPORT_SYMBOL_GPL(nf_osf_match);
  
+const char *nf_osf_find(const struct sk_buff *skb,

+   const struct list_head *nf_osf_fingers)
+{
+   const struct iphdr *ip = ip_hdr(skb);
+   const struct nf_osf_user_finger *f;
+   unsigned char opts[MAX_IPOPTLEN];
+   const struct nf_osf_finger *kf;
+   struct nf_osf_hdr_ctx ctx;
+   const struct tcphdr *tcp;
+   const char *genre = NULL;
+
+   memset(, 0, sizeof(ctx));
+
+   tcp = nf_osf_hdr_ctx_init(, skb, ip, opts);
+   if (!tcp)
+   return false;
+
+   list_for_each_entry_rcu(kf, _osf_fingers[ctx.df], finger_entry) {
+   f = >finger;
+   if (!nf_osf_match_one(skb, f, -1, ))
+   continue;
+
+   genre = f->genre;
+   break;
+   }
+
+   return genre;
+}
+EXPORT_SYMBOL_GPL(nf_osf_find);
+
  MODULE_LICENSE("GPL");


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


Re: [PATCH 1/3 nf-next] netfilter: add missing definitions in nf_osf.h

2018-07-17 Thread Fernando Fernandez Mancera

Tested-by: Fernando Fernandez Mancera 

On 07/14/2018 04:50 PM, Fernando Fernandez Mancera wrote:

Added missing definitions from nf_osf.h in order to extract Passive OS
fingerprint infrastructure from xt_osf.

Signed-off-by: Fernando Fernandez Mancera 
---
  include/uapi/linux/netfilter/nf_osf.h | 13 +
  include/uapi/linux/netfilter/xt_osf.h | 10 ++
  2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
index 8f2f2f403183..a89583099b2a 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -2,6 +2,8 @@
  #define _NF_OSF_H
  
  #include 

+#include 
+#include 
  
  #define MAXGENRELEN	32
  
@@ -16,9 +18,14 @@
  
  #define NF_OSF_TTL_TRUE			0	/* True ip and fingerprint TTL comparison */
  
+/* Check if ip TTL is less than fingerprint one */

+#define NF_OSF_TTL_LESS1
+
  /* Do not compare ip and fingerprint TTL at all */
  #define NF_OSF_TTL_NOCHECK2
  
+#define NF_OSF_FLAGMASK		(NF_OSF_GENRE | NF_OSF_TTL | \

+NF_OSF_LOG | NF_OSF_INVERT)
  /* Wildcard MSS (kind of).
   * It is used to implement a state machine for the different wildcard values
   * of the MSS and window sizes.
@@ -83,4 +90,10 @@ enum iana_options {
OSFOPT_EMPTY = 255,
  };
  
+enum nf_osf_attr_type {

+   OSF_ATTR_UNSPEC,
+   OSF_ATTR_FINGER,
+   OSF_ATTR_MAX,
+};
+
  #endif /* _NF_OSF_H */
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index 72956eceeb09..b189007f4f28 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -37,8 +37,7 @@
  
  #define XT_OSF_TTL_TRUE		NF_OSF_TTL_TRUE

  #define XT_OSF_TTL_NOCHECKNF_OSF_TTL_NOCHECK
-
-#define XT_OSF_TTL_LESS1   /* Check if ip TTL is less than 
fingerprint one */
+#define XT_OSF_TTL_LESSNF_OSF_TTL_LESS
  
  #define xt_osf_wc		nf_osf_wc

  #define xt_osf_optnf_osf_opt
@@ -47,6 +46,7 @@
  #define xt_osf_finger nf_osf_finger
  #define xt_osf_nlmsg  nf_osf_nlmsg
  
+#define xt_osf_attr_type	nf_osf_attr_type

  /*
   * Add/remove fingerprint from the kernel.
   */
@@ -56,10 +56,4 @@ enum xt_osf_msg_types {
OSF_MSG_MAX,
  };
  
-enum xt_osf_attr_type {

-   OSF_ATTR_UNSPEC,
-   OSF_ATTR_FINGER,
-   OSF_ATTR_MAX,
-};
-
  #endif/* _XT_OSF_H */


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


Re: [PATCH 3/3 nf-next] netfilter: add netlink support for osf module

2018-07-16 Thread Fernando Fernandez Mancera

Thanks, I am going to reorder them.

On 07/16/2018 05:12 PM, Pablo Neira Ayuso wrote:

BTW, this patch should be 2/3.

Order patches in a logic way:

1) Small preparation.
2) Add nfnetlink_osf
3) Add support for osf nft.

You can use git rebase interactive mode to reorder patches.

Thanks.


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


Re: [PATCH 3/3 nf-next] netfilter: add netlink support for osf module

2018-07-16 Thread Fernando Fernandez Mancera

On 07/16/2018 05:10 PM, Pablo Neira Ayuso wrote:

On Sat, Jul 14, 2018 at 04:51:01PM +0200, Fernando Fernandez Mancera wrote:

Signed-off-by: Fernando Fernandez Mancera 
---
  include/linux/netfilter/nfnetlink_osf.h |  20 +
  net/netfilter/Kconfig   |  11 ++-
  net/netfilter/Makefile  |   1 +
  net/netfilter/nfnetlink_osf.c   | 100 +++
  net/netfilter/xt_osf.c  | 103 ++--
  5 files changed, 139 insertions(+), 96 deletions(-)
  create mode 100644 include/linux/netfilter/nfnetlink_osf.h
  create mode 100644 net/netfilter/nfnetlink_osf.c

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
new file mode 100644
index ..80fcd21b
--- /dev/null
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -0,0 +1,20 @@
+#ifndef _NFNETLINK_OSF_H
+#define _NFNETLINK_OSF_H
+
+#include 
+
+#include 
+
+extern struct list_head nf_osf_fingers[2];

This declaration you can place it in the existing nf_osf.h file, so we
don't need to create yet another new header file.

And regarding these below...


+int nf_osf_add_callback(struct net *net, struct sock *ctnl,
+   struct sk_buff *skb, const struct nlmsghdr *nlh,
+   const struct nlattr * const osf_attrs[],
+   struct netlink_ext_ack *extack);
+
+int nf_osf_remove_callback(struct net *net, struct sock *ctnl,
+  struct sk_buff *skb, const struct nlmsghdr *nlh,
+  const struct nlattr * const osf_attrs[],
+  struct netlink_ext_ack *extack);


You don't need to place these function declararions in the .h file.

Rule of thumb is: You only place declaration in header file that will
be used by other .c files or other modules...

These are internal, so...



They are going to be used by xt_osf.c and nft_osf.c so we need to define 
them here right?



+
+#endif /* _NFNETLINK_OSF_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 29c8591f87c2..1e156978535b 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG
  and is also scheduled to replace the old syslog-based ipt_LOG
  and ip6t_LOG modules.
  
+config NETFILTER_NETLINK_OSF

+   tristate "Netfilter NFOSF over NFNETLINK interface"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK
+   help
+ If this option is enables, the kernel will include support
+ for passive OS fingerprint via NFNETLINK.
+
  config NF_CONNTRACK
tristate "Netfilter connection tracking support"
default m if NETFILTER_ADVANCED=n
@@ -636,6 +644,7 @@ config NFT_SOCKET
  config NFT_OSF
tristate "Netfilter nf_tables passive OS fingerprinting support"
select NF_OSF
+   select NETFILTER_NETLINK_OSF
help
  This option allows matching packets from an specific OS.
  
@@ -1385,8 +1394,8 @@ config NETFILTER_XT_MATCH_NFACCT
  
  config NETFILTER_XT_MATCH_OSF

tristate '"osf" Passive OS fingerprint match'
-   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
select NF_OSF
+   select NETFILTER_NETLINK_OSF
help
  This option selects the Passive OS Fingerprinting match module
  that allows to passively match the remote operating system by
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 75ddcb0f748d..2fa826d5fdc5 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
  obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
  obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
  obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
+obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o
  
  # connection tracking

  obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
new file mode 100644
index ..df9d49c54655
--- /dev/null
+++ b/net/netfilter/nfnetlink_osf.c
@@ -0,0 +1,100 @@
+#include 
+#include 
+
+/*
+ * Indexed by dont-fragment bit.
+ * It is the only constant value in the fingerprint.
+ */
+struct list_head nf_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nf_osf_fingers);

+static const struct nla_policy nf_osf_policy[OSF_ATTR_MAX + 1] = {
+   [OSF_ATTR_FINGER]   = { .len = sizeof(struct nf_osf_user_finger) },
+};
+
+int nf_osf_add_callback(struct net *net, struct sock *ctnl,


use _static_ here instead.


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


Re: [PATCH 3/3 nf-next] netfilter: add netlink support for osf module

2018-07-14 Thread Fernando Fernandez Mancera

nfnetlink_osf has been testing by adding the following rule in iptables:

iptables -I input -p tcp -j ACCEPT -m osf --genre Linux --log 0 --ttl 2

$ lsmod | grep -i osf

xt_osf 16384  4
nfnetlink_osf  16384  1 xt_osf
nf_osf 16384  1 xt_osf
nfnetlink  16384  1 xt_osf
x_tables   40960  3 iptable_filter,xt_osf,ip_tables


Is it enough?

Thanks!

On 07/14/2018 04:51 PM, Fernando Fernandez Mancera wrote:

Signed-off-by: Fernando Fernandez Mancera 
---
  include/linux/netfilter/nfnetlink_osf.h |  20 +
  net/netfilter/Kconfig   |  11 ++-
  net/netfilter/Makefile  |   1 +
  net/netfilter/nfnetlink_osf.c   | 100 +++
  net/netfilter/xt_osf.c  | 103 ++--
  5 files changed, 139 insertions(+), 96 deletions(-)
  create mode 100644 include/linux/netfilter/nfnetlink_osf.h
  create mode 100644 net/netfilter/nfnetlink_osf.c

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
new file mode 100644
index ..80fcd21b
--- /dev/null
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -0,0 +1,20 @@
+#ifndef _NFNETLINK_OSF_H
+#define _NFNETLINK_OSF_H
+
+#include 
+
+#include 
+
+extern struct list_head nf_osf_fingers[2];
+
+int nf_osf_add_callback(struct net *net, struct sock *ctnl,
+   struct sk_buff *skb, const struct nlmsghdr *nlh,
+   const struct nlattr * const osf_attrs[],
+   struct netlink_ext_ack *extack);
+
+int nf_osf_remove_callback(struct net *net, struct sock *ctnl,
+  struct sk_buff *skb, const struct nlmsghdr *nlh,
+  const struct nlattr * const osf_attrs[],
+  struct netlink_ext_ack *extack);
+
+#endif /* _NFNETLINK_OSF_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 29c8591f87c2..1e156978535b 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG
  and is also scheduled to replace the old syslog-based ipt_LOG
  and ip6t_LOG modules.
  
+config NETFILTER_NETLINK_OSF

+   tristate "Netfilter NFOSF over NFNETLINK interface"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK
+   help
+ If this option is enables, the kernel will include support
+ for passive OS fingerprint via NFNETLINK.
+
  config NF_CONNTRACK
tristate "Netfilter connection tracking support"
default m if NETFILTER_ADVANCED=n
@@ -636,6 +644,7 @@ config NFT_SOCKET
  config NFT_OSF
tristate "Netfilter nf_tables passive OS fingerprinting support"
select NF_OSF
+   select NETFILTER_NETLINK_OSF
help
  This option allows matching packets from an specific OS.
  
@@ -1385,8 +1394,8 @@ config NETFILTER_XT_MATCH_NFACCT
  
  config NETFILTER_XT_MATCH_OSF

tristate '"osf" Passive OS fingerprint match'
-   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
select NF_OSF
+   select NETFILTER_NETLINK_OSF
help
  This option selects the Passive OS Fingerprinting match module
  that allows to passively match the remote operating system by
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 75ddcb0f748d..2fa826d5fdc5 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
  obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
  obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
  obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
+obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o
  
  # connection tracking

  obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
new file mode 100644
index ..df9d49c54655
--- /dev/null
+++ b/net/netfilter/nfnetlink_osf.c
@@ -0,0 +1,100 @@
+#include 
+#include 
+
+/*
+ * Indexed by dont-fragment bit.
+ * It is the only constant value in the fingerprint.
+ */
+struct list_head nf_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nf_osf_fingers);
+
+static const struct nla_policy nf_osf_policy[OSF_ATTR_MAX + 1] = {
+   [OSF_ATTR_FINGER]   = { .len = sizeof(struct nf_osf_user_finger) },
+};
+
+int nf_osf_add_callback(struct net *net, struct sock *ctnl,
+   struct sk_buff *skb, const struct nlmsghdr *nlh,
+   const struct nlattr * const osf_attrs[],
+   struct netlink_ext_ack *extack)
+{
+   struct nf_osf_user_finger *f;
+   struct nf_osf_finger *kf = NULL, *sf;
+   int err = 0;
+
+   if (!capable(CAP_NET_ADMIN))
+   return -EPERM;
+
+   if (!osf_attrs[OSF_ATTR_FINGER])
+   return -EINVAL;
+
+   if (!(nlh->nlmsg_flags & NLM

Re: [PATCH 2/3 WIP nf-next] netfilter: implement Passive OS fingerprint module in nft_osf

2018-07-14 Thread Fernando Fernandez Mancera
It hasn't been tested yet. All necessary changes to introduce 
NFTA_OSF_DREG are already done.


After the review and testing I am going to implement the match_packet 
function.


On 07/14/2018 04:51 PM, Fernando Fernandez Mancera wrote:

Add basic module functions into nft_osf.[ch] in order to start the
implementation of OSF module in nf_tables.

Signed-off-by: Fernando Fernandez Mancera 
---
  include/uapi/linux/netfilter/nf_tables.h |  10 ++
  net/netfilter/Kconfig|   6 ++
  net/netfilter/Makefile   |   1 +
  net/netfilter/nft_osf.c  | 118 +++
  4 files changed, 135 insertions(+)
  create mode 100644 net/netfilter/nft_osf.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 89438e68dc03..48061dead8e6 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1461,6 +1461,16 @@ enum nft_flowtable_hook_attributes {
  };
  #define NFTA_FLOWTABLE_HOOK_MAX   (__NFTA_FLOWTABLE_HOOK_MAX - 1)
  
+enum nft_osf_attributes {

+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_DREG,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
  /**
   * enum nft_device_attributes - nf_tables device netlink attributes
   *
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 6c65d756e603..29c8591f87c2 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -633,6 +633,12 @@ config NFT_SOCKET
  This option allows matching for the presence or absence of a
  corresponding socket and its attributes.
  
+config NFT_OSF

+   tristate "Netfilter nf_tables passive OS fingerprinting support"
+   select NF_OSF
+   help
+ This option allows matching packets from an specific OS.
+
  if NF_TABLES_NETDEV
  
  config NF_DUP_NETDEV

diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0b3851e825fa..75ddcb0f748d 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_NFT_FIB_INET)  += nft_fib_inet.o
  obj-$(CONFIG_NFT_FIB_NETDEV)  += nft_fib_netdev.o
  obj-$(CONFIG_NF_OSF)  += nf_osf.o
  obj-$(CONFIG_NFT_SOCKET)  += nft_socket.o
+obj-$(CONFIG_NFT_OSF)  += nft_osf.o
  
  # nf_tables netdev

  obj-$(CONFIG_NFT_DUP_NETDEV)  += nft_dup_netdev.o
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
new file mode 100644
index ..596f835087a6
--- /dev/null
+++ b/net/netfilter/nft_osf.c
@@ -0,0 +1,118 @@
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nft_osf {
+   __u8flags;
+   __u8loglevel;
+   __u8ttl;
+   union {
+   enum nft_registers  dreg:8;
+   };
+};
+
+/* placeholder function WIP */
+static inline bool match_packet(struct nft_osf *priv, struct sk_buff *skb)
+{
+   return 1;
+}
+
+static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
+   [NFTA_OSF_DREG] = { .type = NLA_U32 },
+   [NFTA_OSF_FLAGS]= { .type = NLA_U8 },
+   [NFTA_OSF_LOGLEVEL] = { .type = NLA_U8 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U8 },
+};
+
+static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   struct sk_buff *skb = pkt->skb;
+
+   if (!match_packet(priv, skb))
+   regs->verdict.code = NFT_BREAK;
+}
+
+static int nft_osf_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   int err;
+   __u8 flags, loglevel, ttl;
+
+   priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
+   err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFTA_DATA_VALUE, OSF_GENRE_SIZE);
+   if (err < 0)
+   return err;
+
+   flags = ntohl(nla_get_be32(tb[NFTA_OSF_FLAGS]));
+   if (flags & ~NF_OSF_FLAGMASK)
+   return -EINVAL;
+   priv->flags  = flags;
+
+   loglevel = ntohl(nla_get_be32(tb[NFTA_OSF_LOGLEVEL]));
+   if (loglevel >= NF_OSF_LOGLEVEL_ALL_KNOWN)
+   return -EINVAL;
+   priv->loglevel   = loglevel;
+
+   ttl = ntohl(nla_get_be32(tb[NFTA_OSF_TTL]));
+   if (ttl >= NF_OSF_TTL_NOCHECK)
+   return -EINVAL;
+   priv->ttl= ttl;
+
+   return 0;
+}
+
+static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr)
+{
+   const struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg) ||
+   nla_put_be32(skb, NFTA_OSF_FLAGS, htonl(priv->flags)) ||
+   nla_put

[PATCH 3/3 nf-next] netfilter: add netlink support for osf module

2018-07-14 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/linux/netfilter/nfnetlink_osf.h |  20 +
 net/netfilter/Kconfig   |  11 ++-
 net/netfilter/Makefile  |   1 +
 net/netfilter/nfnetlink_osf.c   | 100 +++
 net/netfilter/xt_osf.c  | 103 ++--
 5 files changed, 139 insertions(+), 96 deletions(-)
 create mode 100644 include/linux/netfilter/nfnetlink_osf.h
 create mode 100644 net/netfilter/nfnetlink_osf.c

diff --git a/include/linux/netfilter/nfnetlink_osf.h 
b/include/linux/netfilter/nfnetlink_osf.h
new file mode 100644
index ..80fcd21b
--- /dev/null
+++ b/include/linux/netfilter/nfnetlink_osf.h
@@ -0,0 +1,20 @@
+#ifndef _NFNETLINK_OSF_H
+#define _NFNETLINK_OSF_H
+
+#include 
+
+#include 
+
+extern struct list_head nf_osf_fingers[2];
+
+int nf_osf_add_callback(struct net *net, struct sock *ctnl,
+   struct sk_buff *skb, const struct nlmsghdr *nlh,
+   const struct nlattr * const osf_attrs[],
+   struct netlink_ext_ack *extack);
+
+int nf_osf_remove_callback(struct net *net, struct sock *ctnl,
+  struct sk_buff *skb, const struct nlmsghdr *nlh,
+  const struct nlattr * const osf_attrs[],
+  struct netlink_ext_ack *extack);
+
+#endif /* _NFNETLINK_OSF_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 29c8591f87c2..1e156978535b 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG
  and is also scheduled to replace the old syslog-based ipt_LOG
  and ip6t_LOG modules.
 
+config NETFILTER_NETLINK_OSF
+   tristate "Netfilter NFOSF over NFNETLINK interface"
+   depends on NETFILTER_ADVANCED
+   select NETFILTER_NETLINK
+   help
+ If this option is enables, the kernel will include support
+ for passive OS fingerprint via NFNETLINK.
+
 config NF_CONNTRACK
tristate "Netfilter connection tracking support"
default m if NETFILTER_ADVANCED=n
@@ -636,6 +644,7 @@ config NFT_SOCKET
 config NFT_OSF
tristate "Netfilter nf_tables passive OS fingerprinting support"
select NF_OSF
+   select NETFILTER_NETLINK_OSF
help
  This option allows matching packets from an specific OS.
 
@@ -1385,8 +1394,8 @@ config NETFILTER_XT_MATCH_NFACCT
 
 config NETFILTER_XT_MATCH_OSF
tristate '"osf" Passive OS fingerprint match'
-   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
select NF_OSF
+   select NETFILTER_NETLINK_OSF
help
  This option selects the Passive OS Fingerprinting match module
  that allows to passively match the remote operating system by
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 75ddcb0f748d..2fa826d5fdc5 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
 obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
 obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
+obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o
 
 # connection tracking
 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c
new file mode 100644
index ..df9d49c54655
--- /dev/null
+++ b/net/netfilter/nfnetlink_osf.c
@@ -0,0 +1,100 @@
+#include 
+#include 
+
+/*
+ * Indexed by dont-fragment bit.
+ * It is the only constant value in the fingerprint.
+ */
+struct list_head nf_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nf_osf_fingers);
+
+static const struct nla_policy nf_osf_policy[OSF_ATTR_MAX + 1] = {
+   [OSF_ATTR_FINGER]   = { .len = sizeof(struct nf_osf_user_finger) },
+};
+
+int nf_osf_add_callback(struct net *net, struct sock *ctnl,
+   struct sk_buff *skb, const struct nlmsghdr *nlh,
+   const struct nlattr * const osf_attrs[],
+   struct netlink_ext_ack *extack)
+{
+   struct nf_osf_user_finger *f;
+   struct nf_osf_finger *kf = NULL, *sf;
+   int err = 0;
+
+   if (!capable(CAP_NET_ADMIN))
+   return -EPERM;
+
+   if (!osf_attrs[OSF_ATTR_FINGER])
+   return -EINVAL;
+
+   if (!(nlh->nlmsg_flags & NLM_F_CREATE))
+   return -EINVAL;
+
+   f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+   kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL);
+   if (!kf)
+   return -ENOMEM;
+
+   memcpy(>finger, f, sizeof(struct nf_osf_user_finger));
+
+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;
+
+  

[PATCH 1/3 nf-next] netfilter: add missing definitions in nf_osf.h

2018-07-14 Thread Fernando Fernandez Mancera
Added missing definitions from nf_osf.h in order to extract Passive OS
fingerprint infrastructure from xt_osf.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/uapi/linux/netfilter/nf_osf.h | 13 +
 include/uapi/linux/netfilter/xt_osf.h | 10 ++
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
index 8f2f2f403183..a89583099b2a 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -2,6 +2,8 @@
 #define _NF_OSF_H
 
 #include 
+#include 
+#include 
 
 #define MAXGENRELEN32
 
@@ -16,9 +18,14 @@
 
 #define NF_OSF_TTL_TRUE0   /* True ip and 
fingerprint TTL comparison */
 
+/* Check if ip TTL is less than fingerprint one */
+#define NF_OSF_TTL_LESS1
+
 /* Do not compare ip and fingerprint TTL at all */
 #define NF_OSF_TTL_NOCHECK 2
 
+#define NF_OSF_FLAGMASK(NF_OSF_GENRE | NF_OSF_TTL | \
+NF_OSF_LOG | NF_OSF_INVERT)
 /* Wildcard MSS (kind of).
  * It is used to implement a state machine for the different wildcard values
  * of the MSS and window sizes.
@@ -83,4 +90,10 @@ enum iana_options {
OSFOPT_EMPTY = 255,
 };
 
+enum nf_osf_attr_type {
+   OSF_ATTR_UNSPEC,
+   OSF_ATTR_FINGER,
+   OSF_ATTR_MAX,
+};
+
 #endif /* _NF_OSF_H */
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index 72956eceeb09..b189007f4f28 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -37,8 +37,7 @@
 
 #define XT_OSF_TTL_TRUENF_OSF_TTL_TRUE
 #define XT_OSF_TTL_NOCHECK NF_OSF_TTL_NOCHECK
-
-#define XT_OSF_TTL_LESS1   /* Check if ip TTL is less than 
fingerprint one */
+#define XT_OSF_TTL_LESSNF_OSF_TTL_LESS
 
 #define xt_osf_wc  nf_osf_wc
 #define xt_osf_opt nf_osf_opt
@@ -47,6 +46,7 @@
 #define xt_osf_finger  nf_osf_finger
 #define xt_osf_nlmsg   nf_osf_nlmsg
 
+#define xt_osf_attr_type   nf_osf_attr_type
 /*
  * Add/remove fingerprint from the kernel.
  */
@@ -56,10 +56,4 @@ enum xt_osf_msg_types {
OSF_MSG_MAX,
 };
 
-enum xt_osf_attr_type {
-   OSF_ATTR_UNSPEC,
-   OSF_ATTR_FINGER,
-   OSF_ATTR_MAX,
-};
-
 #endif /* _XT_OSF_H */
-- 
2.18.0

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


[PATCH 2/3 WIP nf-next] netfilter: implement Passive OS fingerprint module in nft_osf

2018-07-14 Thread Fernando Fernandez Mancera
Add basic module functions into nft_osf.[ch] in order to start the
implementation of OSF module in nf_tables.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/uapi/linux/netfilter/nf_tables.h |  10 ++
 net/netfilter/Kconfig|   6 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_osf.c  | 118 +++
 4 files changed, 135 insertions(+)
 create mode 100644 net/netfilter/nft_osf.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 89438e68dc03..48061dead8e6 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1461,6 +1461,16 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_DREG,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_device_attributes - nf_tables device netlink attributes
  *
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 6c65d756e603..29c8591f87c2 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -633,6 +633,12 @@ config NFT_SOCKET
  This option allows matching for the presence or absence of a
  corresponding socket and its attributes.
 
+config NFT_OSF
+   tristate "Netfilter nf_tables passive OS fingerprinting support"
+   select NF_OSF
+   help
+ This option allows matching packets from an specific OS.
+
 if NF_TABLES_NETDEV
 
 config NF_DUP_NETDEV
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0b3851e825fa..75ddcb0f748d 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_NFT_FIB_INET)  += nft_fib_inet.o
 obj-$(CONFIG_NFT_FIB_NETDEV)   += nft_fib_netdev.o
 obj-$(CONFIG_NF_OSF)   += nf_osf.o
 obj-$(CONFIG_NFT_SOCKET)   += nft_socket.o
+obj-$(CONFIG_NFT_OSF)  += nft_osf.o
 
 # nf_tables netdev
 obj-$(CONFIG_NFT_DUP_NETDEV)   += nft_dup_netdev.o
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
new file mode 100644
index ..596f835087a6
--- /dev/null
+++ b/net/netfilter/nft_osf.c
@@ -0,0 +1,118 @@
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nft_osf {
+   __u8flags;
+   __u8loglevel;
+   __u8ttl;
+   union {
+   enum nft_registers  dreg:8;
+   };
+};
+
+/* placeholder function WIP */
+static inline bool match_packet(struct nft_osf *priv, struct sk_buff *skb)
+{
+   return 1;
+}
+
+static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
+   [NFTA_OSF_DREG] = { .type = NLA_U32 },
+   [NFTA_OSF_FLAGS]= { .type = NLA_U8 },
+   [NFTA_OSF_LOGLEVEL] = { .type = NLA_U8 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U8 },
+};
+
+static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   struct sk_buff *skb = pkt->skb;
+
+   if (!match_packet(priv, skb))
+   regs->verdict.code = NFT_BREAK;
+}
+
+static int nft_osf_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   int err;
+   __u8 flags, loglevel, ttl;
+
+   priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
+   err = nft_validate_register_store(ctx, priv->dreg, NULL,
+ NFTA_DATA_VALUE, OSF_GENRE_SIZE);
+   if (err < 0)
+   return err;
+
+   flags = ntohl(nla_get_be32(tb[NFTA_OSF_FLAGS]));
+   if (flags & ~NF_OSF_FLAGMASK)
+   return -EINVAL;
+   priv->flags = flags;
+
+   loglevel = ntohl(nla_get_be32(tb[NFTA_OSF_LOGLEVEL]));
+   if (loglevel >= NF_OSF_LOGLEVEL_ALL_KNOWN)
+   return -EINVAL;
+   priv->loglevel  = loglevel;
+
+   ttl = ntohl(nla_get_be32(tb[NFTA_OSF_TTL]));
+   if (ttl >= NF_OSF_TTL_NOCHECK)
+   return -EINVAL;
+   priv->ttl   = ttl;
+
+   return 0;
+}
+
+static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr)
+{
+   const struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg) ||
+   nla_put_be32(skb, NFTA_OSF_FLAGS, htonl(priv->flags)) ||
+   nla_put_be32(skb, NFTA_OSF_LOGLEVEL, htonl(priv->loglevel)) ||
+   nla_put_be32(skb, NFTA_OSF_TTL, htonl(priv->ttl)))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -1;
+}
+
+static struct nft_expr_type nft_

Re: [PATCH 2/2 WIP nf-next] nft: implement the nf_tables_api changes to add osf signatures in nft

2018-07-12 Thread Fernando Fernandez Mancera




On 07/12/2018 01:27 PM, Florian Westphal wrote:

Fernando Fernandez Mancera  wrote:

+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;
+
+   kfree(kf);


Hmm.  So there can't be any duplicate entries in first place.

So I really wonder how this is going to be used or why
all of this code can't live in nft_osf.c .

I mean, we are adding this to core nftables api, and i think this is
something that should only be done if it can't be specific to particular
expression for some reason.


Can we load/unload pf.os signatures from nft_osf.c at the expression init?
If we can do it, then maybe all this code can live in nft_osf.c.


I'd like to see how this is used from grammar point of view first.
What does a rule look like?


A rule will contain a string (the OS we want to match) and two u8 
(loglevel and ttl).




Are the osf signatures global, tied to table, tied to expression?



OSF signatures should be load at the osf expression init if I am not 
wrong, and that only happens once. If we add more rules using osf they 
should use the already loaded signatures.



+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;


list_for_each_entry_safe?


I think it is not necessary and isn't used in xt_osf module, but we can use
it if recommended.


xt_osf use looks buggy too...  I don't see it holding rcu read lock, so
once kfree_rcu() is invoked sf ->next pointer can already reside in
free'd memory.



Okey then let's use list_for_each_entry_safe. Will fix xt_osf too.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2 WIP nf-next] nft: implement the nf_tables_api changes to add osf signatures in nft

2018-07-12 Thread Fernando Fernandez Mancera

Hi Florian, thanks for the review.

On 07/12/2018 01:03 PM, Florian Westphal wrote:

Fernando Fernandez Mancera  wrote:

+extern struct list_head nft_osf_fingers[2];


How is this going to be used?

I find it weird to see this in netfilter core.



This list is used to load the OS signatures from pf.os.


+   f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+   kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL);
+   if (!kf)
+   return -ENOMEM;
+
+   for (i = 0; i < ARRAY_SIZE(nft_osf_fingers); ++i)
+   INIT_LIST_HEAD(_osf_fingers[i]);
+


This is missing input validation.
I see no nla_policy for OSF_ATTR_FINGER.

Userspace could have placed anything from 0 to 0x bytes.

+   memcpy(>finger, f, sizeof(struct nf_osf_user_finger));

Probably should use
nla_memdup() + an nla_plolicy struct entry.

Or nla_memdup() plus manual checking of nla_len() vs. expected/sane
values?


Agree, will fix that.




+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;
+
+   kfree(kf);


Hmm.  So there can't be any duplicate entries in first place.

So I really wonder how this is going to be used or why
all of this code can't live in nft_osf.c .

I mean, we are adding this to core nftables api, and i think this is
something that should only be done if it can't be specific to particular
expression for some reason.


Can we load/unload pf.os signatures from nft_osf.c at the expression 
init? If we can do it, then maybe all this code can live in nft_osf.c.





+   list_for_each_entry(sf, _osf_fingers[!!f->df], finger_entry) {
+   if (memcmp(>finger, f, sizeof(struct nf_osf_user_finger)))
+   continue;


list_for_each_entry_safe?



I think it is not necessary and isn't used in xt_osf module, but we can 
use it if recommended.

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


Re: [PATCH 1/2 WIP nf-next] netfilter: implement Passive OS fingerprint module in nft_osf

2018-07-12 Thread Fernando Fernandez Mancera




On 07/12/2018 12:53 PM, Florian Westphal wrote:

Fernando Fernandez Mancera  wrote:

Add basic module functions into nft_osf.[ch] in order to start the
implementation of OSF module in nf_tables.

+struct nft_osf {
+   chargenre[OSF_GENRE_SIZE];
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+   __u32   len;
+};


48 bytes is quite a lot.  Can this be compressed further?

e.g. len appears to be useless, and flags/loglevel/ttl
can probably be u8 or u16.



Agree, u8 should be enough for flags/loglevel/ttl.


+static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
+   [NFTA_OSF_GENRE]= { .type = NLA_STRING, .len = OSF_GENRE_SIZE },


This allows strlen() of OSF_GENRE_SIZE.


+   [NFTA_OSF_FLAGS]= { .type = NLA_U32 },
+   [NFTA_OSF_LOGLEVEL] = { .type = NLA_U32 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U32 },
+};


This looks ok.


+static int nft_osf_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (tb[NFTA_OSF_GENRE] == NULL)
+   return -EINVAL;
+   nla_strlcpy(priv->genre, tb[NFTA_OSF_GENRE], OSF_GENRE_SIZE);


This then copies OSF_GENRE_SIZE - 1 (for \0).

So its either .len = OSF_GENRE_SIZE - 1,
or genre[OSF_GENRE_SIZE+1], or char *genre + nla_strdup().


+   priv->len = strlen(priv->genre);


I don't understand need for this.


Yes, I am thinking on getting "len" out.


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


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


[PATCH WIP libnftnl] expr: add osf support

2018-07-12 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/libnftnl/expr.h |   7 +
 include/linux/netfilter/nf_tables.h |  20 +++
 src/Makefile.am |   1 +
 src/expr/osf.c  | 262 
 src/expr_ops.c  |   2 +
 5 files changed, 292 insertions(+)
 create mode 100644 src/expr/osf.c

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 219104e..4ee71a5 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -268,6 +268,13 @@ enum {
NFTNL_EXPR_OBJREF_SET_ID,
 };
 
+enum {
+   NFTNL_EXPR_OSF_GENRE= NFTNL_EXPR_BASE,
+   NFTNL_EXPR_OSF_FLAGS,
+   NFTNL_EXPR_OSF_LOGLEVEL,
+   NFTNL_EXPR_OSF_TTL,
+};
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 91449ef..d96636f 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -122,6 +122,8 @@ enum nf_tables_msg_types {
NFT_MSG_NEWFLOWTABLE,
NFT_MSG_GETFLOWTABLE,
NFT_MSG_DELFLOWTABLE,
+   NFT_MSG_NEWOSF,
+   NFT_MSG_DELOSF,
NFT_MSG_MAX,
 };
 
@@ -929,6 +931,24 @@ enum nft_socket_keys {
 };
 #define NFT_SOCKET_MAX (__NFT_SOCKET_MAX - 1)
 
+/**
+ * enum nft_osf_attributes - nf_tables osf expression netlink attributes
+ *
+ * @NFTA_OSF_GENRE: OS to match
+ * @NFTA_OSF_FLAGS: Valid flags
+ * @NFTA_OSF_LOGLEVEL: different log levels
+ * @NFTA_OSF_TTL: different checks on TTL
+ */
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_GENRE,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_ct_keys - nf_tables ct expression keys
  *
diff --git a/src/Makefile.am b/src/Makefile.am
index c66a257..bdc10f7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,6 +56,7 @@ libnftnl_la_SOURCES = utils.c \
  expr/redir.c  \
  expr/hash.c   \
  expr/socket.c \
+ expr/osf.c\
  obj/counter.c \
  obj/ct_helper.c   \
  obj/quota.c   \
diff --git a/src/expr/osf.c b/src/expr/osf.c
new file mode 100644
index 000..a560629
--- /dev/null
+++ b/src/expr/osf.c
@@ -0,0 +1,262 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include 
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nftnl_expr_osf {
+   char*genre;
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+   __u32   len;
+};
+
+static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_GENRE:
+   osf->genre = strdup(data);
+   if (!osf->genre)
+   return -1;
+   break;
+   case NFTNL_EXPR_OSF_FLAGS:
+   osf->len = *((unsigned int *)data);
+   break;
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   osf->loglevel = *((unsigned int *)data);
+   break;
+   case NFTNL_EXPR_OSF_TTL:
+   osf->ttl = *((unsigned int *)data);
+   break;
+   }
+   return 0;
+}
+
+static const void *
+nftnl_expr_osf_get(const struct nftnl_expr *e, uint16_t type,
+  uint32_t *data_len)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_GENRE:
+   *data_len = strlen(osf->genre)+1;
+   return osf->genre;
+   case NFTNL_EXPR_OSF_FLAGS:
+   *data_len = sizeof(osf->flags);
+   return >flags;
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   *data_len = sizeof(osf->loglevel);
+   return >loglevel;
+   case NFTNL_EXPR_OSF_TTL:
+   *data_len = sizeof(osf->ttl);
+   return >ttl;
+   }
+   return NULL;
+}
+
+static int nftnl_expr_osf_cb(const struct nlattr *attr, void *data)
+{
+   const struct nlattr **tb = data;
+   int type = mnl_attr_get_type(attr);
+
+   if (mnl_attr_type_valid(attr, NFTA_OSF_MAX) < 0)
+   return MNL_CB_OK;
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_GENRE:
+   if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+   abi_breakage();
+   break;
+   case NFTNL_EXPR_OSF_FLAGS:
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   case NFTNL_EXPR_OSF_TTL:
+   if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+   abi_breakage();
+   break;
+   }
+
+   tb[type] = attr;
+   

[PATCH 2/2 WIP nf-next] nft: implement the nf_tables_api changes to add osf signatures in nft

2018-07-12 Thread Fernando Fernandez Mancera
Added _ADD and _REMOVE commands to nf_tables_api.c in order to use the
nf_tables interface to add 'osf' signatures in nft.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/net/netfilter/nf_tables_core.h   |   2 +
 include/uapi/linux/netfilter/nf_osf.h|   8 ++
 include/uapi/linux/netfilter/nf_tables.h |  14 +++
 include/uapi/linux/netfilter/xt_osf.h|   7 +-
 net/netfilter/nf_tables_api.c| 110 +++
 net/netfilter/nft_osf.c  |   1 +
 6 files changed, 136 insertions(+), 6 deletions(-)

diff --git a/include/net/netfilter/nf_tables_core.h 
b/include/net/netfilter/nf_tables_core.h
index e0c0c2558ec4..ee7eabc8d3e1 100644
--- a/include/net/netfilter/nf_tables_core.h
+++ b/include/net/netfilter/nf_tables_core.h
@@ -65,4 +65,6 @@ extern const struct nft_expr_ops nft_payload_fast_ops;
 extern struct static_key_false nft_counters_enabled;
 extern struct static_key_false nft_trace_enabled;
 
+extern struct list_head nft_osf_fingers[2];
+
 #endif /* _NET_NF_TABLES_CORE_H */
diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
index 79882b2f7f8e..35352c1cd994 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -2,6 +2,8 @@
 #define _NF_OSF_H
 
 #include 
+#include 
+#include 
 
 #define MAXGENRELEN32
 
@@ -90,4 +92,10 @@ enum iana_options {
OSFOPT_EMPTY = 255,
 };
 
+enum nf_osf_attr_type {
+   OSF_ATTR_UNSPEC,
+   OSF_ATTR_FINGER,
+   OSF_ATTR_MAX,
+};
+
 #endif /* _NF_OSF_H */
diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index c9bf74b94f37..beffa2010b20 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -9,6 +9,8 @@
 #define NFT_OBJ_MAXNAMELEN NFT_NAME_MAXLEN
 #define NFT_USERDATA_MAXLEN256
 
+#define OSF_GENRE_SIZE 32
+
 /**
  * enum nft_registers - nf_tables registers
  *
@@ -122,6 +124,8 @@ enum nf_tables_msg_types {
NFT_MSG_NEWFLOWTABLE,
NFT_MSG_GETFLOWTABLE,
NFT_MSG_DELFLOWTABLE,
+   NFT_MSG_NEWOSF,
+   NFT_MSG_DELOSF,
NFT_MSG_MAX,
 };
 
@@ -1461,6 +1465,16 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_GENRE,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_device_attributes - nf_tables device netlink attributes
  *
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index 2f5d4e6d0434..b7c0f93fe9d4 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -51,6 +51,7 @@
 #define xt_osf_finger  nf_osf_finger
 #define xt_osf_nlmsg   nf_osf_nlmsg
 
+#define xt_osf_attr_type   nf_osf_attr_type
 /*
  * Add/remove fingerprint from the kernel.
  */
@@ -60,10 +61,4 @@ enum xt_osf_msg_types {
OSF_MSG_MAX,
 };
 
-enum xt_osf_attr_type {
-   OSF_ATTR_UNSPEC,
-   OSF_ATTR_FINGER,
-   OSF_ATTR_MAX,
-};
-
 #endif /* _XT_OSF_H */
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index ca4c4d994ddb..1783d8ef658c 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -26,6 +27,7 @@
 static LIST_HEAD(nf_tables_expressions);
 static LIST_HEAD(nf_tables_objects);
 static LIST_HEAD(nf_tables_flowtables);
+
 static u64 table_handle;
 
 enum {
@@ -5851,6 +5853,8 @@ static int nf_tables_flowtable_event(struct 
notifier_block *this,
return NOTIFY_DONE;
 }
 
+
+
 static struct notifier_block nf_tables_flowtable_notifier = {
.notifier_call  = nf_tables_flowtable_event,
 };
@@ -5908,6 +5912,102 @@ static int nf_tables_getgen(struct net *net, struct 
sock *nlsk,
return err;
 }
 
+struct list_head nft_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nft_osf_fingers);
+
+static int nf_tables_newosf(struct net *net, struct sock *ctnl,
+   struct sk_buff *skb, const struct nlmsghdr *nlh,
+   const struct nlattr * const osf_attrs[],
+   struct netlink_ext_ack *extack)
+{
+   struct nf_osf_user_finger *f;
+   struct nf_osf_finger *kf = NULL, *sf;
+   int err = 0;
+   int i = 0;
+
+   if (!capable(CAP_NET_ADMIN))
+   return -EPERM;
+
+   if (!osf_attrs[OSF_ATTR_FINGER])
+   return -EINVAL;
+
+   if (!(nlh->nlmsg_flags & NLM_F_CREATE))
+   return -EINVAL;
+
+   f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+   kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL);
+   if (!kf)
+   return -ENOMEM;
+
+   for (i

Re: [PATCH nf-next WIP] netfilter: implement Passive OS fingerprint module in nft_osf

2018-06-27 Thread Fernando Fernandez Mancera

On 06/27/2018 07:19 PM, Pablo Neira Ayuso wrote:

On Wed, Jun 27, 2018 at 07:11:39PM +0200, Fernando Fernandez Mancera wrote:

Add basic module functions into nft_osf.[ch] in order to start the
implementation of OSF module in nf_tables.

Signed-off-by: Fernando Fernandez Mancera 
---
  include/net/netfilter/nft_osf.h |  15 +
  net/netfilter/Kconfig   |   7 +++
  net/netfilter/Makefile  |   1 +
  net/netfilter/nft_osf.c | 104 
  4 files changed, 127 insertions(+)
  create mode 100644 include/net/netfilter/nft_osf.h
  create mode 100644 net/netfilter/nft_osf.c

diff --git a/include/net/netfilter/nft_osf.h b/include/net/netfilter/nft_osf.h
new file mode 100644
index ..af6c8550f564
--- /dev/null
+++ b/include/net/netfilter/nft_osf.h
@@ -0,0 +1,15 @@
+#ifndef _NFT_OSF_H
+#define _NFT_OSF_H
+
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_GENRE,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
+#endif /* _NFT_OSF_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index dbd7d1fad277..e630aac8a081 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -631,6 +631,13 @@ config NFT_SOCKET
  This option allows matching for the presence or absence of a
  corresponding socket and its attributes.
  
+config NFT_OSF

+   tristate "Netfilter nf_tables passive OS fingerprinting support"
+   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
+   select NF_OSF
+   help
+ This option allows matching packets from an specific OS.
+


I am not completly sure if NFT_OSF depends on NETFILTER_INET too.


  if NF_TABLES_NETDEV
  
  config NF_DUP_NETDEV

diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 9389e527..d15bd858ecef 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_NFT_FIB_INET)  += nft_fib_inet.o
  obj-$(CONFIG_NFT_FIB_NETDEV)  += nft_fib_netdev.o
  obj-$(CONFIG_NF_OSF)  += nf_osf.o
  obj-$(CONFIG_NFT_SOCKET)  += nft_socket.o
+obj-$(CONFIG_NFT_OSF)  += nft_osf.o
  
  # nf_tables netdev

  obj-$(CONFIG_NFT_DUP_NETDEV)  += nft_dup_netdev.o
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
new file mode 100644
index ..008e3484f3da
--- /dev/null
+++ b/net/netfilter/nft_osf.c
@@ -0,0 +1,104 @@
+#include 
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nft_osf {
+   chargenre[OSF_GENRE_SIZE];
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+   __u32   len;
+};
+
+/* placeholder function WIP */
+static inline bool match_packet(struct nft_osf *priv, struct sk_buff *skb)
+{
+   return 1;


OK, so your follow up step is to support this, right?



Yes, my next step is to add _ADD and _REMOVE commands to 
net/netfilter/nf_tables_api.c in order to use the nf_tables interface to 
add osf signatures in nft.



+}
+
+static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
+   [NFTA_OSF_GENRE]= { .type = NLA_STRING, .len = OSF_GENRE_SIZE },
+   [NFTA_OSF_FLAGS]= { .type = NLA_U32 },
+   [NFTA_OSF_LOGLEVEL] = { .type = NLA_U32 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U32 },
+};
+
+static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
+   const struct nft_pktinfo *pkt)
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   struct sk_buff *skb = pkt->skb;
+
+   if (match_packet(priv, skb))
+   regs->verdict.code = NFT_CONTINUE;


NFT_CONTINUE is implicit, so not needed.


+   else
+   regs->verdict.code = NFT_BREAK;


So you can simplify this to:

if (!match_packet(priv, skb))
regs->verdict.code = NFT_BREAK;


+}
+
+static int nft_osf_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (tb[NFTA_OSF_GENRE] == NULL)
+   return -EINVAL;
+   nla_strlcpy(priv->genre, tb[NFTA_OSF_GENRE], OSF_GENRE_SIZE);
+   priv->flags  = ntohl(nla_get_be32(tb[NFTA_OSF_FLAGS]));


I guess you have to check for invalid flags here, eg.

 if (priv->flags & ~MASK_WITH_SUPPORT_FLAGS)
 return -EOPNOTSUPP;


+   priv->loglevel   = ntohl(nla_get_be32(tb[NFTA_OSF_LOGLEVEL]));


Probably same thing here?


+   priv->ttl= ntohl(nla_get_be32(tb[NFTA_OSF_TTL]));
+   priv->len = strlen(priv->genre);
+   return 0;
+}
+
+static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr)
+{
+   const struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (nla_put_string(skb, NFTA_OSF_GENRE, priv->genre) ||
+

[PATCH nf-next WIP] netfilter: implement Passive OS fingerprint module in nft_osf

2018-06-27 Thread Fernando Fernandez Mancera
Add basic module functions into nft_osf.[ch] in order to start the
implementation of OSF module in nf_tables.

Signed-off-by: Fernando Fernandez Mancera 
---
 include/net/netfilter/nft_osf.h |  15 +
 net/netfilter/Kconfig   |   7 +++
 net/netfilter/Makefile  |   1 +
 net/netfilter/nft_osf.c | 104 
 4 files changed, 127 insertions(+)
 create mode 100644 include/net/netfilter/nft_osf.h
 create mode 100644 net/netfilter/nft_osf.c

diff --git a/include/net/netfilter/nft_osf.h b/include/net/netfilter/nft_osf.h
new file mode 100644
index ..af6c8550f564
--- /dev/null
+++ b/include/net/netfilter/nft_osf.h
@@ -0,0 +1,15 @@
+#ifndef _NFT_OSF_H
+#define _NFT_OSF_H
+
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_GENRE,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
+#endif /* _NFT_OSF_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index dbd7d1fad277..e630aac8a081 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -631,6 +631,13 @@ config NFT_SOCKET
  This option allows matching for the presence or absence of a
  corresponding socket and its attributes.
 
+config NFT_OSF
+   tristate "Netfilter nf_tables passive OS fingerprinting support"
+   depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
+   select NF_OSF
+   help
+ This option allows matching packets from an specific OS.
+
 if NF_TABLES_NETDEV
 
 config NF_DUP_NETDEV
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 9389e527..d15bd858ecef 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_NFT_FIB_INET)  += nft_fib_inet.o
 obj-$(CONFIG_NFT_FIB_NETDEV)   += nft_fib_netdev.o
 obj-$(CONFIG_NF_OSF)   += nf_osf.o
 obj-$(CONFIG_NFT_SOCKET)   += nft_socket.o
+obj-$(CONFIG_NFT_OSF)  += nft_osf.o
 
 # nf_tables netdev
 obj-$(CONFIG_NFT_DUP_NETDEV)   += nft_dup_netdev.o
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
new file mode 100644
index ..008e3484f3da
--- /dev/null
+++ b/net/netfilter/nft_osf.c
@@ -0,0 +1,104 @@
+#include 
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nft_osf {
+   chargenre[OSF_GENRE_SIZE];
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+   __u32   len;
+};
+
+/* placeholder function WIP */
+static inline bool match_packet(struct nft_osf *priv, struct sk_buff *skb)
+{
+   return 1;
+}
+
+static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
+   [NFTA_OSF_GENRE]= { .type = NLA_STRING, .len = OSF_GENRE_SIZE },
+   [NFTA_OSF_FLAGS]= { .type = NLA_U32 },
+   [NFTA_OSF_LOGLEVEL] = { .type = NLA_U32 },
+   [NFTA_OSF_TTL]  = { .type = NLA_U32 },
+};
+
+static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
+   const struct nft_pktinfo *pkt)
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+   struct sk_buff *skb = pkt->skb;
+
+   if (match_packet(priv, skb))
+   regs->verdict.code = NFT_CONTINUE;
+   else
+   regs->verdict.code = NFT_BREAK;
+}
+
+static int nft_osf_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (tb[NFTA_OSF_GENRE] == NULL)
+   return -EINVAL;
+   nla_strlcpy(priv->genre, tb[NFTA_OSF_GENRE], OSF_GENRE_SIZE);
+   priv->flags = ntohl(nla_get_be32(tb[NFTA_OSF_FLAGS]));
+   priv->loglevel  = ntohl(nla_get_be32(tb[NFTA_OSF_LOGLEVEL]));
+   priv->ttl   = ntohl(nla_get_be32(tb[NFTA_OSF_TTL]));
+   priv->len = strlen(priv->genre);
+   return 0;
+}
+
+static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr)
+{
+   const struct nft_osf *priv = nft_expr_priv(expr);
+
+   if (nla_put_string(skb, NFTA_OSF_GENRE, priv->genre) ||
+   nla_put_be32(skb, NFTA_OSF_FLAGS, htonl(priv->flags)) ||
+   nla_put_be32(skb, NFTA_OSF_LOGLEVEL, htonl(priv->loglevel)) ||
+   nla_put_be32(skb, NFTA_OSF_TTL, htonl(priv->ttl)))
+   goto nla_put_failure;
+   return 0;
+
+nla_put_failure:
+   return -1;
+}
+
+static struct nft_expr_type nft_osf_type;
+
+static const struct nft_expr_ops nft_osf_op = {
+   .eval = nft_osf_eval,
+   .size = NFT_EXPR_SIZE(sizeof(struct nft_osf)),
+   .init = nft_osf_init,
+   .dump = nft_osf_dump,
+   .type = _osf_type,
+};
+
+static struct nft_expr_type nft_osf_type __read_mostly = {
+   .ops = _osf_op,
+   .name = "osf",
+   .owner = THIS_MODULE,
+   .policy = nft_osf_policy,
+   .maxatt

[PATCH libnftnl WIP] expr: add osf support

2018-06-27 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera 
---
 include/libnftnl/expr.h   |   7 +
 include/linux/netfilter/osf.h |  15 ++
 src/Makefile.am   |   1 +
 src/expr/osf.c| 263 ++
 src/expr_ops.c|   2 +
 5 files changed, 288 insertions(+)
 create mode 100644 include/linux/netfilter/osf.h
 create mode 100644 src/expr/osf.c

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 219104e..4ee71a5 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -268,6 +268,13 @@ enum {
NFTNL_EXPR_OBJREF_SET_ID,
 };
 
+enum {
+   NFTNL_EXPR_OSF_GENRE= NFTNL_EXPR_BASE,
+   NFTNL_EXPR_OSF_FLAGS,
+   NFTNL_EXPR_OSF_LOGLEVEL,
+   NFTNL_EXPR_OSF_TTL,
+};
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/include/linux/netfilter/osf.h b/include/linux/netfilter/osf.h
new file mode 100644
index 000..bbb4ab5
--- /dev/null
+++ b/include/linux/netfilter/osf.h
@@ -0,0 +1,15 @@
+#ifndef __OSF_H
+#define __OSF_H
+
+enum nft_osf_attributes {
+   NFTA_OSF_UNSPEC,
+   NFTA_OSF_GENRE,
+   NFTA_OSF_FLAGS,
+   NFTA_OSF_LOGLEVEL,
+   NFTA_OSF_TTL,
+   __NFTA_OSF_MAX,
+};
+
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
+#endif /* __OSF_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index c66a257..bdc10f7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,6 +56,7 @@ libnftnl_la_SOURCES = utils.c \
  expr/redir.c  \
  expr/hash.c   \
  expr/socket.c \
+ expr/osf.c\
  obj/counter.c \
  obj/ct_helper.c   \
  obj/quota.c   \
diff --git a/src/expr/osf.c b/src/expr/osf.c
new file mode 100644
index 000..546db48
--- /dev/null
+++ b/src/expr/osf.c
@@ -0,0 +1,263 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include 
+#include 
+#include 
+
+#define OSF_GENRE_SIZE 32
+
+struct nftnl_expr_osf {
+   char*genre;
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+   __u32   len;
+};
+
+static int nftnl_expr_osf_set(struct nftnl_expr *e, uint16_t type,
+ const void *data, uint32_t data_len)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_GENRE:
+   osf->genre = strdup(data);
+   if (!osf->genre)
+   return -1;
+   break;
+   case NFTNL_EXPR_OSF_FLAGS:
+   osf->len = *((unsigned int *)data);
+   break;
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   osf->loglevel = *((unsigned int *)data);
+   break;
+   case NFTNL_EXPR_OSF_TTL:
+   osf->ttl = *((unsigned int *)data);
+   break;
+   }
+   return 0;
+}
+
+static const void *
+nftnl_expr_osf_get(const struct nftnl_expr *e, uint16_t type,
+  uint32_t *data_len)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_GENRE:
+   *data_len = strlen(osf->genre)+1;
+   return osf->genre;
+   case NFTNL_EXPR_OSF_FLAGS:
+   *data_len = sizeof(osf->flags);
+   return >flags;
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   *data_len = sizeof(osf->loglevel);
+   return >loglevel;
+   case NFTNL_EXPR_OSF_TTL:
+   *data_len = sizeof(osf->ttl);
+   return >ttl;
+   }
+   return NULL;
+}
+
+static int nftnl_expr_osf_cb(const struct nlattr *attr, void *data)
+{
+   const struct nlattr **tb = data;
+   int type = mnl_attr_get_type(attr);
+
+   if (mnl_attr_type_valid(attr, NFTA_OSF_MAX) < 0)
+   return MNL_CB_OK;
+
+   switch(type) {
+   case NFTNL_EXPR_OSF_GENRE:
+   if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+   abi_breakage();
+   break;
+   case NFTNL_EXPR_OSF_FLAGS:
+   case NFTNL_EXPR_OSF_LOGLEVEL:
+   case NFTNL_EXPR_OSF_TTL:
+   if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+   abi_breakage();
+   break;
+   }
+
+   tb[type] = attr;
+   return MNL_CB_OK;
+}
+
+static void
+nftnl_expr_osf_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
+{
+   struct nftnl_expr_osf *osf = nftnl_expr_data(e);
+
+   if (e->flags & (1 << NFTNL_EXPR_OSF_GENRE))
+   mnl_attr_put_str(nlh, NFTNL_EXPR_OSF_GENRE, osf->genre);
+   if (e->flags & (1 << NFTNL_EXPR_OSF_FLAGS))
+   mnl_attr_put_u32(nlh, NFTNL_EXPR_OSF_FLAGS, htonl(osf->flags));
+   if (e->flags & (1 << NFTNL_EXPR_OSF_LOGLEVEL))

[PATCH nftables] configure.ac: fix a typo in docbook2x error message.

2018-06-05 Thread Fernando Fernandez Mancera
The correct name is "docbook2x-man" not "docbookx2-man".

Signed-off-by: Fernando Fernandez Mancera 
---
 configure.ac | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 36148ae..e698a9b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,7 +62,7 @@ AM_COND_IF([BUILD_MAN], [
  [AS_IF([test "$DOCBOOK2MAN" != "no"], [DB2MAN="$DOCBOOK2MAN"],
 [AS_IF([test "$DB2X_DOCBOOK2MAN" != "no"],
[DB2MAN="$DB2X_DOCBOOK2MAN"],
-   [AC_MSG_ERROR([docbookx2-man/db2x_docbook2man not 
found, required for building man pages])]
+   [AC_MSG_ERROR([docbook2x-man/db2x_docbook2man not 
found, required for building man pages])]
 )]
 )]
)
-- 
2.17.1

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


[PATCH nf-next] netfilter: make NF_OSF non-visible symbol

2018-05-15 Thread Fernando Fernandez Mancera
Signed-off-by: Fernando Fernandez Mancera <ffmanc...@riseup.net>
---
 net/netfilter/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index e57c9d479503..a5b60e6a983e 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -445,7 +445,7 @@ config NETFILTER_SYNPROXY
 endif # NF_CONNTRACK
 
 config NF_OSF
-   tristate 'Passive OS fingerprint infrastructure'
+   tristate
 
 config NF_TABLES
select NETFILTER_NETLINK
-- 
2.17.0

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


[PATCH nf-next v5] netfilter: nf_osf: nf_osf_ttl() and nf_osf_match()

2018-05-03 Thread Fernando Fernandez Mancera
Added nf_osf_ttl() and nf_osf_match() into nf_osf.c in order to start the
nftables OSF implementation.

Signed-off-by: Fernando Fernandez Mancera <ffmanc...@riseup.net>
---
 include/linux/netfilter/nf_osf.h  |  29 
 include/uapi/linux/netfilter/nf_osf.h |  93 +++
 include/uapi/linux/netfilter/xt_osf.h | 108 +++--
 net/netfilter/Kconfig |   4 +
 net/netfilter/Makefile|   1 +
 net/netfilter/nf_osf.c| 218 ++
 net/netfilter/xt_osf.c| 202 +---
 7 files changed, 365 insertions(+), 290 deletions(-)
 create mode 100644 include/linux/netfilter/nf_osf.h
 create mode 100644 include/uapi/linux/netfilter/nf_osf.h
 create mode 100644 net/netfilter/nf_osf.c

diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h
new file mode 100644
index ..6b0167a9274c
--- /dev/null
+++ b/include/linux/netfilter/nf_osf.h
@@ -0,0 +1,29 @@
+#include 
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum nf_osf_window_size_options {
+   OSF_WSS_PLAIN   = 0,
+   OSF_WSS_MSS,
+   OSF_WSS_MTU,
+   OSF_WSS_MODULO,
+   OSF_WSS_MAX,
+};
+
+enum osf_fmatch_states {
+   /* Packet does not match the fingerprint */
+   FMATCH_WRONG = 0,
+   /* Packet matches the fingerprint */
+   FMATCH_OK,
+   /* Options do not match the fingerprint, but header does */
+   FMATCH_OPT_WRONG,
+};
+
+bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
+   int hooknum, struct net_device *in, struct net_device *out,
+   const struct nf_osf_info *info, struct net *net,
+   const struct list_head *nf_osf_fingers);
+
diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
new file mode 100644
index ..076ec2ee5906
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -0,0 +1,93 @@
+#ifndef _NF_OSF_H
+#define _NF_OSF_H
+
+#define MAXGENRELEN32
+
+#define NF_OSF_GENRE   (1<<0)
+#define NF_OSF_TTL (1<<1)
+#define NF_OSF_LOG (1<<2)
+#define NF_OSF_INVERT  (1<<3)
+
+#define NF_OSF_LOGLEVEL_ALL0   /* log all matched fingerprints */
+#define NF_OSF_LOGLEVEL_FIRST  1   /* log only the first matced 
fingerprint */
+#define NF_OSF_LOGLEVEL_ALL_KNOWN  2   /* do not log unknown packets */
+
+#define NF_OSF_TTL_TRUE0   /* True ip and fingerprint TTL 
comparison */
+
+/* Do not compare ip and fingerprint TTL at all */
+#define NF_OSF_TTL_NOCHECK 2
+
+/*
+ * Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct nf_osf_wc {
+   __u32   wc;
+   __u32   val;
+};
+
+/*
+ * This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct nf_osf_opt {
+   __u16   kind, length;
+   struct  nf_osf_wc   wc;
+};
+
+struct nf_osf_info {
+   chargenre[MAXGENRELEN];
+   __u32   len;
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+};
+
+struct nf_osf_user_finger {
+   struct nf_osf_wcwss;
+
+   __u8ttl, df;
+   __u16   ss, mss;
+   __u16   opt_num;
+
+   chargenre[MAXGENRELEN];
+   charversion[MAXGENRELEN];
+   charsubtype[MAXGENRELEN];
+
+   /* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+   struct nf_osf_opt   opt[MAX_IPOPTLEN];
+};
+
+struct nf_osf_finger {
+   struct rcu_head rcu_head;
+   struct list_headfinger_entry;
+   struct nf_osf_user_finger   finger;
+};
+
+struct nf_osf_nlmsg {
+   struct nf_osf_user_finger   f;
+   struct iphdrip;
+   struct tcphdr   tcp;
+};
+
+/* Defines for IANA option kinds */
+
+enum iana_options {
+   OSFOPT_EOL = 0, /* End of options */
+   OSFOPT_NOP, /* NOP */
+   OSFOPT_MSS, /* Maximum segment size */
+   OSFOPT_WSO, /* Window scale option */
+   OSFOPT_SACKP,   /* SACK permitted */
+   OSFOPT_SACK,/* SACK */
+   OSFOPT_ECHO,
+   OSFOPT_ECHOREPLY,
+   OSFOPT_TS,  /* Timestamp option */
+   OSFOPT_POCP,/* Partial Order Connection Permitted */
+   OSFOPT_POSP,/* Partial Order Service Profile */
+
+   /* Others are not used in the current OSF */
+   OSFOPT_EMPTY = 255,
+};
+
+#endif /* _NF_OSF_H */
diff --git a/include/uapi/linux/netfilter/xt_osf.h 
b/include/uapi/linux/netfilter/xt_osf.h
index dad197e2ab99..5d5874b5d747 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux

[PATCH nf-next v4] netfilter: nf_osf: nf_osf_ttl() and nf_osf_match()

2018-04-09 Thread Fernando Fernandez Mancera
Added nf_osf_ttl() and nf_osf_match() into nf_osf.c in order to start the
nftables OSF implementation.

Signed-off-by: Fernando Fernandez Mancera <ffmanc...@riseup.net>
---
 include/linux/netfilter/nf_osf.h  |  28 
 include/uapi/linux/netfilter/nf_osf.h |  97 ++
 include/uapi/linux/netfilter/xt_osf.h | 106 +++
 net/netfilter/Kconfig |   4 +
 net/netfilter/Makefile|   1 +
 net/netfilter/nf_osf.c| 241 ++
 net/netfilter/xt_osf.c| 202 +---
 7 files changed, 390 insertions(+), 289 deletions(-)
 create mode 100644 include/linux/netfilter/nf_osf.h
 create mode 100644 include/uapi/linux/netfilter/nf_osf.h
 create mode 100644 net/netfilter/nf_osf.c

diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h
new file mode 100644
index ..46ae80b1d096
--- /dev/null
+++ b/include/linux/netfilter/nf_osf.h
@@ -0,0 +1,28 @@
+#include 
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum nf_osf_window_size_options {
+   OSF_WSS_PLAIN   = 0,
+   OSF_WSS_MSS,
+   OSF_WSS_MTU,
+   OSF_WSS_MODULO,
+   OSF_WSS_MAX,
+};
+
+enum osf_fmatch_states {
+   /* Packet does not match the fingerprint */
+   FMATCH_WRONG = 0,
+   /* Packet matches the fingerprint */
+   FMATCH_OK,
+   /* Options do not match the fingerprint, but header does */
+   FMATCH_OPT_WRONG,
+};
+
+bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
+   int hooknum, struct net_device *in, struct net_device *out,
+   const struct nf_osf_info *info, struct net *net);
+
diff --git a/include/uapi/linux/netfilter/nf_osf.h 
b/include/uapi/linux/netfilter/nf_osf.h
new file mode 100644
index ..9164ea564bdd
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -0,0 +1,97 @@
+#ifndef _NF_OSF_H
+#define _NF_OSF_H
+
+#define MAXGENRELEN 32
+
+#define NF_OSF_GENRE(1<<0)
+#define NF_OSF_TTL  (1<<1)
+#define NF_OSF_LOG  (1<<2)
+#define NF_OSF_INVERT   (1<<3)
+
+#define NF_OSF_LOGLEVEL_ALL 0   /* log all matched fingerprints */
+#define NF_OSF_LOGLEVEL_FIRST   1   /* log only the first matced fingerprint */
+#define NF_OSF_LOGLEVEL_ALL_KNOWN   2 /* do not log unknown packets */
+
+#define NF_OSF_TTL_TRUE 0   /* True ip and fingerprint TTL comparison */
+
+/* Do not compare ip and fingerprint TTL at all */
+#define NF_OSF_TTL_NOCHECK  2
+
+/*
+ * Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct nf_osf_wc {
+   __u32   wc;
+   __u32   val;
+};
+
+/*
+ * This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct nf_osf_opt {
+   __u16   kind, length;
+   struct nf_osf_wcwc;
+};
+
+struct nf_osf_info {
+   chargenre[MAXGENRELEN];
+   __u32   len;
+   __u32   flags;
+   __u32   loglevel;
+   __u32   ttl;
+};
+
+struct nf_osf_user_finger {
+   struct nf_osf_wcwss;
+
+   __u8ttl, df;
+   __u16   ss, mss;
+   __u16   opt_num;
+
+   chargenre[MAXGENRELEN];
+   charversion[MAXGENRELEN];
+   charsubtype[MAXGENRELEN];
+
+   /* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+   struct nf_osf_opt   opt[MAX_IPOPTLEN];
+};
+
+struct nf_osf_finger {
+   struct rcu_head rcu_head;
+   struct list_headfinger_entry;
+   struct nf_osf_user_finger   finger;
+};
+
+struct nf_osf_nlmsg {
+   struct nf_osf_user_finger   f;
+   struct iphdrip;
+   struct tcphdr   tcp;
+};
+
+/* Defines for IANA option kinds */
+
+enum iana_options {
+   OSFOPT_EOL = 0, /* End of options */
+   OSFOPT_NOP, /* NOP */
+   OSFOPT_MSS, /* Maximum segment size */
+   OSFOPT_WSO, /* Window scale option */
+   OSFOPT_SACKP,   /* SACK permitted */
+   OSFOPT_SACK,/* SACK */
+   OSFOPT_ECHO,
+   OSFOPT_ECHOREPLY,
+   OSFOPT_TS,  /* Timestamp option */
+   OSFOPT_POCP,/* Partial Order Connection Permitted */
+   OSFOPT_POSP,/* Partial Order Service Profile */
+
+   /* Others are not used in the current OSF */
+   OSFOPT_EMPTY = 255,
+};
+
+bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
+   int hooknum, struct net_devi

[PATCH nf-next v2] netfilter: nf_osf implementation: nf_osf_ttl() and nf_osf_match()

2018-03-30 Thread Fernando Fernandez Mancera
>From 520cf8eb6b1c7ae803f26fdfe8b49b642b1d51d8 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmanc...@riseup.net>
Date: Fri, 30 Mar 2018 15:53:09 +0200
Subject: [PATCH] nf_osf implementation: nf_osf_ttl() and nf_osf_match()

Added nf_osf_ttl() and nf_osf_match() into nf_osf.c in order to start the
nftables OSF implementation.

Signed-off-by: Fernando Fernandez Mancera <ffmanc...@riseup.net>
---
 include/linux/netfilter/nf_osf.h  | 110 
 include/uapi/linux/netfilter/xt_osf.h | 101 ++
 net/netfilter/Kconfig |   5 +
 net/netfilter/Makefile|   1 +
 net/netfilter/nf_osf.c| 239 ++
 net/netfilter/xt_osf.c| 219 +--
 6 files changed, 369 insertions(+), 306 deletions(-)
 create mode 100644 include/linux/netfilter/nf_osf.h
 create mode 100644 net/netfilter/nf_osf.c

diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h
new file mode 100644
index ..5f2871fcde42
--- /dev/null
+++ b/include/linux/netfilter/nf_osf.h
@@ -0,0 +1,110 @@
+#define NF_MAXGENRELEN 32
+
+#define NF_OSF_TTL  (1<<1)
+#define NF_OSF_LOG  (1<<2)
+
+#define NF_OSF_LOGLEVEL_ALL 0   /* log all matched fingerprints */
+#define NF_OSF_LOGLEVEL_FIRST   1   /* log only the first matced fingerprint */
+#define NF_OSF_LOGLEVEL_ALL_KNOWN   2 /* do not log unknown packets */
+
+#define NF_OSF_TTL_TRUE 0   /* True ip and fingerprint TTL comparison */
+#define NF_OSF_TTL_NOCHECK  2   /* Do not compare ip and fingerprint TTL at all */
+
+/*
+ * Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct xt_osf_wc {
+__u32   wc;
+__u32   val;
+};
+
+/*
+ * This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct xt_osf_opt {
+__u16   kind, length;
+struct xt_osf_wcwc;
+};
+
+struct xt_osf_info {
+chargenre[NF_MAXGENRELEN];
+__u32   len;
+__u32   flags;
+__u32   loglevel;
+__u32   ttl;
+};
+
+struct xt_osf_user_finger {
+struct xt_osf_wcwss;
+
+__u8ttl, df;
+__u16   ss, mss;
+__u16   opt_num;
+
+chargenre[NF_MAXGENRELEN];
+charversion[NF_MAXGENRELEN];
+charsubtype[NF_MAXGENRELEN];
+
+/* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+struct xt_osf_opt   opt[MAX_IPOPTLEN];
+};
+
+struct xt_osf_finger {
+struct rcu_head rcu_head;
+struct list_headfinger_entry;
+struct xt_osf_user_finger   finger;
+};
+
+struct xt_osf_nlmsg {
+	struct xt_osf_user_finger	f;
+	struct iphdr		ip;
+	struct tcphdr		tcp;
+};
+
+/* Defines for IANA option kinds */
+
+enum iana_options {
+OSFOPT_EOL = 0, /* End of options */
+OSFOPT_NOP, /* NOP */
+OSFOPT_MSS, /* Maximum segment size */
+OSFOPT_WSO, /* Window scale option */
+OSFOPT_SACKP,   /* SACK permitted */
+OSFOPT_SACK,/* SACK */
+OSFOPT_ECHO,
+OSFOPT_ECHOREPLY,
+OSFOPT_TS,  /* Timestamp option */
+OSFOPT_POCP,/* Partial Order Connection Permitted */
+OSFOPT_POSP,/* Partial Order Service Profile */
+
+/* Others are not used in the current OSF */
+OSFOPT_EMPTY = 255,
+};
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum xt_osf_window_size_options {
+OSF_WSS_PLAIN   = 0,
+OSF_WSS_MSS,
+OSF_WSS_MTU,
+OSF_WSS_MODULO,
+OSF_WSS_MAX,
+};
+
+enum osf_fmatch_states {
+/* Packet does not match the fingerprint */
+FMATCH_WRONG = 0,
+/* Packet matches the fingerprint */
+FMATCH_OK,
+/* Options do not match the fingerprint, but header does */
+FMATCH_OPT_WRONG,
+};
+
+bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
+int hooknum, struct net_device *in, struct net_device *out,
+const struct xt_osf_info *info, struct net *net);
diff --git a/include/uapi/linux/netfilter/xt_osf.h b/include/uapi/linux/netfilter/xt_osf.h
index dad197e2ab99..eb71a1c703db 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -23,101 +23,24 @@
 #include 
 #include 
 #include 
+#include 
 
-#define MAXGENREL

[PATCH nf-next] nf_osf implementation: nf_osf_ttl() and nf_osf_match()

2018-03-27 Thread Fernando Fernandez Mancera
Added nf_osf_ttl() and nf_osf_match() into nf_osf.c in order to start
the nftables OSF implementation.

From 26ffd9191052c35726026663d75a1a89c44e5f60 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmanc...@riseup.net>
Date: Sun, 18 Mar 2018 23:54:20 +0100
Subject: [PATCH] nf_osf implementation: nf_osf_ttl() and nf_osf_match()

Added nf_osf_ttl() and nf_osf_match() into nf_osf.c in order to start the
nftables OSF implementation.

Signed-off-by: Fernando Fernandez Mancera <ffmanc...@riseup.net>
---
 include/uapi/linux/netfilter/nf_osf.h | 110 
 include/uapi/linux/netfilter/xt_osf.h |  90 -
 net/netfilter/Kconfig |  13 ++
 net/netfilter/Makefile|   1 +
 net/netfilter/nf_osf.c| 240 ++
 net/netfilter/xt_osf.c| 220 +--
 6 files changed, 367 insertions(+), 307 deletions(-)
 create mode 100644 include/uapi/linux/netfilter/nf_osf.h
 create mode 100644 net/netfilter/nf_osf.c

diff --git a/include/uapi/linux/netfilter/nf_osf.h b/include/uapi/linux/netfilter/nf_osf.h
new file mode 100644
index ..76016b0066f5
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -0,0 +1,110 @@
+#define MAXGENRELEN 32
+
+#define XT_OSF_TTL  (1<<1)
+#define XT_OSF_LOG  (1<<2)
+
+#define XT_OSF_LOGLEVEL_ALL 0   /* log all matched fingerprints */
+#define XT_OSF_LOGLEVEL_FIRST   1   /* log only the first matced fingerprint */
+#define XT_OSF_LOGLEVEL_ALL_KNOWN   2 /* do not log unknown packets */
+
+#define XT_OSF_TTL_TRUE 0   /* True ip and fingerprint TTL comparison */
+#define XT_OSF_TTL_NOCHECK  2   /* Do not compare ip and fingerprint TTL at all */
+
+/*
+ * Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct xt_osf_wc {
+__u32   wc;
+__u32   val;
+};
+
+/*
+ * This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct xt_osf_opt {
+__u16   kind, length;
+struct xt_osf_wcwc;
+};
+
+struct xt_osf_info {
+chargenre[MAXGENRELEN];
+__u32   len;
+__u32   flags;
+__u32   loglevel;
+__u32   ttl;
+};
+
+struct xt_osf_user_finger {
+struct xt_osf_wcwss;
+
+__u8ttl, df;
+__u16   ss, mss;
+__u16   opt_num;
+
+chargenre[MAXGENRELEN];
+charversion[MAXGENRELEN];
+charsubtype[MAXGENRELEN];
+
+/* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+struct xt_osf_opt   opt[MAX_IPOPTLEN];
+};
+
+struct xt_osf_finger {
+struct rcu_head rcu_head;
+struct list_headfinger_entry;
+struct xt_osf_user_finger   finger;
+};
+
+struct xt_osf_nlmsg {
+	struct xt_osf_user_finger	f;
+	struct iphdr		ip;
+	struct tcphdr		tcp;
+};
+
+/* Defines for IANA option kinds */
+
+enum iana_options {
+OSFOPT_EOL = 0, /* End of options */
+OSFOPT_NOP, /* NOP */
+OSFOPT_MSS, /* Maximum segment size */
+OSFOPT_WSO, /* Window scale option */
+OSFOPT_SACKP,   /* SACK permitted */
+OSFOPT_SACK,/* SACK */
+OSFOPT_ECHO,
+OSFOPT_ECHOREPLY,
+OSFOPT_TS,  /* Timestamp option */
+OSFOPT_POCP,/* Partial Order Connection Permitted */
+OSFOPT_POSP,/* Partial Order Service Profile */
+
+/* Others are not used in the current OSF */
+OSFOPT_EMPTY = 255,
+};
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum xt_osf_window_size_options {
+OSF_WSS_PLAIN   = 0,
+OSF_WSS_MSS,
+OSF_WSS_MTU,
+OSF_WSS_MODULO,
+OSF_WSS_MAX,
+};
+
+enum osf_fmatch_states {
+/* Packet does not match the fingerprint */
+FMATCH_WRONG = 0,
+/* Packet matches the fingerprint */
+FMATCH_OK,
+/* Options do not match the fingerprint, but header does */
+FMATCH_OPT_WRONG,
+};
+
+bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
+int hooknum, struct net_device *in, struct net_device *out,
+const struct xt_osf_info *info, struct net *net);
diff --git a/include/uapi/linux/netfilter/xt_osf.h b/include/uapi/linux/netfilter/xt_osf.h
index dad197e2ab99..262ad1607bcf 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfi