From 47b4e499e25f89ff69aeb8bfa0134ff289c676b3 Mon Sep 17 00:00:00 2001 From: Jan Vcelak <jan.vcelak@nic.cz> Date: Tue, 9 Feb 2016 18:26:34 +0100 Subject: [PATCH] sockaddr: add sockaddr_is_any() interface --- Knot.files | 1 + src/contrib/sockaddr.c | 19 +++++++++++++++ src/contrib/sockaddr.h | 8 ++++++- tests/.gitignore | 1 + tests/Makefile.am | 1 + tests/sockaddr.c | 54 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 tests/sockaddr.c diff --git a/Knot.files b/Knot.files index 65b4712014..dd77c651d5 100644 --- a/Knot.files +++ b/Knot.files @@ -526,6 +526,7 @@ tests/rrl.c tests/rrset.c tests/rrset_wire.c tests/server.c +tests/sockaddr.c tests/test_conf.h tests/tsig_key.c tests/wire.c diff --git a/src/contrib/sockaddr.c b/src/contrib/sockaddr.c index a571e0c7a0..f6ecd59af8 100644 --- a/src/contrib/sockaddr.c +++ b/src/contrib/sockaddr.c @@ -240,3 +240,22 @@ char *sockaddr_hostname(void) freeaddrinfo(info); return hname; } + +bool sockaddr_is_any(const struct sockaddr_storage *ss) +{ + if (ss == NULL) { + return false; + } + + if (ss->ss_family == AF_INET) { + const struct sockaddr_in *sa = (struct sockaddr_in *)ss; + return sa->sin_addr.s_addr == INADDR_ANY; + } + + if (ss->ss_family == AF_INET6) { + const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ss; + return memcmp(&sa6->sin6_addr, &in6addr_any, sizeof(sa6->sin6_addr)) == 0; + } + + return false; +} diff --git a/src/contrib/sockaddr.h b/src/contrib/sockaddr.h index 9a2c0ea678..ede9a58382 100644 --- a/src/contrib/sockaddr.h +++ b/src/contrib/sockaddr.h @@ -29,8 +29,9 @@ #define __POSIX_VISIBLE = 200112 #endif -#include <sys/types.h> +#include <stdbool.h> #include <sys/socket.h> +#include <sys/types.h> #include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -132,4 +133,9 @@ void sockaddr_port_set(struct sockaddr_storage *ss, uint16_t port); */ char *sockaddr_hostname(void); +/*! + * \brief Check if address is ANY address. + */ +bool sockaddr_is_any(const struct sockaddr_storage *ss); + /*! @} */ diff --git a/tests/.gitignore b/tests/.gitignore index 3f188dfb72..a45978541b 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -43,6 +43,7 @@ rrl rrset rrset_wire server +sockaddr tsig_key wire wire_ctx diff --git a/tests/Makefile.am b/tests/Makefile.am index df890a1ec1..0147745fe6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -46,6 +46,7 @@ check_PROGRAMS = \ rrset \ rrset_wire \ server \ + sockaddr \ tsig_key \ wire \ wire_ctx \ diff --git a/tests/sockaddr.c b/tests/sockaddr.c new file mode 100644 index 0000000000..665a922567 --- /dev/null +++ b/tests/sockaddr.c @@ -0,0 +1,54 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "contrib/sockaddr.h" + +static void test_sockaddr_is_any(void) +{ + struct sockaddr_storage invalid = { 0 }; + ok(!sockaddr_is_any(&invalid), "sockaddr_is_any: invalid"); + + struct sockaddr_storage path = { 0 }; + path.ss_family = AF_UNIX; + ok(!sockaddr_is_any(&path), "sockaddr_is_any: unix"); + + struct sockaddr_storage ipv4_local = { 0 }; + sockaddr_set(&ipv4_local, AF_INET, "127.0.0.1", 0); + ok(!sockaddr_is_any(&ipv4_local), "sockaddr_is_any: IPv4 local"); + + struct sockaddr_storage ipv4_any = { 0 }; + sockaddr_set(&ipv4_any, AF_INET, "0.0.0.0", 0); + ok(sockaddr_is_any(&ipv4_any), "sockaddr_is_any: IPv4 any"); + + struct sockaddr_storage ipv6_local = { 0 }; + sockaddr_set(&ipv6_local, AF_INET6, "::1", 0); + ok(!sockaddr_is_any(&ipv6_local), "sockaddr_is_any: IPv6 local"); + + struct sockaddr_storage ipv6_any = { 0 }; + sockaddr_set(&ipv6_any, AF_INET6, "::", 0); + ok(sockaddr_is_any(&ipv6_any), "sockaddr_is_any: IPv6 any"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_sockaddr_is_any(); + + return 0; +} -- GitLab