From a14a1afe966a45000fa768df43a25d84a68772dd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 31 May 2014 03:31:29 +0200 Subject: tests: greatly extend the ipv4 bind test Signed-off-by: Michael Adam Reviewed-by: Andreas Schneider --- tests/test_echo_tcp_bind.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/tests/test_echo_tcp_bind.c b/tests/test_echo_tcp_bind.c index e1c55ef..2348a2f 100644 --- a/tests/test_echo_tcp_bind.c +++ b/tests/test_echo_tcp_bind.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -35,8 +36,12 @@ static void teardown(void **state) static void test_bind_ipv4(void **state) { + struct sockaddr sa; + socklen_t salen = sizeof(struct sockaddr); struct sockaddr_in sin; socklen_t slen = sizeof(struct sockaddr_in); + struct sockaddr_un sun; + socklen_t sulen = sizeof(struct sockaddr_un); int rc; int s; @@ -45,6 +50,89 @@ static void test_bind_ipv4(void **state) s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); assert_return_code(s, errno); + /* + * Test various cases with family AF_UNSPEC + */ + + /* UNSPEC, len == 1: EINVAL */ + + sin = (struct sockaddr_in) { + .sin_family = AF_UNSPEC, + }; + rc = bind(s, (struct sockaddr *)&sin, 1); + assert_int_equal(rc, -1); + assert_int_equal(errno, EINVAL); + + /* UNSPEC: EAFNOSUPPORT */ + + sin = (struct sockaddr_in) { + .sin_family = AF_UNSPEC, + }; + rc = inet_pton(AF_INET, "127.0.0.20", &sin.sin_addr); + assert_int_equal(rc, 1); + + rc = bind(s, (struct sockaddr *)&sin, slen); + assert_int_equal(rc, -1); + /* FreeBSD uses EADDRNOTAVAIL here ... */ + assert_true(errno == EAFNOSUPPORT || errno == EADDRNOTAVAIL); + + /* special case: AF_UNSPEC with INADDR_ANY: success mapped to AF_INET */ + + sin = (struct sockaddr_in) { + .sin_family = AF_UNSPEC, + }; + assert_int_equal(sin.sin_addr.s_addr, htonl(INADDR_ANY)); + + rc = bind(s, (struct sockaddr *)&sin, slen); + assert_return_code(rc, errno); + + close(s); + + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + assert_return_code(s, errno); + + /* + * Test various cases with family AF_UNIX + * all fail with EAFNOSUPPORT + */ + + sa = (struct sockaddr) { + .sa_family = AF_UNIX, + }; + rc = bind(s, (struct sockaddr *)&sa, salen); + assert_int_equal(rc, -1); + assert_int_equal(errno, EAFNOSUPPORT); + + sin = (struct sockaddr_in) { + .sin_family = AF_UNIX, + }; + rc = bind(s, (struct sockaddr *)&sin, slen); + assert_int_equal(rc, -1); + assert_int_equal(errno, EAFNOSUPPORT); + + sun = (struct sockaddr_un) { + .sun_family = AF_UNIX, + }; + rc = bind(s, (struct sockaddr *)&sun, sulen); + assert_int_equal(rc, -1); + assert_int_equal(errno, EAFNOSUPPORT); + +#ifdef HAVE_IPV6 + /* + * Test with family AF_INET6 - fail + */ + + sin = (struct sockaddr_in) { + .sin_family = AF_INET6, + }; + rc = bind(s, (struct sockaddr *)&sin, slen); + assert_int_equal(rc, -1); + assert_int_equal(errno, EAFNOSUPPORT); +#endif + + /* + * Finally, success binding a new IPv4 address. + */ ZERO_STRUCT(sin); sin.sin_family = AF_INET; -- cgit