1*57718be8SEnji Cooper /* $NetBSD: t_ping.c,v 1.15 2012/09/04 22:31:58 alnsn Exp $ */ 2*57718be8SEnji Cooper 3*57718be8SEnji Cooper /*- 4*57718be8SEnji Cooper * Copyright (c) 2010 The NetBSD Foundation, Inc. 5*57718be8SEnji Cooper * All rights reserved. 6*57718be8SEnji Cooper * 7*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 8*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 9*57718be8SEnji Cooper * are met: 10*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 11*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 12*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 13*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer in the 14*57718be8SEnji Cooper * documentation and/or other materials provided with the distribution. 15*57718be8SEnji Cooper * 16*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17*57718be8SEnji Cooper * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18*57718be8SEnji Cooper * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19*57718be8SEnji Cooper * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20*57718be8SEnji Cooper * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21*57718be8SEnji Cooper * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*57718be8SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23*57718be8SEnji Cooper * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25*57718be8SEnji Cooper * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26*57718be8SEnji Cooper * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27*57718be8SEnji Cooper * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*57718be8SEnji Cooper */ 29*57718be8SEnji Cooper 30*57718be8SEnji Cooper #include <sys/cdefs.h> 31*57718be8SEnji Cooper #ifndef lint 32*57718be8SEnji Cooper __RCSID("$NetBSD: t_ping.c,v 1.15 2012/09/04 22:31:58 alnsn Exp $"); 33*57718be8SEnji Cooper #endif /* not lint */ 34*57718be8SEnji Cooper 35*57718be8SEnji Cooper #include <sys/types.h> 36*57718be8SEnji Cooper #include <sys/resource.h> 37*57718be8SEnji Cooper #include <sys/sysctl.h> 38*57718be8SEnji Cooper #include <sys/wait.h> 39*57718be8SEnji Cooper 40*57718be8SEnji Cooper #include <atf-c.h> 41*57718be8SEnji Cooper #include <assert.h> 42*57718be8SEnji Cooper #include <fcntl.h> 43*57718be8SEnji Cooper #include <stdio.h> 44*57718be8SEnji Cooper #include <stdlib.h> 45*57718be8SEnji Cooper #include <string.h> 46*57718be8SEnji Cooper #include <unistd.h> 47*57718be8SEnji Cooper #include <signal.h> 48*57718be8SEnji Cooper 49*57718be8SEnji Cooper #include <netinet/in.h> 50*57718be8SEnji Cooper #include <netinet/ip_var.h> 51*57718be8SEnji Cooper 52*57718be8SEnji Cooper #include <rump/rump.h> 53*57718be8SEnji Cooper #include <rump/rump_syscalls.h> 54*57718be8SEnji Cooper 55*57718be8SEnji Cooper #include "../../h_macros.h" 56*57718be8SEnji Cooper #include "../config/netconfig.c" 57*57718be8SEnji Cooper 58*57718be8SEnji Cooper ATF_TC(simpleping); 59*57718be8SEnji Cooper ATF_TC_HEAD(simpleping, tc) 60*57718be8SEnji Cooper { 61*57718be8SEnji Cooper 62*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "check that kernel responds to ping"); 63*57718be8SEnji Cooper atf_tc_set_md_var(tc, "timeout", "2"); 64*57718be8SEnji Cooper } 65*57718be8SEnji Cooper 66*57718be8SEnji Cooper ATF_TC_BODY(simpleping, tc) 67*57718be8SEnji Cooper { 68*57718be8SEnji Cooper char ifname[IFNAMSIZ]; 69*57718be8SEnji Cooper pid_t cpid; 70*57718be8SEnji Cooper bool win, win2; 71*57718be8SEnji Cooper char token; 72*57718be8SEnji Cooper int channel[2]; 73*57718be8SEnji Cooper 74*57718be8SEnji Cooper RL(pipe(channel)); 75*57718be8SEnji Cooper 76*57718be8SEnji Cooper cpid = fork(); 77*57718be8SEnji Cooper rump_init(); 78*57718be8SEnji Cooper netcfg_rump_makeshmif("but-can-i-buy-your-ether-bus", ifname); 79*57718be8SEnji Cooper 80*57718be8SEnji Cooper switch (cpid) { 81*57718be8SEnji Cooper case -1: 82*57718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 83*57718be8SEnji Cooper case 0: 84*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); 85*57718be8SEnji Cooper close(channel[0]); 86*57718be8SEnji Cooper ATF_CHECK(write(channel[1], "U", 1) == 1); 87*57718be8SEnji Cooper close(channel[1]); 88*57718be8SEnji Cooper pause(); 89*57718be8SEnji Cooper break; 90*57718be8SEnji Cooper default: 91*57718be8SEnji Cooper break; 92*57718be8SEnji Cooper } 93*57718be8SEnji Cooper 94*57718be8SEnji Cooper close(channel[1]); 95*57718be8SEnji Cooper ATF_CHECK(read(channel[0], &token, 1) == 1 && token == 'U'); 96*57718be8SEnji Cooper close(channel[0]); 97*57718be8SEnji Cooper 98*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 99*57718be8SEnji Cooper 100*57718be8SEnji Cooper /* 101*57718be8SEnji Cooper * The beauty of shmif is that we don't have races here. 102*57718be8SEnji Cooper */ 103*57718be8SEnji Cooper win = netcfg_rump_pingtest("1.1.1.10", 500); 104*57718be8SEnji Cooper win2 = netcfg_rump_pingtest("1.1.1.30", 500); 105*57718be8SEnji Cooper 106*57718be8SEnji Cooper kill(cpid, SIGKILL); 107*57718be8SEnji Cooper 108*57718be8SEnji Cooper if (!win) 109*57718be8SEnji Cooper atf_tc_fail("ping failed"); 110*57718be8SEnji Cooper if (win2) 111*57718be8SEnji Cooper atf_tc_fail("non-existent host responded"); 112*57718be8SEnji Cooper } 113*57718be8SEnji Cooper 114*57718be8SEnji Cooper ATF_TC(floodping); 115*57718be8SEnji Cooper ATF_TC_HEAD(floodping, tc) 116*57718be8SEnji Cooper { 117*57718be8SEnji Cooper 118*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "see how kernel responds to floodping"); 119*57718be8SEnji Cooper } 120*57718be8SEnji Cooper 121*57718be8SEnji Cooper /* why the hell isn't this available in userspace??? */ 122*57718be8SEnji Cooper static uint16_t 123*57718be8SEnji Cooper in_cksum(void *data, size_t len) 124*57718be8SEnji Cooper { 125*57718be8SEnji Cooper uint16_t *buf = data; 126*57718be8SEnji Cooper unsigned sum; 127*57718be8SEnji Cooper 128*57718be8SEnji Cooper for (sum = 0; len > 1; len -= 2) 129*57718be8SEnji Cooper sum += *buf++; 130*57718be8SEnji Cooper if (len) 131*57718be8SEnji Cooper sum += *(uint8_t *)buf; 132*57718be8SEnji Cooper 133*57718be8SEnji Cooper sum = (sum >> 16) + (sum & 0xffff); 134*57718be8SEnji Cooper sum += (sum >> 16); 135*57718be8SEnji Cooper 136*57718be8SEnji Cooper return ~sum; 137*57718be8SEnji Cooper } 138*57718be8SEnji Cooper 139*57718be8SEnji Cooper static int 140*57718be8SEnji Cooper doping(const char *target, int loops, u_int pktsize) 141*57718be8SEnji Cooper { 142*57718be8SEnji Cooper union { 143*57718be8SEnji Cooper char buf[IP_MAXPACKET - sizeof(struct ip)]; 144*57718be8SEnji Cooper struct icmp i; /* ensure proper alignment */ 145*57718be8SEnji Cooper } sndbuf; 146*57718be8SEnji Cooper char recvbuf[IP_MAXPACKET]; 147*57718be8SEnji Cooper struct sockaddr_in dst, pingee; 148*57718be8SEnji Cooper struct icmp *icmp; 149*57718be8SEnji Cooper socklen_t slen; 150*57718be8SEnji Cooper ssize_t n; 151*57718be8SEnji Cooper int loop, succ; 152*57718be8SEnji Cooper int x, xnon, s; 153*57718be8SEnji Cooper 154*57718be8SEnji Cooper RL(s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)); 155*57718be8SEnji Cooper RL(x = rump_sys_fcntl(s, F_GETFL, 0)); 156*57718be8SEnji Cooper xnon = x | O_NONBLOCK; 157*57718be8SEnji Cooper 158*57718be8SEnji Cooper memset(&dst, 0, sizeof(dst)); 159*57718be8SEnji Cooper dst.sin_len = sizeof(dst); 160*57718be8SEnji Cooper dst.sin_family = AF_INET; 161*57718be8SEnji Cooper dst.sin_addr.s_addr = inet_addr(target); 162*57718be8SEnji Cooper 163*57718be8SEnji Cooper icmp = (struct icmp *)&sndbuf; 164*57718be8SEnji Cooper memset(icmp, 0, sizeof(*icmp)); 165*57718be8SEnji Cooper icmp->icmp_type = ICMP_ECHO; 166*57718be8SEnji Cooper icmp->icmp_id = htons(37); 167*57718be8SEnji Cooper 168*57718be8SEnji Cooper if (pktsize < sizeof(*icmp)) 169*57718be8SEnji Cooper pktsize = sizeof(*icmp); 170*57718be8SEnji Cooper if (pktsize > sizeof(sndbuf.buf)) 171*57718be8SEnji Cooper pktsize = sizeof(sndbuf.buf); 172*57718be8SEnji Cooper 173*57718be8SEnji Cooper RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_SNDBUF, 174*57718be8SEnji Cooper &pktsize, sizeof(pktsize))); 175*57718be8SEnji Cooper RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVBUF, 176*57718be8SEnji Cooper &pktsize, sizeof(pktsize))); 177*57718be8SEnji Cooper 178*57718be8SEnji Cooper slen = sizeof(pingee); 179*57718be8SEnji Cooper succ = 0; 180*57718be8SEnji Cooper for (loop = 0; loop < loops; loop++) { 181*57718be8SEnji Cooper RL(rump_sys_fcntl(s, F_SETFL, x)); 182*57718be8SEnji Cooper icmp->icmp_seq = htons(loop); 183*57718be8SEnji Cooper icmp->icmp_cksum = 0; 184*57718be8SEnji Cooper icmp->icmp_cksum = in_cksum(icmp, pktsize); 185*57718be8SEnji Cooper RL(rump_sys_sendto(s, icmp, pktsize, 0, 186*57718be8SEnji Cooper (struct sockaddr *)&dst, sizeof(dst))); 187*57718be8SEnji Cooper 188*57718be8SEnji Cooper RL(rump_sys_fcntl(s, F_SETFL, xnon)); 189*57718be8SEnji Cooper while ((n = rump_sys_recvfrom(s, recvbuf, sizeof(recvbuf), 0, 190*57718be8SEnji Cooper (struct sockaddr *)&pingee, &slen)) > 0) { 191*57718be8SEnji Cooper succ++; 192*57718be8SEnji Cooper } 193*57718be8SEnji Cooper if (n == -1 && errno == EAGAIN) 194*57718be8SEnji Cooper continue; 195*57718be8SEnji Cooper atf_tc_fail_errno("recv failed"); 196*57718be8SEnji Cooper } 197*57718be8SEnji Cooper 198*57718be8SEnji Cooper rump_sys_close(s); 199*57718be8SEnji Cooper return succ; 200*57718be8SEnji Cooper } 201*57718be8SEnji Cooper 202*57718be8SEnji Cooper #define LOOPS 10000 203*57718be8SEnji Cooper 204*57718be8SEnji Cooper ATF_TC_BODY(floodping, tc) 205*57718be8SEnji Cooper { 206*57718be8SEnji Cooper char ifname[IFNAMSIZ]; 207*57718be8SEnji Cooper pid_t cpid; 208*57718be8SEnji Cooper int succ; 209*57718be8SEnji Cooper 210*57718be8SEnji Cooper cpid = fork(); 211*57718be8SEnji Cooper rump_init(); 212*57718be8SEnji Cooper netcfg_rump_makeshmif("thank-you-driver-for-getting-me-here", ifname); 213*57718be8SEnji Cooper 214*57718be8SEnji Cooper switch (cpid) { 215*57718be8SEnji Cooper case -1: 216*57718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 217*57718be8SEnji Cooper case 0: 218*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); 219*57718be8SEnji Cooper pause(); 220*57718be8SEnji Cooper break; 221*57718be8SEnji Cooper default: 222*57718be8SEnji Cooper break; 223*57718be8SEnji Cooper } 224*57718be8SEnji Cooper 225*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 226*57718be8SEnji Cooper 227*57718be8SEnji Cooper succ = doping("1.1.1.10", LOOPS, 56); 228*57718be8SEnji Cooper printf("got %d/%d\n", succ, LOOPS); 229*57718be8SEnji Cooper 230*57718be8SEnji Cooper kill(cpid, SIGKILL); 231*57718be8SEnji Cooper } 232*57718be8SEnji Cooper 233*57718be8SEnji Cooper ATF_TC(floodping2); 234*57718be8SEnji Cooper ATF_TC_HEAD(floodping2, tc) 235*57718be8SEnji Cooper { 236*57718be8SEnji Cooper 237*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "two hosts floodpinging each other"); 238*57718be8SEnji Cooper } 239*57718be8SEnji Cooper 240*57718be8SEnji Cooper ATF_TC_BODY(floodping2, tc) 241*57718be8SEnji Cooper { 242*57718be8SEnji Cooper char ifname[IFNAMSIZ]; 243*57718be8SEnji Cooper pid_t cpid; 244*57718be8SEnji Cooper int succ; 245*57718be8SEnji Cooper 246*57718be8SEnji Cooper cpid = fork(); 247*57718be8SEnji Cooper rump_init(); 248*57718be8SEnji Cooper netcfg_rump_makeshmif("floodping2", ifname); 249*57718be8SEnji Cooper 250*57718be8SEnji Cooper switch (cpid) { 251*57718be8SEnji Cooper case -1: 252*57718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 253*57718be8SEnji Cooper case 0: 254*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); 255*57718be8SEnji Cooper succ = doping("1.1.1.20", LOOPS, 56); 256*57718be8SEnji Cooper break; 257*57718be8SEnji Cooper default: 258*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 259*57718be8SEnji Cooper succ = doping("1.1.1.10", LOOPS, 56); 260*57718be8SEnji Cooper break; 261*57718be8SEnji Cooper } 262*57718be8SEnji Cooper 263*57718be8SEnji Cooper printf("got %d/%d\n", succ, LOOPS); 264*57718be8SEnji Cooper } 265*57718be8SEnji Cooper 266*57718be8SEnji Cooper ATF_TC(pingsize); 267*57718be8SEnji Cooper ATF_TC_HEAD(pingsize, tc) 268*57718be8SEnji Cooper { 269*57718be8SEnji Cooper 270*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "ping with packets min <= size <= max"); 271*57718be8SEnji Cooper } 272*57718be8SEnji Cooper 273*57718be8SEnji Cooper ATF_TC_BODY(pingsize, tc) 274*57718be8SEnji Cooper { 275*57718be8SEnji Cooper char ifname[IFNAMSIZ]; 276*57718be8SEnji Cooper pid_t cpid; 277*57718be8SEnji Cooper int succ, i; 278*57718be8SEnji Cooper 279*57718be8SEnji Cooper cpid = fork(); 280*57718be8SEnji Cooper rump_init(); 281*57718be8SEnji Cooper netcfg_rump_makeshmif("jippikaiee", ifname); 282*57718be8SEnji Cooper 283*57718be8SEnji Cooper switch (cpid) { 284*57718be8SEnji Cooper case -1: 285*57718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 286*57718be8SEnji Cooper case 0: 287*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); 288*57718be8SEnji Cooper pause(); 289*57718be8SEnji Cooper break; 290*57718be8SEnji Cooper default: 291*57718be8SEnji Cooper break; 292*57718be8SEnji Cooper } 293*57718be8SEnji Cooper 294*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 295*57718be8SEnji Cooper 296*57718be8SEnji Cooper succ = 0; 297*57718be8SEnji Cooper 298*57718be8SEnji Cooper /* small sizes */ 299*57718be8SEnji Cooper for (i = 0 ; i < IP_MAXPACKET - 60000; i++) 300*57718be8SEnji Cooper succ += doping("1.1.1.10", 1, i); 301*57718be8SEnji Cooper 302*57718be8SEnji Cooper /* medium sizes */ 303*57718be8SEnji Cooper for (i = IP_MAXPACKET - 60000; i < IP_MAXPACKET - 100; i += 1000) 304*57718be8SEnji Cooper succ += doping("1.1.1.10", 1, i); 305*57718be8SEnji Cooper 306*57718be8SEnji Cooper /* big sizes */ 307*57718be8SEnji Cooper for (i = IP_MAXPACKET - 100; i < IP_MAXPACKET; i += 10) 308*57718be8SEnji Cooper succ += doping("1.1.1.10", 1, i); 309*57718be8SEnji Cooper 310*57718be8SEnji Cooper printf("got %d/%d\n", succ, IP_MAXPACKET); 311*57718be8SEnji Cooper kill(cpid, SIGKILL); 312*57718be8SEnji Cooper } 313*57718be8SEnji Cooper 314*57718be8SEnji Cooper ATF_TC(ping_of_death); 315*57718be8SEnji Cooper ATF_TC_HEAD(ping_of_death, tc) 316*57718be8SEnji Cooper { 317*57718be8SEnji Cooper 318*57718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "send a \"ping of death\""); 319*57718be8SEnji Cooper atf_tc_set_md_var(tc, "timeout", "2"); 320*57718be8SEnji Cooper } 321*57718be8SEnji Cooper 322*57718be8SEnji Cooper ATF_TC_BODY(ping_of_death, tc) 323*57718be8SEnji Cooper { 324*57718be8SEnji Cooper char data[1500]; 325*57718be8SEnji Cooper struct sockaddr_in dst; 326*57718be8SEnji Cooper struct ip *ip; 327*57718be8SEnji Cooper struct icmp *icmp; 328*57718be8SEnji Cooper char ifname[IFNAMSIZ]; 329*57718be8SEnji Cooper pid_t cpid; 330*57718be8SEnji Cooper size_t tot, frag; 331*57718be8SEnji Cooper int s, x, loop; 332*57718be8SEnji Cooper 333*57718be8SEnji Cooper cpid = fork(); 334*57718be8SEnji Cooper rump_init(); 335*57718be8SEnji Cooper netcfg_rump_makeshmif("jippikaiee", ifname); 336*57718be8SEnji Cooper 337*57718be8SEnji Cooper switch (cpid) { 338*57718be8SEnji Cooper case -1: 339*57718be8SEnji Cooper atf_tc_fail_errno("fork failed"); 340*57718be8SEnji Cooper case 0: 341*57718be8SEnji Cooper /* wait until we receive a too long IP packet */ 342*57718be8SEnji Cooper for (loop = 0;; loop++) { 343*57718be8SEnji Cooper uint64_t ipstat[IP_NSTATS]; 344*57718be8SEnji Cooper size_t arglen; 345*57718be8SEnji Cooper int mib[4]; 346*57718be8SEnji Cooper 347*57718be8SEnji Cooper if (loop == 1) 348*57718be8SEnji Cooper netcfg_rump_if(ifname, 349*57718be8SEnji Cooper "1.1.1.10", "255.255.255.0"); 350*57718be8SEnji Cooper 351*57718be8SEnji Cooper mib[0] = CTL_NET; 352*57718be8SEnji Cooper mib[1] = PF_INET; 353*57718be8SEnji Cooper mib[2] = IPPROTO_IP; 354*57718be8SEnji Cooper mib[3] = IPCTL_STATS; 355*57718be8SEnji Cooper 356*57718be8SEnji Cooper arglen = sizeof(ipstat); 357*57718be8SEnji Cooper RL(rump_sys___sysctl(mib, 4, &ipstat, &arglen, 358*57718be8SEnji Cooper NULL, 0)); 359*57718be8SEnji Cooper if (loop == 0 && ipstat[IP_STAT_TOOLONG] != 0) 360*57718be8SEnji Cooper _exit(1); 361*57718be8SEnji Cooper if (ipstat[IP_STAT_TOOLONG]) 362*57718be8SEnji Cooper break; 363*57718be8SEnji Cooper usleep(10000); 364*57718be8SEnji Cooper } 365*57718be8SEnji Cooper 366*57718be8SEnji Cooper _exit(0); 367*57718be8SEnji Cooper break; 368*57718be8SEnji Cooper default: 369*57718be8SEnji Cooper break; 370*57718be8SEnji Cooper } 371*57718be8SEnji Cooper 372*57718be8SEnji Cooper netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); 373*57718be8SEnji Cooper 374*57718be8SEnji Cooper RL(s = rump_sys_socket(PF_INET, SOCK_RAW, 0)); 375*57718be8SEnji Cooper x = 1; 376*57718be8SEnji Cooper RL(rump_sys_setsockopt(s, IPPROTO_IP, IP_HDRINCL, &x, sizeof(x))); 377*57718be8SEnji Cooper 378*57718be8SEnji Cooper memset(&dst, 0, sizeof(dst)); 379*57718be8SEnji Cooper dst.sin_len = sizeof(dst); 380*57718be8SEnji Cooper dst.sin_family = AF_INET; 381*57718be8SEnji Cooper dst.sin_addr.s_addr = inet_addr("1.1.1.10"); 382*57718be8SEnji Cooper 383*57718be8SEnji Cooper /* construct packet */ 384*57718be8SEnji Cooper memset(data, 0, sizeof(data)); 385*57718be8SEnji Cooper ip = (struct ip *)data; 386*57718be8SEnji Cooper ip->ip_v = 4; 387*57718be8SEnji Cooper ip->ip_hl = sizeof(*ip) >> 2; 388*57718be8SEnji Cooper ip->ip_p = IPPROTO_ICMP; 389*57718be8SEnji Cooper ip->ip_ttl = IPDEFTTL; 390*57718be8SEnji Cooper ip->ip_dst = dst.sin_addr; 391*57718be8SEnji Cooper ip->ip_id = 1234; 392*57718be8SEnji Cooper 393*57718be8SEnji Cooper icmp = (struct icmp *)(ip + 1); 394*57718be8SEnji Cooper icmp->icmp_type = ICMP_ECHO; 395*57718be8SEnji Cooper icmp->icmp_cksum = in_cksum(icmp, sizeof(*icmp)); 396*57718be8SEnji Cooper 397*57718be8SEnji Cooper for (;;) { 398*57718be8SEnji Cooper int status; 399*57718be8SEnji Cooper 400*57718be8SEnji Cooper /* resolve arp before sending raw stuff */ 401*57718be8SEnji Cooper netcfg_rump_pingtest("1.1.1.10", 1); 402*57718be8SEnji Cooper 403*57718be8SEnji Cooper for (tot = 0; 404*57718be8SEnji Cooper tot < 65538 - sizeof(*ip); 405*57718be8SEnji Cooper tot += (frag - sizeof(*ip))) { 406*57718be8SEnji Cooper frag = MIN(65538 - tot, sizeof(data)); 407*57718be8SEnji Cooper ip->ip_off = tot >> 3; 408*57718be8SEnji Cooper assert((size_t)ip->ip_off << 3 == tot); 409*57718be8SEnji Cooper ip->ip_len = frag; 410*57718be8SEnji Cooper 411*57718be8SEnji Cooper if (frag == sizeof(data)) { 412*57718be8SEnji Cooper ip->ip_off |= IP_MF; 413*57718be8SEnji Cooper } 414*57718be8SEnji Cooper 415*57718be8SEnji Cooper RL(rump_sys_sendto(s, data, frag, 0, 416*57718be8SEnji Cooper (struct sockaddr *)&dst, sizeof(dst))); 417*57718be8SEnji Cooper } 418*57718be8SEnji Cooper if (waitpid(-1, &status, WNOHANG) > 0) { 419*57718be8SEnji Cooper if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 420*57718be8SEnji Cooper break; 421*57718be8SEnji Cooper atf_tc_fail("child did not exit clean"); 422*57718be8SEnji Cooper } 423*57718be8SEnji Cooper 424*57718be8SEnji Cooper usleep(10000); 425*57718be8SEnji Cooper } 426*57718be8SEnji Cooper } 427*57718be8SEnji Cooper 428*57718be8SEnji Cooper ATF_TP_ADD_TCS(tp) 429*57718be8SEnji Cooper { 430*57718be8SEnji Cooper 431*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, simpleping); 432*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, floodping); 433*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, floodping2); 434*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, pingsize); 435*57718be8SEnji Cooper ATF_TP_ADD_TC(tp, ping_of_death); 436*57718be8SEnji Cooper 437*57718be8SEnji Cooper return atf_no_error(); 438*57718be8SEnji Cooper } 439