[Midnightbsd-cvs] src [11970] trunk/tests/sys/netinet: add netinet tests

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jul 28 16:41:21 EDT 2018


Revision: 11970
          http://svnweb.midnightbsd.org/src/?rev=11970
Author:   laffer1
Date:     2018-07-28 16:41:20 -0400 (Sat, 28 Jul 2018)
Log Message:
-----------
add netinet tests

Added Paths:
-----------
    trunk/tests/sys/netinet/
    trunk/tests/sys/netinet/Makefile
    trunk/tests/sys/netinet/fibs_test.sh
    trunk/tests/sys/netinet/udp_dontroute.c

Added: trunk/tests/sys/netinet/Makefile
===================================================================
--- trunk/tests/sys/netinet/Makefile	                        (rev 0)
+++ trunk/tests/sys/netinet/Makefile	2018-07-28 20:41:20 UTC (rev 11970)
@@ -0,0 +1,12 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/tests/sys/netinet/Makefile 276486 2014-12-31 23:25:37Z ngie $
+
+TESTSDIR=	${TESTSBASE}/sys/netinet
+BINDIR=		${TESTSDIR}
+
+ATF_TESTS_SH=	fibs_test
+PROGS=	udp_dontroute
+MAN=
+WARNS?=	6
+
+.include <bsd.test.mk>


