]> Zhao Yanbai Git Server - minix.git/commitdiff
tests: adapt existing tests to new LWIP service 83/3483/2
authorDavid van Moolenbroek <david@minix3.org>
Thu, 29 Sep 2016 23:08:31 +0000 (23:08 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Sun, 30 Apr 2017 13:16:10 +0000 (13:16 +0000)
Change-Id: Id744e9d3fbe19733557011f8803593cf3768c35d

minix/tests/common-socket.c
minix/tests/common-socket.h
minix/tests/test48.c
minix/tests/test80.c
minix/tests/test81.c
minix/tests/test83.c

index e84ac351c2155f505447ac53ffeeb1983274b753..5249ae8cc0ee8c4007ac24c25ca1d4dbe69f6400 100644 (file)
@@ -169,10 +169,15 @@ void test_getsockname(const struct socket_test_info *info)
 {
        int sd;
        int rc;
+       int on;
        struct sockaddr_storage sock_addr;
        socklen_t sock_addr_len;
 
        SOCKET(sd, info->domain, info->type, 0);
+
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        rc = bind(sd, info->serveraddr, info->serveraddrlen);
        if (rc == -1) {
                test_fail("bind() should have worked");
@@ -201,6 +206,7 @@ void test_bind(const struct socket_test_info *info)
        int sd;
        int sd2;
        int rc;
+       int on;
 
        debug("entering test_bind()");
        info->callback_cleanup();
@@ -208,6 +214,10 @@ void test_bind(const struct socket_test_info *info)
        debug("Test bind() success");
 
        SOCKET(sd, info->domain, info->type, 0);
+
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        rc = bind(sd, info->serveraddr, info->serveraddrlen);
        if (rc == -1) {
                test_fail("bind() should have worked");
@@ -231,26 +241,23 @@ void test_bind(const struct socket_test_info *info)
        SOCKET(sd2, info->domain, info->type, 0);
        errno = 0;
        rc = bind(sd2, info->serveraddr, info->serveraddrlen);
-       if (!((rc == -1) && (errno == EADDRINUSE)) &&
-               !info->bug_bind_in_use) {
+       if (!((rc == -1) && (errno == EADDRINUSE))) {
                test_fail("bind() should have failed with EADDRINUSE");
        }
        CLOSE(sd2);
        CLOSE(sd);
        info->callback_cleanup();
 
-       if (!info->bug_bind_null) {
-               debug("Test bind() with a NULL address");
+       debug("Test bind() with a NULL address");
 
-               SOCKET(sd, info->domain, info->type, 0);
-               errno = 0;
-               rc = bind(sd, (struct sockaddr *) NULL,
-                       sizeof(struct sockaddr_storage));
-               if (!((rc == -1) && (errno == EFAULT))) {
-                       test_fail("bind() should have failed with EFAULT");
-               }
-               CLOSE(sd);
+       SOCKET(sd, info->domain, info->type, 0);
+       errno = 0;
+       rc = bind(sd, (struct sockaddr *) NULL,
+               sizeof(struct sockaddr_storage));
+       if (!((rc == -1) && (errno == EFAULT))) {
+               test_fail("bind() should have failed with EFAULT");
        }
+       CLOSE(sd);
 
        debug("leaving test_bind()");
 }
@@ -296,13 +303,11 @@ void test_shutdown(const struct socket_test_info *info)
        /* test for each direction (read, write, read-write) */
        for (i = 0; i < 3; i++) {
 
-               if (info->bug_shutdown_read && how[i] == SHUT_RD) continue;
-
                debug("test shutdown() with an invalid descriptor");
 
                errno = 0;
                rc = shutdown(-1, how[i]);
-               if (!(rc == -1 && errno == EBADF) && !info->bug_shutdown) {
+               if (!(rc == -1 && errno == EBADF)) {
                        test_fail("shutdown(-1, how[i]) should have failed");
                }
 
@@ -310,7 +315,7 @@ void test_shutdown(const struct socket_test_info *info)
 
                errno = 0;
                rc = shutdown(0, how[i]);
-               if (!(rc == -1 && errno == ENOTSOCK) && !info->bug_shutdown) {
+               if (!(rc == -1 && errno == ENOTSOCK)) {
                        test_fail("shutdown() should have failed with "
                            "ENOTSOCK");
                }
@@ -320,9 +325,7 @@ void test_shutdown(const struct socket_test_info *info)
                SOCKET(sd, info->domain, info->type, 0);
                errno = 0;
                rc = shutdown(sd, how[i]);
-               if (rc != 0 && !(rc == -1 && errno == ENOTCONN) &&
-                       !info->bug_shutdown_not_conn &&
-                       !info->bug_shutdown) {
+               if (rc != 0 && !(rc == -1 && errno == ENOTCONN)) {
                        test_fail("shutdown() should have failed");
                }
                CLOSE(sd);
@@ -331,9 +334,7 @@ void test_shutdown(const struct socket_test_info *info)
        SOCKET(sd, info->domain, info->type, 0);
        errno = 0;
        rc = shutdown(sd, -1);
-       if (!(rc == -1 && errno == EINVAL) &&
-               !info->bug_shutdown_not_conn &&
-               !info->bug_shutdown) {
+       if (!(rc == -1 && errno == EINVAL)) {
                test_fail("shutdown(sd, -1) should have failed with EINVAL");
        }
        CLOSE(sd);
@@ -344,7 +345,7 @@ void test_shutdown(const struct socket_test_info *info)
 void test_close(const struct socket_test_info *info)
 {
        int sd, sd2;
-       int rc, i;
+       int rc, i, on;
 
        debug("entering test_close()");
 
@@ -353,6 +354,10 @@ void test_close(const struct socket_test_info *info)
        debug("Test close() success");
 
        SOCKET(sd, info->domain, info->type, 0);
+
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        rc = bind(sd, info->serveraddr, info->serveraddrlen);
        if (rc != 0) {
                test_fail("bind() should have worked");
@@ -373,6 +378,10 @@ void test_close(const struct socket_test_info *info)
        debug("dup()'ing a file descriptor and closing both should work");
 
        SOCKET(sd, info->domain, info->type, 0);
+
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        rc = bind(sd, info->serveraddr, info->serveraddrlen);
        if (rc != 0) {
                test_fail("bind() should have worked");
@@ -442,13 +451,9 @@ void test_sockopts(const struct socket_test_info *info)
        option_len = sizeof(option_value);
        errno = 0;
        rc = getsockopt(sd, SOL_SOCKET, SO_SNDBUF, &option_value, &option_len);
-       if (rc != 0 && !info->bug_sockopt_sndbuf) {
-               test_fail("getsockopt() should have worked");
-       }
 
        if (info->expected_sndbuf >= 0 &&
-               option_value != info->expected_sndbuf &&
-               !info->bug_sockopt_sndbuf) {
+               option_value != info->expected_sndbuf) {
                test_fail("SO_SNDBUF didn't seem to work.");
        }
 
@@ -463,13 +468,12 @@ void test_sockopts(const struct socket_test_info *info)
        option_len = sizeof(option_value);
        errno = 0;
        rc = getsockopt(sd, SOL_SOCKET, SO_RCVBUF, &option_value, &option_len);
-       if (rc != 0 && !info->bug_sockopt_rcvbuf) {
+       if (rc != 0) {
                test_fail("getsockopt() should have worked");
        }
 
        if (info->expected_rcvbuf >= 0 &&
-               option_value != info->expected_rcvbuf &&
-               !info->bug_sockopt_rcvbuf) {
+               option_value != info->expected_rcvbuf) {
                test_fail("SO_RCVBUF didn't seem to work.");
        }
 
@@ -525,7 +529,7 @@ void test_dup(const struct socket_test_info *info)
        struct stat info2;
        int sd, sd2;
        int rc;
-       int i;
+       int i, on;
 
        debug("entering test_dup()");
 
@@ -534,6 +538,10 @@ void test_dup(const struct socket_test_info *info)
        debug("Test dup()");
 
        SOCKET(sd, info->domain, info->type, 0);
+
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        rc = bind(sd, info->serveraddr, info->serveraddrlen);
        if (rc != 0) {
                test_fail("bind() should have worked");
@@ -611,12 +619,16 @@ void test_dup2(const struct socket_test_info *info)
        int sd;
        int fd;
        int rc;
+       int on;
 
        debug("entering test_dup2()");
        info->callback_cleanup();
 
        SOCKET(sd, info->domain, info->type, 0);
 
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        rc = bind(sd, info->serveraddr, info->serveraddrlen);
        if (rc != 0) {
                test_fail("bind() should have worked");
@@ -671,6 +683,7 @@ static void test_xfer_server(const struct socket_test_info *info, pid_t pid)
        int status;
        int rc;
        int sd;
+       int on;
        unsigned char buf[BUFSIZE];
        socklen_t client_addr_size;
        int client_sd;
@@ -687,6 +700,9 @@ static void test_xfer_server(const struct socket_test_info *info, pid_t pid)
 
        SOCKET(sd, info->domain, info->type, 0);
 
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        rc = bind(sd, info->serveraddr, info->serveraddrlen);
        if (rc == -1) {
                test_fail("bind() should have worked");
@@ -1129,7 +1145,7 @@ static void test_simple_server(const struct socket_test_info *info, int type,
        pid_t pid)
 {
        char buf[BUFSIZE];
-       int sd, rc, client_sd, status;
+       int sd, rc, client_sd, status, on;
        struct sockaddr_storage addr;
        socklen_t addr_len;
 
@@ -1140,6 +1156,9 @@ static void test_simple_server(const struct socket_test_info *info, int type,
                test_fail("socket");
        }
 
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        assert(info->clientaddrlen <= sizeof(addr));
        memcpy(&addr, info->clientaddr, info->clientaddrlen);
 
@@ -1314,7 +1333,7 @@ static void test_abort_server(const struct socket_test_info *info,
        pid_t pid, int abort_type)
 {
        char buf[BUFSIZE];
-       int sd, rc, client_sd, status;
+       int sd, rc, client_sd, status, on;
        struct sockaddr_storage addr;
        socklen_t addr_len;
 
@@ -1325,6 +1344,9 @@ static void test_abort_server(const struct socket_test_info *info,
                test_fail("socket");
        }
 
+       on = 1;
+       (void)setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        assert(sizeof(addr) >= info->clientaddrlen);
        memcpy(&addr, info->clientaddr, info->clientaddrlen);
 
@@ -1588,13 +1610,16 @@ test_nonblock(const struct socket_test_info *info)
        socklen_t len;
        int server_sd, client_sd;
        struct sockaddr_storage addr;
-       int status;
+       int status, on;
 
        debug("entering test_nonblock()");
        memset(buf, 0, sizeof(buf));
 
        SOCKET(server_sd, info->domain, info->type, 0);
 
+       on = 1;
+       (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
                test_fail("bind() should have worked");
 
@@ -1724,11 +1749,14 @@ test_connect_nb(const struct socket_test_info *info)
        socklen_t len;
        int server_sd, client_sd;
        struct sockaddr_storage addr;
-       int status;
+       int status, on;
 
        debug("entering test_connect_nb()");
        SOCKET(server_sd, info->domain, info->type, 0);
 
+       on = 1;
+       (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
                test_fail("bind() should have worked");
 
@@ -1801,13 +1829,16 @@ test_intr(const struct socket_test_info *info)
        socklen_t len;
        int server_sd, client_sd;
        struct sockaddr_storage addr;
-       int r, status;
+       int r, status, on;
 
        debug("entering test_intr()");
        memset(buf, 0, sizeof(buf));
 
        SOCKET(server_sd, info->domain, info->type, 0);
 
+       on = 1;
+       (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
                test_fail("bind() should have worked");
 
@@ -1926,13 +1957,16 @@ test_intr(const struct socket_test_info *info)
 void
 test_connect_close(const struct socket_test_info *info)
 {
-       int server_sd, client_sd;
+       int server_sd, client_sd, sd, on;
        struct sockaddr_storage addr;
        socklen_t len;
 
        debug("entering test_connect_close()");
        SOCKET(server_sd, info->domain, info->type, 0);
 
+       on = 1;
+       (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
                test_fail("bind() should have worked");
 
@@ -1950,7 +1984,7 @@ test_connect_close(const struct socket_test_info *info)
 
        fcntl(client_sd, F_SETFL, fcntl(client_sd, F_GETFL) | O_NONBLOCK);
 
-       if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1     ||
+       if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1 ||
                errno != EINPROGRESS)
                test_fail("connect() should have yielded EINPROGRESS");
 
@@ -1966,10 +2000,11 @@ test_connect_close(const struct socket_test_info *info)
 
        len = sizeof(addr);
        errno = 0;
-       if (accept(server_sd, (struct sockaddr *) &addr, &len) != -1) {
+       if ((sd = accept(server_sd, (struct sockaddr *) &addr, &len)) != -1) {
                if (!info->ignore_accept_delay) {
                        test_fail("accept() should have failed");
                }
+               close(sd);
        } else if (errno != EAGAIN) {
                test_fail("accept() should have yielded EAGAIN");
        }
@@ -1981,18 +2016,23 @@ test_connect_close(const struct socket_test_info *info)
 
 /*
  * Verify that closing a listening socket will cause a blocking connect to fail
- * with ECONNRESET, and that a subsequent write will yield EPIPE.
+ * with ECONNRESET, and that a subsequent write will yield EPIPE.  This test
+ * works only if the connect(2) does not succeed before accept(2) is called at
+ * all, which means it is limited to UDS with LOCAL_CONNWAIT right now.
  */
 void
 test_listen_close(const struct socket_test_info *info)
 {
        int server_sd, client_sd;
-       int status;
+       int status, on;
        char byte;
 
        debug("entering test_listen_close()");
        SOCKET(server_sd, info->domain, info->type, 0);
 
+       on = 1;
+       (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
                test_fail("bind() should have worked");
 
@@ -2022,24 +2062,18 @@ test_listen_close(const struct socket_test_info *info)
                test_fail("write() should have yielded ENOTCONN");
 
        if (connect(client_sd, info->clientaddr, info->clientaddrlen) != -1) {
-               if (!info->bug_connect_after_close) {
-                       test_fail("connect() should have failed");
-               }
+               test_fail("connect() should have failed");
        } else if (errno != ECONNRESET) {
                test_fail("connect() should have yielded ECONNRESET");
        }
 
        /*
         * The error we get on the next write() depends on whether the socket
-        * may be reused after a failed connect: for TCP/IP, it may not, so we
-        * get EPIPE; for UDS, it may be reused, so we get ENOTCONN.
+        * may be reused after a failed connect.  For UDS, it may be, so we get
+        * ENOTCONN.  Otherwise we would expect EPIPE.
         */
-       if (!info->bug_connect_after_close) {
-               if (write(client_sd, &byte, 1) != -1 ||
-                   (errno != EPIPE && errno != ENOTCONN))
-                       test_fail("write() should have yielded "
-                           "EPIPE/ENOTCONN");
-       }
+       if (write(client_sd, &byte, 1) != -1 || errno != ENOTCONN)
+               test_fail("write() should have yielded ENOTCONN");
 
        close(client_sd);
 
@@ -2061,12 +2095,15 @@ void
 test_listen_close_nb(const struct socket_test_info *info)
 {
        int server_sd, client_sd;
-       int status;
+       int status, on;
        char byte;
 
        debug("entering test_listen_close_nb()");
        SOCKET(server_sd, info->domain, info->type, 0);
 
+       on = 1;
+       (void)setsockopt(server_sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
        if (bind(server_sd, info->serveraddr, info->serveraddrlen) == -1)
                test_fail("bind() should have worked");
 
index 03ba77e6cfc75107ceb3d454de983bbee11f2c75..0613d66919ff86dad90da72f45129a50ac684b08 100644 (file)
@@ -75,16 +75,6 @@ struct socket_test_info {
        const int *types;
        size_t typecount;
 
-       int buf_accept_intr; /* accept can return success when interrupted */
-       int bug_bind_in_use; /* bind does not return EADDRINUSE */
-       int bug_bind_null; /* bind segfaults with NULL pointer */
-       int bug_connect_after_close; /* connect succeeds after server closed */
-       int bug_select_nonblock; /* select unexpected results for nb sockets */
-       int bug_shutdown; /* shutdown not supported */
-       int bug_shutdown_not_conn; /* shutdown does not return ENOTCONN */
-       int bug_shutdown_read; /* shutdown does not support SHUT_RD */
-       int bug_sockopt_rcvbuf; /* get/setsockopt does not support SO_RCVBUF */
-       int bug_sockopt_sndbuf; /* get/setsockopt does not support SO_SNDBUF */
        int ignore_accept_delay; /* success from accept after aborted connect */
        int ignore_connect_delay; /* nb connect not instant */
        int ignore_connect_unaccepted; /* connect succeeds without accept */
index 5cb239176045e4804fa8da632bcd900f6c5d8d01..8b8d2458fa4e65ecab59a44e0de64b911b982d3b 100644 (file)
@@ -165,6 +165,17 @@ static void test_getaddrinfo(
        ai_count_stream = 0;
        while (ai_cur)
        {
+               /*
+                * TODO: this test was written for IPv4.  For now, skip IPv6
+                * results altogether.  Later, we should add additional code
+                * for IPv6.  However, since this test now largely exercises
+                * NetBSD code, it is not as important as it once was.
+                */
+               if (ai_cur->ai_family == AF_INET6) {
+                       ai_cur = ai_cur->ai_next;
+                       continue;
+               }
+
                /* test result fields */
                if (ai_cur->ai_family != AF_INET) 
                        test_getaddrinfo_err_nr(2, TEST_GETADDRINFO_ERR_PARAMS,
@@ -316,8 +327,6 @@ static struct
        { "127.0.0.1",      0x7f000001, 1, 0, 0, 0                 },
        { "localhost",      0x7f000001, 0, 1, 0, 0,                },
        { "test48.minix3.org", 0x7f010203, 0, 1, 1, 0,             },
-       { "",               0x00000000, 1, 0, 0, (1<<EAI_NONAME)|(1<<EAI_FAIL)|(1<<EAI_NODATA)},
-       { "256.256.256.256",0x00000000, 1, 0, 0, (1<<EAI_NONAME)|(1<<EAI_FAIL)|(1<<EAI_NODATA)},
        { "minix3.example.com",     0x00000000, 0, 0, 1, (1<<EAI_NONAME)|(1<<EAI_FAIL)|(1<<EAI_NODATA)}};
 
 static struct
index f6bc69ad9897e624062373705a2187fa64ebad6b..99e65376b1201ac5267b42562788ac4ff12c75cd 100644 (file)
@@ -88,11 +88,13 @@ int main(int argc, char *argv[])
                .types                     = &info.type,
                .typecount                 = 1,
 
-               .bug_bind_in_use           = 1,
-               .bug_bind_null             = 1,
-               .bug_connect_after_close   = 1,
-               .bug_shutdown_not_conn     = 1,
-               .bug_shutdown_read         = 1,
+               /*
+                * Maintainer's note: common-socket was adapted from test56 in
+                * a time that UDS's LOCAL_CONNWAIT was the default.  Due to
+                * this as well as inherent behavioral differences between TCP
+                * and UDS, these exceptions basically work around the fact
+                * that common-socket was not designed for its current task.
+                */
                .ignore_accept_delay       = 1,
                .ignore_connect_unaccepted = 1,
                .ignore_connect_delay      = 1,
@@ -130,7 +132,7 @@ int main(int argc, char *argv[])
        test_connect_nb(&info);
        test_intr(&info);
        test_connect_close(&info);
-       test_listen_close(&info);
+       /* test_listen_close(&info); -- not suitable for TCP */
        test_listen_close_nb(&info);
 
        quit();
index f23c174d3427806dd674bf72fea2c9674a9fc70b..61510cf0caf31f497cef4f6b131bff39bac6dbcc 100644 (file)
@@ -78,8 +78,8 @@ int main(int argc, char *argv[])
                .clientaddrsym             = (struct sockaddr *) &clientaddr,
                .clientaddrsymlen          = sizeof(clientaddr),
                .domain                    = PF_INET,
-               .expected_rcvbuf           = -1,
-               .expected_sndbuf           = -1,
+               .expected_rcvbuf           = 32768,
+               .expected_sndbuf           = 8192,
                .serveraddr                = (struct sockaddr *) &serveraddr,
                .serveraddrlen             = sizeof(serveraddr),
                .serveraddr2               = (struct sockaddr *) &serveraddr2,
@@ -87,22 +87,6 @@ int main(int argc, char *argv[])
                .type                      = SOCK_DGRAM,
                .types                     = &info.type,
                .typecount                 = 1,
-
-               .bug_bind_in_use           = 1,
-               .bug_bind_null             = 1,
-               .bug_connect_after_close   = 1,
-               .bug_shutdown              = 1, /* UDP only problem */
-               .bug_shutdown_not_conn     = 1,
-               .bug_shutdown_read         = 1,
-               .bug_sockopt_rcvbuf        = 1, /* UDP only problem */
-               .bug_sockopt_sndbuf        = 1, /* UDP only problem */
-               .ignore_accept_delay       = 1,
-               .ignore_connect_unaccepted = 1,
-               .ignore_connect_delay      = 1,
-               .ignore_select_delay       = 1,
-               .ignore_send_waiting       = 1,
-               .ignore_write_conn_reset   = 1,
-
                .callback_check_sockaddr   = callback_check_sockaddr,
                .callback_cleanup          = callback_cleanup,
                .callback_xfer_prepclient  = NULL,
index e8fcb293650c44f1e52a5c3209a276b1e2e22fe2..094bd5b4cfc52e3a177426dd0125ced04a76f6a9 100644 (file)
 #include <sys/time.h>
 #include <sys/wait.h>
 
-#include <net/gen/ether.h>
-#include <net/gen/eth_io.h>
-#include <net/gen/in.h>
-#include <net/gen/ip_io.h>
-
 #include "common.h"
 
 int max_error = 100;
@@ -124,16 +119,11 @@ static const size_t payloadsizes[] = {
        65535 - sizeof(struct header_ip) - sizeof(struct header_udp),
 };
 
-#define ADDR_COUNT_MAX 10
-static size_t addr_count;
-static uint32_t addrsrc = 0xc0000201; /* 192.0.2.1 (TEST-NET) */
-static uint32_t addrdst = 0x7f000001; /* 127.0.0.1 (localhost) */
-static uint32_t addrs[ADDR_COUNT_MAX] = {
-       0x00000000, /* 0.0.0.0 (INADDR_NONE) */
-       0x7f000001, /* 127.0.0.1 (localhost) */
-       0xc0000201, /* 192.0.2.1 (TEST-NET) */
-       0xffffffff, /* 255.255.255.255 (broadcast) */
-       /* local addresses will be added */
+/* In its current configuration, this test uses the loopback interface only. */
+static uint32_t addrsrc = INADDR_LOOPBACK; /* 127.0.0.1 (localhost) */
+static uint32_t addrdst = INADDR_LOOPBACK; /* 127.0.0.1 (localhost) */
+static uint32_t addrs[] = {
+       INADDR_LOOPBACK, /* 127.0.0.1 (localhost) */
 };
 
 #define CLOSE(fd) do { assert(fd >= 0); if (close((fd)) != 0) efmt("close failed"); } while (0);
@@ -472,7 +462,7 @@ static pid_t server_start(int type, int port, enum server_action action) {
                .sin_port = htons(port),
                .sin_addr = { htonl(INADDR_ANY) },
        };
-       int fd;
+       int fd, on;
        pid_t pid = -1;
 
        dbgprintf("server_start port %d\n", port);
@@ -484,6 +474,12 @@ static pid_t server_start(int type, int port, enum server_action action) {
                goto cleanup;
        }
 
+       on = 1;
+       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
+               efmt("cannot set SO_REUSEADDR option on socket");
+               goto cleanup;
+       }
+
        /* bind socket */
        if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) {
                efmt("cannot bind socket");
@@ -524,7 +520,13 @@ cleanup:
 }
 
 static ssize_t send_packet_raw(int fd, const void *buf, size_t size) {
-       return write(fd, buf, size);
+       struct sockaddr_in sin;
+
+       memset(&sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+       return sendto(fd, buf, size, 0, (struct sockaddr *)&sin, sizeof(sin));
 }
 
 enum settings_ip {
@@ -604,7 +606,7 @@ static void send_packet_ip_base(
        struct header_ip header = {
                .tos     = tos,
                .id      = htons(id),
-               .fl_fo   = htons((fl << 13) | fo),
+               .fl_fo   = (fl << 13) | fo, /* no htons(), lwip swaps this */
                .ttl     = ttl,
                .prot    = prot,
                .cs      = 0,
@@ -652,7 +654,7 @@ static void send_packet_ip_base(
        if (ipsettings & si_bad_len_small) len = ihl * 4 - 1;
        if (ipsettings & si_bad_len_big) len += 1;
        if (ipsettings & si_bad_len_huge) len = 0xffff;
-       header.len = htons(len);
+       header.len = len; /* no htons(), lwip swaps this */
 
        packetsize = ihl * 4 + payloadsize;
        if (packetsize > sizeof(packet)) {
@@ -973,8 +975,8 @@ static void send_packets_ip(int fd) {
 
        /* send packets with various addresses and corruptions */
        params = paramsbase;
-       for (i = 0; i < addr_count; i++) {
-       for (j = 0; j < addr_count; j++) {
+       for (i = 0; i < __arraycount(addrs); i++) {
+       for (j = 0; j < __arraycount(addrs); j++) {
                params.srcip = addrs[i];
                params.dstip = addrs[j];
                send_packets_ip_settings(&params);
@@ -1050,8 +1052,8 @@ static void send_packets_udp(int fd) {
 
        /* send packets with various addresses and ports */
        params = paramsbase;
-       for (i = 0; i < addr_count; i++) {
-       for (j = 0; j < addr_count; j++) {
+       for (i = 0; i < __arraycount(addrs); i++) {
+       for (j = 0; j < __arraycount(addrs); j++) {
        for (k = 0; k < 5; k++) {
                params.srcip = addrs[i];
                params.dstip = addrs[j];
@@ -1061,7 +1063,7 @@ static void send_packets_udp(int fd) {
        }
        }
        params = paramsbase;
-       for (i = 0; i < addr_count; i++) {
+       for (i = 0; i < __arraycount(addrs); i++) {
        for (j = 0; j < 5; j++) {
        for (k = 0; k < 5; k++) {
                params.dstip = addrs[i];
@@ -1307,8 +1309,8 @@ static void send_packets_tcp(int fd) {
 
        /* send packets with various addresses and ports */
        params = paramsbase;
-       for (i = 0; i < addr_count; i++) {
-       for (j = 0; j < addr_count; j++) {
+       for (i = 0; i < __arraycount(addrs); i++) {
+       for (j = 0; j < __arraycount(addrs); j++) {
        for (k = 0; k < 7; k++) {
                params.srcip = addrs[i];
                params.dstip = addrs[j];
@@ -1318,7 +1320,7 @@ static void send_packets_tcp(int fd) {
        }
        }
        params = paramsbase;
-       for (i = 0; i < addr_count; i++) {
+       for (i = 0; i < __arraycount(addrs); i++) {
        for (j = 0; j < 7; j++) {
        for (k = 0; k < 7; k++) {
                params.dstip = addrs[i];
@@ -1477,65 +1479,14 @@ static void recv_packets_select(int fd) {
 }
 
 static int open_raw_socket(int broadcast) {
-       int fd;
-       struct nwio_ethopt opt = { };
-       struct nwio_ethstat stat = { };
-
-       fd = open("/dev/eth", O_RDWR);
-       if (fd < 0) efmt("cannot open /dev/eth");
+       int fd, on;
 
-       /* test NWIOGETHOPT */
-       if (ioctl(fd, NWIOGETHOPT, &opt) != 0) {
-               efmt("ioctl(NWIOGETHOPT) failed");
-       }
+       fd = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
+       if (fd < 0) efmt("cannot create raw socket");
 
-       /* test NWIOGETHSTAT */
-       if (ioctl(fd, NWIOGETHSTAT, &stat) != 0) {
-               efmt("ioctl(NWIOGETHSTAT) failed");
-       }
-
-       /* test invalid NWIOSETHOPT input */
-       opt.nweo_flags = NWEO_COPY << 16;
-       if (ioctl(fd, NWIOSETHOPT, &opt) != -1 && errno != EBADMODE) {
-               efmt("ioctl(NWIOSETHOPT) should have returned EBADMODE");
-       }
-
-       opt.nweo_flags = NWEO_EN_LOC | NWEO_DI_LOC;
-       if (ioctl(fd, NWIOSETHOPT, &opt) != -1 && errno != EBADMODE) {
-               efmt("ioctl(NWIOSETHOPT) should have returned EBADMODE");
-       }
-
-       /* test NWIOSETHOPT with defaults */
-       opt.nweo_flags = 0;
-       if (ioctl(fd, NWIOSETHOPT, &opt) != 0) {
-               efmt("ioctl(NWIOSETHOPT) failed");
-       }
-
-       /* test NWIOGETHSTAT right after reconfiguring */
-       opt.nweo_flags = NWEO_EN_BROAD | NWEO_EN_MULTI | NWEO_EN_PROMISC;
-       if (ioctl(fd, NWIOSETHOPT, &opt) != 0) {
-               efmt("ioctl(NWIOSETHOPT) failed");
-       }
-
-       opt.nweo_flags = NWEO_DI_BROAD | NWEO_DI_MULTI | NWEO_DI_PROMISC;
-       if (ioctl(fd, NWIOSETHOPT, &opt) != 0) {
-               efmt("ioctl(NWIOSETHOPT) failed");
-       }
-
-       if (ioctl(fd, NWIOGETHSTAT, &stat) != 0) {
-               efmt("ioctl(NWIOGETHSTAT) failed");
-       }
-
-       /* configure /dev/eth the way we want it for the rest of the test */
-       opt.nweo_flags = NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD |
-               NWEO_EN_MULTI | NWEO_EN_PROMISC |
-               (broadcast ? NWEO_REMANY : NWEO_REMSPEC) |
-               NWEO_TYPESPEC | NWEO_RWDATONLY;
-       opt.nweo_type = htons(ETH_IP_PROTO);
-       memcpy(&opt.nweo_rem, &stat.nwes_addr, sizeof(opt.nweo_rem));
-       if (ioctl(fd, NWIOSETHOPT, &opt) != 0) {
-               efmt("ioctl(NWIOSETHOPT) failed");
-       }
+       on = 1;
+       if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) != 0)
+               efmt("ioctl(IP_HDRINCL) failed");
 
        return fd;
 }
@@ -1563,71 +1514,6 @@ static void do_packets(void) {
        CLOSE(fd);
 }
 
-static void add_local_ip(uint32_t ip) {
-       static int first = 1;
-       int i;
-
-       for (i = 0; i < addr_count; i++) {
-               if (addrs[i] == ip) return;
-       }
-       dbgprintf("found local IP: %d.%d.%d.%d\n",
-               (uint8_t) (ip >> 24), (uint8_t) (ip >> 16),
-               (uint8_t) (ip >> 8), (uint8_t) (ip >> 0));
-       if (addr_count < ADDR_COUNT_MAX) {
-               addrs[addr_count++] = ip;
-       }
-       if (first) {
-               addrdst = ip;
-               first = 0;
-       }
-}
-
-static void get_local_ip(void) {
-       char device[16];
-       int flags;
-       int ifno;
-       nwio_ipconf_t ipconf;
-       int ip_fd;
-
-       /* inspired by ifconfig */
-       for (ifno = 0; ifno < 32; ifno++) {
-               snprintf(device, sizeof(device), "/dev/ip%d", ifno);
-               ip_fd = open(device, O_RDWR);
-               if (ip_fd < 0) {
-                       if (errno != ENOENT && errno != ENXIO) {
-                               efmt("cannot open %s", device);
-                       }
-                       continue;
-               }
-
-               flags = fcntl(ip_fd, F_GETFL);
-               if (flags == -1) {
-                       efmt("cannot get flags for %s", device);
-                       goto next;
-               }
-               if (fcntl(ip_fd, F_SETFL, flags | O_NONBLOCK) == -1) {
-                       efmt("cannot set flags for %s", device);
-                       goto next;
-               }
-
-               if (ioctl(ip_fd, NWIOGIPCONF, &ipconf) == -1) {
-                       if (errno != EAGAIN) {
-                               efmt("cannot get IP address for %s", device);
-                       }
-                       goto next;
-               }
-
-               if (fcntl(ip_fd, F_SETFL, flags) == -1) {
-                       efmt("cannot restore flags for %s", device);
-               }
-
-               add_local_ip(ntohl(ipconf.nwic_ipaddr));
-
-next:
-               CLOSE(ip_fd);
-       }
-}
-
 int main(int argc, char **argv)
 {
        int i;
@@ -1644,8 +1530,7 @@ int main(int argc, char **argv)
        pids[5] = server_start(SOCK_DGRAM,  PORT_BASE + 1, sa_selectr);
 
        /* send some bogus packets */
-       get_local_ip();
-       if (get_setting_use_network()) do_packets();
+       do_packets();
 
        /* stop the servers */
        for (i = 0; i < PORT_COUNT; i++) server_stop(pids[i]);