]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: Revert --literal, add -S/--service
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 24 Oct 2018 15:37:47 +0000 (17:37 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 29 Oct 2018 14:07:34 +0000 (15:07 +0100)
This is a partial revert of b0f6a45b25dd1 ("src: add --literal option")
which was added during the development cycle before 0.9.1 is released.

After looking at patch: https://patchwork.ozlabs.org/patch/969864/ that
allows to print priority, uid, gid and protocols as numerics, I decided
to revisit this to provide individual options to turn on literal
printing.

What I'm proposing is to provide a good default for everyone, and
provide options to turn on literal/numeric printing.

This patch adds nft_ctx_output_{set,get}_flags() and define two flags to
enable reverse DNS lookups and to print ports as service names.

This patch introduces -S/--services, to print service names as per
/etc/services.

Acked-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
doc/libnftables.adoc
doc/nft.txt
include/nftables.h
include/nftables/libnftables.h
src/datatype.c
src/expression.c
src/json.c
src/libnftables.c
src/main.c

index 0387652fa3c151c3697bb00118a73496f03558b9..9655834f6d8710b06b369d10274d0e6cda16132b 100644 (file)
@@ -18,6 +18,9 @@ void nft_ctx_free(struct nft_ctx* '\*ctx'*);
 bool nft_ctx_get_dry_run(struct nft_ctx* '\*ctx'*);
 void nft_ctx_set_dry_run(struct nft_ctx* '\*ctx'*, bool* 'dry'*);
 
+unsigned int nft_ctx_output_get_flags(struct nft_ctx* '\*ctx'*);
+void nft_ctx_output_set_flags(struct nft_ctx* '\*ctx'*, unsigned int* 'flags'*);
+
 enum nft_numeric_level nft_ctx_output_get_numeric(struct nft_ctx* '\*ctx'*);
 void nft_ctx_output_set_numeric(struct nft_ctx* '\*ctx'*,
                                enum nft_numeric_level* 'level'*);
@@ -25,9 +28,6 @@ void nft_ctx_output_set_numeric(struct nft_ctx* '\*ctx'*,
 bool nft_ctx_output_get_stateless(struct nft_ctx* '\*ctx'*);
 void nft_ctx_output_set_stateless(struct nft_ctx* '\*ctx'*, bool* 'val'*);
 
-enum nft_literal_level nft_ctx_output_get_literal(struct nft_ctx* '\*ctx'*);
-void nft_ctx_output_set_literal(struct nft_ctx* '\*ctx'*, bool* 'val'*);
-
 unsigned int nft_ctx_output_get_debug(struct nft_ctx* '\*ctx'*);
 void nft_ctx_output_set_debug(struct nft_ctx* '\*ctx'*, unsigned int* 'mask'*);
 
@@ -91,6 +91,25 @@ The *nft_ctx_get_dry_run*() function returns the dry-run setting's value contain
 
 The *nft_ctx_set_dry_run*() function sets the dry-run setting in 'ctx' to the value of 'dry'.
 
+=== nft_ctx_output_get_flags() and nft_ctx_output_set_flags()
+The flags setting controls the output format.
+
+----
+enum {
+        NFT_CTX_OUTPUT_REVERSEDNS  = (1 << 0),
+        NFT_CTX_OUTPUT_SERVICE     = (1 << 1),
+};
+----
+
+NFT_CTX_OUTPUT_REVERSEDNS::
+       Reverse DNS lookups are performed for IP addresses when printing. Note that this may add significant delay to *list* commands depending on DNS resolver speed.
+NFT_CTX_OUTPUT_SERVICE::
+       Print port numbers as services as described in the /etc/services file.
+
+The *nft_ctx_output_get_flags*() function returns the output flags setting's value in 'ctx'.
+
+The *nft_ctx_output_set_flags*() function sets the output flags setting in 'ctx' to the value of 'val'.
+
 === nft_ctx_output_get_numeric() and nft_ctx_output_set_numeric()
 These functions allow control over value representation in library output.
 For instance, port numbers by default are printed by their name (as listed in '/etc/services' file), if known.
@@ -133,15 +152,6 @@ The *nft_ctx_output_get_stateless*() function returns the stateless output setti
 
 The *nft_ctx_output_set_stateless*() function sets the stateless output setting in 'ctx' to the value of 'val'.
 
-=== nft_ctx_output_get_literal() and nft_ctx_output_set_literal()
-The literal setting controls whether reverse DNS lookups are performed for IP addresses when printing them.
-Note that this may add significant delay to *list* commands depending on DNS resolver speed.
-The default setting is *NFT_LITERAL_NONE*.
-
-The *nft_ctx_output_get_literal*() function returns the literal output setting's value in 'ctx'.
-
-The *nft_ctx_output_set_literal*() function sets the literal output setting in 'ctx' to the value of 'val'.
-
 === nft_ctx_output_get_debug() and nft_ctx_output_set_debug()
 Libnftables supports separate debugging of different parts of its internals.
 To facilitate this, debugging output is controlled via a bit mask.
index 2a76a6cc63c4e9d73d58496560fd85d972064b83..711d8a4f56b99a66287777b97b992903aa7a2e52 100644 (file)
@@ -9,7 +9,7 @@ nft - Administration tool of the nftables framework for packet filtering and cla
 SYNOPSIS
 --------
 [verse]
-*nft* [ *-nNscae* ] [ *-I* 'directory' ] [ *-f* 'filename' | *-i* | 'cmd' ...]
+*nft* [ *-nNscaeS* ] [ *-I* 'directory' ] [ *-f* 'filename' | *-i* | 'cmd' ...]
 *nft* *-h*
 *nft* *-v*
 
@@ -43,13 +43,14 @@ For a full summary of options, run *nft --help*.
 *--stateless*::
        Omit stateful information of rules and stateful objects.
 
-*-l*::
-*--literal*::
-       Translate numeric to literal. When used once (the default
-       behaviour), print services (instead of numerical port numbers). Use
-       twice to perform the IP address to name lookup, this usually
-       requires network traffic for DNS lookup that slows down the
-       ruleset listing.
+*-N*::
+*--reversedns*::
+       Translate IP address to names via reverse DNS lookup. This may slow down
+       your listing since it generates network traffic.
+
+*-S*::
+*--service*::
+       Translate ports to service names as defined by /etc/services.
 
 *-c*::
 *--check*::
index 1009e266752fd5bd9678c0bbcdcba935af8153a0..86b44f17d6e2f34a483ca2a2bc606acc10beb2e0 100644 (file)
@@ -16,9 +16,9 @@ struct cookie {
 };
 
 struct output_ctx {
+       unsigned int flags;
        unsigned int numeric;
        unsigned int stateless;
-       unsigned int literal;
        unsigned int handle;
        unsigned int echo;
        unsigned int json;
@@ -32,6 +32,16 @@ struct output_ctx {
        };
 };
 
+static inline bool nft_output_reversedns(const struct output_ctx *octx)
+{
+       return octx->flags & NFT_CTX_OUTPUT_REVERSEDNS;
+}
+
+static inline bool nft_output_service(const struct output_ctx *octx)
+{
+       return octx->flags & NFT_CTX_OUTPUT_SERVICE;
+}
+
 struct nft_cache {
        uint16_t                genid;
        struct list_head        list;
index dee099f279c10a66f74ff033fc81311612c287d5..321441b03ca84fc01b00e75a4394e1f1929717e1 100644 (file)
@@ -33,12 +33,6 @@ enum nft_numeric_level {
        NFT_NUMERIC_ALL,
 };
 
-enum nft_literal_level {
-       NFT_LITERAL_NONE,
-       NFT_LITERAL_PORT,
-       NFT_LITERAL_ADDR,
-};
-
 /**
  * Possible flags to pass to nft_ctx_new()
  */
@@ -49,12 +43,19 @@ void nft_ctx_free(struct nft_ctx *ctx);
 
 bool nft_ctx_get_dry_run(struct nft_ctx *ctx);
 void nft_ctx_set_dry_run(struct nft_ctx *ctx, bool dry);
+
+enum {
+       NFT_CTX_OUTPUT_REVERSEDNS       = (1 << 0),
+       NFT_CTX_OUTPUT_SERVICE          = (1 << 1),
+};
+
+unsigned int nft_ctx_output_get_flags(struct nft_ctx *ctx);
+void nft_ctx_output_set_flags(struct nft_ctx *ctx, unsigned int flags);
+
 enum nft_numeric_level nft_ctx_output_get_numeric(struct nft_ctx *ctx);
 void nft_ctx_output_set_numeric(struct nft_ctx *ctx, enum nft_numeric_level level);
 bool nft_ctx_output_get_stateless(struct nft_ctx *ctx);
 void nft_ctx_output_set_stateless(struct nft_ctx *ctx, bool val);
-enum nft_literal_level nft_ctx_output_get_literal(struct nft_ctx *ctx);
-void nft_ctx_output_set_literal(struct nft_ctx *ctx, enum nft_literal_level val);
 unsigned int nft_ctx_output_get_debug(struct nft_ctx *ctx);
 void nft_ctx_output_set_debug(struct nft_ctx *ctx, unsigned int mask);
 bool nft_ctx_output_get_handle(struct nft_ctx *ctx);
index 50af3df04f744ffb4f457ad956bc932516e45477..48eaca2777573c94f5359b868d1f0c78c332f90a 100644 (file)
@@ -454,7 +454,7 @@ static void ipaddr_type_print(const struct expr *expr, struct output_ctx *octx)
        sin.sin_addr.s_addr = mpz_get_be32(expr->value);
        err = getnameinfo((struct sockaddr *)&sin, sizeof(sin), buf,
                          sizeof(buf), NULL, 0,
-                         octx->literal >= NFT_LITERAL_ADDR ? 0 : NI_NUMERICHOST);
+                         nft_output_reversedns(octx) ? 0 : NI_NUMERICHOST);
        if (err != 0) {
                getnameinfo((struct sockaddr *)&sin, sizeof(sin), buf,
                            sizeof(buf), NULL, 0, NI_NUMERICHOST);
@@ -512,7 +512,7 @@ static void ip6addr_type_print(const struct expr *expr, struct output_ctx *octx)
 
        err = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), buf,
                          sizeof(buf), NULL, 0,
-                         octx->literal >= NFT_LITERAL_ADDR ? 0 : NI_NUMERICHOST);
+                         nft_output_reversedns(octx) ? 0 : NI_NUMERICHOST);
        if (err != 0) {
                getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), buf,
                            sizeof(buf), NULL, 0, NI_NUMERICHOST);