Property changes on: trunk/tests/sys/netinet/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tests/sys/netinet/fibs_test.sh
===================================================================
--- trunk/tests/sys/netinet/fibs_test.sh	                        (rev 0)
+++ trunk/tests/sys/netinet/fibs_test.sh	2018-07-28 20:41:20 UTC (rev 11970)
@@ -0,0 +1,489 @@
+#
+#  Copyright (c) 2014 Spectra Logic Corporation
+#  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,
+#     without modification.
+#  2. Redistributions in binary form must reproduce at minimum a disclaimer
+#     substantially similar to the "NO WARRANTY" disclaimer below
+#     ("Disclaimer") and any redistribution must be conditioned upon
+#     including a substantially similar Disclaimer requirement for further
+#     binary redistribution.
+#
+#  NO WARRANTY
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#  HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+#
+#  Authors: Alan Somers         (Spectra Logic Corporation)
+#
+# $MidnightBSD$
+
+# All of the tests in this file requires the test-suite config variable "fibs"
+# to be defined to a space-delimited list of FIBs that may be used for testing.
+
+# arpresolve should check the interface fib for routes to a target when
+# creating an ARP table entry.  This is a regression for kern/167947, where
+# arpresolve only checked the default route.
+#
+# Outline:
+# Create two tap(4) interfaces
+# Simulate a crossover cable between them by using net/socat
+# Use nping (from security/nmap) to send an ICMP echo request from one
+# interface to the other, spoofing the source IP.  The source IP must be
+# spoofed, or else it will already have an entry in the arp table.
+# Check whether an arp entry exists for the spoofed IP
+atf_test_case arpresolve_checks_interface_fib cleanup
+arpresolve_checks_interface_fib_head()
+{
+	atf_set "descr" "arpresolve should check the interface fib, not the default fib, for routes"
+	atf_set "require.user" "root"
+	atf_set "require.config" "fibs"
+	atf_set "require.progs" "socat nping"
+}
+arpresolve_checks_interface_fib_body()
+{
+	# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
+	# and a non-default fib
+	ADDR0="192.0.2.2"
+	ADDR1="192.0.2.3"
+	SUBNET="192.0.2.0"
+	# Due to bug TBD (regressed by multiple_fibs_on_same_subnet) we need
+	# diffferent subnet masks, or FIB1 won't have a subnet route.
+	MASK0="24"
+	MASK1="25"
+	# Spoof a MAC that is reserved per RFC7042
+	SPOOF_ADDR="192.0.2.4"
+	SPOOF_MAC="00:00:5E:00:53:00"
+
+	# Check system configuration
+	if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
+		atf_skip "This test requires net.add_addr_allfibs=0"
+	fi
+	get_fibs 2
+
+	# Configure TAP interfaces
+	setup_tap "$FIB0" ${ADDR0} ${MASK0}
+	TAP0=$TAP
+	setup_tap "$FIB1" ${ADDR1} ${MASK1}
+	TAP1=$TAP
+
+	# Simulate a crossover cable
+	socat /dev/${TAP0} /dev/${TAP1} &
+	SOCAT_PID=$!
+	echo ${SOCAT_PID} >> "processes_to_kill"
+
+	# Send an ICMP echo request with a spoofed source IP
+	setfib 2 nping -c 1 -e ${TAP0} -S ${SPOOF_ADDR} \
+		--source-mac ${SPOOF_MAC} --icmp --icmp-type "echo-request" \
+		--icmp-code 0 --icmp-id 0xdead --icmp-seq 1 --data 0xbeef \
+		${ADDR1}
+	# For informational and debugging purposes only, look for the
+	# characteristic error message
+	dmesg | grep "llinfo.*${SPOOF_ADDR}"
+	# Check that the ARP entry exists
+	atf_check -o match:"${SPOOF_ADDR}.*expires" setfib 3 arp ${SPOOF_ADDR}
+}
+arpresolve_checks_interface_fib_cleanup()
+{
+	if [ -f processes_to_kill ]; then
+		for pid in $(cat processes_to_kill); do
+			kill "${pid}"
+		done
+		rm -f processes_to_kill
+	fi
+	cleanup_tap
+}
+
+
+# Regression test for kern/187549
+atf_test_case loopback_and_network_routes_on_nondefault_fib cleanup
+loopback_and_network_routes_on_nondefault_fib_head()
+{
+	atf_set "descr" "When creating and deleting loopback routes, use the interface's fib"
+	atf_set "require.user" "root"
+	atf_set "require.config" "fibs"
+}
+
+loopback_and_network_routes_on_nondefault_fib_body()
+{
+	# Configure the TAP interface to use an RFC5737 nonrouteable address
+	# and a non-default fib
+	ADDR="192.0.2.2"
+	SUBNET="192.0.2.0"
+	MASK="24"
+
+	# Check system configuration
+	if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
+		atf_skip "This test requires net.add_addr_allfibs=0"
+	fi
+	get_fibs 1
+
+	# Configure a TAP interface
+	setup_tap ${FIB0} ${ADDR} ${MASK}
+
+	# Check whether the host route exists in only the correct FIB
+	setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
+	if [ 0 -ne $? ]; then
+		setfib ${FIB0} netstat -rn -f inet
+		atf_fail "Host route did not appear in the correct FIB"
+	fi
+	setfib 0 netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
+	if [ 0 -eq $? ]; then
+		setfib 0 netstat -rn -f inet
+		atf_fail "Host route appeared in the wrong FIB"
+	fi
+
+	# Check whether the network route exists in only the correct FIB
+	setfib ${FIB0} netstat -rn -f inet | \
+		grep -q "^${SUBNET}/${MASK}.*${TAPD}"
+	if [ 0 -ne $? ]; then
+		setfib ${FIB0} netstat -rn -f inet
+		atf_fail "Network route did not appear in the correct FIB"
+	fi
+	setfib 0 netstat -rn -f inet | \
+		grep -q "^${SUBNET}/${MASK}.*${TAPD}"
+	if [ 0 -eq $? ]; then
+		setfib ${FIB0} netstat -rn -f inet
+		atf_fail "Network route appeared in the wrong FIB"
+	fi
+}
+
+loopback_and_network_routes_on_nondefault_fib_cleanup()
+{
+	cleanup_tap
+}
+
+
+# Regression test for kern/187552
+atf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup
+default_route_with_multiple_fibs_on_same_subnet_head()
+{
+	atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default routes"
+	atf_set "require.user" "root"
+	atf_set "require.config" "fibs"
+}
+
+default_route_with_multiple_fibs_on_same_subnet_body()
+{
+	# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
+	# and a non-default fib
+	ADDR0="192.0.2.2"
+	ADDR1="192.0.2.3"
+	GATEWAY="192.0.2.1"
+	SUBNET="192.0.2.0"
+	MASK="24"
+
+	# Check system configuration
+	if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
+		atf_skip "This test requires net.add_addr_allfibs=0"
+	fi
+	get_fibs 2
+
+	# Configure TAP interfaces
+	setup_tap "$FIB0" ${ADDR0} ${MASK}
+	TAP0=$TAP
+	setup_tap "$FIB1" ${ADDR1} ${MASK}
+	TAP1=$TAP
+
+	# Attempt to add default routes
+	setfib ${FIB0} route add default ${GATEWAY}
+	setfib ${FIB1} route add default ${GATEWAY}
+
+	# Verify that the default route exists for both fibs, with their
+	# respective interfaces.
+	atf_check -o match:"^default.*${TAP0}$" \
+		setfib ${FIB0} netstat -rn -f inet
+	atf_check -o match:"^default.*${TAP1}$" \
+		setfib ${FIB1} netstat -rn -f inet
+}
+
+default_route_with_multiple_fibs_on_same_subnet_cleanup()
+{
+	cleanup_tap
+}
+
+
+# Regression test for PR kern/189089
+# Create two tap interfaces and assign them both the same IP address but with
+# different netmasks, and both on the default FIB.  Then remove one's IP
+# address.  Hopefully the machine won't panic.
+atf_test_case same_ip_multiple_ifaces_fib0 cleanup
+same_ip_multiple_ifaces_fib0_head()
+{
+	atf_set "descr" "Can remove an IP alias from an interface when the same IP is also assigned to another interface."
+	atf_set "require.user" "root"
+	atf_set "require.config" "fibs"
+}
+same_ip_multiple_ifaces_fib0_body()
+{
+	ADDR="192.0.2.2"
+	MASK0="24"
+	MASK1="32"
+
+	# Unlike most of the tests in this file, this is applicable regardless
+	# of net.add_addr_allfibs
+
+	# Setup the interfaces, then remove one alias.  It should not panic.
+	setup_tap 0 ${ADDR} ${MASK0}
+	TAP0=${TAP}
+	setup_tap 0 ${ADDR} ${MASK1}
+	TAP1=${TAP}
+	ifconfig ${TAP1} -alias ${ADDR}
+
+	# Do it again, in the opposite order.  It should not panic.
+	setup_tap 0 ${ADDR} ${MASK0}
+	TAP0=${TAP}
+	setup_tap 0 ${ADDR} ${MASK1}
+	TAP1=${TAP}
+	ifconfig ${TAP0} -alias ${ADDR}
+}
+same_ip_multiple_ifaces_fib0_cleanup()
+{
+	cleanup_tap
+}
+
+# Regression test for PR kern/189088
+# Test that removing an IP address works even if the same IP is assigned to a
+# different interface, on a different FIB.  Tests the same code that whose
+# panic was regressed by same_ip_multiple_ifaces_fib0.  
+# Create two tap interfaces and assign them both the same IP address but with
+# different netmasks, and on different FIBs.  Then remove one's IP
+# address.  Hopefully the machine won't panic.  Also, the IP's hostroute should
+# dissappear from the correct fib.
+atf_test_case same_ip_multiple_ifaces cleanup
+same_ip_multiple_ifaces_head()
+{
+	atf_set "descr" "Can remove an IP alias from an interface when the same IP is also assigned to another interface, on non-default FIBs."
+	atf_set "require.user" "root"
+	atf_set "require.config" "fibs"
+}
+same_ip_multiple_ifaces_body()
+{
+	atf_expect_fail "kern/189088 Assigning the same IP to multiple interfaces in different FIBs creates a host route for only one"
+	ADDR="192.0.2.2"
+	MASK0="24"
+	MASK1="32"
+
+	# Unlike most of the tests in this file, this is applicable regardless
+	# of net.add_addr_allfibs
+	get_fibs 2
+
+	# Setup the interfaces, then remove one alias.  It should not panic.
+	setup_tap ${FIB0} ${ADDR} ${MASK0}
+	TAP0=${TAP}
+	setup_tap ${FIB1} ${ADDR} ${MASK1}
+	TAP1=${TAP}
+	ifconfig ${TAP1} -alias ${ADDR}
+	atf_check -o not-match:"^${ADDR}[[:space:]]" \
+		setfib ${FIB1} netstat -rn -f inet
+
+	# Do it again, in the opposite order.  It should not panic.
+	setup_tap ${FIB0} ${ADDR} ${MASK0}
+	TAP0=${TAP}
+	setup_tap ${FIB1} ${ADDR} ${MASK1}
+	TAP1=${TAP}
+	ifconfig ${TAP0} -alias ${ADDR}
+	atf_check -o not-match:"^${ADDR}[[:space:]]" \
+		setfib ${FIB0} netstat -rn -f inet
+}
+same_ip_multiple_ifaces_cleanup()
+{
+	# Due to PR kern/189088, we must destroy the interfaces in LIFO order
+	# in order for the routes to be correctly cleaned up.
+	for TAPD in `tail -r "tap_devices_to_cleanup"`; do
+		ifconfig ${TAPD} destroy
+	done
+}
+
+# Regression test for kern/187550
+atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup
+subnet_route_with_multiple_fibs_on_same_subnet_head()
+{
+	atf_set "descr" "Multiple FIBs can have subnet routes for the same subnet"
+	atf_set "require.user" "root"
+	atf_set "require.config" "fibs"
+}
+
+subnet_route_with_multiple_fibs_on_same_subnet_body()
+{
+	# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
+	# and a non-default fib
+	ADDR0="192.0.2.2"
+	ADDR1="192.0.2.3"
+	SUBNET="192.0.2.0"
+	MASK="24"
+
+	# Check system configuration
+	if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
+		atf_skip "This test requires net.add_addr_allfibs=0"
+	fi
+	get_fibs 2
+
+	# Configure TAP interfaces
+	setup_tap "$FIB0" ${ADDR0} ${MASK}
+	setup_tap "$FIB1" ${ADDR1} ${MASK}
+
+	# Check that a subnet route exists on both fibs
+	atf_check -o ignore setfib "$FIB0" route get $ADDR1
+	atf_check -o ignore setfib "$FIB1" route get $ADDR0
+}
+
+subnet_route_with_multiple_fibs_on_same_subnet_cleanup()
+{
+	cleanup_tap
+}
+
+# Test that source address selection works correctly for UDP packets with
+# SO_DONTROUTE set that are sent on non-default FIBs.
+# This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host"
+# Regression test for kern/187553
+#
+# The root cause was that ifa_ifwithnet() did not have a fib argument.  It
+# would return an address from an interface on any FIB that had a subnet route
+# for the destination.  If more than one were available, it would choose the
+# most specific.  This is most easily tested by creating a FIB without a
+# default route, then trying to send a UDP packet with SO_DONTROUTE set to an
+# address which is not routable on that FIB.  Absent the fix for this bug,
+# in_pcbladdr would choose an interface on any FIB with a default route.  With
+# the fix, you will get EUNREACH or ENETUNREACH.
+atf_test_case udp_dontroute cleanup
+udp_dontroute_head()
+{
+	atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works"
+	atf_set "require.user" "root"
+	atf_set "require.config" "fibs"
+}
+
+udp_dontroute_body()
+{
+	atf_expect_fail "kern/187553 Source address selection for UDP packets with SO_DONTROUTE uses the default FIB"
+	# Configure the TAP interface to use an RFC5737 nonrouteable address
+	# and a non-default fib
+	ADDR0="192.0.2.2"
+	ADDR1="192.0.2.3"
+	SUBNET="192.0.2.0"
+	MASK="24"
+	# Use a different IP on the same subnet as the target
+	TARGET="192.0.2.100"
+	SRCDIR=`atf_get_srcdir`
+
+	# Check system configuration
+	if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
+		atf_skip "This test requires net.add_addr_allfibs=0"
+	fi
+	get_fibs 2
+
+	# Configure the TAP interfaces
+	setup_tap ${FIB0} ${ADDR0} ${MASK}
+	TARGET_TAP=${TAP}
+	setup_tap ${FIB1} ${ADDR1} ${MASK}
+
+	# Send a UDP packet with SO_DONTROUTE.  In the failure case, it will
+	# return ENETUNREACH, or send the packet to the wrong tap
+	atf_check -o ignore setfib ${FIB0} \
+		${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP}
+	cleanup_tap
+
+	# Repeat, but this time target the other tap
+	setup_tap ${FIB0} ${ADDR0} ${MASK}
+	setup_tap ${FIB1} ${ADDR1} ${MASK}
+	TARGET_TAP=${TAP}
+
+	atf_check -o ignore setfib ${FIB1} \
+		${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP}
+}
+
+udp_dontroute_cleanup()
+{
+	cleanup_tap
+}
+
+
+atf_init_test_cases()
+{
+	atf_add_test_case arpresolve_checks_interface_fib
+	atf_add_test_case loopback_and_network_routes_on_nondefault_fib
+	atf_add_test_case default_route_with_multiple_fibs_on_same_subnet
+	atf_add_test_case same_ip_multiple_ifaces_fib0
+	atf_add_test_case same_ip_multiple_ifaces
+	atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet
+	atf_add_test_case udp_dontroute
+}
+
+# Looks up one or more fibs from the configuration data and validates them.
+# Returns the results in the env varilables FIB0, FIB1, etc.
+
+# parameter numfibs	The number of fibs to lookup
+get_fibs()
+{
+	NUMFIBS=$1
+	net_fibs=`sysctl -n net.fibs`
+	i=0
+	while [ $i -lt "$NUMFIBS" ]; do
+		fib=`atf_config_get "fibs" | \
+			awk -v i=$(( i + 1 )) '{print $i}'`
+		echo "fib is ${fib}"
+		eval FIB${i}=${fib}
+		if [ "$fib" -ge "$net_fibs" ]; then
+			atf_skip "The ${i}th configured fib is ${fib}, which is not less than net.fibs, which is ${net_fibs}"
+		fi
+		i=$(( $i + 1 ))
+	done
+}
+
+# Creates a new tap(4) interface, registers it for cleanup, and returns the
+# name via the environment variable TAP
+get_tap()
+{
+	local TAPN=0
+	while ! ifconfig tap${TAPN} create > /dev/null 2>&1; do
+		if [ "$TAPN" -ge 8 ]; then
+			atf_skip "Could not create a tap(4) interface"
+		else
+			TAPN=$(($TAPN + 1))
+		fi
+	done
+	local TAPD=tap${TAPN}
+	# Record the TAP device so we can clean it up later
+	echo ${TAPD} >> "tap_devices_to_cleanup"
+	TAP=${TAPD}
+}
+
+# Create a tap(4) interface, configure it, and register it for cleanup.
+# parameters:
+# fib
+# IP address
+# Netmask in number of bits (eg 24 or 8)
+# Return: the tap interface name as the env variable TAP
+setup_tap()
+{
+	local FIB=$1
+	local ADDR=$2
+	local MASK=$3
+	get_tap
+	echo setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB
+	setfib ${FIB} ifconfig $TAP ${ADDR}/${MASK} fib $FIB
+}
+
+cleanup_tap()
+{
+	if [ -f tap_devices_to_cleanup ]; then
+		for tap_device in $(cat tap_devices_to_cleanup); do
+			ifconfig "${tap_device}" destroy
+		done
+		rm -f tap_devices_to_cleanup
+	fi
+}


