diff options
Diffstat (limited to 'lib/libc/tests/net')
33 files changed, 2292 insertions, 14 deletions
diff --git a/lib/libc/tests/net/Makefile b/lib/libc/tests/net/Makefile index 0a49683ea3d1..ec0668633508 100644 --- a/lib/libc/tests/net/Makefile +++ b/lib/libc/tests/net/Makefile @@ -3,6 +3,11 @@ 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 +ATF_TESTS_CXX+= inet_net_test + +CXXSTD.link_addr_test= c++20 +CXXSTD.inet_net_test= c++20 CFLAGS+= -I${.CURDIR} @@ -31,8 +36,7 @@ aton_ether_subr.c: gen_ether_subr ${SRCTOP}/sys/net/if_ethersubr.c .include "../Makefile.netbsd-tests" -# TODO: the testcases needs to be ported to FreeBSD -#TESTS_SUBDIRS= getaddrinfo +TESTS_SUBDIRS= getaddrinfo ${PACKAGE}FILES+= hosts ${PACKAGE}FILES+= resolv.conf diff --git a/lib/libc/tests/net/getaddrinfo/Makefile b/lib/libc/tests/net/getaddrinfo/Makefile index 5d98aa31a86a..1299e91615b7 100644 --- a/lib/libc/tests/net/getaddrinfo/Makefile +++ b/lib/libc/tests/net/getaddrinfo/Makefile @@ -1,14 +1,11 @@ PACKAGE= tests -TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libc/net/${.CURDIR:T} - .include <bsd.own.mk> BINDIR= ${TESTSDIR} -.error This testcase needs to be ported to FreeBSD (the output from getaddrinfo_test differs from NetBSD) - -NETBSD_ATF_TESTS_SH= getaddrinfo_test +ATF_TESTS_SH= getaddrinfo_test +ATF_TESTS_C= getaddrinfo PROGS= h_gai @@ -17,13 +14,33 @@ ${PACKAGE}DATA_FILESPACKAGE= tests ${PACKAGE}DATA_FILESDIR= ${TESTSDIR}/data -${PACKAGE}DATA_FILES+= basics_v4.exp basics_v4v6.exp -${PACKAGE}DATA_FILES+= no_host_v4.exp no_host_v4v6.exp -${PACKAGE}DATA_FILES+= no_serv_v4.exp no_serv_v4v6.exp -${PACKAGE}DATA_FILES+= sock_raw_v4.exp sock_raw_v4v6.exp -${PACKAGE}DATA_FILES+= spec_fam_v4.exp spec_fam_v4v6.exp -${PACKAGE}DATA_FILES+= scoped.exp -${PACKAGE}DATA_FILES+= unsup_fam.exp +${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" 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/inet_net_test.cc b/lib/libc/tests/net/inet_net_test.cc new file mode 100644 index 000000000000..60b60b152eca --- /dev/null +++ b/lib/libc/tests/net/inet_net_test.cc @@ -0,0 +1,333 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2025 Lexi Winter <ivy@FreeBSD.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Tests for inet_net_pton() and inet_net_ntop(). + */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <ranges> +#include <string> +#include <vector> + +#include <atf-c++.hpp> + +using namespace std::literals; + +/* + * inet_net_ntop() and inet_net_pton() for IPv4. + */ +ATF_TEST_CASE_WITHOUT_HEAD(inet_net_inet4) +ATF_TEST_CASE_BODY(inet_net_inet4) +{ + /* + * Define a list of addresses we want to check. Each address is passed + * to inet_net_pton() to convert it to an in_addr, then we convert the + * in_addr back to a string and compare it with the expected value. We + * want to test over-long prefixes here (such as 10.0.0.1/8), so we also + * specify what the result is expected to be. + */ + + struct test_addr { + std::string input; + int bits; + std::string output; + }; + + auto test_addrs = std::vector<test_addr>{ + // Simple prefixes that fall on octet boundaries. + { "10.0.0.0/8", 8, "10/8" }, + { "10.1.0.0/16", 16, "10.1/16" }, + { "10.1.2.0/24", 24, "10.1.2/24" }, + { "10.1.2.3/32", 32, "10.1.2.3/32" }, + + // Simple prefixes with the short-form address. + { "10/8", 8, "10/8" }, + { "10.1/16", 16, "10.1/16" }, + { "10.1.2/24", 24, "10.1.2/24" }, + + // A prefix that doesn't fall on an octet boundary. + { "10.1.64/18", 18, "10.1.64/18" }, + + // An overlong prefix with bits that aren't part of the prefix. + { "10.0.0.1/8", 8, "10/8" }, + }; + + for (auto const &addr: test_addrs) { + /* + * Convert the input string to an in_addr + bits, and make + * sure the result produces the number of bits we expected. + */ + + auto in = in_addr{}; + auto bits = inet_net_pton(AF_INET, addr.input.c_str(), + &in, sizeof(in)); + ATF_REQUIRE(bits != -1); + ATF_REQUIRE_EQ(bits, addr.bits); + + /* + * Convert the in_addr back to a string + */ + + /* + * XXX: Should there be a constant for the size of the result + * buffer? For now, use ADDRSTRLEN + 3 ("/32") + 1 (NUL). + * + * Fill the buffer with 'Z', so we can check the result was + * properly terminated. + */ + auto strbuf = std::vector<char>(INET_ADDRSTRLEN + 3 + 1, 'Z'); + auto ret = inet_net_ntop(AF_INET, &in, bits, + strbuf.data(), strbuf.size()); + ATF_REQUIRE(ret != NULL); + ATF_REQUIRE_EQ(ret, strbuf.data()); + + /* Make sure the result was NUL-terminated and find the NUL */ + ATF_REQUIRE(strbuf.size() >= 1); + auto end = std::ranges::find(strbuf, '\0'); + ATF_REQUIRE(end != strbuf.end()); + + /* + * Check the result matches what we expect. Use a temporary + * string here instead of std::ranges::equal because this + * means ATF can print the mismatch. + */ + auto str = std::string(std::ranges::begin(strbuf), end); + ATF_REQUIRE_EQ(str, addr.output); + } +} + +/* + * inet_net_ntop() and inet_net_pton() for IPv6. + */ +ATF_TEST_CASE_WITHOUT_HEAD(inet_net_inet6) +ATF_TEST_CASE_BODY(inet_net_inet6) +{ + /* + * Define a list of addresses we want to check. Each address is + * passed to inet_net_pton() to convert it to an in6_addr, then we + * convert the in6_addr back to a string and compare it with the + * expected value. We want to test over-long prefixes here (such + * as 2001:db8::1/32), so we also specify what the result is + * expected to be. + */ + + struct test_addr { + std::string input; + int bits; + std::string output; + }; + + auto test_addrs = std::vector<test_addr>{ + // A prefix with a trailing :: + { "2001:db8::/32", 32, "2001:db8::/32" }, + + // A prefix with a leading ::. Note that the output is + // different from the input because inet_ntop() renders + // this prefix with an IPv4 suffix for legacy reasons. + { "::ffff:0:0/96", 96, "::ffff:0.0.0.0/96" }, + + // The same prefix but with the IPv4 legacy form as input. + { "::ffff:0.0.0.0/96", 96, "::ffff:0.0.0.0/96" }, + + // A prefix with an infix ::. + { "2001:db8::1/128", 128, "2001:db8::1/128" }, + + // A prefix with bits set which are outside the prefix; + // these should be silently ignored. + { "2001:db8:1:1:1:1:1:1/32", 32, "2001:db8::/32" }, + + // As above but with infix ::. + { "2001:db8::1/32", 32, "2001:db8::/32" }, + + // A prefix with only ::, commonly used to represent the + // entire address space. + { "::/0", 0, "::/0" }, + + // A single address with no ::. + { "2001:db8:1:1:1:1:1:1/128", 128, "2001:db8:1:1:1:1:1:1/128" }, + + // A prefix with no ::. + { "2001:db8:1:1:0:0:0:0/64", 64, "2001:db8:1:1::/64" }, + + // A prefix which isn't on a 16-bit boundary. + { "2001:db8:c000::/56", 56, "2001:db8:c000::/56" }, + + // A prefix which isn't on a nibble boundary. + { "2001:db8:c100::/57", 57, "2001:db8:c100::/57" }, + + // An address without a prefix length, which should be treated + // as a /128. + { "2001:db8::", 128, "2001:db8::/128" }, + { "2001:db8::1", 128, "2001:db8::1/128" }, + + // Test vectors provided in PR bin/289198. + { "fe80::1/64", 64, "fe80::/64" }, + { "fe80::f000:74ff:fe54:bed2/64", + 64, "fe80::/64" }, + { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64", + 64, "ffff:ffff:ffff:ffff::/64" }, + { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" }, + }; + + for (auto const &addr: test_addrs) { + /* + * Convert the input string to an in6_addr + bits, and make + * sure the result produces the number of bits we expected. + */ + + auto in6 = in6_addr{}; + errno = 0; + auto bits = inet_net_pton(AF_INET6, addr.input.c_str(), + &in6, sizeof(in6)); + ATF_REQUIRE(bits != -1); + ATF_REQUIRE_EQ(bits, addr.bits); + + /* + * Convert the in6_addr back to a string + */ + + /* + * XXX: Should there be a constant for the size of the result + * buffer? For now, use ADDRSTRLEN + 4 ("/128") + 1 (NUL). + * + * Fill the buffer with 'Z', so we can check the result was + * properly terminated. + */ + auto strbuf = std::vector<char>(INET6_ADDRSTRLEN + 4 + 1, 'Z'); + auto ret = inet_net_ntop(AF_INET6, &in6, bits, + strbuf.data(), strbuf.size()); + ATF_REQUIRE(ret != NULL); + ATF_REQUIRE_EQ(ret, strbuf.data()); + + /* Make sure the result was NUL-terminated and find the NUL */ + ATF_REQUIRE(strbuf.size() >= 1); + auto end = std::ranges::find(strbuf, '\0'); + ATF_REQUIRE(end != strbuf.end()); + + /* + * Check the result matches what we expect. Use a temporary + * string here instead of std::ranges::equal because this + * means ATF can print the mismatch. + */ + auto str = std::string(std::ranges::begin(strbuf), end); + ATF_REQUIRE_EQ(str, addr.output); + } +} + +ATF_TEST_CASE_WITHOUT_HEAD(inet_net_pton_invalid) +ATF_TEST_CASE_BODY(inet_net_pton_invalid) +{ + auto ret = int{}; + auto addr4 = in_addr{}; + auto str4 = "10.0.0.0"s; + auto addr6 = in6_addr{}; + auto str6 = "2001:db8::"s; + + /* Passing an address which is too short should be an error */ + ret = inet_net_pton(AF_INET6, str6.c_str(), &addr6, sizeof(addr6) - 1); + ATF_REQUIRE_EQ(ret, -1); + + ret = inet_net_pton(AF_INET, str4.c_str(), &addr4, sizeof(addr4) - 1); + ATF_REQUIRE_EQ(ret, -1); + + /* Test some generally invalid addresses. */ + auto invalid4 = std::vector<std::string>{ + // Prefix length too big + "10.0.0.0/33", + // Prefix length is negative + "10.0.0.0/-1", + // Prefix length is not a number + "10.0.0.0/foo", + // Input is not a network prefix + "this is not an IP address", + }; + + for (auto const &addr: invalid4) { + auto ret = inet_net_pton(AF_INET, addr.c_str(), &addr4, + sizeof(addr4)); + ATF_REQUIRE_EQ(ret, -1); + } + + auto invalid6 = std::vector<std::string>{ + // Prefix length too big + "2001:db8::/129", + // Prefix length is negative + "2001:db8::/-1", + // Prefix length is not a number + "2001:db8::/foo", + // Input is not a network prefix + "this is not an IP address", + }; + + for (auto const &addr: invalid6) { + auto ret = inet_net_pton(AF_INET6, addr.c_str(), &addr6, + sizeof(addr6)); + ATF_REQUIRE_EQ(ret, -1); + } +} + +ATF_TEST_CASE_WITHOUT_HEAD(inet_net_ntop_invalid) +ATF_TEST_CASE_BODY(inet_net_ntop_invalid) +{ + auto addr4 = in_addr{}; + auto addr6 = in6_addr{}; + auto strbuf = std::vector<char>(INET6_ADDRSTRLEN + 4 + 1); + + /* + * Passing a buffer which is too small should not overrun the buffer. + * Test this by initialising the buffer to 'Z', and only providing + * part of it to the function. + */ + + std::ranges::fill(strbuf, 'Z'); + auto ret = inet_net_ntop(AF_INET6, &addr6, 128, strbuf.data(), 1); + ATF_REQUIRE_EQ(ret, nullptr); + ATF_REQUIRE_EQ(strbuf[1], 'Z'); + + std::ranges::fill(strbuf, 'Z'); + ret = inet_net_ntop(AF_INET, &addr4, 32, strbuf.data(), 1); + ATF_REQUIRE_EQ(ret, nullptr); + ATF_REQUIRE_EQ(strbuf[1], 'Z'); + + /* Check that invalid prefix lengths return an error */ + + ret = inet_net_ntop(AF_INET6, &addr6, 129, strbuf.data(), strbuf.size()); + ATF_REQUIRE_EQ(ret, nullptr); + ret = inet_net_ntop(AF_INET6, &addr6, -1, strbuf.data(), strbuf.size()); + ATF_REQUIRE_EQ(ret, nullptr); + + ret = inet_net_ntop(AF_INET, &addr4, 33, strbuf.data(), strbuf.size()); + ATF_REQUIRE_EQ(ret, nullptr); + ret = inet_net_ntop(AF_INET, &addr4, -1, strbuf.data(), strbuf.size()); + ATF_REQUIRE_EQ(ret, nullptr); +} + +ATF_INIT_TEST_CASES(tcs) +{ + ATF_ADD_TEST_CASE(tcs, inet_net_inet4); + ATF_ADD_TEST_CASE(tcs, inet_net_inet6); + ATF_ADD_TEST_CASE(tcs, inet_net_pton_invalid); + ATF_ADD_TEST_CASE(tcs, inet_net_ntop_invalid); +} 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); +} |
