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