]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
json: Fix osf ttl support
authorPhil Sutter <phil@nwl.cc>
Wed, 24 Oct 2018 10:35:03 +0000 (12:35 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 24 Oct 2018 10:55:13 +0000 (12:55 +0200)
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 <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
doc/libnftables-json.adoc
src/json.c
src/parser_json.c
tests/py/inet/osf.t.json

index 98303b357f10c267ebea11d1a7f49da58e28e9a2..ea5fbe818302f4cb709023d8cc0fab3e6d172d0c 100644 (file)
@@ -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.
index cea9f19cd99829f5639e9bea87ea688a2de2cfa0..d21536afd714e774d0e8bee0f3e35b75433ef8e9 100644 (file)
@@ -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)
index fc0dc9a9e40468f797bb2b68ba7e6353b6a6ffb9..46a02fe14de030c87221a5d0d4cad4380106a9af 100644 (file)
@@ -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", &key))
+       if (json_unpack_err(ctx, root, "{s:s}", "key", &key))
                return NULL;
 
+       if (!json_unpack(root, "{s:s}", "ttl", &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;
index 45335cab30c0b0765d5d2844072617ff64f8f496..452f3023585b3f53632896270e5d5e3c5eca1fa0 100644 (file)
@@ -4,7 +4,6 @@
         "match": {
             "left": {
                 "osf": {
-                    "ttl": 0,
                     "key": "name"
                 }
             },
     }
 ]
 
+# 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"
                 }
             },
@@ -60,7 +90,6 @@
                     },
                     "key": {
                         "osf": {
-                            "ttl": 0,
                             "key": "name"
                         }
                     }