From: David van Moolenbroek Date: Thu, 29 Sep 2016 23:08:31 +0000 (+0000) Subject: tests: adapt existing tests to new LWIP service X-Git-Url: http://zhaoyanbai.com/repos/doxygen.log?a=commitdiff_plain;h=refs%2Fchanges%2F83%2F3483%2F2;p=minix.git tests: adapt existing tests to new LWIP service Change-Id: Id744e9d3fbe19733557011f8803593cf3768c35d --- diff --git a/minix/tests/common-socket.c b/minix/tests/common-socket.c index e84ac351c..5249ae8cc 100644 --- a/minix/tests/common-socket.c +++ b/minix/tests/common-socket.c @@ -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"); diff --git a/minix/tests/common-socket.h b/minix/tests/common-socket.h index 03ba77e6c..0613d6691 100644 --- a/minix/tests/common-socket.h +++ b/minix/tests/common-socket.h @@ -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 */ diff --git a/minix/tests/test48.c b/minix/tests/test48.c index 5cb239176..8b8d2458f 100644 --- a/minix/tests/test48.c +++ b/minix/tests/test48.c @@ -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< #include -#include -#include -#include -#include - #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(¶ms); @@ -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]);