Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/tests/net/bpfilter Add t_bpfilter test. At the moment, it on...
details: https://anonhg.NetBSD.org/src/rev/101f94d1c7b8
branches: trunk
changeset: 781000:101f94d1c7b8
user: alnsn <alnsn%NetBSD.org@localhost>
date: Tue Aug 14 19:09:15 2012 +0000
description:
Add t_bpfilter test. At the moment, it only checks
that bpf program can read bytes from mbuf chain.
diffstat:
tests/net/bpfilter/Makefile | 14 ++
tests/net/bpfilter/t_bpfilter.c | 269 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 283 insertions(+), 0 deletions(-)
diffs (291 lines):
diff -r c94952d02c1b -r 101f94d1c7b8 tests/net/bpfilter/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/net/bpfilter/Makefile Tue Aug 14 19:09:15 2012 +0000
@@ -0,0 +1,14 @@
+# $NetBSD: Makefile,v 1.1 2012/08/14 19:09:15 alnsn Exp $
+#
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/net/bpfilter
+
+TESTS_C= t_bpfilter
+
+LDADD+= -lrumpnet_shmif
+LDADD+= -lrumpdev_bpf -lrumpdev -lrumpnet_netinet -lrumpnet_net
+LDADD+= -lrumpnet -lrumpvfs -lrump -lrumpuser -lpthread
+
+.include <bsd.test.mk>
diff -r c94952d02c1b -r 101f94d1c7b8 tests/net/bpfilter/t_bpfilter.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/net/bpfilter/t_bpfilter.c Tue Aug 14 19:09:15 2012 +0000
@@ -0,0 +1,269 @@
+/* $NetBSD: t_bpfilter.c,v 1.1 2012/08/14 19:09:15 alnsn Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_bpfilter.c,v 1.1 2012/08/14 19:09:15 alnsn Exp $");
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/mbuf.h>
+#include <sys/sysctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <net/if.h>
+#include <net/if_ether.h>
+#include <net/bpf.h>
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+/* XXX: atf-c.h has collisions with mbuf */
+#undef m_type
+#undef m_data
+#include <atf-c.h>
+
+#include "../../h_macros.h"
+#include "../config/netconfig.c"
+
+
+#define SNAPLEN UINT32_MAX
+
+#define BMAGIC UINT32_C(0x37)
+#define HMAGIC UINT32_C(0xc2c2)
+#define WMAGIC UINT32_C(0x7d7d7d7d)
+
+static const char magic_echo_reply_tail[7] = {
+ BMAGIC,
+ HMAGIC & 0xff,
+ HMAGIC & 0xff,
+ WMAGIC & 0xff,
+ WMAGIC & 0xff,
+ WMAGIC & 0xff,
+ WMAGIC & 0xff
+};
+
+/*
+ * Match ICMP_ECHOREPLY packet with 7 magic bytes at the end.
+ */
+static struct bpf_insn magic_echo_reply_prog[] = {
+ BPF_STMT(BPF_LD+BPF_ABS+BPF_B,
+ sizeof(struct ip) + offsetof(struct icmp, icmp_type)),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ICMP_ECHOREPLY, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), /* A <- len */
+ BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 7), /* A <- A - 7 */
+ BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */
+
+ BPF_STMT(BPF_LD+BPF_IND+BPF_B, 0),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, BMAGIC, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+
+ BPF_STMT(BPF_LD+BPF_IND+BPF_H, 1),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, HMAGIC, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+
+ BPF_STMT(BPF_LD+BPF_IND+BPF_W, 3),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, WMAGIC, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+
+ BPF_STMT(BPF_RET+BPF_K, SNAPLEN)
+};
+
+static uint16_t
+in_cksum(void *data, size_t len)
+{
+ 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;
+}
+
+/*
+ * Based on netcfg_rump_pingtest().
+ */
+static bool __unused
+pingtest(const char *dst, unsigned int wirelen, const char tail[7])
+{
+ struct timeval tv;
+ struct sockaddr_in sin;
+ struct icmp *icmp;
+ char *pkt;
+ unsigned int pktsize;
+ socklen_t slen;
+ int s;
+ bool rv = false;
+
+ if (wirelen < ETHER_HDR_LEN + sizeof(struct ip))
+ return false;
+
+ pktsize = wirelen - ETHER_HDR_LEN - sizeof(struct ip);
+ if (pktsize < sizeof(struct icmp) + 7)
+ return false;
+
+ s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
+ if (s == -1)
+ return false;
+
+ pkt = NULL;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ if (rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
+ &tv, sizeof(tv)) == -1)
+ goto out;
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = inet_addr(dst);
+
+ pkt = calloc(1, pktsize);
+ icmp = (struct icmp *)pkt;
+ if (pkt == NULL)
+ goto out;
+
+ memcpy(pkt + pktsize - 7, tail, 7);
+ icmp->icmp_type = ICMP_ECHO;
+ icmp->icmp_id = htons(37);
+ icmp->icmp_seq = htons(1);
+ icmp->icmp_cksum = in_cksum(pkt, pktsize);
+
+ slen = sizeof(sin);
+ if (rump_sys_sendto(s, pkt, pktsize, 0,
+ (struct sockaddr *)&sin, slen) == -1) {
+ goto out;
+ }
+
+ if (rump_sys_recvfrom(s, pkt, pktsize, 0,
+ (struct sockaddr *)&sin, &slen) == -1)
+ goto out;
+
+ rv = true;
+ out:
+ if (pkt != NULL)
+ free(pkt);
+ rump_sys_close(s);
+ return rv;
+}
+
+ATF_TC(bpfiltermchain);
+ATF_TC_HEAD(bpfiltermchain, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks that bpf program "
+ "can read bytes from mbuf chain.");
+}
+
+ATF_TC_BODY(bpfiltermchain, tc)
+{
+ struct bpf_program prog;
+ struct bpf_stat bstat;
+ struct ifreq ifr;
+ struct timeval tv;
+ unsigned int bufsize, wirelen;
+ bool pinged;
+ ssize_t n;
+ char *buf;
+ pid_t child;
+ int bpfd;
+
+ struct bpf_hdr *hdr;
+
+ prog.bf_len = __arraycount(magic_echo_reply_prog);
+ prog.bf_insns = magic_echo_reply_prog;
+
+ child = fork();
+ RZ(rump_init());
+ netcfg_rump_makeshmif("bpfiltermchain", ifr.ifr_name);
+
+ switch (child) {
+ case -1:
+ atf_tc_fail_errno("fork failed");
+ case 0:
+ netcfg_rump_if(ifr.ifr_name, "10.1.1.10", "255.0.0.0");
+ pause();
+ return;
+ default:
+ break;
+ }
+
+ netcfg_rump_if(ifr.ifr_name, "10.1.1.20", "255.0.0.0");
+
+ RL(bpfd = rump_sys_open("/dev/bpf", O_RDONLY));
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ RL(rump_sys_ioctl(bpfd, BIOCSRTIMEOUT, &tv));
+
+ RL(rump_sys_ioctl(bpfd, BIOCGBLEN, &bufsize));
+ RL(rump_sys_ioctl(bpfd, BIOCSETF, &prog));
+ RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr));
+
+ wirelen = MINCLSIZE + 1;
+ pinged = pingtest("10.1.1.10", wirelen, magic_echo_reply_tail);
+ ATF_CHECK(pinged);
+
+ buf = malloc(bufsize);
+ hdr = (struct bpf_hdr *)buf;
+ ATF_REQUIRE(buf != NULL);
+
+ n = rump_sys_read(bpfd, buf, bufsize);
+
+ ATF_CHECK(n > (int)sizeof(struct bpf_hdr *));
+ ATF_CHECK(hdr->bh_caplen == MIN(SNAPLEN, wirelen));
+
+ RL(rump_sys_ioctl(bpfd, BIOCGSTATS, &bstat));
+ ATF_CHECK(bstat.bs_capt > 1); /* XXX == 1 */
+
+ rump_sys_close(bpfd);
+ free(buf);
+ kill(child, SIGKILL);
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, bpfiltermchain);
+
+ return atf_no_error();
+}
Home |
Main Index |
Thread Index |
Old Index