tests: adapt existing tests to new LWIP service

Change-Id: Id744e9d3fbe19733557011f8803593cf3768c35d
This commit is contained in:
David van Moolenbroek 2016-09-29 23:08:31 +00:00
parent bb9622b5ed
commit ad920fc485
6 changed files with 148 additions and 241 deletions

View 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,15 +241,13 @@ 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");
SOCKET(sd, info->domain, info->type, 0);
@ -250,7 +258,6 @@ void test_bind(const struct socket_test_info *info)
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");
@ -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");
}
} 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");

View 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 */

View 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

View 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();

View 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,

View File

@ -38,11 +38,6 @@
#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 = { };
int fd, on;
fd = open("/dev/eth", O_RDWR);
if (fd < 0) efmt("cannot open /dev/eth");
fd = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (fd < 0) efmt("cannot create raw socket");
/* test NWIOGETHOPT */
if (ioctl(fd, NWIOGETHOPT, &opt) != 0) {
efmt("ioctl(NWIOGETHOPT) failed");
}
/* 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]);