Importing NetBSD "Kyua" test framework

To do so, a few dependencies have been imported:

 * external/bsd/lutok
 * external/mit/lua
 * external/public-domain/sqlite
 * external/public-domain/xz

The Kyua framework is the new generation of ATF (Automated Test
Framework), it is composed of:

 * external/bsd/atf
 * external/bsd/kyua-atf-compat
 * external/bsd/kyua-cli
 * external/bsd/kyua-tester
 * tests

Kyua/ATF being written in C++, it depends on libstdc++ which is
provided by GCC. As this is not part of the sources, Kyua is only
compiled when the native GCC utils are installed.

To install Kyua do the following:

 * In a cross-build enviromnent, add the following to the build.sh
   commandline: -V MKBINUTILS=yes -V MKGCCCMDS=yes

WARNING:
  At this point the import is still experimental, and not supported
  on native builds (a.k.a make build).

Change-Id: I26aee23c5bbd2d64adcb7c1beb98fe0d479d7ada
This commit is contained in:
2013-07-23 20:43:41 +02:00
committed by Gerrit Code Review
parent 003ff52ebb
commit 11be35a165
2893 changed files with 502052 additions and 2630 deletions
+12
View File
@@ -0,0 +1,12 @@
# $NetBSD: Makefile,v 1.14 2013/07/03 14:01:29 nakayama Exp $
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net
TESTS_SUBDIRS= fdpass net route sys
.if (${MKRUMP} != "no")
TESTS_SUBDIRS+= bpf bpfilter carp icmp if if_loop npf
.endif
.include <bsd.test.mk>
+1
View File
@@ -0,0 +1 @@
.include "../Makefile.inc"
+15
View File
@@ -0,0 +1,15 @@
# $NetBSD: Makefile,v 1.3 2011/01/03 02:53:15 christos Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/bpf
TESTS_C= t_bpf
TESTS_C+= t_div-by-zero
LDADD+= -lrumpnet_shmif
LDADD+= -lrumpdev_bpf -lrumpdev -lrumpnet_netinet -lrumpnet_net
LDADD+= -lrumpnet -lrumpvfs -lrump -lrumpuser -lpthread
.include <bsd.test.mk>
+177
View File
@@ -0,0 +1,177 @@
/* $NetBSD: t_bpf.c,v 1.5 2012/08/14 19:40:30 alnsn Exp $ */
/*-
* Copyright (c) 2010 Antti Kantee. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 <sys/cdefs.h>
__RCSID("$NetBSD: t_bpf.c,v 1.5 2012/08/14 19:40:30 alnsn Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <net/if.h>
#include <net/bpf.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
/* XXX: atf-c.h has collisions with mbuf */
#undef m_type
#undef m_data
#include <atf-c.h>
#include "../../h_macros.h"
#include "../config/netconfig.c"
ATF_TC(bpfwriteleak);
ATF_TC_HEAD(bpfwriteleak, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks that writing to /dev/bpf "
"does not leak mbufs");
}
static int
getmtdata(void)
{
struct mbstat mbstat;
size_t mbstatlen = sizeof(mbstat);
const int mbstat_mib[] = { CTL_KERN, KERN_MBUF, MBUF_STATS };
RL(rump_sys___sysctl(mbstat_mib, __arraycount(mbstat_mib),
&mbstat, &mbstatlen, NULL, 0));
return mbstat.m_mtypes[MT_DATA];
}
ATF_TC_BODY(bpfwriteleak, tc)
{
char buf[28]; /* sizeof(garbage) > etherhdrlen */
struct ifreq ifr;
int ifnum, bpfd;
RZ(rump_init());
RZ(rump_pub_shmif_create(NULL, &ifnum));
sprintf(ifr.ifr_name, "shmif%d", ifnum);
RL(bpfd = rump_sys_open("/dev/bpf", O_RDWR));
RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr));
RL(rump_sys_ioctl(bpfd, BIOCSFEEDBACK, &ifr));
if (getmtdata() != 0)
atf_tc_fail("test precondition failed: MT_DATA mbufs != 0");
ATF_REQUIRE_ERRNO(ENETDOWN, rump_sys_write(bpfd, buf, sizeof(buf))==-1);
ATF_REQUIRE_EQ(getmtdata(), 0);
}
#if (SIZE_MAX > UINT_MAX)
ATF_TC(bpfwritetrunc);
ATF_TC_HEAD(bpfwritetrunc, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks that write to /dev/bpf "
"does not truncate size_t to int");
}
ATF_TC_BODY(bpfwritetrunc, tc)
{
int bpfd;
struct ifreq ifr;
struct iovec *iov;
size_t iovlen, sz;
const size_t extra_bytes = 28;
const size_t total = extra_bytes + UINT_MAX + 1;
long iov_max, vm_page_size; /* round_page wants vm_page_size variable */
memset(&ifr, 0, sizeof(ifr));
iov_max = sysconf(_SC_IOV_MAX);
vm_page_size = sysconf(_SC_PAGE_SIZE);
ATF_REQUIRE(iov_max > 1 && vm_page_size > 1);
/*
* Minimize memory consumption by using many iovecs
* all pointing to one memory region.
*/
iov = calloc(iov_max, sizeof(struct iovec));
ATF_REQUIRE(iov != NULL);
sz = round_page((total + (iov_max - 1)) / iov_max);
iov[0].iov_len = sz;
iov[0].iov_base = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0);
ATF_REQUIRE(iov[0].iov_base != MAP_FAILED);
iovlen = 1;
while (sz + iov[0].iov_len <= total)
{
iov[iovlen].iov_len = iov[0].iov_len;
iov[iovlen].iov_base = iov[0].iov_base;
sz += iov[0].iov_len;
iovlen++;
}
if (sz < total)
{
iov[iovlen].iov_len = total - sz;
iov[iovlen].iov_base = iov[0].iov_base;
iovlen++;
}
/* Sanity checks */
ATF_REQUIRE(iovlen >= 1 && iovlen <= (size_t)iov_max);
ATF_REQUIRE_EQ(iov[iovlen-1].iov_len, total % iov[0].iov_len);
RZ(rump_init());
netcfg_rump_makeshmif("bpfwritetrunc", ifr.ifr_name);
netcfg_rump_if(ifr.ifr_name, "10.1.1.1", "255.0.0.0");
RL(bpfd = rump_sys_open("/dev/bpf", O_RDWR));
RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr));
ATF_CHECK_ERRNO(EMSGSIZE, rump_sys_writev(bpfd, iov, iovlen) == -1);
munmap(iov[0].iov_base, iov[0].iov_len);
free(iov);
}
#endif /* #if (SIZE_MAX > UINT_MAX) */
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, bpfwriteleak);
#if (SIZE_MAX > UINT_MAX)
ATF_TP_ADD_TC(tp, bpfwritetrunc);
#endif
return atf_no_error();
}
+52
View File
@@ -0,0 +1,52 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <atf-c.h>
#include <fcntl.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
ATF_TC(div_by_zero);
ATF_TC_HEAD(div_by_zero, tc)
{
atf_tc_set_md_var(tc, "descr", "Check that BPF rejects a filter "
"which divides by 0");
}
ATF_TC_BODY(div_by_zero, tc)
{
struct bpf_program bp;
int fd;
/*
* Source code for following program:
* link[0:4]/0 = 2
*/
struct bpf_insn bins[] = {
{ 0x20, 0, 0, 0x00000000 },
{ 0x34, 0, 0, 0x00000000 },
{ 0x15, 0, 1, 0x00000002 },
{ 0x6, 0, 0, 0x00000060 },
{ 0x6, 0, 0, 0x00000000 },
};
bp.bf_len = __arraycount(bins);
bp.bf_insns = bins;
rump_init();
fd = rump_sys_open("/dev/bpf", O_RDWR);
ATF_CHECK(fd != -1);
ATF_REQUIRE_EQ_MSG(rump_sys_ioctl(fd, BIOCSETF, &bp), -1,
"bpf accepted program with division by zero");
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, div_by_zero);
return atf_no_error();
}
+14
View File
@@ -0,0 +1,14 @@
# $NetBSD: Makefile,v 1.1 2012/08/14 19:09:15 alnsn Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/bpfilter
TESTS_C= t_bpfilter
LDADD+= -lrumpnet_shmif
LDADD+= -lrumpdev_bpf -lrumpdev -lrumpnet_netinet -lrumpnet_net
LDADD+= -lrumpnet -lrumpvfs -lrump -lrumpuser -lpthread
.include <bsd.test.mk>
+308
View File
@@ -0,0 +1,308 @@
/* $NetBSD: t_bpfilter.c,v 1.6 2012/09/03 21:27:14 alnsn Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
*
* 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 ``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 <sys/cdefs.h>
__RCSID("$NetBSD: t_bpfilter.c,v 1.6 2012/09/03 21:27:14 alnsn Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/mbuf.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <unistd.h>
#include <net/if.h>
#include <net/if_ether.h>
#include <net/bpf.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
/* XXX: atf-c.h has collisions with mbuf */
#undef m_type
#undef m_data
#include <atf-c.h>
#include "../../h_macros.h"
#include "../config/netconfig.c"
#define SNAPLEN UINT32_MAX
#define BMAGIC UINT32_C(0x37)
#define HMAGIC UINT32_C(0xc2c2)
#define WMAGIC UINT32_C(0x7d7d7d7d)
static const char magic_echo_reply_tail[7] = {
BMAGIC,
HMAGIC & 0xff,
HMAGIC & 0xff,
WMAGIC & 0xff,
WMAGIC & 0xff,
WMAGIC & 0xff,
WMAGIC & 0xff
};
/*
* Match ICMP_ECHOREPLY packet with 7 magic bytes at the end.
*/
static struct bpf_insn magic_echo_reply_prog[] = {
BPF_STMT(BPF_LD+BPF_ABS+BPF_B,
sizeof(struct ip) + offsetof(struct icmp, icmp_type)),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ICMP_ECHOREPLY, 1, 0),
BPF_STMT(BPF_RET+BPF_K, 0),
BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), /* A <- len */
BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 7), /* A <- A - 7 */
BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */
BPF_STMT(BPF_LD+BPF_IND+BPF_B, 0),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, BMAGIC, 1, 0),
BPF_STMT(BPF_RET+BPF_K, 0),
BPF_STMT(BPF_LD+BPF_IND+BPF_H, 1),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, HMAGIC, 1, 0),
BPF_STMT(BPF_RET+BPF_K, 0),
BPF_STMT(BPF_LD+BPF_IND+BPF_W, 3),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, WMAGIC, 1, 0),
BPF_STMT(BPF_RET+BPF_K, 0),
BPF_STMT(BPF_RET+BPF_K, SNAPLEN)
};
static uint16_t
in_cksum(void *data, size_t len)
{
uint16_t *buf = data;
unsigned sum;
for (sum = 0; len > 1; len -= 2)
sum += *buf++;
if (len)
sum += *(uint8_t *)buf;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
/*
* Based on netcfg_rump_pingtest().
*/
static bool __unused
pingtest(const char *dst, unsigned int wirelen, const char tail[7])
{
struct timeval tv;
struct sockaddr_in sin;
struct icmp *icmp;
char *pkt;
unsigned int pktsize;
socklen_t slen;
int s;
bool rv = false;
if (wirelen < ETHER_HDR_LEN + sizeof(struct ip))
return false;
pktsize = wirelen - ETHER_HDR_LEN - sizeof(struct ip);
if (pktsize < sizeof(struct icmp) + 7)
return false;
s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
if (s == -1)
return false;
pkt = NULL;
tv.tv_sec = 1;
tv.tv_usec = 0;
if (rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
&tv, sizeof(tv)) == -1)
goto out;
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(dst);
pkt = calloc(1, pktsize);
icmp = (struct icmp *)pkt;
if (pkt == NULL)
goto out;
memcpy(pkt + pktsize - 7, tail, 7);
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_id = htons(37);
icmp->icmp_seq = htons(1);
icmp->icmp_cksum = in_cksum(pkt, pktsize);
slen = sizeof(sin);
if (rump_sys_sendto(s, pkt, pktsize, 0,
(struct sockaddr *)&sin, slen) == -1) {
goto out;
}
if (rump_sys_recvfrom(s, pkt, pktsize, 0,
(struct sockaddr *)&sin, &slen) == -1)
goto out;
rv = true;
out:
if (pkt != NULL)
free(pkt);
rump_sys_close(s);
return rv;
}
static void
magic_ping_test(const char *name, unsigned int wirelen)
{
struct bpf_program prog;
struct bpf_stat bstat;
struct ifreq ifr;
struct timeval tv;
unsigned int bufsize;
bool pinged;
ssize_t n;
char *buf;
pid_t child;
int bpfd;
char token;
int channel[2];
struct bpf_hdr *hdr;
RL(pipe(channel));
prog.bf_len = __arraycount(magic_echo_reply_prog);
prog.bf_insns = magic_echo_reply_prog;
child = fork();
RZ(rump_init());
netcfg_rump_makeshmif(name, ifr.ifr_name);
switch (child) {
case -1:
atf_tc_fail_errno("fork failed");
case 0:
netcfg_rump_if(ifr.ifr_name, "10.1.1.10", "255.0.0.0");
close(channel[0]);
ATF_CHECK(write(channel[1], "U", 1) == 1);
close(channel[1]);
pause();
return;
default:
break;
}
netcfg_rump_if(ifr.ifr_name, "10.1.1.20", "255.0.0.0");
RL(bpfd = rump_sys_open("/dev/bpf", O_RDONLY));
tv.tv_sec = 0;
tv.tv_usec = 500;
RL(rump_sys_ioctl(bpfd, BIOCSRTIMEOUT, &tv));
RL(rump_sys_ioctl(bpfd, BIOCGBLEN, &bufsize));
RL(rump_sys_ioctl(bpfd, BIOCSETF, &prog));
RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr));
close(channel[1]);
ATF_CHECK(read(channel[0], &token, 1) == 1 && token == 'U');
pinged = pingtest("10.1.1.10", wirelen, magic_echo_reply_tail);
ATF_CHECK(pinged);
buf = malloc(bufsize);
hdr = (struct bpf_hdr *)buf;
ATF_REQUIRE(buf != NULL);
ATF_REQUIRE(bufsize > sizeof(struct bpf_hdr));
n = rump_sys_read(bpfd, buf, bufsize);
ATF_CHECK(n > (int)sizeof(struct bpf_hdr));
ATF_CHECK(hdr->bh_caplen == MIN(SNAPLEN, wirelen));
RL(rump_sys_ioctl(bpfd, BIOCGSTATS, &bstat));
ATF_CHECK(bstat.bs_capt >= 1); /* XXX == 1 */
rump_sys_close(bpfd);
free(buf);
close(channel[0]);
kill(child, SIGKILL);
}
ATF_TC(bpfiltercontig);
ATF_TC_HEAD(bpfiltercontig, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks that bpf program "
"can read bytes from contiguous buffer.");
atf_tc_set_md_var(tc, "timeout", "30");
}
ATF_TC_BODY(bpfiltercontig, tc)
{
magic_ping_test("bpfiltercontig", 128);
}
ATF_TC(bpfiltermchain);
ATF_TC_HEAD(bpfiltermchain, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks that bpf program "
"can read bytes from mbuf chain.");
atf_tc_set_md_var(tc, "timeout", "30");
}
ATF_TC_BODY(bpfiltermchain, tc)
{
magic_ping_test("bpfiltermchain", MINCLSIZE + 1);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, bpfiltercontig);
ATF_TP_ADD_TC(tp, bpfiltermchain);
return atf_no_error();
}
+13
View File
@@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.1 2010/08/10 21:55:28 pooka Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/carp
TESTS_C= t_basic
LDADD+= -lrumpnet_shmif -lrumpnet_netinet -lrumpnet_net
LDADD+= -lrumpnet -lrump -lrumpuser -lpthread
.include <bsd.test.mk>
+221
View File
@@ -0,0 +1,221 @@
/* $NetBSD: t_basic.c,v 1.5 2011/06/26 13:13:31 christos Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: t_basic.c,v 1.5 2011/06/26 13:13:31 christos Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip_carp.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include <atf-c.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include "../config/netconfig.c"
#include "../../h_macros.h"
static bool oknow = false;
static void
sighnd(int sig)
{
ATF_REQUIRE_EQ(sig, SIGCHLD);
if (oknow)
return;
atf_tc_fail("child died unexpectedly");
}
ATF_TC(handover);
ATF_TC_HEAD(handover, tc)
{
atf_tc_set_md_var(tc, "descr", "check that carp handover works if "
"the master dies");
}
#define THEBUS "buuuuuuus,etherbus"
static void
child(bool master)
{
char ifname[IFNAMSIZ];
struct carpreq cr;
struct ifreq ifr;
const char *carpif;
int s;
/* helps reading carp debug output */
if (master)
carpif = "carp0";
else
carpif = "carp1";
/*
* Should use sysctl, bug debug is dabug.
*/
{
//extern int rumpns_carp_opts[]; /* XXX */
//rumpns_carp_opts[CARPCTL_LOG] = 1;
}
rump_init();
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, carpif, sizeof(ifr.ifr_name));
RL(s = rump_sys_socket(PF_INET, SOCK_DGRAM, 0));
RL(rump_sys_ioctl(s, SIOCIFCREATE, &ifr));
netcfg_rump_makeshmif(THEBUS, ifname);
if (master)
netcfg_rump_if(ifname, "10.1.1.1", "255.255.255.0");
else
netcfg_rump_if(ifname, "10.1.1.2", "255.255.255.0");
/* configure the carp interface */
ifr.ifr_data = &cr;
RL(rump_sys_ioctl(s, SIOCGVH, &ifr));
strlcpy(cr.carpr_carpdev, ifname, sizeof(cr.carpr_carpdev));
cr.carpr_vhid = 175;
if (master)
cr.carpr_advskew = 0;
else
cr.carpr_advskew = 200;
cr.carpr_advbase = 1;
strcpy((char *)cr.carpr_key, "s3cret");
RL(rump_sys_ioctl(s, SIOCSVH, &ifr));
netcfg_rump_if(carpif, "10.1.1.100", "255.255.255.0");
/* tassa pause()en enka muuta voi */
pause();
}
ATF_TC_BODY(handover, tc)
{
char ifname[IFNAMSIZ];
pid_t mpid, cpid;
int i, status;
signal(SIGCHLD, sighnd);
/* fork master */
switch (mpid = fork()) {
case -1:
atf_tc_fail_errno("fork failed");
/*NOTREACHED*/
case 0:
child(true);
/*NOTREACHED*/
default:
break;
}
usleep(500000);
/* fork backup */
switch (cpid = fork()) {
case -1:
kill(mpid, SIGKILL);
atf_tc_fail_errno("fork failed");
/*NOTREACHED*/
case 0:
child(false);
/*NOTREACHED*/
default:
break;
}
usleep(500000);
rump_init();
netcfg_rump_makeshmif(THEBUS, ifname);
netcfg_rump_if(ifname, "10.1.1.240", "255.255.255.0");
/* check that the primary addresses are up */
ATF_REQUIRE_EQ(netcfg_rump_pingtest("10.1.1.1", 1000), true);
ATF_REQUIRE_EQ(netcfg_rump_pingtest("10.1.1.2", 1000), true);
/* give carp a while to croak */
sleep(4);
/* check that the shared IP works */
ATF_REQUIRE_EQ(netcfg_rump_pingtest("10.1.1.100", 500), true);
/* KILLING SPREE */
oknow = true;
kill(mpid, SIGKILL);
wait(&status);
usleep(10000); /* just in case */
oknow = false;
/* check that primary is now dead */
ATF_REQUIRE_EQ(netcfg_rump_pingtest("10.1.1.1", 100), false);
/* do it in installments. carp will cluck meanwhile */
for (i = 0; i < 5; i++) {
if (netcfg_rump_pingtest("10.1.1.100", 1000) == true)
break;
}
if (i == 5)
atf_tc_fail("failed to failover");
/* to kill the child */
oknow = true;
kill(cpid, SIGKILL);
/* clean & done */
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, handover);
return atf_no_error();
}
+231
View File
@@ -0,0 +1,231 @@
/* $NetBSD: netconfig.c,v 1.8 2013/07/03 19:13:33 pooka Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: netconfig.c,v 1.8 2013/07/03 19:13:33 pooka Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <atf-c.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include "../../h_macros.h"
int noatf;
static void __unused
netcfg_rump_makeshmif(const char *busname, char *ifname)
{
int rv, ifnum;
if ((rv = rump_pub_shmif_create(busname, &ifnum)) != 0) {
if (noatf)
err(1, "makeshmif: rump_pub_shmif_create %d", rv);
else
atf_tc_fail("makeshmif: rump_pub_shmif_create %d", rv);
}
sprintf(ifname, "shmif%d", ifnum);
}
static void __unused
netcfg_rump_if(const char *ifname, const char *addr, const char *mask)
{
struct ifaliasreq ia;
struct sockaddr_in *sin;
in_addr_t inaddr, inmask;
int s, rv;
s = -1;
if ((s = rump_sys_socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
if (noatf)
err(1, "if config socket");
else
atf_tc_fail_errno("if config socket");
}
inaddr = inet_addr(addr);
inmask = inet_addr(mask);
/* Address */
memset(&ia, 0, sizeof(ia));
strcpy(ia.ifra_name, ifname);
sin = (struct sockaddr_in *)&ia.ifra_addr;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_addr.s_addr = inaddr;
/* Netmask */
sin = (struct sockaddr_in *)&ia.ifra_mask;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_addr.s_addr = inmask;
/* Broadcast address */
sin = (struct sockaddr_in *)&ia.ifra_broadaddr;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_addr.s_addr = inaddr | ~inmask;
rv = rump_sys_ioctl(s, SIOCAIFADDR, &ia);
if (rv == -1) {
if (noatf)
err(1, "SIOCAIFADDR");
else
atf_tc_fail_errno("SIOCAIFADDR");
}
rump_sys_close(s);
}
static void __unused
netcfg_rump_route(const char *dst, const char *mask, const char *gw)
{
size_t len;
struct {
struct rt_msghdr m_rtm;
uint8_t m_space[512];
} m_rtmsg;
#define rtm m_rtmsg.m_rtm
uint8_t *bp = m_rtmsg.m_space;
struct sockaddr_in sinstore;
int s, rv;
s = rump_sys_socket(PF_ROUTE, SOCK_RAW, 0);
if (s == -1) {
if (noatf)
err(1, "routing socket");
else
atf_tc_fail_errno("routing socket");
}
memset(&m_rtmsg, 0, sizeof(m_rtmsg));
rtm.rtm_type = RTM_ADD;
rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
rtm.rtm_version = RTM_VERSION;
rtm.rtm_seq = 2;
rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
/* dst */
memset(&sinstore, 0, sizeof(sinstore));
sinstore.sin_family = AF_INET;
sinstore.sin_len = sizeof(sinstore);
sinstore.sin_addr.s_addr = inet_addr(dst);
memcpy(bp, &sinstore, sizeof(sinstore));
bp += sizeof(sinstore);
/* gw */
memset(&sinstore, 0, sizeof(sinstore));
sinstore.sin_family = AF_INET;
sinstore.sin_len = sizeof(sinstore);
sinstore.sin_addr.s_addr = inet_addr(gw);
memcpy(bp, &sinstore, sizeof(sinstore));
bp += sizeof(sinstore);
/* netmask */
memset(&sinstore, 0, sizeof(sinstore));
sinstore.sin_family = AF_INET;
sinstore.sin_len = sizeof(sinstore);
sinstore.sin_addr.s_addr = inet_addr(mask);
memcpy(bp, &sinstore, sizeof(sinstore));
bp += sizeof(sinstore);
len = bp - (uint8_t *)&m_rtmsg;
rtm.rtm_msglen = len;
rv = rump_sys_write(s, &m_rtmsg, len);
if (rv != (int)len) {
if (noatf)
err(1, "write routing message");
else
atf_tc_fail_errno("write routing message");
}
rump_sys_close(s);
}
static bool __unused
netcfg_rump_pingtest(const char *dst, int ms_timo)
{
struct timeval tv;
struct sockaddr_in sin;
struct icmp icmp;
socklen_t slen;
int s;
bool rv = false;
s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
if (s == -1)
return false;
tv.tv_sec = ms_timo / 1000;
tv.tv_usec = 1000 * (ms_timo % 1000);
if (rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
&tv, sizeof(tv)) == -1)
goto out;
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(dst);
memset(&icmp, 0, sizeof(icmp));
icmp.icmp_type = ICMP_ECHO;
icmp.icmp_id = htons(37);
icmp.icmp_cksum = htons(0xf7da); /* precalc */
slen = sizeof(sin);
if (rump_sys_sendto(s, &icmp, sizeof(icmp), 0,
(struct sockaddr *)&sin, slen) == -1) {
goto out;
}
if (rump_sys_recvfrom(s, &icmp, sizeof(icmp), 0,
(struct sockaddr *)&sin, &slen) == -1)
goto out;
rv = true;
out:
rump_sys_close(s);
return rv;
}
+30
View File
@@ -0,0 +1,30 @@
# $NetBSD: Makefile,v 1.4 2012/09/13 21:13:34 joerg Exp $
#
SHLIBDIR= /usr/lib
SHLIBINSTALLDIR= /usr/lib
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/fdpass
TESTS_SH= t_fdpass
PROGS= fdpass64 fdpass32
MAN.fdpass64= # empty
BINDIR.fdpass64= ${TESTSDIR}
.if (${MACHINE} == "sparc64" || ${MACHINE} == "amd64") && ${MKCOMPAT} != "no"
COPTS.fdpass32.c += -m32
LDFLAGS.fdpass32 += -m32
.endif
MAN.fdpass32= # empty
BINDIR.fdpass32= ${TESTSDIR}
fdpass64.c fdpass32.c: fdpass.c
ln -s ${.CURDIR}/fdpass.c ${.TARGET}
CLEANFILES += fdpass64.c fdpass32.c
.include <bsd.test.mk>
+231
View File
@@ -0,0 +1,231 @@
/* $NetBSD: fdpass.c,v 1.1 2012/08/13 11:15:05 christos Exp $ */
/* $OpenBSD: monitor_fdpass.c,v 1.19 2010/01/12 00:58:25 djm Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 <sys/cdefs.h>
__RCSID("$NetBSD: fdpass.c,v 1.1 2012/08/13 11:15:05 christos Exp $");
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <err.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <string.h>
static int debug;
static int
send_fd(int sock, int fd)
{
struct msghdr msg;
union {
struct cmsghdr hdr;
char buf[1024];
} cmsgbuf;
struct cmsghdr *cmsg;
struct iovec vec;
char ch = '\0';
ssize_t n;
struct pollfd pfd;
if (sizeof(cmsgbuf.buf) < CMSG_SPACE(sizeof(int)))
errx(1, "%s: %zu < %zu, recompile", __func__,
sizeof(cmsgbuf.buf), CMSG_SPACE(sizeof(int)));
memset(&msg, 0, sizeof(msg));
msg.msg_control = &cmsgbuf.buf;
msg.msg_controllen = CMSG_SPACE(sizeof(int));
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(cmsg) = fd;
msg.msg_controllen = cmsg->cmsg_len;
vec.iov_base = &ch;
vec.iov_len = 1;
msg.msg_iov = &vec;
msg.msg_iovlen = 1;
pfd.fd = sock;
pfd.events = POLLOUT;
while ((n = sendmsg(sock, &msg, 0)) == -1 &&
(errno == EAGAIN || errno == EINTR)) {
(void)poll(&pfd, 1, -1);
}
switch (n) {
case -1:
err(1, "%s: sendmsg(%d)", __func__, fd);
case 1:
if (debug)
fprintf(stderr, "%d: send fd %d\n", getpid(), fd);
return 0;
default:
errx(1, "%s: sendmsg: expected sent 1 got %ld",
__func__, (long)n);
}
}
static int
recv_fd(int sock)
{
struct msghdr msg;
union {
struct cmsghdr hdr;
char buf[1024];
} cmsgbuf;
struct cmsghdr *cmsg;
struct iovec vec;
ssize_t n;
char ch;
int fd;
struct pollfd pfd;
if (sizeof(cmsgbuf.buf) < CMSG_SPACE(sizeof(int)))
errx(1, "%s: %zu < %zu, recompile", __func__,
sizeof(cmsgbuf.buf), CMSG_SPACE(sizeof(int)));
memset(&msg, 0, sizeof(msg));
vec.iov_base = &ch;
vec.iov_len = 1;
msg.msg_iov = &vec;
msg.msg_iovlen = 1;
msg.msg_control = &cmsgbuf.buf;
msg.msg_controllen = CMSG_SPACE(sizeof(int));
pfd.fd = sock;
pfd.events = POLLIN;
while ((n = recvmsg(sock, &msg, 0)) == -1 &&
(errno == EAGAIN || errno == EINTR)) {
(void)poll(&pfd, 1, -1);
}
switch (n) {
case -1:
err(1, "%s: recvmsg", __func__);
case 1:
break;
default:
errx(1, "%s: recvmsg: expected received 1 got %ld",
__func__, (long)n);
}
cmsg = CMSG_FIRSTHDR(&msg);
if (cmsg == NULL)
errx(1, "%s: no message header", __func__);
if (cmsg->cmsg_type != SCM_RIGHTS)
err(1, "%s: expected type %d got %d", __func__,
SCM_RIGHTS, cmsg->cmsg_type);
fd = (*(int *)CMSG_DATA(cmsg));
if (debug)
fprintf(stderr, "%d: recv fd %d\n", getpid(), fd);
return fd;
}
static void usage(void) __attribute__((__noreturn__));
static void
usage(void)
{
fprintf(stderr, "Usage: %s [-vd] -i <input> -o <output>\n"
"\t %s [-v] -p <progname>\n", getprogname(), getprogname());
exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
int s[2], fd, status, c, verbose;
char buf[1024], *prog;
prog = NULL;
s[0] = s[1] = -1;
verbose = 0;
while ((c = getopt(argc, argv, "di:o:p:")) != -1)
switch (c) {
case 'd':
debug++;
break;
case 'i':
s[0] = atoi(optarg);
break;
case 'o':
s[1] = atoi(optarg);
break;
case 'p':
prog = optarg;
break;
default:
usage();
}
if ((s[0] == -1 && s[1] != -1) || (s[0] != -1 && s[1] == -1))
usage();
if (s[0] == -1) {
if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, s) == -1)
err(1, "socketpair");
} else
goto recv;
switch (fork()) {
case -1:
err(1, "fork");
default:
fd = open("foo", O_RDWR|O_CREAT|O_TRUNC, 0666);
if (fd == -1)
err(1, "open");
send_fd(s[0], fd);
wait(&status);
return 0;
case 0:
if (prog != NULL) {
char i[64], o[64];
snprintf(i, sizeof(i), "%d", s[0]);
snprintf(o, sizeof(o), "%d", s[1]);
execlp(prog, prog, "-i", i, "-o", o, NULL);
err(1, "execlp");
}
recv:
fd = recv_fd(s[1]);
if (verbose) {
snprintf(buf, sizeof(buf), "ls -l /proc/%d/fd",
getpid());
system(buf);
}
if (write(fd, "foo\n", 4) == -1)
err(1, "write");
close(fd);
return 0;
}
}
+99
View File
@@ -0,0 +1,99 @@
# $NetBSD: t_fdpass.sh,v 1.2 2012/08/16 08:39:43 martin Exp $
#
# Copyright (c) 2012 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by Christos Zoulas
#
# 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
#
have32() {
local src="$(atf_get_srcdir)"
if cmp "${src}/fdpass64" "${src}/fdpass32" > /dev/null
then
# echo "no -m32 support"
return 1
else
return 0
fi
}
atf_test_case fdpass_normal
fdpass_normal_head() {
atf_set "descr" "Test file descriptor passing (default)"
}
fdpass_normal_body() {
local src="$(atf_get_srcdir)"
atf_check "${src}/fdpass64"
}
atf_test_case fdpass_compat
fdpass_compat_head() {
atf_set "descr" "Test file descriptor passing (compat)"
}
fdpass_compat_body() {
local src="$(atf_get_srcdir)"
have32 && atf_check "${src}/fdpass32"
}
atf_test_case fdpass_normal_compat
fdpass_normal_compat_head() {
atf_set "descr" "Test file descriptor passing (normal->compat)"
}
fdpass_normal_compat_body() {
local src="$(atf_get_srcdir)"
have32 && atf_check "${src}/fdpass64" -p "${src}/fdpass32"
}
atf_test_case fdpass_compat_normal
fdpass_compat_normal_head() {
atf_set "descr" "Test file descriptor passing (normal->compat)"
}
fdpass_compat_normal_body() {
local src="$(atf_get_srcdir)"
have32 && atf_check "${src}/fdpass32" -p "${src}/fdpass64"
}
atf_init_test_cases()
{
atf_add_test_case fdpass_normal
if have32
then
atf_add_test_case fdpass_compat
atf_add_test_case fdpass_compat_normal
atf_add_test_case fdpass_normal_compat
fi
}
+16
View File
@@ -0,0 +1,16 @@
# $NetBSD: Makefile,v 1.3 2010/12/14 11:03:17 pooka Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/icmp
TESTS_C= t_forward
TESTS_C+= t_ping
TESTS_SH= t_ping2
LDADD+= -lrumpnet_shmif -lrumpnet_netinet -lrumpnet_net -lrumpnet
LDADD+= -lrump -lrumpuser -lpthread
.include <bsd.test.mk>
+169
View File
@@ -0,0 +1,169 @@
/* $NetBSD: t_forward.c,v 1.8 2012/03/18 09:46:50 jruoho Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: t_forward.c,v 1.8 2012/03/18 09:46:50 jruoho Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/sysctl.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp_var.h>
#include <net/route.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include <atf-c.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../../h_macros.h"
#include "../config/netconfig.c"
/*
* Since our maxttl is in our private namespace, we don't need raw packet
* construction like traceroute(8) -- we can just use the global maxttl.
*/
static void
sendttl(void)
{
struct sockaddr_in sin;
char payload[1024];
char ifname[IFNAMSIZ];
int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
int nv;
int s;
netcfg_rump_makeshmif("bus1", ifname);
netcfg_rump_if(ifname, "1.0.0.1", "255.255.255.0");
netcfg_rump_route("0.0.0.0", "0.0.0.0", "1.0.0.2"); /* default router */
/* set global ttl to 1 */
nv = 1;
if (rump_sys___sysctl(mib, 4, NULL, NULL, &nv, sizeof(nv)) == -1)
atf_tc_fail_errno("set ttl");
s = rump_sys_socket(PF_INET, SOCK_DGRAM, 0);
if (s == -1)
atf_tc_fail_errno("create send socket");
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_port = htons(33434);
sin.sin_addr.s_addr = inet_addr("9.9.9.9");
/* send udp datagram with ttl == 1 */
if (rump_sys_sendto(s, payload, sizeof(payload), 0,
(struct sockaddr *)&sin, sizeof(sin)) == -1)
atf_tc_fail_errno("sendto");
}
static void
router(void)
{
int mib[4] = { CTL_NET, PF_INET, IPPROTO_ICMP,
ICMPCTL_RETURNDATABYTES };
char ifname[IFNAMSIZ];
int nv;
/* set returndatabytes to 200 */
nv = 200;
if (rump_sys___sysctl(mib, 4, NULL, NULL, &nv, sizeof(nv)) == -1)
atf_tc_fail_errno("sysctl returndatabytes");
netcfg_rump_makeshmif("bus1", ifname);
netcfg_rump_if(ifname, "1.0.0.2", "255.255.255.0");
/*
* Wait for parent to send us the data and for us to have
* a chance to process it.
*/
sleep(1);
exit(0);
}
ATF_TC(returndatabytes);
ATF_TC_HEAD(returndatabytes, tc)
{
atf_tc_set_md_var(tc, "descr", "icmp.returndatabytes with certain "
"packets can cause kernel panic (PR kern/43548)");
atf_tc_set_md_var(tc, "timeout", "4"); /* just in case */
}
ATF_TC_BODY(returndatabytes, tc)
{
pid_t cpid;
int status;
cpid = fork();
rump_init();
switch (cpid) {
case -1:
atf_tc_fail_errno("fork failed");
case 0:
router();
break;
default:
sendttl();
if (wait(&status) == -1)
atf_tc_fail_errno("wait");
if (WIFEXITED(status)) {
if (WEXITSTATUS(status))
atf_tc_fail("child exited with status %d",
WEXITSTATUS(status));
} else {
atf_tc_fail("child died");
}
}
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, returndatabytes);
return atf_no_error();
}
+438
View File
@@ -0,0 +1,438 @@
/* $NetBSD: t_ping.c,v 1.15 2012/09/04 22:31:58 alnsn Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: t_ping.c,v 1.15 2012/09/04 22:31:58 alnsn Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <sys/wait.h>
#include <atf-c.h>
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <netinet/ip_var.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include "../../h_macros.h"
#include "../config/netconfig.c"
ATF_TC(simpleping);
ATF_TC_HEAD(simpleping, tc)
{
atf_tc_set_md_var(tc, "descr", "check that kernel responds to ping");
atf_tc_set_md_var(tc, "timeout", "2");
}
ATF_TC_BODY(simpleping, tc)
{
char ifname[IFNAMSIZ];
pid_t cpid;
bool win, win2;
char token;
int channel[2];
RL(pipe(channel));
cpid = fork();
rump_init();
netcfg_rump_makeshmif("but-can-i-buy-your-ether-bus", ifname);
switch (cpid) {
case -1:
atf_tc_fail_errno("fork failed");
case 0:
netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0");
close(channel[0]);
ATF_CHECK(write(channel[1], "U", 1) == 1);
close(channel[1]);
pause();
break;
default:
break;
}
close(channel[1]);
ATF_CHECK(read(channel[0], &token, 1) == 1 && token == 'U');
close(channel[0]);
netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0");
/*
* The beauty of shmif is that we don't have races here.
*/
win = netcfg_rump_pingtest("1.1.1.10", 500);
win2 = netcfg_rump_pingtest("1.1.1.30", 500);
kill(cpid, SIGKILL);
if (!win)
atf_tc_fail("ping failed");
if (win2)
atf_tc_fail("non-existent host responded");
}
ATF_TC(floodping);
ATF_TC_HEAD(floodping, tc)
{
atf_tc_set_md_var(tc, "descr", "see how kernel responds to floodping");
}
/* why the hell isn't this available in userspace??? */
static uint16_t
in_cksum(void *data, size_t len)
{
uint16_t *buf = data;
unsigned sum;
for (sum = 0; len > 1; len -= 2)
sum += *buf++;
if (len)
sum += *(uint8_t *)buf;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
static int
doping(const char *target, int loops, u_int pktsize)
{
union {
char buf[IP_MAXPACKET - sizeof(struct ip)];
struct icmp i; /* ensure proper alignment */
} sndbuf;
char recvbuf[IP_MAXPACKET];
struct sockaddr_in dst, pingee;
struct icmp *icmp;
socklen_t slen;
ssize_t n;
int loop, succ;
int x, xnon, s;
RL(s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP));
RL(x = rump_sys_fcntl(s, F_GETFL, 0));
xnon = x | O_NONBLOCK;
memset(&dst, 0, sizeof(dst));
dst.sin_len = sizeof(dst);
dst.sin_family = AF_INET;
dst.sin_addr.s_addr = inet_addr(target);
icmp = (struct icmp *)&sndbuf;
memset(icmp, 0, sizeof(*icmp));
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_id = htons(37);
if (pktsize < sizeof(*icmp))
pktsize = sizeof(*icmp);
if (pktsize > sizeof(sndbuf.buf))
pktsize = sizeof(sndbuf.buf);
RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_SNDBUF,
&pktsize, sizeof(pktsize)));
RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVBUF,
&pktsize, sizeof(pktsize)));
slen = sizeof(pingee);
succ = 0;
for (loop = 0; loop < loops; loop++) {
RL(rump_sys_fcntl(s, F_SETFL, x));
icmp->icmp_seq = htons(loop);
icmp->icmp_cksum = 0;
icmp->icmp_cksum = in_cksum(icmp, pktsize);
RL(rump_sys_sendto(s, icmp, pktsize, 0,
(struct sockaddr *)&dst, sizeof(dst)));
RL(rump_sys_fcntl(s, F_SETFL, xnon));
while ((n = rump_sys_recvfrom(s, recvbuf, sizeof(recvbuf), 0,
(struct sockaddr *)&pingee, &slen)) > 0) {
succ++;
}
if (n == -1 && errno == EAGAIN)
continue;
atf_tc_fail_errno("recv failed");
}
rump_sys_close(s);
return succ;
}
#define LOOPS 10000
ATF_TC_BODY(floodping, tc)
{
char ifname[IFNAMSIZ];
pid_t cpid;
int succ;
cpid = fork();
rump_init();
netcfg_rump_makeshmif("thank-you-driver-for-getting-me-here", ifname);
switch (cpid) {
case -1:
atf_tc_fail_errno("fork failed");
case 0:
netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0");
pause();
break;
default:
break;
}
netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0");
succ = doping("1.1.1.10", LOOPS, 56);
printf("got %d/%d\n", succ, LOOPS);
kill(cpid, SIGKILL);
}
ATF_TC(floodping2);
ATF_TC_HEAD(floodping2, tc)
{
atf_tc_set_md_var(tc, "descr", "two hosts floodpinging each other");
}
ATF_TC_BODY(floodping2, tc)
{
char ifname[IFNAMSIZ];
pid_t cpid;
int succ;
cpid = fork();
rump_init();
netcfg_rump_makeshmif("floodping2", ifname);
switch (cpid) {
case -1:
atf_tc_fail_errno("fork failed");
case 0:
netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0");
succ = doping("1.1.1.20", LOOPS, 56);
break;
default:
netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0");
succ = doping("1.1.1.10", LOOPS, 56);
break;
}
printf("got %d/%d\n", succ, LOOPS);
}
ATF_TC(pingsize);
ATF_TC_HEAD(pingsize, tc)
{
atf_tc_set_md_var(tc, "descr", "ping with packets min <= size <= max");
}
ATF_TC_BODY(pingsize, tc)
{
char ifname[IFNAMSIZ];
pid_t cpid;
int succ, i;
cpid = fork();
rump_init();
netcfg_rump_makeshmif("jippikaiee", ifname);
switch (cpid) {
case -1:
atf_tc_fail_errno("fork failed");
case 0:
netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0");
pause();
break;
default:
break;
}
netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0");
succ = 0;
/* small sizes */
for (i = 0 ; i < IP_MAXPACKET - 60000; i++)
succ += doping("1.1.1.10", 1, i);
/* medium sizes */
for (i = IP_MAXPACKET - 60000; i < IP_MAXPACKET - 100; i += 1000)
succ += doping("1.1.1.10", 1, i);
/* big sizes */
for (i = IP_MAXPACKET - 100; i < IP_MAXPACKET; i += 10)
succ += doping("1.1.1.10", 1, i);
printf("got %d/%d\n", succ, IP_MAXPACKET);
kill(cpid, SIGKILL);
}
ATF_TC(ping_of_death);
ATF_TC_HEAD(ping_of_death, tc)
{
atf_tc_set_md_var(tc, "descr", "send a \"ping of death\"");
atf_tc_set_md_var(tc, "timeout", "2");
}
ATF_TC_BODY(ping_of_death, tc)
{
char data[1500];
struct sockaddr_in dst;
struct ip *ip;
struct icmp *icmp;
char ifname[IFNAMSIZ];
pid_t cpid;
size_t tot, frag;
int s, x, loop;
cpid = fork();
rump_init();
netcfg_rump_makeshmif("jippikaiee", ifname);
switch (cpid) {
case -1:
atf_tc_fail_errno("fork failed");
case 0:
/* wait until we receive a too long IP packet */
for (loop = 0;; loop++) {
uint64_t ipstat[IP_NSTATS];
size_t arglen;
int mib[4];
if (loop == 1)
netcfg_rump_if(ifname,
"1.1.1.10", "255.255.255.0");
mib[0] = CTL_NET;
mib[1] = PF_INET;
mib[2] = IPPROTO_IP;
mib[3] = IPCTL_STATS;
arglen = sizeof(ipstat);
RL(rump_sys___sysctl(mib, 4, &ipstat, &arglen,
NULL, 0));
if (loop == 0 && ipstat[IP_STAT_TOOLONG] != 0)
_exit(1);
if (ipstat[IP_STAT_TOOLONG])
break;
usleep(10000);
}
_exit(0);
break;
default:
break;
}
netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0");
RL(s = rump_sys_socket(PF_INET, SOCK_RAW, 0));
x = 1;
RL(rump_sys_setsockopt(s, IPPROTO_IP, IP_HDRINCL, &x, sizeof(x)));
memset(&dst, 0, sizeof(dst));
dst.sin_len = sizeof(dst);
dst.sin_family = AF_INET;
dst.sin_addr.s_addr = inet_addr("1.1.1.10");
/* construct packet */
memset(data, 0, sizeof(data));
ip = (struct ip *)data;
ip->ip_v = 4;
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_p = IPPROTO_ICMP;
ip->ip_ttl = IPDEFTTL;
ip->ip_dst = dst.sin_addr;
ip->ip_id = 1234;
icmp = (struct icmp *)(ip + 1);
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_cksum = in_cksum(icmp, sizeof(*icmp));
for (;;) {
int status;
/* resolve arp before sending raw stuff */
netcfg_rump_pingtest("1.1.1.10", 1);
for (tot = 0;
tot < 65538 - sizeof(*ip);
tot += (frag - sizeof(*ip))) {
frag = MIN(65538 - tot, sizeof(data));
ip->ip_off = tot >> 3;
assert((size_t)ip->ip_off << 3 == tot);
ip->ip_len = frag;
if (frag == sizeof(data)) {
ip->ip_off |= IP_MF;
}
RL(rump_sys_sendto(s, data, frag, 0,
(struct sockaddr *)&dst, sizeof(dst)));
}
if (waitpid(-1, &status, WNOHANG) > 0) {
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
break;
atf_tc_fail("child did not exit clean");
}
usleep(10000);
}
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, simpleping);
ATF_TP_ADD_TC(tp, floodping);
ATF_TP_ADD_TC(tp, floodping2);
ATF_TP_ADD_TC(tp, pingsize);
ATF_TP_ADD_TC(tp, ping_of_death);
return atf_no_error();
}
+78
View File
@@ -0,0 +1,78 @@
# $NetBSD: t_ping2.sh,v 1.4 2010/12/30 16:58:07 pooka Exp $
#
# Copyright (c) 2010 The NetBSD Foundation, Inc.
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
#
netserver=\
"rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif"
atf_test_case basic cleanup
basic_head()
{
atf_set "descr" "Checks that a simple ping works"
}
docfg ()
{
sock=${1}
addr=${2}
atf_check -s exit:0 \
env RUMP_SERVER=${sock} rump.ifconfig shmif0 create
atf_check -s exit:0 \
env RUMP_SERVER=${sock} rump.ifconfig shmif0 linkstr bus
atf_check -s exit:0 \
env RUMP_SERVER=${sock} rump.ifconfig shmif0 inet ${addr}
}
basic_body()
{
atf_check -s exit:0 ${netserver} unix://commsock1
atf_check -s exit:0 ${netserver} unix://commsock2
docfg unix://commsock1 1.2.3.4
docfg unix://commsock2 1.2.3.5
atf_check -s exit:0 -o ignore \
env RUMP_SERVER=unix://commsock1 rump.ping -n -c 1 1.2.3.5
atf_check -s exit:0 -o ignore \
env RUMP_SERVER=unix://commsock2 rump.ping -n -c 1 1.2.3.5
}
basic_cleanup()
{
env RUMP_SERVER=unix://commsock1 rump.halt
env RUMP_SERVER=unix://commsock2 rump.halt
}
atf_init_test_cases()
{
atf_add_test_case basic
}
+13
View File
@@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.1 2010/11/07 19:53:42 pooka Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/if
TESTS_C= t_compat
LDADD+= -lrumpnet_shmif -lrumpnet_netinet -lrumpnet_net -lrumpnet -lrump
LDADD+= -lrumpuser -lpthread
.include <bsd.test.mk>
+83
View File
@@ -0,0 +1,83 @@
/* $NetBSD: t_compat.c,v 1.1 2010/11/07 19:53:42 pooka Exp $ */
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include "../config/netconfig.c"
/*
* Test for stack smashing in compat ioctl handling. Adapted as an
* atf test from code provided by Onno van der Linden in PR kern/44054
*/
struct oifreq {
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags;
int ifru_metric;
int ifru_mtu;
int ifru_dlt;
u_int ifru_value;
void * ifru_data;
struct {
uint32_t b_buflen;
void *b_buf;
} ifru_b;
} ifr_ifru;
};
#define OOSIOCGIFBRDADDR _IOWR('i', 18, struct oifreq)
ATF_TC(OOSIOCGIFBRDADDR);
ATF_TC_HEAD(OOSIOCGIFBRDADDR, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks that OOSIOCGIFBRDADDR works "
"(PR kern/44054)");
}
ATF_TC_BODY(OOSIOCGIFBRDADDR, tc)
{
int fd, ifnum;
struct oifreq ifreq;
struct sockaddr_in *sin;
int rv;
memset(&ifreq,'\0',sizeof ifreq);
rump_init();
/* create an interface and give it netmask 0xffff0000 */
rv = rump_pub_shmif_create("bus", &ifnum);
if (rv)
atf_tc_fail("failed to create shmif: %s", strerror(rv));
sprintf(ifreq.ifr_name, "shmif%d", ifnum);
netcfg_rump_if(ifreq.ifr_name, "1.7.64.10", "255.255.0.0");
/* query kernel for iface bcast */
RL(fd = rump_sys_socket(AF_INET, SOCK_DGRAM, 0));
RL(rump_sys_ioctl(fd, OOSIOCGIFBRDADDR, &ifreq));
/* make sure we got what we deserve */
sin = (struct sockaddr_in *)&ifreq.ifr_broadaddr;
ATF_REQUIRE_EQ(sin->sin_addr.s_addr, htonl(0x0107ffff));
rump_sys_close(fd);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, OOSIOCGIFBRDADDR);
return atf_no_error();
}
+13
View File
@@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.1 2010/07/25 21:42:08 pooka Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/if_loop
TESTS_C= t_pr
LDADD+= -lrumpnet_netinet -lrumpnet_net -lrumpnet
LDADD+= -lrump -lrumpuser -lpthread
.include <bsd.test.mk>
+229
View File
@@ -0,0 +1,229 @@
/* $NetBSD: t_pr.c,v 1.7 2012/03/18 09:46:50 jruoho Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: t_pr.c,v 1.7 2012/03/18 09:46:50 jruoho Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <netinet/in.h>
#include <net/route.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include <atf-c.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../config/netconfig.c"
#include "../../h_macros.h"
/*
* Prepare rump, configure interface and route to cause fragmentation
*/
static void
setup(void)
{
char ifname[IFNAMSIZ];
struct {
struct rt_msghdr m_rtm;
struct sockaddr_in m_sin;
} m_rtmsg;
#define rtm m_rtmsg.m_rtm
#define rsin m_rtmsg.m_sin
struct ifreq ifr;
int s;
rump_init();
/* first, config lo0 & route */
strcpy(ifname, "lo0");
netcfg_rump_if(ifname, "127.0.0.1", "255.0.0.0");
netcfg_rump_route("127.0.0.1", "255.0.0.0", "127.0.0.1");
if ((s = rump_sys_socket(PF_ROUTE, SOCK_RAW, 0)) == -1)
atf_tc_fail_errno("routing socket");
/*
* set MTU for interface so that route MTU doesn't
* get overridden by it.
*/
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, "lo0");
ifr.ifr_mtu = 1300;
if (rump_sys_ioctl(s, SIOCSIFMTU, &ifr) == -1)
atf_tc_fail_errno("set mtu");
/* change route MTU to 100 */
memset(&m_rtmsg, 0, sizeof(m_rtmsg));
rtm.rtm_type = RTM_CHANGE;
rtm.rtm_flags = RTF_STATIC;
rtm.rtm_version = RTM_VERSION;
rtm.rtm_seq = 3;
rtm.rtm_inits = RTV_MTU;
rtm.rtm_addrs = RTA_DST;
rtm.rtm_rmx.rmx_mtu = 100;
rtm.rtm_msglen = sizeof(m_rtmsg);
memset(&rsin, 0, sizeof(rsin));
rsin.sin_family = AF_INET;
rsin.sin_len = sizeof(rsin);
rsin.sin_addr.s_addr = inet_addr("127.0.0.1");
if (rump_sys_write(s, &m_rtmsg, sizeof(m_rtmsg)) != sizeof(m_rtmsg))
atf_tc_fail_errno("set route mtu");
rump_sys_close(s);
}
/*
* Turn on checksums on loopback interfaces
*/
static int
enable_locsums(void)
{
struct sysctlnode q, ans[256];
int mib[5], enable;
size_t alen;
unsigned i;
mib[0] = CTL_NET;
mib[1] = PF_INET;
mib[2] = IPPROTO_IP;
mib[3] = CTL_QUERY;
alen = sizeof(ans);
memset(&q, 0, sizeof(q));
q.sysctl_flags = SYSCTL_VERSION;
if (rump_sys___sysctl(mib, 4, ans, &alen, &q, sizeof(q)) == -1)
return -1;
for (i = 0; i < __arraycount(ans); i++)
if (strcmp("do_loopback_cksum", ans[i].sysctl_name) == 0)
break;
if (i == __arraycount(ans)) {
errno = ENOENT;
return -1;
}
mib[3] = ans[i].sysctl_num;
enable = 1;
if (rump_sys___sysctl(mib, 4, NULL, NULL, &enable,
sizeof(enable)) == -1)
return errno;
return 0;
}
ATF_TC(loopmtu);
ATF_TC_HEAD(loopmtu, tc)
{
atf_tc_set_md_var(tc, "descr",
"test lo0 fragmentation (PR kern/43664)");
}
ATF_TC_BODY(loopmtu, tc)
{
struct sockaddr_in sin;
char data[2000];
int s;
setup();
/* open raw socket */
s = rump_sys_socket(PF_INET, SOCK_RAW, 0);
if (s == -1)
atf_tc_fail_errno("raw socket");
/* then, send data */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_len = sizeof(sin);
sin.sin_port = htons(12345);
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
if (rump_sys_sendto(s, data, sizeof(data), 0,
(struct sockaddr *)&sin, sizeof(sin)) == -1)
atf_tc_fail_errno("sendto failed");
}
ATF_TC(loopmtu_csum);
ATF_TC_HEAD(loopmtu_csum, tc)
{
atf_tc_set_md_var(tc, "descr",
"test lo0 fragmentation with checksums (PR kern/43664)");
}
ATF_TC_BODY(loopmtu_csum, tc)
{
struct sockaddr_in sin;
char data[2000];
int s;
setup();
ATF_CHECK(enable_locsums() == 0);
/* open raw socket */
s = rump_sys_socket(PF_INET, SOCK_RAW, 0);
if (s == -1)
atf_tc_fail_errno("raw socket");
/* then, send data */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_len = sizeof(sin);
sin.sin_port = htons(12345);
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
if (rump_sys_sendto(s, data, sizeof(data), 0,
(struct sockaddr *)&sin, sizeof(sin)) == -1)
atf_tc_fail_errno("sendto failed");
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, loopmtu);
ATF_TP_ADD_TC(tp, loopmtu_csum);
return atf_no_error();
}
+18
View File
@@ -0,0 +1,18 @@
# $NetBSD: Makefile,v 1.6 2013/07/03 14:01:29 nakayama Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/net
TESTS_C= t_unix
TESTS_C+= t_udp
TESTS_C+= t_pktinfo
.if (${MKRUMP} != "no")
TESTS_C+= t_raw
.endif
LDADD.t_raw+= -lrumpnet_local -lrumpnet_netinet -lrumpnet_net
LDADD.t_raw+= -lrumpnet -lrumpvfs -lrump -lrumpuser -lpthread
.include <bsd.test.mk>
+193
View File
@@ -0,0 +1,193 @@
/* $NetBSD: t_pktinfo.c,v 1.1 2013/06/27 20:01:24 christos Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h>
__RCSID("$NetBSD: t_pktinfo.c,v 1.1 2013/06/27 20:01:24 christos Exp $");
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
static const char traffic[] = "foo";
#ifdef TEST
#include <err.h>
#define ERR(msg) err(EXIT_FAILURE, msg)
#define ERRX(msg, a) errx(EXIT_FAILURE, msg, a)
#define ERRX2(msg, a1, a2) errx(EXIT_FAILURE, msg, a1, a2)
#else
#include <atf-c.h>
#define ERR(msg) ATF_REQUIRE_MSG(0, "%s: %s", msg, strerror(errno))
#define ERRX(msg, a) ATF_REQUIRE_MSG(0, msg, a)
#define ERRX2(msg, a1, a2) ATF_REQUIRE_MSG(0, msg, a1, a2)
#endif
static int
server(struct sockaddr_in *sin) {
int s, one;
socklen_t len = sizeof(*sin);
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
ERR("socket");
memset(sin, 0, len);
sin->sin_family = AF_INET;
sin->sin_len = len;
sin->sin_port = 0;
sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (bind(s, (const struct sockaddr *)sin, len) == -1)
ERR("bind");
if (getsockname(s, (struct sockaddr *)sin, &len) == -1)
ERR("getsockname");
one = 1;
if (setsockopt(s, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)) == -1)
ERR("setsockopt");
if (setsockopt(s, IPPROTO_IP, IP_RECVPKTINFO, &one, sizeof(one)) == -1)
ERR("setsockopt");
return s;
}
static int
client(struct sockaddr_in *sin) {
int s;
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
ERR("socket");
if (sendto(s, traffic, sizeof(traffic), 0,
(const struct sockaddr *)sin, sizeof(*sin)) == -1)
ERR("sendto");
return s;
}
static void
receive(int s) {
struct msghdr msg;
struct cmsghdr *cmsg;
struct iovec iov;
char buf[sizeof(traffic)];
struct in_pktinfo *ipi;
char control[CMSG_SPACE(sizeof(*ipi)) * 2];
memset(&msg, 0, sizeof(msg));
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
memset(&iov, 0, sizeof(iov));
iov.iov_base = buf;
iov.iov_len = sizeof(buf);
msg.msg_iovlen = 1;
msg.msg_control = control;
msg.msg_controllen = sizeof(control);
msg.msg_flags = 0;
if (recvmsg(s, &msg, 0) == -1)
ERR("recvmsg");
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level != IPPROTO_IP)
ERRX("bad level %d", cmsg->cmsg_level);
const char *m;
switch (cmsg->cmsg_type) {
case IP_PKTINFO:
m = "pktinfo";
break;
case IP_RECVPKTINFO:
m = "recvpktinfo";
break;
default:
m = NULL;
ERRX("bad type %d", cmsg->cmsg_type);
}
ipi = (void *)CMSG_DATA(cmsg);
#ifdef TEST
printf("%s message received on address %s at interface %d\n",
m, inet_ntoa(ipi->ipi_addr), ipi->ipi_ifindex);
#else
ATF_REQUIRE_MSG(ipi->ipi_addr.s_addr == htonl(INADDR_LOOPBACK),
"address 0x%x != 0x%x", ipi->ipi_addr.s_addr,
htonl(INADDR_LOOPBACK));
#endif
}
if (strcmp(traffic, buf) != 0)
ERRX2("Bad message '%s' != '%s'", buf, traffic);
}
static void
doit(void)
{
struct sockaddr_in sin;
int s, c;
s = server(&sin);
c = client(&sin);
receive(s);
close(s);
close(c);
}
#ifndef TEST
ATF_TC(pktinfo);
ATF_TC_HEAD(pktinfo, tc)
{
atf_tc_set_md_var(tc, "descr", "Check that IP_PKTINFO and "
"IP_RECVPKTINFO work");
}
ATF_TC_BODY(pktinfo, tc)
{
doit();
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, pktinfo);
return atf_no_error();
}
#else
int
main(int argc, char *argv[]) {
doit();
return 0;
}
#endif
+41
View File
@@ -0,0 +1,41 @@
/* $NetBSD: t_raw.c,v 1.1 2011/01/11 10:51:45 pooka Exp $ */
#include <sys/socket.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include <atf-c.h>
#include "../../h_macros.h"
ATF_TC(PRU_SENSE);
ATF_TC_HEAD(PRU_SENSE, tc)
{
atf_tc_set_md_var(tc, "descr", "Biglock leak with PRU_SENSE on "
"raw sockets (PR kern/44369)");
}
ATF_TC_BODY(PRU_SENSE, tc)
{
struct stat sb;
int s;
rump_init();
RL(s = rump_sys_socket(PF_ROUTE, SOCK_RAW, 0));
/* call PRU_SENSE. unfixed bug causes panic in rump_unschedule() */
RL(rump_sys_fstat(s, &sb));
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, PRU_SENSE);
return atf_no_error();
}
+110
View File
@@ -0,0 +1,110 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD: t_udp.c,v 1.2 2013/01/06 02:22:50 christos Exp $");
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <atf-c.h>
static const char msg[] = "sendto test";
static void
sendit(int family)
{
struct addrinfo hints;
struct addrinfo *res;
int S, s;
int e;
/* lookup localhost addr, depending on argv[1] */
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = 0;
e = getaddrinfo("localhost", "9999", &hints, &res);
ATF_REQUIRE_MSG(e == 0, "getaddrinfo AF=%d: %s", family,
gai_strerror(e));
/* server socket */
S = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
ATF_REQUIRE_MSG(S >= 0, "server-socket AF=%d: %s", family,
strerror(errno));
e = bind(S, res->ai_addr, res->ai_addrlen);
ATF_REQUIRE_MSG(e == 0, "bind AF=%d: %s", family,
strerror(errno));
/* client socket */
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
ATF_REQUIRE_MSG(s >= 0, "client-socket AF=%d: %s", family,
strerror(errno));
/* sendto */
e = sendto(s, msg, sizeof(msg), 0, res->ai_addr, res->ai_addrlen);
ATF_REQUIRE_MSG(e == sizeof(msg), "sendto(1) AF=%d: %s", family,
strerror(errno));
e = sendto(s, msg, sizeof(msg), 0, res->ai_addr, res->ai_addrlen);
ATF_REQUIRE_MSG(e == sizeof(msg), "sendto(2) AF=%d: %s", family,
strerror(errno));
/* connect + send */
e = connect(s, res->ai_addr, res->ai_addrlen);
ATF_REQUIRE_MSG(e == 0, "connect(1) AF=%d: %s", family,
strerror(errno));
e = send(s, msg, sizeof(msg), 0);
ATF_REQUIRE_MSG(e == sizeof(msg), "send(1) AF=%d: %s", family,
strerror(errno));
e = connect(s, res->ai_addr, res->ai_addrlen);
ATF_REQUIRE_MSG(e == 0, "connect(2) AF=%d: %s", family,
strerror(errno));
e = send(s, msg, sizeof(msg), 0);
ATF_REQUIRE_MSG(e == sizeof(msg), "send(2) AF=%d: %s", family,
strerror(errno));
close(s);
}
ATF_TC(udp4_send);
ATF_TC_HEAD(udp4_send, tc)
{
atf_tc_set_md_var(tc, "descr", "Check that inet4 udp send works both"
" for connected and unconnected sockets");
}
ATF_TC_BODY(udp4_send, tc)
{
sendit(AF_INET);
}
ATF_TC(udp6_send);
ATF_TC_HEAD(udp6_send, tc)
{
atf_tc_set_md_var(tc, "descr", "Check that inet6 udp send works both"
" for connected and unconnected sockets");
}
ATF_TC_BODY(udp6_send, tc)
{
sendit(AF_INET6);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, udp4_send);
ATF_TP_ADD_TC(tp, udp6_send);
return atf_no_error();
}
+184
View File
@@ -0,0 +1,184 @@
/* $NetBSD: t_unix.c,v 1.6 2011/10/04 16:28:26 christos Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h>
__RCSID("$Id: t_unix.c,v 1.6 2011/10/04 16:28:26 christos Exp $");
#include <stdio.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef TEST
#define FAIL(msg, ...) err(EXIT_FAILURE, msg, ## __VA_ARGS__)
#else
#include <atf-c.h>
#define FAIL(msg, ...) ATF_CHECK_MSG(0, msg, ## __VA_ARGS__)
#endif
static __dead int
acc(int s)
{
char guard1;
struct sockaddr_un sun;
char guard2;
socklen_t len;
guard1 = guard2 = 's';
len = sizeof(sun);
if (accept(s, (struct sockaddr *)&sun, &len) == -1)
FAIL("accept");
if (guard1 != 's')
errx(EXIT_FAILURE, "guard1 = '%c'", guard1);
if (guard2 != 's')
errx(EXIT_FAILURE, "guard2 = '%c'", guard2);
close(s);
exit(0);
}
static int
test(size_t len)
{
struct sockaddr_un *sun;
int s, s2;
size_t slen;
socklen_t sl;
slen = len + offsetof(struct sockaddr_un, sun_path) + 1;
if ((sun = calloc(1, slen)) == NULL)
FAIL("calloc");
s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s == -1)
FAIL("socket");
memset(sun->sun_path, 'a', len);
sun->sun_path[len] = '\0';
(void)unlink(sun->sun_path);
sl = SUN_LEN(sun);
sun->sun_len = sl;
sun->sun_family = AF_UNIX;
if (bind(s, (struct sockaddr *)sun, sl) == -1) {
if (errno == EINVAL && sl >= 256)
return -1;
FAIL("bind");
}
if (listen(s, 5) == -1)
FAIL("listen");
switch (fork()) {
case -1:
FAIL("fork");
case 0:
acc(s);
/*NOTREACHED*/
default:
sleep(1);
s2 = socket(AF_UNIX, SOCK_STREAM, 0);
if (s2 == -1)
FAIL("socket");
if (connect(s2, (struct sockaddr *)sun, sl) == -1)
FAIL("connect");
close(s2);
break;
}
return 0;
}
#ifndef TEST
ATF_TC(sockaddr_un_len_exceed);
ATF_TC_HEAD(sockaddr_un_len_exceed, tc)
{
atf_tc_set_md_var(tc, "descr", "Check that exceeding the size of "
"unix domain sockets does not trash memory or kernel when "
"exceeding the size of the fixed sun_path");
}
ATF_TC_BODY(sockaddr_un_len_exceed, tc)
{
ATF_REQUIRE_MSG(test(254) == -1, "test(254): %s", strerror(errno));
}
ATF_TC(sockaddr_un_len_max);
ATF_TC_HEAD(sockaddr_un_len_max, tc)
{
atf_tc_set_md_var(tc, "descr", "Check that we can use the maximum "
"unix domain socket pathlen (253): 255 - sizeof(sun_len) - "
"sizeof(sun_family)");
}
ATF_TC_BODY(sockaddr_un_len_max, tc)
{
ATF_REQUIRE_MSG(test(253) == 0, "test(253): %s", strerror(errno));
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, sockaddr_un_len_exceed);
ATF_TP_ADD_TC(tp, sockaddr_un_len_max);
return atf_no_error();
}
#else
int
main(int argc, char *argv[])
{
size_t len;
if (argc == 1) {
fprintf(stderr, "Usage: %s <len>\n", getprogname());
return EXIT_FAILURE;
}
test(atoi(argv[1]));
}
#endif
+12
View File
@@ -0,0 +1,12 @@
# $NetBSD: Makefile,v 1.1 2012/09/12 14:06:31 martin Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/npf
FILESDIR= ${TESTSDIR}
TESTS_SH= t_npf
FILES= ../../../usr.sbin/npf/npftest/npftest.conf
.include <bsd.test.mk>
+63
View File
@@ -0,0 +1,63 @@
# $NetBSD: t_npf.sh,v 1.2 2012/09/18 08:28:15 martin Exp $
#
# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
#
run_test()
{
local name="${1}"
atf_check -o ignore -e ignore npfctl debug "$(atf_get_srcdir)/npftest.conf" ./npf.plist
atf_check -o ignore npftest -c npf.plist -T "${name}"
}
add_test()
{
local name="${1}"; shift
local desc="${*}";
atf_test_case "npf_${name}"
eval "npf_${name}_head() { \
atf_set \"descr\" \"${desc}\"; \
atf_set \"require.progs\" \"npfctl npftest\"; \
}; \
npf_${name}_body() { \
run_test \"${name}\"; \
}"
atf_add_test_case "npf_${name}"
}
atf_init_test_cases()
{
LIST=/tmp/t_npf.$$
trap "rm -f $LIST" EXIT
sh -ec 'npftest -L || printf "dummy\tnone\n"' > $LIST 2>/dev/null
while read tag desc
do
add_test "${tag}" "${desc}"
done < $LIST
}
+10
View File
@@ -0,0 +1,10 @@
# $NetBSD: Makefile,v 1.1 2011/02/08 10:11:29 pooka Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/route
TESTS_SH= t_change
.include <bsd.test.mk>
+65
View File
@@ -0,0 +1,65 @@
# $NetBSD: t_change.sh,v 1.4 2013/02/19 21:08:25 joerg Exp $
#
# Copyright (c) 2011 The NetBSD Foundation, Inc.
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
#
netserver=\
"rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet"
export RUMP_SERVER=unix://commsock
atf_test_case reject2blackhole cleanup
reject2blackhole_head()
{
atf_set "descr" "Change a reject route to blackhole"
atf_set "require.progs" "rump_server"
}
reject2blackhole_body()
{
atf_check -s exit:0 ${netserver} ${RUMP_SERVER}
atf_check -s exit:0 -o ignore \
rump.route add 207.46.197.32 127.0.0.1 -reject
atf_check -s exit:0 -o match:UGHR -x \
"rump.route -n show -inet | grep ^207.46"
atf_check -s exit:0 -o ignore \
rump.route change 207.46.197.32 127.0.0.1 -blackhole
atf_check -s exit:0 -o match:' UGHBS ' -e ignore -x \
"rump.netstat -rn -f inet | grep ^207.46| grep ^207.46"
}
reject2blackhole_cleanup()
{
env RUMP_SERVER=unix://commsock rump.halt
}
atf_init_test_cases()
{
atf_add_test_case reject2blackhole
}
+11
View File
@@ -0,0 +1,11 @@
# $NetBSD: Makefile,v 1.5 2011/11/05 18:19:02 jruoho Exp $
# NOTE: please add all syscall-tests to tests/lib/libc/sys.
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/sys
TESTS_C+= t_rfc6056
.include <bsd.test.mk>
+152
View File
@@ -0,0 +1,152 @@
/* $NetBSD: t_rfc6056.c,v 1.3 2012/06/22 14:54:35 christos Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <sys/cdefs.h>
__RCSID("$NetBSD: t_rfc6056.c,v 1.3 2012/06/22 14:54:35 christos Exp $");
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <netdb.h>
#include <err.h>
#include <atf-c.h>
static void
test(const char *hostname, const char *service, int family, int al)
{
static const char hello[] = "hello\n";
int s, error, proto, option;
struct sockaddr_storage ss;
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM;
switch (family) {
case AF_INET:
proto = IPPROTO_IP;
option = IP_PORTALGO;
break;
case AF_INET6:
proto = IPPROTO_IPV6;
option = IPV6_PORTALGO;
break;
default:
abort();
}
error = getaddrinfo(hostname, service, &hints, &res);
if (error)
errx(EXIT_FAILURE, "Cannot get address for %s (%s)",
hostname, gai_strerror(error));
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s == -1)
err(EXIT_FAILURE, "socket");
if (setsockopt(s, proto, option, &al, sizeof(al)) == -1)
err(EXIT_FAILURE, "setsockopt");
memset(&ss, 0, sizeof(ss));
ss.ss_len = res->ai_addrlen;
ss.ss_family = res->ai_family;
if (bind(s, (struct sockaddr *)&ss, ss.ss_len) == -1)
err(EXIT_FAILURE, "bind");
if (sendto(s, hello, sizeof(hello) - 1, 0,
res->ai_addr, res->ai_addrlen) == -1)
err(EXIT_FAILURE, "sendto");
if (close(s) == -1)
err(EXIT_FAILURE, "close");
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s == -1)
err(EXIT_FAILURE, "socket");
if (setsockopt(s, proto, option, &al, sizeof(al)) == -1)
err(EXIT_FAILURE, "setsockopt");
if (connect(s, res->ai_addr, res->ai_addrlen) == -1)
err(EXIT_FAILURE, "connect");
if (send(s, hello, sizeof(hello) - 1, 0) == -1)
err(EXIT_FAILURE, "send");
if (close(s) == -1)
err(EXIT_FAILURE, "close");
freeaddrinfo(res);
}
ATF_TC(inet4);
ATF_TC_HEAD(inet4, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks random port allocation "
"for ipv4");
}
ATF_TC_BODY(inet4, tc)
{
for (int i = 0; i < 6; i++)
test("localhost", "http", AF_INET, i);
}
ATF_TC(inet6);
ATF_TC_HEAD(inet6, tc)
{
atf_tc_set_md_var(tc, "descr", "Checks random port allocation "
"for ipv6");
}
ATF_TC_BODY(inet6, tc)
{
for (int i = 0; i < 6; i++)
test("localhost", "http", AF_INET6, i);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, inet4);
ATF_TP_ADD_TC(tp, inet6);
return atf_no_error();
}