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