Property changes on: trunk/tests/sys/netinet/fibs_test.sh
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tests/sys/netinet/udp_dontroute.c
===================================================================
--- trunk/tests/sys/netinet/udp_dontroute.c	                        (rev 0)
+++ trunk/tests/sys/netinet/udp_dontroute.c	2018-07-28 20:41:20 UTC (rev 11970)
@@ -0,0 +1,112 @@
+/* $MidnightBSD$ */
+/*
+ *  Copyright (c) 2014 Spectra Logic Corporation
+ *  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,
+ *     without modification.
+ *  2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *     substantially similar to the "NO WARRANTY" disclaimer below
+ *     ("Disclaimer") and any redistribution must be conditioned upon
+ *     including a substantially similar Disclaimer requirement for further
+ *     binary redistribution.
+ *
+ *  NO WARRANTY
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ *  Authors: Alan Somers         (Spectra Logic Corporation)
+ *
+ * $FreeBSD: stable/10/tests/sys/netinet/udp_dontroute.c 267186 2014-06-06 20:35:40Z asomers $
+ */
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * Sends a single UDP packet to the provided address, with SO_DONTROUTE set
+ * I couldn't find a way to do this with builtin utilities like nc(1)
+ */
+int
+main(int argc, char **argv)
+{
+	struct sockaddr_in dst;
+	int s, t;
+	int opt;
+	int ret;
+	ssize_t len;
+	const char* sendbuf = "Hello, World!";
+	const size_t buflen = 80;
+	char recvbuf[buflen];
+
+	if (argc != 3) {
+		fprintf(stderr, "Usage: %s ip_address tapdev\n", argv[0]);
+		exit(2);
+	}
+
+	t = open(argv[2], O_RDWR | O_NONBLOCK);
+	if (t < 0)
+		err(EXIT_FAILURE, "open");
+
+	s = socket(PF_INET, SOCK_DGRAM, 0);
+	if (s < 0)
+		err(EXIT_FAILURE, "socket");
+	opt = 1;
+
+	ret = setsockopt(s, SOL_SOCKET, SO_DONTROUTE, &opt, sizeof(opt));
+	if (ret == -1)
+		err(EXIT_FAILURE, "setsockopt(SO_DONTROUTE)");
+
+	dst.sin_len = sizeof(dst);
+	dst.sin_family = AF_INET;
+	dst.sin_port = htons(46120);
+	dst.sin_addr.s_addr = inet_addr(argv[1]);
+	if (dst.sin_addr.s_addr == htonl(INADDR_NONE)) {
+		fprintf(stderr, "Invalid address: %s\n", argv[1]);
+		exit(2);
+	}
+	ret = sendto(s, sendbuf, strlen(sendbuf), 0, (struct sockaddr*)&dst,
+	    dst.sin_len);
+	if (ret == -1)
+		err(EXIT_FAILURE, "sendto");
+
+	/* Verify that the packet went to the desired tap device */
+
+	len = read(t, recvbuf, buflen);
+	if (len == 0)
+		errx(EXIT_FAILURE, "read returned EOF");
+	else if (len < 0 && errno == EAGAIN)
+		errx(EXIT_FAILURE, "Did not receive any packets");
+	else if (len < 0)
+		err(EXIT_FAILURE, "read");
+
+	/*
+	 * If read returned anything at all, consider it a success.  The packet
+	 * should be an Ethernet frame containing an ARP request for
+	 * ip_address.  We won't bother to decode it
+	 */
+	return (0);
+}


Property changes on: trunk/tests/sys/netinet/udp_dontroute.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list