1*640235e2SEnji Cooper /* $NetBSD: t_ping.c,v 1.16 2015/02/26 13:06:10 martin Exp $ */ 257718be8SEnji Cooper 357718be8SEnji Cooper /*- 457718be8SEnji Cooper * Copyright (c) 2010 The NetBSD Foundation, Inc. 557718be8SEnji Cooper * All rights reserved. 657718be8SEnji Cooper * 757718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 857718be8SEnji Cooper * modification, are permitted provided that the following conditions 957718be8SEnji Cooper * are met: 1057718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 1157718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 1257718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1357718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 1457718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 1557718be8SEnji Cooper * 1657718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 1757718be8SEnji Cooper * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 1857718be8SEnji Cooper * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1957718be8SEnji Cooper * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2057718be8SEnji Cooper * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 2157718be8SEnji Cooper * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2257718be8SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 2357718be8SEnji Cooper * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2457718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 2557718be8SEnji Cooper * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2657718be8SEnji Cooper * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 2757718be8SEnji Cooper * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2857718be8SEnji Cooper */ 2957718be8SEnji Cooper 3057718be8SEnji Cooper #include <sys/cdefs.h> 3157718be8SEnji Cooper #ifndef lint 32*640235e2SEnji Cooper __RCSID("$NetBSD: t_ping.c,v 1.16 2015/02/26 13:06:10 martin Exp $"); 3357718be8SEnji Cooper #endif /* not lint */ 3457718be8SEnji Cooper 3557718be8SEnji Cooper #include <sys/types.h> 3657718be8SEnji Cooper #include <sys/resource.h> 3757718be8SEnji Cooper #include <sys/sysctl.h> 3857718be8SEnji Cooper #include <sys/wait.h> 3957718be8SEnji Cooper 4057718be8SEnji Cooper #include <atf-c.h> 4157718be8SEnji Cooper #include <assert.h> 4257718be8SEnji Cooper #include <fcntl.h> 4357718be8SEnji Cooper #include <stdio.h> 4457718be8SEnji Cooper #include <stdlib.h> 4557718be8SEnji Cooper #include <string.h> 4657718be8SEnji Cooper #include <unistd.h> 4757718be8SEnji Cooper #include <signal.h> 4857718be8SEnji Cooper 4957718be8SEnji Cooper #include <netinet/in.h> 5057718be8SEnji Cooper #include <netinet/ip_var.h> 5157718be8SEnji Cooper 5257718be8SEnji Cooper #include <rump/rump.h> 5357718be8SEnji Cooper #include <rump/rump_syscalls.h> 5457718be8SEnji Cooper 5557718be8SEnji Cooper #include "../../h_macros.h" 5657718be8SEnji Cooper #include "../config/netconfig.c" 5757718be8SEnji Cooper 5857718be8SEnji Cooper ATF_TC(simpleping); 5957718be8SEnji Cooper ATF_TC_HEAD(simpleping, tc) 6057718be8SEnji Cooper { 6157718be8SEnji Cooper 6257718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that kernel responds to ping"); 63*640235e2SEnji Cooper atf_tc_set_md_var(tc, "timeout", "20"); 6457718be8SEnji Cooper } 6557718be8SEnji Cooper 6657718be8SEnji Cooper ATF_TC_BODY(simpleping, tc) 6757718be8SEnji Cooper { 6857718be8SEnji Cooper char ifname[IFNAMSIZ]; 6957718be8SEnji Cooper pid_t cpid; 7057718be8SEnji Cooper bool win, win2; 7157718be8SEnji Cooper char token; 7257718be8SEnji Cooper int channel[2]; 7357718be8SEnji Cooper 7457718be8SEnji Cooper RL(pipe(channel)); 7557718be8SEnji Cooper 7657718be8SEnji Cooper cpid = fork(); 7757718be8SEnji Cooper rump_init(); 7857718be8SEnji Cooper netcfg_rump_makeshmif("but-can-i-buy-your-ether-bus", ifname); 7957718be8SEnji Cooper 8057718be8SEnji Cooper switch (cpid) { 8157718be8SEnji Cooper case -1: 8257718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 8357718be8SEnji Cooper case 0: 8457718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); 8557718be8SEnji Cooper close(channel[0]); 8657718be8SEnji Cooper ATF_CHECK(write(channel[1], "U", 1) == 1); 8757718be8SEnji Cooper close(channel[1]); 8857718be8SEnji Cooper pause(); 8957718be8SEnji Cooper break; 9057718be8SEnji Cooper default: 9157718be8SEnji Cooper break; 9257718be8SEnji Cooper } 9357718be8SEnji Cooper 9457718be8SEnji Cooper close(channel[1]); 9557718be8SEnji Cooper ATF_CHECK(read(channel[0], &token, 1) == 1 && token == 'U'); 9657718be8SEnji Cooper close(channel[0]); 9757718be8SEnji Cooper 9857718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 9957718be8SEnji Cooper 10057718be8SEnji Cooper /* 10157718be8SEnji Cooper * The beauty of shmif is that we don't have races here. 10257718be8SEnji Cooper */ 10357718be8SEnji Cooper win = netcfg_rump_pingtest("1.1.1.10", 500); 10457718be8SEnji Cooper win2 = netcfg_rump_pingtest("1.1.1.30", 500); 10557718be8SEnji Cooper 10657718be8SEnji Cooper kill(cpid, SIGKILL); 10757718be8SEnji Cooper 10857718be8SEnji Cooper if (!win) 10957718be8SEnji Cooper atf_tc_fail("ping failed"); 11057718be8SEnji Cooper if (win2) 11157718be8SEnji Cooper atf_tc_fail("non-existent host responded"); 11257718be8SEnji Cooper } 11357718be8SEnji Cooper 11457718be8SEnji Cooper ATF_TC(floodping); 11557718be8SEnji Cooper ATF_TC_HEAD(floodping, tc) 11657718be8SEnji Cooper { 11757718be8SEnji Cooper 11857718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "see how kernel responds to floodping"); 11957718be8SEnji Cooper } 12057718be8SEnji Cooper 12157718be8SEnji Cooper /* why the hell isn't this available in userspace??? */ 12257718be8SEnji Cooper static uint16_t 12357718be8SEnji Cooper in_cksum(void *data, size_t len) 12457718be8SEnji Cooper { 12557718be8SEnji Cooper uint16_t *buf = data; 12657718be8SEnji Cooper unsigned sum; 12757718be8SEnji Cooper 12857718be8SEnji Cooper for (sum = 0; len > 1; len -= 2) 12957718be8SEnji Cooper sum += *buf++; 13057718be8SEnji Cooper if (len) 13157718be8SEnji Cooper sum += *(uint8_t *)buf; 13257718be8SEnji Cooper 13357718be8SEnji Cooper sum = (sum >> 16) + (sum & 0xffff); 13457718be8SEnji Cooper sum += (sum >> 16); 13557718be8SEnji Cooper 13657718be8SEnji Cooper return ~sum; 13757718be8SEnji Cooper } 13857718be8SEnji Cooper 13957718be8SEnji Cooper static int 14057718be8SEnji Cooper doping(const char *target, int loops, u_int pktsize) 14157718be8SEnji Cooper { 14257718be8SEnji Cooper union { 14357718be8SEnji Cooper char buf[IP_MAXPACKET - sizeof(struct ip)]; 14457718be8SEnji Cooper struct icmp i; /* ensure proper alignment */ 14557718be8SEnji Cooper } sndbuf; 14657718be8SEnji Cooper char recvbuf[IP_MAXPACKET]; 14757718be8SEnji Cooper struct sockaddr_in dst, pingee; 14857718be8SEnji Cooper struct icmp *icmp; 14957718be8SEnji Cooper socklen_t slen; 15057718be8SEnji Cooper ssize_t n; 15157718be8SEnji Cooper int loop, succ; 15257718be8SEnji Cooper int x, xnon, s; 15357718be8SEnji Cooper 15457718be8SEnji Cooper RL(s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)); 15557718be8SEnji Cooper RL(x = rump_sys_fcntl(s, F_GETFL, 0)); 15657718be8SEnji Cooper xnon = x | O_NONBLOCK; 15757718be8SEnji Cooper 15857718be8SEnji Cooper memset(&dst, 0, sizeof(dst)); 15957718be8SEnji Cooper dst.sin_len = sizeof(dst); 16057718be8SEnji Cooper dst.sin_family = AF_INET; 16157718be8SEnji Cooper dst.sin_addr.s_addr = inet_addr(target); 16257718be8SEnji Cooper 16357718be8SEnji Cooper icmp = (struct icmp *)&sndbuf; 16457718be8SEnji Cooper memset(icmp, 0, sizeof(*icmp)); 16557718be8SEnji Cooper icmp->icmp_type = ICMP_ECHO; 16657718be8SEnji Cooper icmp->icmp_id = htons(37); 16757718be8SEnji Cooper 16857718be8SEnji Cooper if (pktsize < sizeof(*icmp)) 16957718be8SEnji Cooper pktsize = sizeof(*icmp); 17057718be8SEnji Cooper if (pktsize > sizeof(sndbuf.buf)) 17157718be8SEnji Cooper pktsize = sizeof(sndbuf.buf); 17257718be8SEnji Cooper 17357718be8SEnji Cooper RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_SNDBUF, 17457718be8SEnji Cooper &pktsize, sizeof(pktsize))); 17557718be8SEnji Cooper RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVBUF, 17657718be8SEnji Cooper &pktsize, sizeof(pktsize))); 17757718be8SEnji Cooper 17857718be8SEnji Cooper slen = sizeof(pingee); 17957718be8SEnji Cooper succ = 0; 18057718be8SEnji Cooper for (loop = 0; loop < loops; loop++) { 18157718be8SEnji Cooper RL(rump_sys_fcntl(s, F_SETFL, x)); 18257718be8SEnji Cooper icmp->icmp_seq = htons(loop); 18357718be8SEnji Cooper icmp->icmp_cksum = 0; 18457718be8SEnji Cooper icmp->icmp_cksum = in_cksum(icmp, pktsize); 18557718be8SEnji Cooper RL(rump_sys_sendto(s, icmp, pktsize, 0, 18657718be8SEnji Cooper (struct sockaddr *)&dst, sizeof(dst))); 18757718be8SEnji Cooper 18857718be8SEnji Cooper RL(rump_sys_fcntl(s, F_SETFL, xnon)); 18957718be8SEnji Cooper while ((n = rump_sys_recvfrom(s, recvbuf, sizeof(recvbuf), 0, 19057718be8SEnji Cooper (struct sockaddr *)&pingee, &slen)) > 0) { 19157718be8SEnji Cooper succ++; 19257718be8SEnji Cooper } 19357718be8SEnji Cooper if (n == -1 && errno == EAGAIN) 19457718be8SEnji Cooper continue; 19557718be8SEnji Cooper atf_tc_fail_errno("recv failed"); 19657718be8SEnji Cooper } 19757718be8SEnji Cooper 19857718be8SEnji Cooper rump_sys_close(s); 19957718be8SEnji Cooper return succ; 20057718be8SEnji Cooper } 20157718be8SEnji Cooper 20257718be8SEnji Cooper #define LOOPS 10000 20357718be8SEnji Cooper 20457718be8SEnji Cooper ATF_TC_BODY(floodping, tc) 20557718be8SEnji Cooper { 20657718be8SEnji Cooper char ifname[IFNAMSIZ]; 20757718be8SEnji Cooper pid_t cpid; 20857718be8SEnji Cooper int succ; 20957718be8SEnji Cooper 21057718be8SEnji Cooper cpid = fork(); 21157718be8SEnji Cooper rump_init(); 21257718be8SEnji Cooper netcfg_rump_makeshmif("thank-you-driver-for-getting-me-here", ifname); 21357718be8SEnji Cooper 21457718be8SEnji Cooper switch (cpid) { 21557718be8SEnji Cooper case -1: 21657718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 21757718be8SEnji Cooper case 0: 21857718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); 21957718be8SEnji Cooper pause(); 22057718be8SEnji Cooper break; 22157718be8SEnji Cooper default: 22257718be8SEnji Cooper break; 22357718be8SEnji Cooper } 22457718be8SEnji Cooper 22557718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 22657718be8SEnji Cooper 22757718be8SEnji Cooper succ = doping("1.1.1.10", LOOPS, 56); 22857718be8SEnji Cooper printf("got %d/%d\n", succ, LOOPS); 22957718be8SEnji Cooper 23057718be8SEnji Cooper kill(cpid, SIGKILL); 23157718be8SEnji Cooper } 23257718be8SEnji Cooper 23357718be8SEnji Cooper ATF_TC(floodping2); 23457718be8SEnji Cooper ATF_TC_HEAD(floodping2, tc) 23557718be8SEnji Cooper { 23657718be8SEnji Cooper 23757718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "two hosts floodpinging each other"); 23857718be8SEnji Cooper } 23957718be8SEnji Cooper 24057718be8SEnji Cooper ATF_TC_BODY(floodping2, tc) 24157718be8SEnji Cooper { 24257718be8SEnji Cooper char ifname[IFNAMSIZ]; 24357718be8SEnji Cooper pid_t cpid; 24457718be8SEnji Cooper int succ; 24557718be8SEnji Cooper 24657718be8SEnji Cooper cpid = fork(); 24757718be8SEnji Cooper rump_init(); 24857718be8SEnji Cooper netcfg_rump_makeshmif("floodping2", ifname); 24957718be8SEnji Cooper 25057718be8SEnji Cooper switch (cpid) { 25157718be8SEnji Cooper case -1: 25257718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 25357718be8SEnji Cooper case 0: 25457718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); 25557718be8SEnji Cooper succ = doping("1.1.1.20", LOOPS, 56); 25657718be8SEnji Cooper break; 25757718be8SEnji Cooper default: 25857718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 25957718be8SEnji Cooper succ = doping("1.1.1.10", LOOPS, 56); 26057718be8SEnji Cooper break; 26157718be8SEnji Cooper } 26257718be8SEnji Cooper 26357718be8SEnji Cooper printf("got %d/%d\n", succ, LOOPS); 26457718be8SEnji Cooper } 26557718be8SEnji Cooper 26657718be8SEnji Cooper ATF_TC(pingsize); 26757718be8SEnji Cooper ATF_TC_HEAD(pingsize, tc) 26857718be8SEnji Cooper { 26957718be8SEnji Cooper 27057718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "ping with packets min <= size <= max"); 27157718be8SEnji Cooper } 27257718be8SEnji Cooper 27357718be8SEnji Cooper ATF_TC_BODY(pingsize, tc) 27457718be8SEnji Cooper { 27557718be8SEnji Cooper char ifname[IFNAMSIZ]; 27657718be8SEnji Cooper pid_t cpid; 27757718be8SEnji Cooper int succ, i; 27857718be8SEnji Cooper 27957718be8SEnji Cooper cpid = fork(); 28057718be8SEnji Cooper rump_init(); 28157718be8SEnji Cooper netcfg_rump_makeshmif("jippikaiee", ifname); 28257718be8SEnji Cooper 28357718be8SEnji Cooper switch (cpid) { 28457718be8SEnji Cooper case -1: 28557718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 28657718be8SEnji Cooper case 0: 28757718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); 28857718be8SEnji Cooper pause(); 28957718be8SEnji Cooper break; 29057718be8SEnji Cooper default: 29157718be8SEnji Cooper break; 29257718be8SEnji Cooper } 29357718be8SEnji Cooper 29457718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 29557718be8SEnji Cooper 29657718be8SEnji Cooper succ = 0; 29757718be8SEnji Cooper 29857718be8SEnji Cooper /* small sizes */ 29957718be8SEnji Cooper for (i = 0 ; i < IP_MAXPACKET - 60000; i++) 30057718be8SEnji Cooper succ += doping("1.1.1.10", 1, i); 30157718be8SEnji Cooper 30257718be8SEnji Cooper /* medium sizes */ 30357718be8SEnji Cooper for (i = IP_MAXPACKET - 60000; i < IP_MAXPACKET - 100; i += 1000) 30457718be8SEnji Cooper succ += doping("1.1.1.10", 1, i); 30557718be8SEnji Cooper 30657718be8SEnji Cooper /* big sizes */ 30757718be8SEnji Cooper for (i = IP_MAXPACKET - 100; i < IP_MAXPACKET; i += 10) 30857718be8SEnji Cooper succ += doping("1.1.1.10", 1, i); 30957718be8SEnji Cooper 31057718be8SEnji Cooper printf("got %d/%d\n", succ, IP_MAXPACKET); 31157718be8SEnji Cooper kill(cpid, SIGKILL); 31257718be8SEnji Cooper } 31357718be8SEnji Cooper 31457718be8SEnji Cooper ATF_TC(ping_of_death); 31557718be8SEnji Cooper ATF_TC_HEAD(ping_of_death, tc) 31657718be8SEnji Cooper { 31757718be8SEnji Cooper 31857718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "send a \"ping of death\""); 319*640235e2SEnji Cooper atf_tc_set_md_var(tc, "timeout", "20"); 32057718be8SEnji Cooper } 32157718be8SEnji Cooper 32257718be8SEnji Cooper ATF_TC_BODY(ping_of_death, tc) 32357718be8SEnji Cooper { 32457718be8SEnji Cooper char data[1500]; 32557718be8SEnji Cooper struct sockaddr_in dst; 32657718be8SEnji Cooper struct ip *ip; 32757718be8SEnji Cooper struct icmp *icmp; 32857718be8SEnji Cooper char ifname[IFNAMSIZ]; 32957718be8SEnji Cooper pid_t cpid; 33057718be8SEnji Cooper size_t tot, frag; 33157718be8SEnji Cooper int s, x, loop; 33257718be8SEnji Cooper 33357718be8SEnji Cooper cpid = fork(); 33457718be8SEnji Cooper rump_init(); 33557718be8SEnji Cooper netcfg_rump_makeshmif("jippikaiee", ifname); 33657718be8SEnji Cooper 33757718be8SEnji Cooper switch (cpid) { 33857718be8SEnji Cooper case -1: 33957718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 34057718be8SEnji Cooper case 0: 34157718be8SEnji Cooper /* wait until we receive a too long IP packet */ 34257718be8SEnji Cooper for (loop = 0;; loop++) { 34357718be8SEnji Cooper uint64_t ipstat[IP_NSTATS]; 34457718be8SEnji Cooper size_t arglen; 34557718be8SEnji Cooper int mib[4]; 34657718be8SEnji Cooper 34757718be8SEnji Cooper if (loop == 1) 34857718be8SEnji Cooper netcfg_rump_if(ifname, 34957718be8SEnji Cooper "1.1.1.10", "255.255.255.0"); 35057718be8SEnji Cooper 35157718be8SEnji Cooper mib[0] = CTL_NET; 35257718be8SEnji Cooper mib[1] = PF_INET; 35357718be8SEnji Cooper mib[2] = IPPROTO_IP; 35457718be8SEnji Cooper mib[3] = IPCTL_STATS; 35557718be8SEnji Cooper 35657718be8SEnji Cooper arglen = sizeof(ipstat); 35757718be8SEnji Cooper RL(rump_sys___sysctl(mib, 4, &ipstat, &arglen, 35857718be8SEnji Cooper NULL, 0)); 35957718be8SEnji Cooper if (loop == 0 && ipstat[IP_STAT_TOOLONG] != 0) 36057718be8SEnji Cooper _exit(1); 36157718be8SEnji Cooper if (ipstat[IP_STAT_TOOLONG]) 36257718be8SEnji Cooper break; 36357718be8SEnji Cooper usleep(10000); 36457718be8SEnji Cooper } 36557718be8SEnji Cooper 36657718be8SEnji Cooper _exit(0); 36757718be8SEnji Cooper break; 36857718be8SEnji Cooper default: 36957718be8SEnji Cooper break; 37057718be8SEnji Cooper } 37157718be8SEnji Cooper 37257718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 37357718be8SEnji Cooper 37457718be8SEnji Cooper RL(s = rump_sys_socket(PF_INET, SOCK_RAW, 0)); 37557718be8SEnji Cooper x = 1; 37657718be8SEnji Cooper RL(rump_sys_setsockopt(s, IPPROTO_IP, IP_HDRINCL, &x, sizeof(x))); 37757718be8SEnji Cooper 37857718be8SEnji Cooper memset(&dst, 0, sizeof(dst)); 37957718be8SEnji Cooper dst.sin_len = sizeof(dst); 38057718be8SEnji Cooper dst.sin_family = AF_INET; 38157718be8SEnji Cooper dst.sin_addr.s_addr = inet_addr("1.1.1.10"); 38257718be8SEnji Cooper 38357718be8SEnji Cooper /* construct packet */ 38457718be8SEnji Cooper memset(data, 0, sizeof(data)); 38557718be8SEnji Cooper ip = (struct ip *)data; 38657718be8SEnji Cooper ip->ip_v = 4; 38757718be8SEnji Cooper ip->ip_hl = sizeof(*ip) >> 2; 38857718be8SEnji Cooper ip->ip_p = IPPROTO_ICMP; 38957718be8SEnji Cooper ip->ip_ttl = IPDEFTTL; 39057718be8SEnji Cooper ip->ip_dst = dst.sin_addr; 39157718be8SEnji Cooper ip->ip_id = 1234; 39257718be8SEnji Cooper 39357718be8SEnji Cooper icmp = (struct icmp *)(ip + 1); 39457718be8SEnji Cooper icmp->icmp_type = ICMP_ECHO; 39557718be8SEnji Cooper icmp->icmp_cksum = in_cksum(icmp, sizeof(*icmp)); 39657718be8SEnji Cooper 39757718be8SEnji Cooper for (;;) { 39857718be8SEnji Cooper int status; 39957718be8SEnji Cooper 40057718be8SEnji Cooper /* resolve arp before sending raw stuff */ 40157718be8SEnji Cooper netcfg_rump_pingtest("1.1.1.10", 1); 40257718be8SEnji Cooper 40357718be8SEnji Cooper for (tot = 0; 40457718be8SEnji Cooper tot < 65538 - sizeof(*ip); 40557718be8SEnji Cooper tot += (frag - sizeof(*ip))) { 40657718be8SEnji Cooper frag = MIN(65538 - tot, sizeof(data)); 40757718be8SEnji Cooper ip->ip_off = tot >> 3; 40857718be8SEnji Cooper assert((size_t)ip->ip_off << 3 == tot); 40957718be8SEnji Cooper ip->ip_len = frag; 41057718be8SEnji Cooper 41157718be8SEnji Cooper if (frag == sizeof(data)) { 41257718be8SEnji Cooper ip->ip_off |= IP_MF; 41357718be8SEnji Cooper } 41457718be8SEnji Cooper 41557718be8SEnji Cooper RL(rump_sys_sendto(s, data, frag, 0, 41657718be8SEnji Cooper (struct sockaddr *)&dst, sizeof(dst))); 41757718be8SEnji Cooper } 41857718be8SEnji Cooper if (waitpid(-1, &status, WNOHANG) > 0) { 41957718be8SEnji Cooper if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 42057718be8SEnji Cooper break; 42157718be8SEnji Cooper atf_tc_fail("child did not exit clean"); 42257718be8SEnji Cooper } 42357718be8SEnji Cooper 42457718be8SEnji Cooper usleep(10000); 42557718be8SEnji Cooper } 42657718be8SEnji Cooper } 42757718be8SEnji Cooper 42857718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 42957718be8SEnji Cooper { 43057718be8SEnji Cooper 43157718be8SEnji Cooper ATF_TP_ADD_TC(tp, simpleping); 43257718be8SEnji Cooper ATF_TP_ADD_TC(tp, floodping); 43357718be8SEnji Cooper ATF_TP_ADD_TC(tp, floodping2); 43457718be8SEnji Cooper ATF_TP_ADD_TC(tp, pingsize); 43557718be8SEnji Cooper ATF_TP_ADD_TC(tp, ping_of_death); 43657718be8SEnji Cooper 43757718be8SEnji Cooper return atf_no_error(); 43857718be8SEnji Cooper } 439