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. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- v4: add nft_output_reversedns() and nft_output_service(). Refer to /etc/services in documentation and use them. Rename to --service as all options are in single form. doc/libnftables.adoc | 34 ++++++++++++++++++++++------------ doc/nft.txt | 17 +++++++++-------- include/nftables.h | 12 +++++++++++- include/nftables/libnftables.h | 17 +++++++++-------- src/datatype.c | 6 +++--- src/json.c | 2 +- src/libnftables.c | 8 ++++---- src/main.c | 30 ++++++++++-------------------- 8 files changed, 69 insertions(+), 57 deletions(-) diff --git a/doc/libnftables.adoc b/doc/libnftables.adoc index 0387652fa3c1..1c6ea0152d13 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:: + Perform 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 2a76a6cc63c4..1735a3577beb 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. +*-S*:: +*--service*:: + Translate ports to service names as defined by /etc/services. + +*-N*:: +*--reversedns*:: + Translate IP address to names via reverse DNS lookup. This may slow down + your listing since it generates network traffic. *-c*:: *--check*:: diff --git a/include/nftables.h b/include/nftables.h index 1009e266752f..86b44f17d6e2 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 dee099f279c1..321441b03ca8 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 50af3df04f74..48eaca277757 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/json.c b/src/json.c index f08a3b643c40..5ddf6ef4da3a 100644 --- a/src/json.c +++ b/src/json.c @@ -976,7 +976,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 2f67bb341aef..06d7c177cde3 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 792136f527d9..f7dd818f0789 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", @@ -178,7 +178,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 +230,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 +278,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(" "); -- 2.11.0