xref: /netbsd-src/tests/net/icmp/t_forward.c (revision c54cb81102ced2313cb40993fe05548aca9933a1)
1*c54cb811Schristos /*	$NetBSD: t_forward.c,v 1.10 2017/01/13 21:30:42 christos Exp $	*/
23665ca1dSpooka 
33665ca1dSpooka /*-
43665ca1dSpooka  * Copyright (c) 2010 The NetBSD Foundation, Inc.
53665ca1dSpooka  * All rights reserved.
63665ca1dSpooka  *
73665ca1dSpooka  * Redistribution and use in source and binary forms, with or without
83665ca1dSpooka  * modification, are permitted provided that the following conditions
93665ca1dSpooka  * are met:
103665ca1dSpooka  * 1. Redistributions of source code must retain the above copyright
113665ca1dSpooka  *    notice, this list of conditions and the following disclaimer.
123665ca1dSpooka  * 2. Redistributions in binary form must reproduce the above copyright
133665ca1dSpooka  *    notice, this list of conditions and the following disclaimer in the
143665ca1dSpooka  *    documentation and/or other materials provided with the distribution.
153665ca1dSpooka  *
163665ca1dSpooka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
173665ca1dSpooka  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
183665ca1dSpooka  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
193665ca1dSpooka  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
203665ca1dSpooka  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
213665ca1dSpooka  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
223665ca1dSpooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
233665ca1dSpooka  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
243665ca1dSpooka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
253665ca1dSpooka  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
263665ca1dSpooka  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
273665ca1dSpooka  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
283665ca1dSpooka  */
293665ca1dSpooka 
303665ca1dSpooka #include <sys/cdefs.h>
313665ca1dSpooka #ifndef lint
32*c54cb811Schristos __RCSID("$NetBSD: t_forward.c,v 1.10 2017/01/13 21:30:42 christos Exp $");
333665ca1dSpooka #endif /* not lint */
343665ca1dSpooka 
353665ca1dSpooka #include <sys/types.h>
363665ca1dSpooka #include <sys/socket.h>
373665ca1dSpooka #include <sys/time.h>
383665ca1dSpooka #include <sys/sysctl.h>
393665ca1dSpooka #include <sys/wait.h>
403665ca1dSpooka 
413665ca1dSpooka #include <arpa/inet.h>
423665ca1dSpooka 
433665ca1dSpooka #include <netinet/in.h>
443665ca1dSpooka #include <netinet/in_systm.h>
453665ca1dSpooka #include <netinet/ip.h>
463665ca1dSpooka #include <netinet/ip_icmp.h>
473665ca1dSpooka #include <netinet/icmp_var.h>
483665ca1dSpooka #include <net/route.h>
493665ca1dSpooka 
503665ca1dSpooka #include <rump/rump.h>
513665ca1dSpooka #include <rump/rump_syscalls.h>
523665ca1dSpooka 
533665ca1dSpooka #include <atf-c.h>
543665ca1dSpooka #include <errno.h>
553665ca1dSpooka #include <stdio.h>
563665ca1dSpooka #include <stdlib.h>
573665ca1dSpooka #include <string.h>
583665ca1dSpooka #include <unistd.h>
593665ca1dSpooka 
60*c54cb811Schristos #include "h_macros.h"
61772871eaSpooka #include "../config/netconfig.c"
623665ca1dSpooka 
633665ca1dSpooka /*
643665ca1dSpooka  * Since our maxttl is in our private namespace, we don't need raw packet
653665ca1dSpooka  * construction like traceroute(8) -- we can just use the global maxttl.
663665ca1dSpooka  */
673665ca1dSpooka static void
sendttl(void)683665ca1dSpooka sendttl(void)
693665ca1dSpooka {
703665ca1dSpooka 	struct sockaddr_in sin;
713665ca1dSpooka 	char payload[1024];
72772871eaSpooka 	char ifname[IFNAMSIZ];
733665ca1dSpooka 	int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
743665ca1dSpooka 	int nv;
753665ca1dSpooka 	int s;
763665ca1dSpooka 
77772871eaSpooka 	netcfg_rump_makeshmif("bus1", ifname);
786b624412Spooka 	netcfg_rump_if(ifname, "1.0.0.1", "255.255.255.0");
79772871eaSpooka 	netcfg_rump_route("0.0.0.0", "0.0.0.0", "1.0.0.2"); /* default router */
803665ca1dSpooka 
813665ca1dSpooka 	/* set global ttl to 1 */
823665ca1dSpooka 	nv = 1;
833665ca1dSpooka 	if (rump_sys___sysctl(mib, 4, NULL, NULL, &nv, sizeof(nv)) == -1)
843665ca1dSpooka 		atf_tc_fail_errno("set ttl");
853665ca1dSpooka 
863665ca1dSpooka 	s = rump_sys_socket(PF_INET, SOCK_DGRAM, 0);
873665ca1dSpooka 	if (s == -1)
883665ca1dSpooka 		atf_tc_fail_errno("create send socket");
893665ca1dSpooka 
903665ca1dSpooka 	memset(&sin, 0, sizeof(sin));
913665ca1dSpooka 	sin.sin_len = sizeof(sin);
923665ca1dSpooka 	sin.sin_family = AF_INET;
933665ca1dSpooka 	sin.sin_port = htons(33434);
943665ca1dSpooka 	sin.sin_addr.s_addr = inet_addr("9.9.9.9");
953665ca1dSpooka 
963665ca1dSpooka 	/* send udp datagram with ttl == 1 */
973665ca1dSpooka 	if (rump_sys_sendto(s, payload, sizeof(payload), 0,
983665ca1dSpooka 	    (struct sockaddr *)&sin, sizeof(sin)) == -1)
993665ca1dSpooka 		atf_tc_fail_errno("sendto");
1003665ca1dSpooka }
1013665ca1dSpooka 
1023665ca1dSpooka static void
router(void)1033665ca1dSpooka router(void)
1043665ca1dSpooka {
1053665ca1dSpooka 	int mib[4] = { CTL_NET, PF_INET, IPPROTO_ICMP,
1063665ca1dSpooka 		    ICMPCTL_RETURNDATABYTES };
1073c23c993Spooka 	char ifname[IFNAMSIZ];
1083665ca1dSpooka 	int nv;
1093665ca1dSpooka 
1103665ca1dSpooka 	/* set returndatabytes to 200 */
1113665ca1dSpooka 	nv = 200;
1123665ca1dSpooka 	if (rump_sys___sysctl(mib, 4, NULL, NULL, &nv, sizeof(nv)) == -1)
1133665ca1dSpooka 		atf_tc_fail_errno("sysctl returndatabytes");
1143665ca1dSpooka 
1153c23c993Spooka 	netcfg_rump_makeshmif("bus1", ifname);
1163c23c993Spooka 	netcfg_rump_if(ifname, "1.0.0.2", "255.255.255.0");
1173665ca1dSpooka 
1183665ca1dSpooka 	/*
1193665ca1dSpooka 	 * Wait for parent to send us the data and for us to have
1203665ca1dSpooka 	 * a chance to process it.
1213665ca1dSpooka 	 */
1223665ca1dSpooka 	sleep(1);
1233665ca1dSpooka 	exit(0);
1243665ca1dSpooka }
1253665ca1dSpooka 
1263665ca1dSpooka ATF_TC(returndatabytes);
ATF_TC_HEAD(returndatabytes,tc)1273665ca1dSpooka ATF_TC_HEAD(returndatabytes, tc)
1283665ca1dSpooka {
1293665ca1dSpooka 
1303665ca1dSpooka 	atf_tc_set_md_var(tc, "descr", "icmp.returndatabytes with certain "
131543143cfSjruoho 	    "packets can cause kernel panic (PR kern/43548)");
132270998d2Smartin 	atf_tc_set_md_var(tc, "timeout", "20"); /* just in case */
1333665ca1dSpooka }
1343665ca1dSpooka 
ATF_TC_BODY(returndatabytes,tc)1353665ca1dSpooka ATF_TC_BODY(returndatabytes, tc)
1363665ca1dSpooka {
1373665ca1dSpooka 	pid_t cpid;
1383665ca1dSpooka 	int status;
1393665ca1dSpooka 
1403665ca1dSpooka 	cpid = fork();
1413665ca1dSpooka 	rump_init();
1423665ca1dSpooka 
1433665ca1dSpooka 	switch (cpid) {
1443665ca1dSpooka 	case -1:
1453665ca1dSpooka 		atf_tc_fail_errno("fork failed");
1463665ca1dSpooka 	case 0:
1473665ca1dSpooka 		router();
1483665ca1dSpooka 		break;
1493665ca1dSpooka 	default:
1503665ca1dSpooka 		sendttl();
1513665ca1dSpooka 		if (wait(&status) == -1)
1523665ca1dSpooka 			atf_tc_fail_errno("wait");
1533665ca1dSpooka 		if (WIFEXITED(status)) {
1543665ca1dSpooka 			if (WEXITSTATUS(status))
1553665ca1dSpooka 				atf_tc_fail("child exited with status %d",
1563665ca1dSpooka 				    WEXITSTATUS(status));
1573665ca1dSpooka 		} else {
1583665ca1dSpooka 			atf_tc_fail("child died");
1593665ca1dSpooka 		}
1603665ca1dSpooka 	}
1613665ca1dSpooka }
1623665ca1dSpooka 
ATF_TP_ADD_TCS(tp)1633665ca1dSpooka ATF_TP_ADD_TCS(tp)
1643665ca1dSpooka {
1653665ca1dSpooka 
1663665ca1dSpooka 	ATF_TP_ADD_TC(tp, returndatabytes);
1673665ca1dSpooka 
1683665ca1dSpooka 	return atf_no_error();
1693665ca1dSpooka }
170