@@ -648,7 +648,7 @@ static void inet_service_print(const struct expr *expr, struct output_ctx *octx)
 
 void inet_service_type_print(const struct expr *expr, struct output_ctx *octx)
 {
-       if (octx->literal >= NFT_LITERAL_PORT) {
+       if (nft_output_service(octx)) {
                inet_service_print(expr, octx);
                return;
        }
index 0bd5112287e7db9422d5047362f3a9b99f6fb029..d1d6bee4ff1a0a6904a9ad0b955756a4c6e3e325 100644 (file)
@@ -660,11 +660,13 @@ void relational_expr_pctx_update(struct proto_ctx *ctx,
 
 static void range_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
-       octx->numeric += NFT_NUMERIC_ALL + 1;
+       unsigned int flags = octx->flags;
+
+       octx->flags &= ~NFT_CTX_OUTPUT_SERVICE;
        expr_print(expr->left, octx);
        nft_print(octx, "-");
        expr_print(expr->right, octx);
-       octx->numeric -= NFT_NUMERIC_ALL + 1;
+       octx->flags = flags;
 }
 
 static void range_expr_clone(struct expr *new, const struct expr *expr)
index f08a3b643c40215ad4127256d1f34012bc1df93a..5c426ce776ec55b83ad7aaed44574fb8732d2e90 100644 (file)
@@ -444,13 +444,14 @@ json_t *relational_expr_json(const struct expr *expr, struct output_ctx *octx)
 
 json_t *range_expr_json(const struct expr *expr, struct output_ctx *octx)
 {
+       unsigned int flags = octx->flags;
        json_t *root;
 
-       octx->numeric += NFT_NUMERIC_ALL + 1;
+       octx->flags &= ~NFT_CTX_OUTPUT_SERVICE;
        root = json_pack("{s:[o, o]}", "range",
                         expr_print_json(expr->left, octx),
                         expr_print_json(expr->right, octx));
-       octx->numeric -= NFT_NUMERIC_ALL + 1;
+       octx->flags = flags;
 
        return root;
 }
@@ -976,7 +977,7 @@ json_t *inet_service_type_json(const struct expr *expr, struct output_ctx *octx)
        };
        char buf[NI_MAXSERV];
 
-       if (octx->literal < NFT_LITERAL_PORT ||
+       if (!nft_output_service(octx) ||
            getnameinfo((struct sockaddr *)&sin, sizeof(sin),
                        NULL, 0, buf, sizeof(buf), 0))
                return json_integer(ntohs(sin.sin_port));
index 2f67bb341aef601b31cb8c3bf8915f702cc17dc3..06d7c177cde3bbfe33520baffc090f5200e98e73 100644 (file)
@@ -333,14 +333,14 @@ void nft_ctx_output_set_stateless(struct nft_ctx *ctx, bool val)
        ctx->output.stateless = val;
 }
 
-enum nft_literal_level nft_ctx_output_get_literal(struct nft_ctx *ctx)
+unsigned int nft_ctx_output_get_flags(struct nft_ctx *ctx)
 {
-       return ctx->output.literal;
+       return ctx->output.flags;
 }
 
-void nft_ctx_output_set_literal(struct nft_ctx *ctx, enum nft_literal_level val)
+void nft_ctx_output_set_flags(struct nft_ctx *ctx, unsigned int flags)
 {
-       ctx->output.literal = val;
+       ctx->output.flags = flags;
 }
 
 unsigned int nft_ctx_output_get_debug(struct nft_ctx *ctx)
index 792136f527d94605e187a37cca2087f83da17a8c..86c8fe8854fde5709706ec42159e919c0f1b61ea 100644 (file)
@@ -35,14 +35,14 @@ enum opt_vals {
        OPT_NUMERIC             = 'n',
        OPT_STATELESS           = 's',
        OPT_IP2NAME             = 'N',
-       OPT_LITERAL             = 'l',
+       OPT_SERVICE             = 'S',
        OPT_DEBUG               = 'd',
        OPT_HANDLE_OUTPUT       = 'a',
        OPT_ECHO                = 'e',
        OPT_INVALID             = '?',
 };
 
-#define OPTSTRING      "hvcf:iI:jvnsNael"
+#define OPTSTRING      "hvcf:iI:jvnsNaeS"
 
 static const struct option options[] = {
        {
@@ -79,8 +79,8 @@ static const struct option options[] = {
                .val            = OPT_IP2NAME,
        },
        {
-               .name           = "literal",
-               .val            = OPT_LITERAL,
+               .name           = "service",
+               .val            = OPT_SERVICE,
        },
        {
                .name           = "includepath",
@@ -128,6 +128,7 @@ static void show_help(const char *name)
 "                              Specify three times to also show protocols, user IDs, and group IDs numerically.\n"
 "  -s, --stateless             Omit stateful information of ruleset.\n"
 "  -N                          Translate IP addresses to names.\n"
+"  -S, --service                       Translate ports to service names as described in /etc/services.\n"
 "  -a, --handle                        Output rule handle.\n"
 "  -e, --echo                  Echo what has been added, inserted or replaced.\n"
 "  -I, --includepath <directory>       Add <directory> to the paths searched for include files. Default is: %s\n"
@@ -178,7 +179,7 @@ int main(int argc, char * const *argv)
 {
        char *buf = NULL, *filename = NULL;
        enum nft_numeric_level numeric;
-       enum nft_literal_level literal;
+       unsigned int output_flags = 0;
        bool interactive = false;
        unsigned int debug_mask;
        unsigned int len;
@@ -230,22 +231,10 @@ int main(int argc, char * const *argv)
                        nft_ctx_output_set_stateless(nft, true);
                        break;
                case OPT_IP2NAME:
-                       literal = nft_ctx_output_get_literal(nft);
-                       if (literal + 2 > NFT_LITERAL_ADDR) {
-                               fprintf(stderr, "Cannot combine `-N' with `-l'\n");
-                               exit(EXIT_FAILURE);
-                       }
-                       nft_ctx_output_set_literal(nft, literal + 2);
+                       output_flags |= NFT_CTX_OUTPUT_REVERSEDNS;
                        break;
-               case OPT_LITERAL:
-                       literal = nft_ctx_output_get_literal(nft);
-                       if (literal + 1 > NFT_LITERAL_ADDR) {
-                               fprintf(stderr, "Too many `-l' options or "
-                                               "perhaps you combined `-l' "
-                                               "with `-N'?\n");
-                               exit(EXIT_FAILURE);
-                       }
-                       nft_ctx_output_set_literal(nft, literal + 1);
+               case OPT_SERVICE:
+                       output_flags |= NFT_CTX_OUTPUT_SERVICE;
                        break;
                case OPT_DEBUG:
                        debug_mask = nft_ctx_output_get_debug(nft);
@@ -290,6 +279,8 @@ int main(int argc, char * const *argv)
                }
        }
 
+       nft_ctx_output_set_flags(nft, output_flags);
+
        if (optind != argc) {
                for (len = 0, i = optind; i < argc; i++)
                        len += strlen(argv[i]) + strlen(" ");