aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/tests/net
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/tests/net')
-rw-r--r--lib/libc/tests/net/Makefile43
-rw-r--r--lib/libc/tests/net/Makefile.depend19
-rw-r--r--lib/libc/tests/net/ether_test.c190
-rw-r--r--lib/libc/tests/net/eui64_aton_test.c102
-rw-r--r--lib/libc/tests/net/eui64_ntoa_test.c62
-rw-r--r--lib/libc/tests/net/getaddrinfo/Makefile47
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/basics_v4.exp42
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/basics_v4_only.exp50
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/basics_v4v6.exp50
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/basics_v4v6_prefer_v4.exp50
-rwxr-xr-xlib/libc/tests/net/getaddrinfo/data/generate_testdata.sh45
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/no_host_v4.exp44
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/no_host_v4_only.exp68
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/no_host_v4v6.exp68
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/no_host_v4v6_prefer_v4.exp68
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/no_serv_v4.exp17
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/no_serv_v4_only.exp20
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/no_serv_v4v6.exp20
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/no_serv_v4v6_prefer_v4.exp20
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/scoped.exp5
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/scoped_v4_only.exp5
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/scoped_v4v6_prefer_v4.exp5
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/sock_raw_v4.exp13
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/sock_raw_v4_only.exp15
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/sock_raw_v4v6.exp15
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/sock_raw_v4v6_prefer_v4.exp15
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/spec_fam_v4.exp7
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/spec_fam_v4_only.exp10
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/spec_fam_v4v6.exp10
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/spec_fam_v4v6_prefer_v4.exp10
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/unsup_fam.exp2
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/unsup_fam_v4_only.exp2
-rw-r--r--lib/libc/tests/net/getaddrinfo/data/unsup_fam_v4v6_prefer_v4.exp2
-rw-r--r--lib/libc/tests/net/getaddrinfo/getaddrinfo.c271
-rwxr-xr-xlib/libc/tests/net/getaddrinfo/getaddrinfo_test.sh443
-rw-r--r--lib/libc/tests/net/link_addr_test.cc532
-rw-r--r--lib/libc/tests/net/test-eui64.h53
37 files changed, 2440 insertions, 0 deletions
diff --git a/lib/libc/tests/net/Makefile b/lib/libc/tests/net/Makefile
new file mode 100644
index 000000000000..24cff61e8d24
--- /dev/null
+++ b/lib/libc/tests/net/Makefile
@@ -0,0 +1,43 @@
+PACKAGE= tests
+
+ATF_TESTS_C+= ether_test
+ATF_TESTS_C+= eui64_aton_test
+ATF_TESTS_C+= eui64_ntoa_test
+ATF_TESTS_CXX+= link_addr_test
+
+CXXSTD.link_addr_test= c++20
+
+CFLAGS+= -I${.CURDIR}
+
+NETBSD_ATF_TESTS_C+= getprotoent_test
+NETBSD_ATF_TESTS_C+= ether_aton_test
+
+SRCS.ether_aton_test= aton_ether_subr.c t_ether_aton.c
+
+# TODO: hostent_test
+NETBSD_ATF_TESTS_SH= nsdispatch_test
+NETBSD_ATF_TESTS_SH+= protoent_test
+NETBSD_ATF_TESTS_SH+= servent_test
+
+BINDIR= ${TESTSDIR}
+
+PROGS= h_nsd_recurse
+PROGS+= h_protoent
+PROGS+= h_servent
+PROGS+= h_dns_server
+
+LIBADD.h_nsd_recurse+= pthread
+
+CLEANFILES+= aton_ether_subr.c
+aton_ether_subr.c: gen_ether_subr ${SRCTOP}/sys/net/if_ethersubr.c
+ ${__MAKE_SHELL} ${.ALLSRC} ${.TARGET}
+
+.include "../Makefile.netbsd-tests"
+
+TESTS_SUBDIRS= getaddrinfo
+${PACKAGE}FILES+= hosts
+${PACKAGE}FILES+= resolv.conf
+
+ATF_TESTS_SH_SED_servent_test= -e 's,services.cdb,services.db,g'
+
+.include <bsd.test.mk>
diff --git a/lib/libc/tests/net/Makefile.depend b/lib/libc/tests/net/Makefile.depend
new file mode 100644
index 000000000000..daaf971bd513
--- /dev/null
+++ b/lib/libc/tests/net/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+ gnu/lib/csu \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/atf/libatf-c \
+ lib/libc \
+ lib/libcompiler_rt \
+ lib/libnetbsd \
+ lib/libthr \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libc/tests/net/ether_test.c b/lib/libc/tests/net/ether_test.c
new file mode 100644
index 000000000000..fbeed15efaa7
--- /dev/null
+++ b/lib/libc/tests/net/ether_test.c
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 2007 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+
+#include <net/ethernet.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+static const char *ether_line_string = "01:23:45:67:89:ab ether_line_hostname";
+static const char *ether_line_hostname = "ether_line_hostname";
+static const struct ether_addr ether_line_addr = {
+ { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }
+};
+
+ATF_TC_WITHOUT_HEAD(ether_line);
+ATF_TC_BODY(ether_line, tc)
+{
+ struct ether_addr e;
+ char hostname[256];
+
+ ATF_REQUIRE_MSG(ether_line(ether_line_string, &e, hostname) == 0,
+ "ether_line failed; errno=%d", errno);
+ ATF_REQUIRE_MSG(bcmp(&e, &ether_line_addr, ETHER_ADDR_LEN) == 0,
+ "bad address");
+ ATF_REQUIRE_MSG(strcmp(hostname, ether_line_hostname) == 0,
+ "bad hostname");
+}
+
+static const char *ether_line_bad_1_string = "x";
+
+ATF_TC_WITHOUT_HEAD(ether_line_bad_1);
+ATF_TC_BODY(ether_line_bad_1, tc)
+{
+ struct ether_addr e;
+ char hostname[256];
+
+ ATF_REQUIRE_MSG(ether_line(ether_line_bad_1_string, &e, hostname) != 0,
+ "ether_line succeeded unexpectedly");
+}
+
+static const char *ether_line_bad_2_string = "x x";
+
+ATF_TC_WITHOUT_HEAD(ether_line_bad_2);
+ATF_TC_BODY(ether_line_bad_2, tc)
+{
+ struct ether_addr e;
+ char hostname[256];
+
+ ATF_REQUIRE_MSG(ether_line(ether_line_bad_2_string, &e, hostname) != 0,
+ "ether_line succeeded unexpectedly");
+}
+
+static const char *ether_aton_string = "01:23:45:67:89:ab";
+static const struct ether_addr ether_aton_addr = {
+ { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }
+};
+
+ATF_TC_WITHOUT_HEAD(ether_aton_r);
+ATF_TC_BODY(ether_aton_r, tc)
+{
+ struct ether_addr e, *ep;
+
+ ep = ether_aton_r(ether_aton_string, &e);
+
+ ATF_REQUIRE_MSG(ep != NULL, "ether_aton_r failed; errno=%d", errno);
+ ATF_REQUIRE_MSG(ep == &e,
+ "ether_aton_r returned different pointers; %p != %p", ep, &e);
+}
+
+static const char *ether_aton_bad_string = "x";
+
+ATF_TC_WITHOUT_HEAD(ether_aton_r_bad);
+ATF_TC_BODY(ether_aton_r_bad, tc)
+{
+ struct ether_addr e, *ep;
+
+ ep = ether_aton_r(ether_aton_bad_string, &e);
+ ATF_REQUIRE_MSG(ep == NULL, "ether_aton_r succeeded unexpectedly");
+}
+
+ATF_TC_WITHOUT_HEAD(ether_aton);
+ATF_TC_BODY(ether_aton, tc)
+{
+ struct ether_addr *ep;
+
+ ep = ether_aton(ether_aton_string);
+ ATF_REQUIRE_MSG(ep != NULL, "ether_aton failed");
+ ATF_REQUIRE_MSG(bcmp(ep, &ether_aton_addr, ETHER_ADDR_LEN) == 0,
+ "bad address");
+}
+
+ATF_TC_WITHOUT_HEAD(ether_aton_bad);
+ATF_TC_BODY(ether_aton_bad, tc)
+{
+ struct ether_addr *ep;
+
+ ep = ether_aton(ether_aton_bad_string);
+ ATF_REQUIRE_MSG(ep == NULL, "ether_aton succeeded unexpectedly");
+}
+
+static const char *ether_ntoa_string = "01:23:45:67:89:ab";
+static const struct ether_addr ether_ntoa_addr = {
+ { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }
+};
+
+ATF_TC_WITHOUT_HEAD(ether_ntoa_r);
+ATF_TC_BODY(ether_ntoa_r, tc)
+{
+ char buf[256], *cp;
+
+ cp = ether_ntoa_r(&ether_ntoa_addr, buf);
+ ATF_REQUIRE_MSG(cp != NULL, "ether_ntoa_r failed");
+ ATF_REQUIRE_MSG(cp == buf,
+ "ether_ntoa_r returned a different pointer; %p != %p", cp, buf);
+ ATF_REQUIRE_MSG(strcmp(cp, ether_ntoa_string) == 0,
+ "strings did not match (`%s` != `%s`)", cp, ether_ntoa_string);
+}
+
+ATF_TC_WITHOUT_HEAD(ether_ntoa);
+ATF_TC_BODY(ether_ntoa, tc)
+{
+ char *cp;
+
+ cp = ether_ntoa(&ether_ntoa_addr);
+ ATF_REQUIRE_MSG(cp != NULL, "ether_ntoa failed");
+ ATF_REQUIRE_MSG(strcmp(cp, ether_ntoa_string) == 0,
+ "strings did not match (`%s` != `%s`)", cp, ether_ntoa_string);
+}
+
+#if 0
+ATF_TC_WITHOUT_HEAD(ether_ntohost);
+ATF_TC_BODY(ether_ntohost, tc)
+{
+
+}
+
+ATF_TC_WITHOUT_HEAD(ether_hostton);
+ATF_TC_BODY(ether_hostton, tc)
+{
+
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ether_line);
+ ATF_TP_ADD_TC(tp, ether_line_bad_1);
+ ATF_TP_ADD_TC(tp, ether_line_bad_2);
+ ATF_TP_ADD_TC(tp, ether_aton_r);
+ ATF_TP_ADD_TC(tp, ether_aton_r_bad);
+ ATF_TP_ADD_TC(tp, ether_aton);
+ ATF_TP_ADD_TC(tp, ether_aton_bad);
+ ATF_TP_ADD_TC(tp, ether_ntoa_r);
+ ATF_TP_ADD_TC(tp, ether_ntoa);
+#if 0
+ ATF_TP_ADD_TC(tp, ether_ntohost);
+ ATF_TP_ADD_TC(tp, ether_hostton);
+#endif
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/net/eui64_aton_test.c b/lib/libc/tests/net/eui64_aton_test.c
new file mode 100644
index 000000000000..a4b09695fda9
--- /dev/null
+++ b/lib/libc/tests/net/eui64_aton_test.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2004 The Aerospace Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions, and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of The Aerospace Corporation may not be used to endorse or
+ * promote products derived from this software.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/eui64.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "test-eui64.h"
+
+static void
+test_str(const char *str, const struct eui64 *eui)
+{
+ struct eui64 e;
+ char buf[EUI64_SIZ];
+ int rc;
+
+ ATF_REQUIRE_MSG(eui64_aton(str, &e) == 0, "eui64_aton failed");
+ rc = memcmp(&e, eui, sizeof(e));
+ if (rc != 0) {
+ eui64_ntoa(&e, buf, sizeof(buf));
+ atf_tc_fail(
+ "eui64_aton(\"%s\", ..) failed; memcmp returned %d. "
+ "String obtained form eui64_ntoa was: `%s`",
+ str, rc, buf);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(id_ascii);
+ATF_TC_BODY(id_ascii, tc)
+{
+
+ test_str(test_eui64_id_ascii, &test_eui64_id);
+}
+
+ATF_TC_WITHOUT_HEAD(id_colon_ascii);
+ATF_TC_BODY(id_colon_ascii, tc)
+{
+
+ test_str(test_eui64_id_colon_ascii, &test_eui64_id);
+}
+
+ATF_TC_WITHOUT_HEAD(mac_ascii);
+ATF_TC_BODY(mac_ascii, tc)
+{
+
+ test_str(test_eui64_mac_ascii, &test_eui64_eui48);
+}
+
+ATF_TC_WITHOUT_HEAD(mac_colon_ascii);
+ATF_TC_BODY(mac_colon_ascii, tc)
+{
+
+ test_str(test_eui64_mac_colon_ascii, &test_eui64_eui48);
+}
+
+ATF_TC_WITHOUT_HEAD(hex_ascii);
+ATF_TC_BODY(hex_ascii, tc)
+{
+
+ test_str(test_eui64_hex_ascii, &test_eui64_id);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, id_ascii);
+ ATF_TP_ADD_TC(tp, id_colon_ascii);
+ ATF_TP_ADD_TC(tp, mac_ascii);
+ ATF_TP_ADD_TC(tp, mac_colon_ascii);
+ ATF_TP_ADD_TC(tp, hex_ascii);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/net/eui64_ntoa_test.c b/lib/libc/tests/net/eui64_ntoa_test.c
new file mode 100644
index 000000000000..1da80fc2ea02
--- /dev/null
+++ b/lib/libc/tests/net/eui64_ntoa_test.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2004 The Aerospace Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions, and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of The Aerospace Corporation may not be used to endorse or
+ * promote products derived from this software.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/eui64.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "test-eui64.h"
+
+static void
+test_str(const char *str, const struct eui64 *eui)
+{
+ char a[EUI64_SIZ];
+
+ ATF_REQUIRE_MSG(eui64_ntoa(&test_eui64_id, a, sizeof(a)) == 0,
+ "eui64_ntoa failed");
+ ATF_REQUIRE_MSG(strcmp(a, test_eui64_id_ascii) == 0,
+ "the strings mismatched: `%s` != `%s`", a, test_eui64_id_ascii);
+}
+
+ATF_TC_WITHOUT_HEAD(id_ascii);
+ATF_TC_BODY(id_ascii, tc)
+{
+
+ test_str(test_eui64_id_ascii, &test_eui64_id);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, id_ascii);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/net/getaddrinfo/Makefile b/lib/libc/tests/net/getaddrinfo/Makefile
new file mode 100644
index 000000000000..1299e91615b7
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/Makefile
@@ -0,0 +1,47 @@
+PACKAGE= tests
+
+.include <bsd.own.mk>
+
+BINDIR= ${TESTSDIR}
+
+ATF_TESTS_SH= getaddrinfo_test
+ATF_TESTS_C= getaddrinfo
+
+PROGS= h_gai
+
+FILESGROUPS+= ${PACKAGE}DATA_FILES
+${PACKAGE}DATA_FILESPACKAGE= tests
+
+${PACKAGE}DATA_FILESDIR= ${TESTSDIR}/data
+
+${PACKAGE}DATA_FILES+= data/basics_v4.exp
+${PACKAGE}DATA_FILES+= data/basics_v4_only.exp
+${PACKAGE}DATA_FILES+= data/basics_v4v6.exp
+${PACKAGE}DATA_FILES+= data/basics_v4v6_prefer_v4.exp
+${PACKAGE}DATA_FILES+= data/no_host_v4.exp
+${PACKAGE}DATA_FILES+= data/no_host_v4_only.exp
+${PACKAGE}DATA_FILES+= data/no_host_v4v6.exp
+${PACKAGE}DATA_FILES+= data/no_host_v4v6_prefer_v4.exp
+${PACKAGE}DATA_FILES+= data/no_serv_v4.exp
+${PACKAGE}DATA_FILES+= data/no_serv_v4_only.exp
+${PACKAGE}DATA_FILES+= data/no_serv_v4v6.exp
+${PACKAGE}DATA_FILES+= data/no_serv_v4v6_prefer_v4.exp
+${PACKAGE}DATA_FILES+= data/scoped.exp
+${PACKAGE}DATA_FILES+= data/scoped_v4_only.exp
+${PACKAGE}DATA_FILES+= data/scoped_v4v6_prefer_v4.exp
+${PACKAGE}DATA_FILES+= data/sock_raw_v4.exp
+${PACKAGE}DATA_FILES+= data/sock_raw_v4_only.exp
+${PACKAGE}DATA_FILES+= data/sock_raw_v4v6.exp
+${PACKAGE}DATA_FILES+= data/sock_raw_v4v6_prefer_v4.exp
+${PACKAGE}DATA_FILES+= data/spec_fam_v4.exp
+${PACKAGE}DATA_FILES+= data/spec_fam_v4_only.exp
+${PACKAGE}DATA_FILES+= data/spec_fam_v4v6.exp
+${PACKAGE}DATA_FILES+= data/spec_fam_v4v6_prefer_v4.exp
+${PACKAGE}DATA_FILES+= data/unsup_fam.exp
+${PACKAGE}DATA_FILES+= data/unsup_fam_v4_only.exp
+${PACKAGE}DATA_FILES+= data/unsup_fam_v4v6_prefer_v4.exp
+
+
+.include "../../Makefile.netbsd-tests"
+
+.include <bsd.test.mk>
diff --git a/lib/libc/tests/net/getaddrinfo/data/basics_v4.exp b/lib/libc/tests/net/getaddrinfo/data/basics_v4.exp
new file mode 100644
index 000000000000..4f1ee3517211
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/basics_v4.exp
@@ -0,0 +1,42 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/basics_v4_only.exp b/lib/libc/tests/net/getaddrinfo/data/basics_v4_only.exp
new file mode 100644
index 000000000000..0a37d3212649
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/basics_v4_only.exp
@@ -0,0 +1,50 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+ai4: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai5: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai6: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+ai3: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai4: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+ai4: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai5: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai6: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/basics_v4v6.exp b/lib/libc/tests/net/getaddrinfo/data/basics_v4v6.exp
new file mode 100644
index 000000000000..b74758e93e2e
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/basics_v4v6.exp
@@ -0,0 +1,50 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/basics_v4v6_prefer_v4.exp b/lib/libc/tests/net/getaddrinfo/data/basics_v4v6_prefer_v4.exp
new file mode 100644
index 000000000000..0a37d3212649
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/basics_v4v6_prefer_v4.exp
@@ -0,0 +1,50 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+ai4: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai5: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai6: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+ai3: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai4: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+ai4: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai5: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai6: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/generate_testdata.sh b/lib/libc/tests/net/getaddrinfo/data/generate_testdata.sh
new file mode 100755
index 000000000000..f0425a3b0283
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/generate_testdata.sh
@@ -0,0 +1,45 @@
+#service ip6addrctl prefer_ipv4
+TEST=./h_gai
+family=v4_only
+
+( $TEST ::1 http
+ $TEST 127.0.0.1 http
+ $TEST localhost http
+ $TEST ::1 tftp
+ $TEST 127.0.0.1 tftp
+ $TEST localhost tftp
+ $TEST ::1 echo
+ $TEST 127.0.0.1 echo
+ $TEST localhost echo ) > basics_${family}.exp
+
+( $TEST -4 localhost http
+ $TEST -6 localhost http ) > spec_fam_${family}.exp
+
+( $TEST '' http
+ $TEST '' echo
+ $TEST '' tftp
+ $TEST '' 80
+ $TEST -P '' http
+ $TEST -P '' echo
+ $TEST -P '' tftp
+ $TEST -P '' 80
+ $TEST -S '' 80
+ $TEST -D '' 80 ) > no_host_${family}.exp
+
+( $TEST ::1 ''
+ $TEST 127.0.0.1 ''
+ $TEST localhost ''
+ $TEST '' '' ) > no_serv_${family}.exp
+
+( $TEST -R -p 0 localhost ''
+ $TEST -R -p 59 localhost ''
+ $TEST -R -p 59 localhost 80
+ $TEST -R -p 59 localhost www
+ $TEST -R -p 59 ::1 '' ) > sock_raw_${family}.exp
+
+( $TEST -f 99 localhost '' ) > unsup_fam_${family}.exp
+
+( $TEST fe80::1%lo0 http
+# IF=`ifconfig -a | grep -v '^ ' | sed -e 's/:.*//' | head -1 | awk '{print $1}'`
+# $TEST fe80::1%$IF http
+) > scoped_${family}.exp
diff --git a/lib/libc/tests/net/getaddrinfo/data/no_host_v4.exp b/lib/libc/tests/net/getaddrinfo/data/no_host_v4.exp
new file mode 100644
index 000000000000..7ed41cd9d88a
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/no_host_v4.exp
@@ -0,0 +1,44 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+ai3: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo
+ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo
+ai3: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv echo
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp
+ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+ai3: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/no_host_v4_only.exp b/lib/libc/tests/net/getaddrinfo/data/no_host_v4_only.exp
new file mode 100644
index 000000000000..596799305117
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/no_host_v4_only.exp
@@ -0,0 +1,68 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv http
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv http
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv http
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv echo
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv echo
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv echo
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv echo
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv tftp
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv tftp
+ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp
+ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv http
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv http
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv http
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/no_host_v4v6.exp b/lib/libc/tests/net/getaddrinfo/data/no_host_v4v6.exp
new file mode 100644
index 000000000000..596799305117
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/no_host_v4v6.exp
@@ -0,0 +1,68 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv http
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv http
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv http
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv echo
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv echo
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv echo
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv echo
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv tftp
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv tftp
+ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp
+ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv http
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv http
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv http
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/no_host_v4v6_prefer_v4.exp b/lib/libc/tests/net/getaddrinfo/data/no_host_v4v6_prefer_v4.exp
new file mode 100644
index 000000000000..596799305117
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/no_host_v4v6_prefer_v4.exp
@@ -0,0 +1,68 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv echo
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv http
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv http
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv http
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv echo
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv echo
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv echo
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv echo
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv tftp
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv tftp
+ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp
+ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x3 family 28 socktype 2 protocol 17 addrlen 28 host :: serv http
+ai2: flags 0x3 family 28 socktype 1 protocol 6 addrlen 28 host :: serv http
+ai3: flags 0x3 family 28 socktype 5 protocol 132 addrlen 28 host :: serv http
+ai4: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai5: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+ai6: flags 0x3 family 2 socktype 5 protocol 132 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/no_serv_v4.exp b/lib/libc/tests/net/getaddrinfo/data/no_serv_v4.exp
new file mode 100644
index 000000000000..667234d2161f
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/no_serv_v4.exp
@@ -0,0 +1,17 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty)
+Name does not resolve
diff --git a/lib/libc/tests/net/getaddrinfo/data/no_serv_v4_only.exp b/lib/libc/tests/net/getaddrinfo/data/no_serv_v4_only.exp
new file mode 100644
index 000000000000..0d28490c8d81
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/no_serv_v4_only.exp
@@ -0,0 +1,20 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv 0
+ai4: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai5: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+ai6: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty)
+Name does not resolve
diff --git a/lib/libc/tests/net/getaddrinfo/data/no_serv_v4v6.exp b/lib/libc/tests/net/getaddrinfo/data/no_serv_v4v6.exp
new file mode 100644
index 000000000000..53502547c40e
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/no_serv_v4v6.exp
@@ -0,0 +1,20 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv 0
+ai4: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai5: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+ai6: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty)
+Name does not resolve
diff --git a/lib/libc/tests/net/getaddrinfo/data/no_serv_v4v6_prefer_v4.exp b/lib/libc/tests/net/getaddrinfo/data/no_serv_v4v6_prefer_v4.exp
new file mode 100644
index 000000000000..0d28490c8d81
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/no_serv_v4v6_prefer_v4.exp
@@ -0,0 +1,20 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv 0
+ai4: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai5: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+ai6: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty)
+Name does not resolve
diff --git a/lib/libc/tests/net/getaddrinfo/data/scoped.exp b/lib/libc/tests/net/getaddrinfo/data/scoped.exp
new file mode 100644
index 000000000000..f5ddb4bf6feb
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/scoped.exp
@@ -0,0 +1,5 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host fe80::1%lo0 serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host fe80::1%lo0 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host fe80::1%lo0 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host fe80::1%lo0 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/scoped_v4_only.exp b/lib/libc/tests/net/getaddrinfo/data/scoped_v4_only.exp
new file mode 100644
index 000000000000..f5ddb4bf6feb
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/scoped_v4_only.exp
@@ -0,0 +1,5 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host fe80::1%lo0 serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host fe80::1%lo0 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host fe80::1%lo0 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host fe80::1%lo0 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/scoped_v4v6_prefer_v4.exp b/lib/libc/tests/net/getaddrinfo/data/scoped_v4v6_prefer_v4.exp
new file mode 100644
index 000000000000..f5ddb4bf6feb
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/scoped_v4v6_prefer_v4.exp
@@ -0,0 +1,5 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host fe80::1%lo0 serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host fe80::1%lo0 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host fe80::1%lo0 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host fe80::1%lo0 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4.exp b/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4.exp
new file mode 100644
index 000000000000..021038b81dcc
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4.exp
@@ -0,0 +1,13 @@
+arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80
+Service was not recognized for socket type
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www
+Service was not recognized for socket type
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 28 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4_only.exp b/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4_only.exp
new file mode 100644
index 000000000000..932c1faab0d3
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4_only.exp
@@ -0,0 +1,15 @@
+arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 28 socktype 3 protocol 0 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 28 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80
+Service was not recognized for socket type
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www
+Service was not recognized for socket type
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 28 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4v6.exp b/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4v6.exp
new file mode 100644
index 000000000000..e494271a3d35
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4v6.exp
@@ -0,0 +1,15 @@
+arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 28 socktype 3 protocol 0 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 28 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80
+Service was not recognized for socket type
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www
+Service was not recognized for socket type
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 28 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4v6_prefer_v4.exp b/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4v6_prefer_v4.exp
new file mode 100644
index 000000000000..932c1faab0d3
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/sock_raw_v4v6_prefer_v4.exp
@@ -0,0 +1,15 @@
+arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 28 socktype 3 protocol 0 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 28 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80
+Service was not recognized for socket type
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www
+Service was not recognized for socket type
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 28 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4.exp b/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4.exp
new file mode 100644
index 000000000000..924d2a16f47c
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4.exp
@@ -0,0 +1,7 @@
+arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 28 socktype 0 protocol 0 addrlen 0 host localhost serv http
+Address family for hostname not supported
diff --git a/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4_only.exp b/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4_only.exp
new file mode 100644
index 000000000000..af3506938503
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4_only.exp
@@ -0,0 +1,10 @@
+arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 28 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4v6.exp b/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4v6.exp
new file mode 100644
index 000000000000..af3506938503
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4v6.exp
@@ -0,0 +1,10 @@
+arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 28 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4v6_prefer_v4.exp b/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4v6_prefer_v4.exp
new file mode 100644
index 000000000000..af3506938503
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/spec_fam_v4v6_prefer_v4.exp
@@ -0,0 +1,10 @@
+arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 2 socktype 5 protocol 132 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 28 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 28 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 28 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 28 socktype 5 protocol 132 addrlen 28 host ::1 serv http
+
diff --git a/lib/libc/tests/net/getaddrinfo/data/unsup_fam.exp b/lib/libc/tests/net/getaddrinfo/data/unsup_fam.exp
new file mode 100644
index 000000000000..69e6b48a854b
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/unsup_fam.exp
@@ -0,0 +1,2 @@
+arg: flags 0x2 family 99 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+Address family not recognized
diff --git a/lib/libc/tests/net/getaddrinfo/data/unsup_fam_v4_only.exp b/lib/libc/tests/net/getaddrinfo/data/unsup_fam_v4_only.exp
new file mode 100644
index 000000000000..69e6b48a854b
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/unsup_fam_v4_only.exp
@@ -0,0 +1,2 @@
+arg: flags 0x2 family 99 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+Address family not recognized
diff --git a/lib/libc/tests/net/getaddrinfo/data/unsup_fam_v4v6_prefer_v4.exp b/lib/libc/tests/net/getaddrinfo/data/unsup_fam_v4v6_prefer_v4.exp
new file mode 100644
index 000000000000..69e6b48a854b
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/data/unsup_fam_v4v6_prefer_v4.exp
@@ -0,0 +1,2 @@
+arg: flags 0x2 family 99 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+Address family not recognized
diff --git a/lib/libc/tests/net/getaddrinfo/getaddrinfo.c b/lib/libc/tests/net/getaddrinfo/getaddrinfo.c
new file mode 100644
index 000000000000..1e066add3119
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/getaddrinfo.c
@@ -0,0 +1,271 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Gleb Smirnoff <glebius@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <resolv.h>
+
+#include <atf-c.h>
+
+static const char goodname[] = "www.freebsd.org";
+static const char goodname_dot[] = "www.freebsd.org.";
+static const char badname[] = "does-not-exist.freebsd.org";
+static const char badname_dot[] = "does-not-exist.freebsd.org.";
+static const char ipv6onlyname[] = "beefy15.nyi.freebsd.org";
+static const char ipv6onlyname_dot[] = "beefy15.nyi.freebsd.org.";
+static const char ipv4onlyname[] = "ipv4only.arpa";
+static const char ipv4onlyname_dot[] = "ipv4only.arpa.";
+/*
+ * We need an IP address that doesn't exist, but not reported with ICMP
+ * unreachable by the nearest router. Let's try TEST-NET-3.
+ */
+static char badresolvconf[] = "nameserver 203.0.113.1";
+static char badresolvconf2[] = "nameserver 203.0.113.1\n"
+ "nameserver 203.0.113.2";
+static char *resconf = NULL;
+FILE *
+fopen(const char * restrict path, const char * restrict mode)
+{
+ static FILE *(*orig)(const char *, const char *);
+
+ if (orig == NULL && (orig = dlsym(RTLD_NEXT, "fopen")) == NULL)
+ atf_libc_error(ENOENT, "dlsym(fopen): %s", dlerror());
+ if (resconf != NULL && strcmp(path, _PATH_RESCONF) == 0)
+ return (fmemopen(resconf, strlen(resconf), mode));
+ else
+ return (orig(path, mode));
+}
+
+static int send_error = 0;
+ssize_t
+send(int s, const void *msg, size_t len, int flags)
+{
+ static ssize_t (*orig)(int, const void *, size_t, int);
+
+ if (orig == NULL && (orig = dlsym(RTLD_NEXT, "send")) == NULL)
+ atf_libc_error(ENOENT, "dlsym(send): %s", dlerror());
+ if (send_error != 0) {
+ errno = send_error;
+ return (-1);
+ } else {
+ return (orig(s, msg, len, flags));
+ }
+}
+
+ATF_TC(basic);
+ATF_TC_HEAD(basic, tc)
+{
+ atf_tc_set_md_var(tc, "require.config", "allow_network_access");
+}
+
+ATF_TC_BODY(basic, tc)
+{
+ static const struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_CANONNAME,
+ };
+ struct addrinfo *res;
+ int rv;
+
+ rv = getaddrinfo(goodname, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == 0,
+ "Expected 0, got %d (%s)", rv, gai_strerror(rv));
+ freeaddrinfo(res);
+
+ rv = getaddrinfo(goodname_dot, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == 0,
+ "Expected 0, got %d (%s)", rv, gai_strerror(rv));
+ freeaddrinfo(res);
+
+ rv = getaddrinfo(badname, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_NONAME,
+ "Expected %d (EAI_NONAME), got %d (%s)",
+ EAI_NONAME, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(badname_dot, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_NONAME,
+ "Expected %d (EAI_NONAME), got %d (%s)",
+ EAI_NONAME, rv, gai_strerror(rv));
+}
+
+ATF_TC_WITHOUT_HEAD(timeout);
+ATF_TC_BODY(timeout, tc)
+{
+ static const struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_CANONNAME,
+ };
+ struct addrinfo *res;
+ int rv;
+
+ resconf = badresolvconf;
+ rv = getaddrinfo(goodname, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(goodname_dot, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
+}
+
+ATF_TC_WITHOUT_HEAD(timeout_specific);
+ATF_TC_BODY(timeout_specific, tc)
+{
+ static const struct addrinfo hints = {
+ .ai_family = AF_INET,
+ .ai_socktype = SOCK_STREAM,
+ .ai_flags = AI_CANONNAME,
+ };
+ struct addrinfo *res;
+ int rv;
+
+ resconf = badresolvconf;
+ rv = getaddrinfo(goodname, "666", &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(goodname_dot, "666", &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
+}
+
+ATF_TC_WITHOUT_HEAD(timeout2);
+ATF_TC_BODY(timeout2, tc)
+{
+ static const struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_CANONNAME,
+ };
+ struct addrinfo *res;
+ int rv;
+
+ resconf = badresolvconf2;
+ rv = getaddrinfo(goodname, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(goodname_dot, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
+}
+
+/*
+ * Emulate interface/network down.
+ */
+ATF_TC_WITHOUT_HEAD(netdown);
+ATF_TC_BODY(netdown, tc)
+{
+ static const struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_CANONNAME,
+ };
+ struct addrinfo *res;
+ int rv;
+
+ send_error = ENETDOWN;
+ rv = getaddrinfo(goodname, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(goodname_dot, NULL, &hints, &res);
+ ATF_REQUIRE_MSG(rv == EAI_AGAIN,
+ "Expected %d (EAI_AGAIN), got %d (%s)",
+ EAI_AGAIN, rv, gai_strerror(rv));
+}
+
+/*
+ * See https://reviews.freebsd.org/D37139.
+ */
+ATF_TC(nofamily);
+ATF_TC_HEAD(nofamily, tc)
+{
+ atf_tc_set_md_var(tc, "require.config", "allow_network_access");
+}
+ATF_TC_BODY(nofamily, tc)
+{
+ static const struct addrinfo hints4 = {
+ .ai_family = AF_INET,
+ .ai_flags = AI_CANONNAME,
+ }, hints6 = {
+ .ai_family = AF_INET6,
+ .ai_flags = AI_CANONNAME,
+ };
+ struct addrinfo *res;
+ int rv;
+
+ rv = getaddrinfo(ipv6onlyname, NULL, &hints4, &res);
+ ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
+ "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
+ EAI_ADDRFAMILY, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(ipv6onlyname_dot, NULL, &hints4, &res);
+ ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
+ "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
+ EAI_ADDRFAMILY, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(ipv4onlyname, NULL, &hints6, &res);
+ ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
+ "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
+ EAI_ADDRFAMILY, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(ipv4onlyname_dot, NULL, &hints6, &res);
+ ATF_REQUIRE_MSG(rv == EAI_ADDRFAMILY,
+ "Expected %d (EAI_ADDRFAMILY), got %d (%s)",
+ EAI_ADDRFAMILY, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(badname, NULL, &hints4, &res);
+ ATF_REQUIRE_MSG(rv == EAI_NONAME,
+ "Expected %d (EAI_NONAME), got %d (%s)",
+ EAI_NONAME, rv, gai_strerror(rv));
+
+ rv = getaddrinfo(badname_dot, NULL, &hints6, &res);
+ ATF_REQUIRE_MSG(rv == EAI_NONAME,
+ "Expected %d (EAI_NONAME), got %d (%s)",
+ EAI_NONAME, rv, gai_strerror(rv));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, basic);
+ ATF_TP_ADD_TC(tp, timeout);
+ ATF_TP_ADD_TC(tp, timeout_specific);
+ ATF_TP_ADD_TC(tp, timeout2);
+ ATF_TP_ADD_TC(tp, netdown);
+ ATF_TP_ADD_TC(tp, nofamily);
+
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/net/getaddrinfo/getaddrinfo_test.sh b/lib/libc/tests/net/getaddrinfo/getaddrinfo_test.sh
new file mode 100755
index 000000000000..dd17ab2e3f4a
--- /dev/null
+++ b/lib/libc/tests/net/getaddrinfo/getaddrinfo_test.sh
@@ -0,0 +1,443 @@
+# $NetBSD: t_getaddrinfo.sh,v 1.2 2011/06/15 07:54:32 jmmv Exp $
+
+#
+# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the project nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+if [ "$(sysctl -i -n kern.features.vimage)" != 1 ]; then
+ atf_skip "This test requires VIMAGE"
+fi
+
+vnet_mkjail()
+{
+ jailname=getaddrinfo_test_$1
+ jail -c name=${jailname} persist vnet
+ ifconfig -j ${jailname} lo0 inet 127.0.0.1/8
+ # For those machines not support IPv6
+ ifconfig -j ${jailname} lo0 inet6 ::1/64 || true
+ service -j ${jailname} ip6addrctl $2 || true
+}
+
+vnet_cleanup()
+{
+ jailname=getaddrinfo_test_$1
+ jail -r ${jailname}
+}
+
+check_output()
+{
+ if [ "$2" = "none" ]; then
+ if [ "$3" = "prefer_v6" ]; then
+ exp="${1}.exp"
+ else
+ exp="${1}_v4_only.exp"
+ fi
+ elif [ "$2" = "hosts" ]; then
+ lcl=$(cat /etc/hosts | sed -e 's/#.*$//' -e 's/[ ][ ]*/ /g' | awk '/ localhost($| )/ {printf "%s ", $1}')
+ if [ "${lcl%*::*}" = "${lcl}" ]; then
+ exp="${1}_v4_only.exp"
+ else
+ if [ "$3" = "prefer_v6" ]; then
+ exp="${1}_v4v6.exp"
+ else
+ exp="${1}_v4v6_prefer_v4.exp"
+ fi
+ fi
+ elif [ "$2" = "ifconfig" ]; then
+ lcl=$(ifconfig lo0 | grep inet6)
+ if [ -n "${lcl}" ]; then
+ if [ "$3" = "prefer_v6" ]; then
+ exp="${1}_v4v6.exp"
+ else
+ exp="${1}_v4v6_prefer_v4.exp"
+ fi
+ else
+ exp="${1}_v4_only.exp"
+ fi
+ else
+ atf_fail "Invalid family_match_type $2 requested."
+ fi
+
+ cmp -s "$(atf_get_srcdir)/data/${exp}" out && return
+ diff -u "$(atf_get_srcdir)/data/${exp}" out || atf_fail "Actual output does not match expected output"
+}
+
+atf_test_case basic_prefer_v4 cleanup
+basic_prefer_v4_head()
+{
+ atf_set "descr" "Testing basic ones with prefer_v4"
+ atf_set "require.user" "root"
+}
+basic_prefer_v4_body()
+{
+ vnet_mkjail basic_prefer_v4 prefer_ipv4
+ TEST="jexec getaddrinfo_test_basic_prefer_v4 $(atf_get_srcdir)/h_gai"
+
+ ( $TEST ::1 http
+ $TEST 127.0.0.1 http
+ $TEST localhost http
+ $TEST ::1 tftp
+ $TEST 127.0.0.1 tftp
+ $TEST localhost tftp
+ $TEST ::1 echo
+ $TEST 127.0.0.1 echo
+ $TEST localhost echo ) > out 2>&1
+
+ check_output basics hosts prefer_v4
+}
+basic_prefer_v4_cleanup()
+{
+ vnet_cleanup basic_prefer_v4
+}
+
+atf_test_case basic cleanup
+basic_head()
+{
+ atf_set "descr" "Testing basic ones with prefer_v6"
+ atf_set "require.user" "root"
+}
+basic_body()
+{
+ vnet_mkjail basic prefer_ipv6
+ TEST="jexec getaddrinfo_test_basic $(atf_get_srcdir)/h_gai"
+
+ ( $TEST ::1 http
+ $TEST 127.0.0.1 http
+ $TEST localhost http
+ $TEST ::1 tftp
+ $TEST 127.0.0.1 tftp
+ $TEST localhost tftp
+ $TEST ::1 echo
+ $TEST 127.0.0.1 echo
+ $TEST localhost echo ) > out 2>&1
+
+ check_output basics ifconfig prefer_v6
+}
+basic_cleanup()
+{
+ vnet_cleanup basic
+}
+
+atf_test_case specific_prefer_v4 cleanup
+specific_prefer_v4_head()
+{
+ atf_set "descr" "Testing specific address family with prefer_v4"
+ atf_set "require.user" "root"
+}
+specific_prefer_v4_body()
+{
+ vnet_mkjail specific_prefer_v4 prefer_ipv4
+ TEST="jexec getaddrinfo_test_specific_prefer_v4 $(atf_get_srcdir)/h_gai"
+
+ ( $TEST -4 localhost http
+ $TEST -6 localhost http ) > out 2>&1
+
+ check_output spec_fam hosts prefer_v4
+}
+specific_prefer_v4_cleanup()
+{
+ vnet_cleanup specific_prefer_v4
+}
+
+atf_test_case specific cleanup
+specific_head()
+{
+ atf_set "descr" "Testing specific address family with prefer_v6"
+ atf_set "require.user" "root"
+}
+specific_body()
+{
+ vnet_mkjail specific prefer_ipv6
+ TEST="jexec getaddrinfo_test_specific $(atf_get_srcdir)/h_gai"
+
+ ( $TEST -4 localhost http
+ $TEST -6 localhost http ) > out 2>&1
+
+ check_output spec_fam hosts prefer_v6
+}
+specific_cleanup()
+{
+ vnet_cleanup specific
+}
+
+atf_test_case empty_hostname_prefer_v4 cleanup
+empty_hostname_prefer_v4_head()
+{
+ atf_set "descr" "Testing empty hostname with prefer_v4"
+ atf_set "require.user" "root"
+}
+empty_hostname_prefer_v4_body()
+{
+ vnet_mkjail empty_hostname_prefer_v4 prefer_ipv4
+ TEST="jexec getaddrinfo_test_empty_hostname_prefer_v4 $(atf_get_srcdir)/h_gai"
+
+ ( $TEST '' http
+ $TEST '' echo
+ $TEST '' tftp
+ $TEST '' 80
+ $TEST -P '' http
+ $TEST -P '' echo
+ $TEST -P '' tftp
+ $TEST -P '' 80
+ $TEST -S '' 80
+ $TEST -D '' 80 ) > out 2>&1
+
+ check_output no_host ifconfig prefer_v4
+}
+empty_hostname_prefer_v4_cleanup()
+{
+ vnet_cleanup empty_hostname_prefer_v4
+}
+
+atf_test_case empty_hostname cleanup
+empty_hostname_head()
+{
+ atf_set "descr" "Testing empty hostname with prefer_v6"
+ atf_set "require.user" "root"
+}
+empty_hostname_body()
+{
+ vnet_mkjail empty_hostname prefer_ipv6
+ TEST="jexec getaddrinfo_test_empty_hostname $(atf_get_srcdir)/h_gai"
+
+ ( $TEST '' http
+ $TEST '' echo
+ $TEST '' tftp
+ $TEST '' 80
+ $TEST -P '' http
+ $TEST -P '' echo
+ $TEST -P '' tftp
+ $TEST -P '' 80
+ $TEST -S '' 80
+ $TEST -D '' 80 ) > out 2>&1
+
+ check_output no_host ifconfig prefer_v6
+}
+empty_hostname_cleanup()
+{
+ vnet_cleanup empty_hostname
+}
+
+atf_test_case empty_servname_prefer_v4 cleanup
+empty_servname_prefer_v4_head()
+{
+ atf_set "descr" "Testing empty service name with prefer_v4"
+ atf_set "require.user" "root"
+}
+empty_servname_prefer_v4_body()
+{
+ vnet_mkjail empty_servname_prefer_v4 prefer_ipv4
+ TEST="jexec getaddrinfo_test_empty_servname_prefer_v4 $(atf_get_srcdir)/h_gai"
+
+ ( $TEST ::1 ''
+ $TEST 127.0.0.1 ''
+ $TEST localhost ''
+ $TEST '' '' ) > out 2>&1
+
+ check_output no_serv hosts prefer_v4
+}
+empty_servname_prefer_v4_cleanup()
+{
+ vnet_cleanup empty_servname_prefer_v4
+}
+
+atf_test_case empty_servname cleanup
+empty_servname_head()
+{
+ atf_set "descr" "Testing empty service name with prefer_v6"
+ atf_set "require.user" "root"
+}
+empty_servname_body()
+{
+ vnet_mkjail empty_servname prefer_ipv6
+ TEST="jexec getaddrinfo_test_empty_servname $(atf_get_srcdir)/h_gai"
+
+ ( $TEST ::1 ''
+ $TEST 127.0.0.1 ''
+ $TEST localhost ''
+ $TEST '' '' ) > out 2>&1
+
+ check_output no_serv ifconfig prefer_v6
+}
+empty_servname_cleanup()
+{
+ vnet_cleanup empty_servname
+}
+
+atf_test_case sock_raw_prefer_v4 cleanup
+sock_raw_prefer_v4_head()
+{
+ atf_set "descr" "Testing raw socket with prefer_v4"
+ atf_set "require.user" "root"
+}
+sock_raw_prefer_v4_body()
+{
+ vnet_mkjail sock_raw_prefer_v4 prefer_ipv4
+ TEST="jexec getaddrinfo_test_sock_raw_prefer_v4 $(atf_get_srcdir)/h_gai"
+
+ ( $TEST -R -p 0 localhost ''
+ $TEST -R -p 59 localhost ''
+ $TEST -R -p 59 localhost 80
+ $TEST -R -p 59 localhost www
+ $TEST -R -p 59 ::1 '' ) > out 2>&1
+
+ check_output sock_raw hosts prefer_v4
+}
+sock_raw_prefer_v4_cleanup()
+{
+ vnet_cleanup sock_raw_prefer_v4
+}
+
+atf_test_case sock_raw cleanup
+sock_raw_head()
+{
+ atf_set "descr" "Testing raw socket with prefer_v6"
+ atf_set "require.user" "root"
+}
+sock_raw_body()
+{
+ vnet_mkjail sock_raw prefer_ipv6
+ TEST="jexec getaddrinfo_test_sock_raw $(atf_get_srcdir)/h_gai"
+
+ ( $TEST -R -p 0 localhost ''
+ $TEST -R -p 59 localhost ''
+ $TEST -R -p 59 localhost 80
+ $TEST -R -p 59 localhost www
+ $TEST -R -p 59 ::1 '' ) > out 2>&1
+
+ check_output sock_raw ifconfig prefer_v6
+}
+sock_raw_cleanup()
+{
+ vnet_cleanup sock_raw
+}
+
+atf_test_case unsupported_family_prefer_v4 cleanup
+unsupported_family_prefer_v4_head()
+{
+ atf_set "descr" "Testing unsupported family with prefer_v4"
+ atf_set "require.user" "root"
+}
+unsupported_family_prefer_v4_body()
+{
+ vnet_mkjail unsupported_family_prefer_v4 prefer_ipv4
+ TEST="jexec getaddrinfo_test_unsupported_family_prefer_v4 $(atf_get_srcdir)/h_gai"
+
+ ( $TEST -f 99 localhost '' ) > out 2>&1
+
+ check_output unsup_fam ifconfig prefer_v4
+}
+unsupported_family_prefer_v4_cleanup()
+{
+ vnet_cleanup unsupported_family_prefer_v4
+}
+
+atf_test_case unsupported_family cleanup
+unsupported_family_head()
+{
+ atf_set "descr" "Testing unsupported family with prefer_v6"
+ atf_set "require.user" "root"
+}
+unsupported_family_body()
+{
+ vnet_mkjail unsupported_family prefer_ipv6
+ TEST="jexec getaddrinfo_test_unsupported_family $(atf_get_srcdir)/h_gai"
+
+ ( $TEST -f 99 localhost '' ) > out 2>&1
+
+ check_output unsup_fam none prefer_v6
+}
+unsupported_family_cleanup()
+{
+ vnet_cleanup unsupported_family
+}
+
+atf_test_case scopeaddr_prefer_v4 cleanup
+scopeaddr_prefer_v4_head()
+{
+ atf_set "descr" "Testing scoped address format with prefer_v4"
+ atf_set "require.user" "root"
+}
+scopeaddr_prefer_v4_body()
+{
+ vnet_mkjail scopeaddr_prefer_v4 prefer_ipv4
+ TEST="jexec getaddrinfo_test_scopeaddr_prefer_v4 $(atf_get_srcdir)/h_gai"
+
+ ( $TEST fe80::1%lo0 http
+# IF=ifconfig -a | grep -v '^ ' | sed -e 's/:.*//' | head -1 | awk '{print $1}'
+# $TEST fe80::1%$IF http
+ ) > out 2>&1
+
+ check_output scoped ifconfig prefer_v4
+}
+scopeaddr_prefer_v4_cleanup()
+{
+ vnet_cleanup scopeaddr_prefer_v4
+}
+
+atf_test_case scopeaddr cleanup
+scopeaddr_head()
+{
+ atf_set "descr" "Testing scoped address format with prefer_v6"
+ atf_set "require.user" "root"
+}
+scopeaddr_body()
+{
+ vnet_mkjail scopeaddr prefer_ipv6
+ TEST="jexec getaddrinfo_test_scopeaddr $(atf_get_srcdir)/h_gai"
+
+ ( $TEST fe80::1%lo0 http
+# IF=ifconfig -a | grep -v '^ ' | sed -e 's/:.*//' | head -1 | awk '{print $1}'
+# $TEST fe80::1%$IF http
+ ) > out 2>&1
+
+ check_output scoped none prefer_v6
+}
+scopeaddr_cleanup()
+{
+ vnet_cleanup scopeaddr
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case basic_prefer_v4
+ atf_add_test_case specific_prefer_v4
+ atf_add_test_case empty_hostname_prefer_v4
+ atf_add_test_case empty_servname_prefer_v4
+ atf_add_test_case sock_raw_prefer_v4
+ atf_add_test_case unsupported_family_prefer_v4
+ atf_add_test_case scopeaddr_prefer_v4
+
+ atf_add_test_case basic
+ atf_add_test_case specific
+ atf_add_test_case empty_hostname
+ atf_add_test_case empty_servname
+ atf_add_test_case sock_raw
+ atf_add_test_case unsupported_family
+ atf_add_test_case scopeaddr
+}
diff --git a/lib/libc/tests/net/link_addr_test.cc b/lib/libc/tests/net/link_addr_test.cc
new file mode 100644
index 000000000000..b973b924dc13
--- /dev/null
+++ b/lib/libc/tests/net/link_addr_test.cc
@@ -0,0 +1,532 @@
+/*
+ * Copyright (c) 2025 Lexi Winter
+ *
+ * SPDX-License-Identifier: ISC
+ */
+
+/*
+ * Tests for link_addr() and link_ntoa().
+ *
+ * link_addr converts a string representing an (optionally null) interface name
+ * followed by an Ethernet address into a sockaddr_dl. The expected format is
+ * "[ifname]:lladdr". This means if ifname is not specified, the leading colon
+ * is still required.
+ *
+ * link_ntoa does the inverse of link_addr, returning a string representation
+ * of the address.
+ *
+ * Note that the output format of link_ntoa is not valid input for link_addr
+ * since the leading colon may be omitted. This is by design.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+
+#include <format>
+#include <iostream>
+#include <ranges>
+#include <span>
+#include <utility>
+#include <vector>
+
+#include <cstddef>
+#include <cstdint>
+
+#include <atf-c++.hpp>
+
+using namespace std::literals;
+
+/*
+ * Define operator== and operator<< for ether_addr so we can use them in
+ * ATF_EXPECT_EQ expressions.
+ */
+
+bool
+operator==(ether_addr a, ether_addr b)
+{
+ return (std::ranges::equal(a.octet, b.octet));
+}
+
+std::ostream &
+operator<<(std::ostream &s, ether_addr a)
+{
+ for (unsigned i = 0; i < ETHER_ADDR_LEN; ++i) {
+ if (i > 0)
+ s << ":";
+
+ s << std::format("{:02x}", static_cast<int>(a.octet[i]));
+ }
+
+ return (s);
+}
+
+/*
+ * Create a sockaddr_dl from a string using link_addr(), and ensure the
+ * returned struct looks valid.
+ */
+sockaddr_dl
+make_linkaddr(const std::string &addr)
+{
+ auto sdl = sockaddr_dl{};
+ int ret;
+
+ sdl.sdl_len = sizeof(sdl);
+ ret = ::link_addr(addr.c_str(), &sdl);
+
+ ATF_REQUIRE_EQ(0, ret);
+ ATF_REQUIRE_EQ(AF_LINK, static_cast<int>(sdl.sdl_family));
+ ATF_REQUIRE_EQ(true, sdl.sdl_len > 0);
+ ATF_REQUIRE_EQ(true, sdl.sdl_nlen >= 0);
+
+ return (sdl);
+}
+
+/*
+ * Return the data stored in a sockaddr_dl as a span.
+ */
+std::span<const char>
+data(const sockaddr_dl &sdl)
+{
+ // sdl_len is the entire structure, but we only want the length of the
+ // data area.
+ auto dlen = sdl.sdl_len - offsetof(sockaddr_dl, sdl_data);
+ return {&sdl.sdl_data[0], dlen};
+}
+
+/*
+ * Return the interface name stored in a sockaddr_dl as a string.
+ */
+std::string_view
+ifname(const sockaddr_dl &sdl)
+{
+ auto name = data(sdl).subspan(0, sdl.sdl_nlen);
+ return {name.begin(), name.end()};
+}
+
+/*
+ * Return the Ethernet address stored in a sockaddr_dl as an ether_addr.
+ */
+ether_addr
+addr(const sockaddr_dl &sdl)
+{
+ ether_addr ret{};
+ ATF_REQUIRE_EQ(ETHER_ADDR_LEN, sdl.sdl_alen);
+ std::ranges::copy(data(sdl).subspan(sdl.sdl_nlen, ETHER_ADDR_LEN),
+ &ret.octet[0]);
+ return (ret);
+}
+
+/*
+ * Return the link address stored in a sockaddr_dl as a span of octets.
+ */
+std::span<const std::uint8_t>
+lladdr(const sockaddr_dl &sdl)
+{
+ auto data = reinterpret_cast<const uint8_t *>(LLADDR(&sdl));
+ return {data, data + sdl.sdl_alen};
+}
+
+
+/*
+ * Some sample addresses we use for testing. Include at least one address for
+ * each format we want to support.
+ */
+
+struct test_address {
+ std::string input; /* value passed to link_addr */
+ std::string ntoa; /* expected return from link_ntoa */
+ ether_addr addr{}; /* expected return from link_addr */
+};
+
+std::vector<test_address> test_addresses{
+ // No delimiter
+ {"001122334455"s, "0.11.22.33.44.55",
+ ether_addr{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}},
+
+ // Colon delimiter
+ {"00:11:22:33:44:55"s, "0.11.22.33.44.55",
+ ether_addr{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}},
+
+ // Dash delimiter
+ {"00-11-22-33-44-55"s, "0.11.22.33.44.55",
+ ether_addr{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}},
+
+ // Period delimiter (link_ntoa format)
+ {"00.11.22.33.44.55"s, "0.11.22.33.44.55",
+ ether_addr{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}},
+
+ // Period delimiter (Cisco format)
+ {"0011.2233.4455"s, "0.11.22.33.44.55",
+ ether_addr{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}},
+
+ // An addresses without leading zeroes.
+ {"0:1:02:30:4:55"s, "0.1.2.30.4.55",
+ ether_addr{0x00, 0x01, 0x02, 0x30, 0x04, 0x55}},
+
+ // An address with some uppercase letters.
+ {"AA:B:cC:Dd:e0:1f"s, "aa.b.cc.dd.e0.1f",
+ ether_addr{0xaa, 0x0b, 0xcc, 0xdd, 0xe0, 0x1f}},
+
+ // Addresses composed only of letters, to make sure they're not
+ // confused with an interface name.
+
+ {"aabbccddeeff"s, "aa.bb.cc.dd.ee.ff",
+ ether_addr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+
+ {"aa:bb:cc:dd:ee:ff"s, "aa.bb.cc.dd.ee.ff",
+ ether_addr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+
+ // Address with a blank octet; this is an old form of Ethernet address.
+ {"00:11::33:44:55"s, "0.11.0.33.44.55",
+ ether_addr{0x00, 0x11, 0x00, 0x33, 0x44, 0x55}},
+};
+
+/*
+ * Test without an interface name.
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(basic)
+ATF_TEST_CASE_BODY(basic)
+{
+ for (const auto &ta : test_addresses) {
+ // This does basic tests on the returned value.
+ auto sdl = make_linkaddr(":" + ta.input);
+
+ // Check the ifname and address.
+ ATF_REQUIRE_EQ(""s, ifname(sdl));
+ ATF_REQUIRE_EQ(ETHER_ADDR_LEN, static_cast<int>(sdl.sdl_alen));
+ ATF_REQUIRE_EQ(ta.addr, addr(sdl));
+
+ // Check link_ntoa returns the expected value.
+ auto ntoa = std::string(::link_ntoa(&sdl));
+ ATF_REQUIRE_EQ(ta.ntoa, ntoa);
+ }
+
+}
+
+/*
+ * Test with an interface name.
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(ifname)
+ATF_TEST_CASE_BODY(ifname)
+{
+ for (const auto &ta : test_addresses) {
+ auto sdl = make_linkaddr("ix0:" + ta.input);
+
+ ATF_REQUIRE_EQ("ix0", ifname(sdl));
+ ATF_REQUIRE_EQ(ETHER_ADDR_LEN, static_cast<int>(sdl.sdl_alen));
+ ATF_REQUIRE_EQ(ta.addr, addr(sdl));
+
+ auto ntoa = std::string(::link_ntoa(&sdl));
+ ATF_REQUIRE_EQ("ix0:" + ta.ntoa, ntoa);
+ }
+
+}
+
+/*
+ * Test with some invalid addresses.
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(invalid)
+ATF_TEST_CASE_BODY(invalid)
+{
+ auto const invalid_addresses = std::vector{
+ // Invalid separator
+ ":1/2/3"s,
+ "ix0:1/2/3"s,
+
+ // Multiple different separators
+ ":1.2-3"s,
+ "ix0:1.2-3"s,
+
+ // An IP address
+ ":10.1.2.200/28"s,
+ "ix0:10.1.2.200/28"s,
+
+ // Valid address followed by garbage
+ ":1.2.3xxx"s,
+ ":1.2.3.xxx"s,
+ "ix0:1.2.3xxx"s,
+ "ix0:1.2.3.xxx"s,
+ };
+
+ for (auto const &addr : invalid_addresses) {
+ int ret;
+
+ auto sdl = sockaddr_dl{};
+ sdl.sdl_len = sizeof(sdl);
+
+ ret = link_addr(addr.c_str(), &sdl);
+ ATF_REQUIRE_EQ(-1, ret);
+ }
+}
+
+/*
+ * Test some non-Ethernet addresses.
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(nonether)
+ATF_TEST_CASE_BODY(nonether)
+{
+ sockaddr_dl sdl;
+
+ /* A short address */
+ sdl = make_linkaddr(":1:23:cc");
+ ATF_REQUIRE_EQ("", ifname(sdl));
+ ATF_REQUIRE_EQ("1.23.cc"s, ::link_ntoa(&sdl));
+ ATF_REQUIRE_EQ(3, sdl.sdl_alen);
+ ATF_REQUIRE_EQ(true,
+ std::ranges::equal(std::vector{0x01u, 0x23u, 0xccu}, lladdr(sdl)));
+
+ /* A long address */
+ sdl = make_linkaddr(":1:23:cc:a:b:c:d:e:f");
+ ATF_REQUIRE_EQ("", ifname(sdl));
+ ATF_REQUIRE_EQ("1.23.cc.a.b.c.d.e.f"s, ::link_ntoa(&sdl));
+ ATF_REQUIRE_EQ(9, sdl.sdl_alen);
+ ATF_REQUIRE_EQ(true, std::ranges::equal(
+ std::vector{0x01u, 0x23u, 0xccu, 0xau, 0xbu, 0xcu, 0xdu, 0xeu, 0xfu},
+ lladdr(sdl)));
+}
+
+/*
+ * Test link_addr behaviour with undersized buffers.
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(smallbuf)
+ATF_TEST_CASE_BODY(smallbuf)
+{
+ static constexpr auto garbage = std::byte{0xcc};
+ auto buf = std::vector<std::byte>();
+ sockaddr_dl *sdl;
+ int ret;
+
+ /*
+ * Make an sdl with an sdl_data member of the appropriate size, and
+ * place it in buf. Ensure it's followed by a trailing byte of garbage
+ * so we can test that link_addr doesn't write past the end.
+ */
+ auto mksdl = [&buf](std::size_t datalen) -> sockaddr_dl * {
+ auto actual_size = datalen + offsetof(sockaddr_dl, sdl_data);
+
+ buf.resize(actual_size + 1);
+ std::ranges::fill(buf, garbage);
+
+ auto *sdl = new(reinterpret_cast<sockaddr_dl *>(&buf[0]))
+ sockaddr_dl;
+ sdl->sdl_len = actual_size;
+ return (sdl);
+ };
+
+ /* An sdl large enough to store the interface name */
+ sdl = mksdl(3);
+ ret = link_addr("ix0:1.2.3", sdl);
+ ATF_REQUIRE(*rbegin(buf) == garbage);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(ENOSPC, errno);
+ ATF_REQUIRE_EQ(3, sdl->sdl_nlen);
+ ATF_REQUIRE_EQ("ix0", ifname(*sdl));
+ ATF_REQUIRE_EQ(0, static_cast<int>(sdl->sdl_alen));
+
+ /*
+ * For these tests, test both with and without an interface name, since
+ * that will overflow the buffer in different places.
+ */
+
+ /* An empty sdl. Nothing may grow on this cursed ground. */
+
+ sdl = mksdl(0);
+ ret = link_addr("ix0:1.2.3", sdl);
+ ATF_REQUIRE(*rbegin(buf) == garbage);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(ENOSPC, errno);
+ ATF_REQUIRE_EQ(0, sdl->sdl_nlen);
+ ATF_REQUIRE_EQ(0, static_cast<int>(sdl->sdl_alen));
+
+ sdl = mksdl(0);
+ ret = link_addr(":1.2.3", sdl);
+ ATF_REQUIRE(*rbegin(buf) == garbage);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(ENOSPC, errno);
+ ATF_REQUIRE_EQ(0, sdl->sdl_nlen);
+ ATF_REQUIRE_EQ(0, static_cast<int>(sdl->sdl_alen));
+
+ /*
+ * An sdl large enough to store the interface name and two octets of the
+ * address.
+ */
+
+ sdl = mksdl(5);
+ ret = link_addr("ix0:1.2.3", sdl);
+ ATF_REQUIRE(*rbegin(buf) == garbage);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(ENOSPC, errno);
+ ATF_REQUIRE_EQ("ix0", ifname(*sdl));
+ ATF_REQUIRE(std::ranges::equal(
+ std::vector{ 0x01, 0x02 }, lladdr(*sdl)));
+
+ sdl = mksdl(2);
+ ret = link_addr(":1.2.3", sdl);
+ ATF_REQUIRE(*rbegin(buf) == garbage);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(ENOSPC, errno);
+ ATF_REQUIRE_EQ("", ifname(*sdl));
+ ATF_REQUIRE(std::ranges::equal(
+ std::vector{ 0x01, 0x02 }, lladdr(*sdl)));
+
+ /*
+ * An sdl large enough to store the entire address.
+ */
+
+ sdl = mksdl(6);
+ ret = link_addr("ix0:1.2.3", sdl);
+ ATF_REQUIRE(*rbegin(buf) == garbage);
+ ATF_REQUIRE_EQ(0, ret);
+ ATF_REQUIRE_EQ("ix0", ifname(*sdl));
+ ATF_REQUIRE(std::ranges::equal(
+ std::vector{ 0x01, 0x02, 0x03 }, lladdr(*sdl)));
+
+ sdl = mksdl(3);
+ ret = link_addr(":1.2.3", sdl);
+ ATF_REQUIRE(*rbegin(buf) == garbage);
+ ATF_REQUIRE_EQ(0, ret);
+ ATF_REQUIRE_EQ("", ifname(*sdl));
+ ATF_REQUIRE(std::ranges::equal(
+ std::vector{ 0x01, 0x02, 0x03 }, lladdr(*sdl)));
+}
+
+/*
+ * Test an extremely long address which would overflow link_ntoa's internal
+ * buffer. It should handle this by truncating the output.
+ * (Test for SA-16:37.libc / CVE-2016-6559.)
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(overlong)
+ATF_TEST_CASE_BODY(overlong)
+{
+ auto sdl = make_linkaddr(
+ ":01.02.03.04.05.06.07.08.09.0a.0b.0c.0d.0e.0f."
+ "11.12.13.14.15.16.17.18.19.1a.1b.1c.1d.1e.1f."
+ "22.22.23.24.25.26.27.28.29.2a.2b.2c.2d.2e.2f");
+
+ ATF_REQUIRE_EQ(
+ "1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.11.12.13.14.15.16.17.18.19.1a.1b."s,
+ ::link_ntoa(&sdl));
+}
+
+/*
+ * Test link_ntoa_r, the re-entrant version of link_ntoa().
+ */
+ATF_TEST_CASE_WITHOUT_HEAD(link_ntoa_r)
+ATF_TEST_CASE_BODY(link_ntoa_r)
+{
+ static constexpr char garbage = 0x41;
+ std::vector<char> buf;
+ sockaddr_dl sdl;
+ size_t len;
+ int ret;
+
+ // Return the contents of buf as a string, using the NUL terminator to
+ // determine length. This is to ensure we're using the return value in
+ // the same way C code would, but we do a bit more verification to
+ // elicit a test failure rather than a SEGV if it's broken.
+ auto bufstr = [&buf]() -> std::string_view {
+ // Find the NUL.
+ auto end = std::ranges::find(buf, '\0');
+ ATF_REQUIRE(end != buf.end());
+
+ // Intentionally chopping the NUL off.
+ return {begin(buf), end};
+ };
+
+ // Resize the buffer and set the contents to a known garbage value, so
+ // we don't accidentally have a NUL in the right place when link_ntoa_r
+ // didn't put it there.
+ auto resetbuf = [&buf, &len](std::size_t size) {
+ len = size;
+ buf.resize(len);
+ std::ranges::fill(buf, garbage);
+ };
+
+ // Test a short address with a large buffer.
+ sdl = make_linkaddr("ix0:1.2.3");
+ resetbuf(64);
+ ret = ::link_ntoa_r(&sdl, &buf[0], &len);
+ ATF_REQUIRE_EQ(0, ret);
+ ATF_REQUIRE_EQ(10, len);
+ ATF_REQUIRE_EQ("ix0:1.2.3"s, bufstr());
+
+ // Test a buffer which is exactly the right size.
+ sdl = make_linkaddr("ix0:1.2.3");
+ resetbuf(10);
+ ret = ::link_ntoa_r(&sdl, &buf[0], &len);
+ ATF_REQUIRE_EQ(0, ret);
+ ATF_REQUIRE_EQ(10, len);
+ ATF_REQUIRE_EQ("ix0:1.2.3"sv, bufstr());
+
+ // Test various short buffers, using a table of buffer length and the
+ // output we expect. All of these should produce valid but truncated
+ // strings, with a trailing NUL and with buflen set correctly.
+
+ auto buftests = std::vector<std::pair<std::size_t, std::string_view>>{
+ {1u, ""sv},
+ {2u, ""sv},
+ {3u, ""sv},
+ {4u, "ix0"sv},
+ {5u, "ix0:"sv},
+ {6u, "ix0:1"sv},
+ {7u, "ix0:1."sv},
+ {8u, "ix0:1.2"sv},
+ {9u, "ix0:1.2."sv},
+ };
+
+ for (auto const &[buflen, expected] : buftests) {
+ sdl = make_linkaddr("ix0:1.2.3");
+ resetbuf(buflen);
+ ret = ::link_ntoa_r(&sdl, &buf[0], &len);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(10, len);
+ ATF_REQUIRE_EQ(expected, bufstr());
+ }
+
+ // Test a NULL buffer, which should just set buflen.
+ sdl = make_linkaddr("ix0:1.2.3");
+ len = 0;
+ ret = ::link_ntoa_r(&sdl, NULL, &len);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(10, len);
+
+ // A NULL buffer with a non-zero length should also be accepted.
+ sdl = make_linkaddr("ix0:1.2.3");
+ len = 64;
+ ret = ::link_ntoa_r(&sdl, NULL, &len);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(10, len);
+
+ // Test a non-NULL buffer, but with a length of zero.
+ sdl = make_linkaddr("ix0:1.2.3");
+ resetbuf(1);
+ len = 0;
+ ret = ::link_ntoa_r(&sdl, &buf[0], &len);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(10, len);
+ // Check we really didn't write anything.
+ ATF_REQUIRE_EQ(garbage, buf[0]);
+
+ // Test a buffer which would be truncated in the middle of a two-digit
+ // hex octet, which should not write the truncated octet at all.
+ sdl = make_linkaddr("ix0:1.22.3");
+ resetbuf(8);
+ ret = ::link_ntoa_r(&sdl, &buf[0], &len);
+ ATF_REQUIRE_EQ(-1, ret);
+ ATF_REQUIRE_EQ(11, len);
+ ATF_REQUIRE_EQ("ix0:1."sv, bufstr());
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+ ATF_ADD_TEST_CASE(tcs, basic);
+ ATF_ADD_TEST_CASE(tcs, ifname);
+ ATF_ADD_TEST_CASE(tcs, smallbuf);
+ ATF_ADD_TEST_CASE(tcs, invalid);
+ ATF_ADD_TEST_CASE(tcs, nonether);
+ ATF_ADD_TEST_CASE(tcs, overlong);
+ ATF_ADD_TEST_CASE(tcs, link_ntoa_r);
+}
diff --git a/lib/libc/tests/net/test-eui64.h b/lib/libc/tests/net/test-eui64.h
new file mode 100644
index 000000000000..8bb5fbb956b7
--- /dev/null
+++ b/lib/libc/tests/net/test-eui64.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2004 The Aerospace Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions, and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of The Aerospace Corporation may not be used to endorse or
+ * promote products derived from this software.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _TEST_EUI64_H
+#define _TEST_EUI64_H
+
+struct eui64 test_eui64_id = {{0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}};
+struct eui64 test_eui64_eui48 = {{0x00,0x11,0x22,0xFF,0xFE,0x33,0x44,0x55}};
+struct eui64 test_eui64_mac48 = {{0x00,0x11,0x22,0xFF,0xFF,0x33,0x44,0x55}};
+
+#define test_eui64_id_ascii "00-11-22-33-44-55-66-77"
+#define test_eui64_id_colon_ascii "00:11:22:33:44:55:66:77"
+#define test_eui64_hex_ascii "0x0011223344556677"
+#define test_eui64_eui48_ascii "00-11-22-ff-fe-33-44-55"
+#define test_eui64_mac48_ascii "00-11-22-ff-fe-33-44-55"
+#define test_eui64_mac_ascii "00-11-22-33-44-55"
+#define test_eui64_mac_colon_ascii "00:11:22:33:44:55"
+#define test_eui64_id_host "id"
+#define test_eui64_eui48_host "eui-48"
+#define test_eui64_mac48_host "mac-48"
+
+#define test_eui64_line_id "00-11-22-33-44-55-66-77 id"
+#define test_eui64_line_id_colon "00:11:22:33:44:55:66:77 id"
+#define test_eui64_line_eui48 "00-11-22-FF-fe-33-44-55 eui-48"
+#define test_eui64_line_mac48 "00-11-22-FF-ff-33-44-55 mac-48"
+#define test_eui64_line_eui48_6byte "00-11-22-33-44-55 eui-48"
+#define test_eui64_line_eui48_6byte_c "00:11:22:33:44:55 eui-48"
+
+#endif /* !_TEST_EUI64_H */