summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-10-24 17:37:47 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2018-10-29 15:07:34 +0100
commita42d2865bc7e96fe63276e22acd523d996aaf0a4 (patch)
treeb0779465bba8cf7562628ae884278fed73963362
parentf27fc14cbd3097e98c4d3549ff93c9284134b866 (diff)
src: Revert --literal, add -S/--service
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>
-rw-r--r--doc/libnftables.adoc34
-rw-r--r--doc/nft.txt17
-rw-r--r--include/nftables.h12
-rw-r--r--include/nftables/libnftables.h17
-rw-r--r--src/datatype.c6
-rw-r--r--src/expression.c6
-rw-r--r--src/json.c7
-rw-r--r--src/libnftables.c8
-rw-r--r--src/main.c31
9 files changed, 77 insertions, 61 deletions
diff --git a/doc/libnftables.adoc b/doc/libnftables.adoc
index 0387652f..9655834f 100644
--- a/doc/libnftables.adoc
+++ b/doc/libnftables.adoc
@@ -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.
diff --git a/doc/nft.txt b/doc/nft.txt
index 2a76a6cc..711d8a4f 100644
--- a/doc/nft.txt
+++ b/doc/nft.txt
@@ -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*::
diff --git a/include/nftables.h b/include/nftables.h
index 1009e266..86b44f17 100644
--- a/include/nftables.h
+++ b/include/nftables.h
@@ -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;
diff --git a/include/nftables/libnftables.h b/include/nftables/libnftables.h
index dee099f2..321441b0 100644
--- a/include/nftables/libnftables.h
+++ b/include/nftables/libnftables.h
@@ -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);
diff --git a/src/datatype.c b/src/datatype.c
index 50af3df0..48eaca27 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -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;
}
diff --git a/src/expression.c b/src/expression.c
index 0bd51122..d1d6bee4 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -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)
diff --git a/src/json.c b/src/json.c
index f08a3b64..5c426ce7 100644
--- a/src/json.c
+++ b/src/json.c
@@ -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));
diff --git a/src/libnftables.c b/src/libnftables.c
index 2f67bb34..06d7c177 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -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)
diff --git a/src/main.c b/src/main.c
index 792136f5..86c8fe88 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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(" ");