Module Name: src Committed By: pooka Date: Wed Aug 18 16:39:22 UTC 2010
Modified Files: src/tests/net/icmp: t_ping.c Log Message: Add a two-way floodping test and a test which sends icmp echos with various sizes. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/tests/net/icmp/t_ping.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/net/icmp/t_ping.c diff -u src/tests/net/icmp/t_ping.c:1.2 src/tests/net/icmp/t_ping.c:1.3 --- src/tests/net/icmp/t_ping.c:1.2 Tue Aug 17 15:51:11 2010 +++ src/tests/net/icmp/t_ping.c Wed Aug 18 16:39:22 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: t_ping.c,v 1.2 2010/08/17 15:51:11 pooka Exp $ */ +/* $NetBSD: t_ping.c,v 1.3 2010/08/18 16:39:22 pooka Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: t_ping.c,v 1.2 2010/08/17 15:51:11 pooka Exp $"); +__RCSID("$NetBSD: t_ping.c,v 1.3 2010/08/18 16:39:22 pooka Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -101,20 +101,92 @@ atf_tc_set_md_var(tc, "use.fs", "true"); } -#define PERLOOP 100 -#define LOOPS 100 -ATF_TC_BODY(floodping, tc) +/* why the hell isn't this available in userspace??? */ +static uint16_t +in_cksum(void *data, size_t len) { - char buf[8192]; - char ifname[IFNAMSIZ]; - pid_t cpid; - int loop, i, succ; + uint16_t *buf = data; + unsigned sum; + + for (sum = 0; len > 1; len -= 2) + sum += *buf++; + if (len) + sum += *(uint8_t *)buf; + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + + return ~sum; +} + +static int +doping(const char *target, int loops, size_t pktsize) +{ + char sndbuf[IP_MAXPACKET - sizeof(struct ip)]; + char recvbuf[IP_MAXPACKET]; struct sockaddr_in dst, pingee; - struct icmp icmp; + struct icmp *icmp; socklen_t slen; ssize_t n; + int loop, i, succ; int x, xnon, s; + RL(s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)); + RL(x = rump_sys_fcntl(s, F_GETFL, 0)); + xnon = x | O_NONBLOCK; + + memset(&dst, 0, sizeof(dst)); + dst.sin_len = sizeof(dst); + dst.sin_family = AF_INET; + dst.sin_addr.s_addr = inet_addr(target); + + icmp = (struct icmp *)sndbuf; + memset(icmp, 0, sizeof(*icmp)); + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_id = htons(37); + + if (pktsize < sizeof(*icmp)) + pktsize = sizeof(*icmp); + if (pktsize > sizeof(sndbuf)) + pktsize = sizeof(sndbuf); + + RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_SNDBUF, + &pktsize, sizeof(pktsize))); + RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVBUF, + &pktsize, sizeof(pktsize))); + + slen = sizeof(pingee); + succ = 0; + for (loop = 0; loop < loops; loop++) { + RL(rump_sys_fcntl(s, F_SETFL, x)); + icmp->icmp_seq = htons(loop); + icmp->icmp_cksum = 0; + icmp->icmp_cksum = in_cksum(icmp, pktsize); + RL(rump_sys_sendto(s, icmp, pktsize, 0, + (struct sockaddr *)&dst, sizeof(dst))); + + RL(rump_sys_fcntl(s, F_SETFL, xnon)); + while ((n = rump_sys_recvfrom(s, recvbuf, sizeof(recvbuf), 0, + (struct sockaddr *)&pingee, &slen)) > 0) { + succ++; + } + if (n == -1 && errno == EAGAIN) + continue; + atf_tc_fail_errno("recv failed"); + } + + rump_sys_close(s); + return succ; +} + +#define LOOPS 10000 + +ATF_TC_BODY(floodping, tc) +{ + char ifname[IFNAMSIZ]; + pid_t cpid; + int succ; + cpid = fork(); rump_init(); netcfg_rump_makeshmif("thank-you-driver-for-getting-me-here", ifname); @@ -132,40 +204,92 @@ netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); - RL(s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)); - RL(x = rump_sys_fcntl(s, F_GETFL, 0)); - xnon = x | O_NONBLOCK; + succ = doping("1.1.1.10", LOOPS, 56); + printf("got %d/%d\n", succ, LOOPS); - memset(&dst, 0, sizeof(dst)); - dst.sin_len = sizeof(dst); - dst.sin_family = AF_INET; - dst.sin_addr.s_addr = inet_addr("1.1.1.10"); + kill(cpid, SIGKILL); +} - memset(&icmp, 0, sizeof(icmp)); - icmp.icmp_type = ICMP_ECHO; - icmp.icmp_id = htons(37); - icmp.icmp_cksum = htons(0xf7da); +ATF_TC(floodping2); +ATF_TC_HEAD(floodping2, tc) +{ - slen = sizeof(pingee); - succ = 0; - for (loop = 0; loop < LOOPS; loop++) { - RL(rump_sys_fcntl(s, F_SETFL, x)); - for (i = 0; i < PERLOOP; i++) { - RL(rump_sys_sendto(s, &icmp, sizeof(icmp), 0, - (struct sockaddr *)&dst, sizeof(dst))); - } - RL(rump_sys_fcntl(s, F_SETFL, xnon)); - while ((n = rump_sys_recvfrom(s, buf, sizeof(buf), 0, - (struct sockaddr *)&pingee, &slen)) > 0) { - succ++; - } - if (n == -1 && errno == EAGAIN) - continue; - atf_tc_fail_errno("recv failed"); + atf_tc_set_md_var(tc, "descr", "two hosts floodpinging each other"); + atf_tc_set_md_var(tc, "use.fs", "true"); +} + +ATF_TC_BODY(floodping2, tc) +{ + char ifname[IFNAMSIZ]; + pid_t cpid; + int succ; + + cpid = fork(); + rump_init(); + netcfg_rump_makeshmif("floodping2", ifname); + + switch (cpid) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); + succ = doping("1.1.1.20", LOOPS, 56); + break; + default: + netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); + succ = doping("1.1.1.10", LOOPS, 56); + break; + } + + printf("got %d/%d\n", succ, LOOPS); +} + +ATF_TC(pingsize); +ATF_TC_HEAD(pingsize, tc) +{ + + atf_tc_set_md_var(tc, "descr", "ping with packets min <= size <= max"); + atf_tc_set_md_var(tc, "use.fs", "true"); +} + +ATF_TC_BODY(pingsize, tc) +{ + char ifname[IFNAMSIZ]; + pid_t cpid; + int succ, i; + + cpid = fork(); + rump_init(); + netcfg_rump_makeshmif("jippikaiee", ifname); + + switch (cpid) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); + pause(); + break; + default: + break; } - printf("got %d/%d\n", succ, LOOPS * PERLOOP); + netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); + + succ = 0; + + /* small sizes */ + for (i = IP_MAXPACKET - 60000; i > 0; i--) + succ += doping("1.1.1.10", 1, i); + + /* medium sizes */ + for (i = IP_MAXPACKET - 100; i > IP_MAXPACKET - 60000; i -= 1000) + succ += doping("1.1.1.10", 1, i); + + /* big sizes */ + for (i = IP_MAXPACKET; i > IP_MAXPACKET - 100; i -= 10) + succ += doping("1.1.1.10", 1, i); + printf("got %d/%d\n", succ, IP_MAXPACKET); kill(cpid, SIGKILL); } @@ -174,6 +298,8 @@ ATF_TP_ADD_TC(tp, simpleping); ATF_TP_ADD_TC(tp, floodping); + ATF_TP_ADD_TC(tp, floodping2); + ATF_TP_ADD_TC(tp, pingsize); return atf_no_error(); }