diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-07-06 16:38:18 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-07-06 16:47:28 +0200 |
commit | cdc8e6f7e27dcd552d820ce97871b6486d0fea0c (patch) | |
tree | 0d99430f56aa2b781289818343afe30303c4ad3f /src/datatype.c | |
parent | da015ff415f021294aed8668ddf212acb279cd68 (diff) |
datatype: fix table listing if name resolution is not available
nft list table filter returns garbage here for IP and IPv6 addresses if
no name resolution is available. The output looks good if `-n' is used
in that case.
The problem is that getnameinfo() returns:
EAI_AGAIN -3 /* Temporary failure in name resolution. */
Without working name resolution. To fix this, force a fall back to
numeric resolution in that case.
While at it, fix also possible resolution of services in case of
that /etc/services is missing in the system.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/datatype.c')
-rw-r--r-- | src/datatype.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/src/datatype.c b/src/datatype.c index ca6c92f5..62539957 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -329,10 +329,16 @@ static void ipaddr_type_print(const struct expr *expr) { struct sockaddr_in sin = { .sin_family = AF_INET, }; char buf[NI_MAXHOST]; + int err; sin.sin_addr.s_addr = mpz_get_be32(expr->value); - getnameinfo((struct sockaddr *)&sin, sizeof(sin), buf, sizeof(buf), - NULL, 0, numeric_output ? NI_NUMERICHOST : 0); + err = getnameinfo((struct sockaddr *)&sin, sizeof(sin), buf, + sizeof(buf), NULL, 0, + numeric_output ? NI_NUMERICHOST : 0); + if (err != 0) { + getnameinfo((struct sockaddr *)&sin, sizeof(sin), buf, + sizeof(buf), NULL, 0, NI_NUMERICHOST); + } printf("%s", buf); } @@ -378,12 +384,18 @@ static void ip6addr_type_print(const struct expr *expr) { struct sockaddr_in6 sin6 = { .sin6_family = AF_INET6 }; char buf[NI_MAXHOST]; + int err; mpz_export_data(&sin6.sin6_addr, expr->value, BYTEORDER_BIG_ENDIAN, sizeof(sin6.sin6_addr)); - getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), buf, sizeof(buf), - NULL, 0, numeric_output ? NI_NUMERICHOST : 0); + err = getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), buf, + sizeof(buf), NULL, 0, + numeric_output ? NI_NUMERICHOST : 0); + if (err != 0) { + getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), buf, + sizeof(buf), NULL, 0, NI_NUMERICHOST); + } printf("%s", buf); } @@ -468,11 +480,16 @@ static void inet_service_type_print(const struct expr *expr) { struct sockaddr_in sin = { .sin_family = AF_INET }; char buf[NI_MAXSERV]; + int err; sin.sin_port = mpz_get_be16(expr->value); - getnameinfo((struct sockaddr *)&sin, sizeof(sin), NULL, 0, - buf, sizeof(buf), - numeric_output < NUMERIC_ALL ? 0 : NI_NUMERICSERV); + err = getnameinfo((struct sockaddr *)&sin, sizeof(sin), NULL, 0, + buf, sizeof(buf), + numeric_output < NUMERIC_ALL ? 0 : NI_NUMERICSERV); + if (err != 0) { + getnameinfo((struct sockaddr *)&sin, sizeof(sin), NULL, + 0, buf, sizeof(buf), NI_NUMERICSERV); + } printf("%s", buf); } |