Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/rump/net/rumptest * add option to use bpf to dump response
details: https://anonhg.NetBSD.org/src/rev/1da28b2dc84d
branches: trunk
changeset: 750852:1da28b2dc84d
user: pooka <pooka%NetBSD.org@localhost>
date: Sat Jan 16 20:47:01 2010 +0000
description:
* add option to use bpf to dump response
* randomize local address to avoid poor confused peers due to us
"rebooting" quite rapidly when testing.
diffstat:
sys/rump/net/rumptest/rumptest_net.c | 142 ++++++++++++++++++++++++++++++++++-
1 files changed, 138 insertions(+), 4 deletions(-)
diffs (216 lines):
diff -r 2da9daf51986 -r 1da28b2dc84d sys/rump/net/rumptest/rumptest_net.c
--- a/sys/rump/net/rumptest/rumptest_net.c Sat Jan 16 18:47:50 2010 +0000
+++ b/sys/rump/net/rumptest/rumptest_net.c Sat Jan 16 20:47:01 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rumptest_net.c,v 1.13 2010/01/15 18:38:16 pooka Exp $ */
+/* $NetBSD: rumptest_net.c,v 1.14 2010/01/16 20:47:01 pooka Exp $ */
/*
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
@@ -35,14 +35,21 @@
#include <sys/sysctl.h>
#include <arpa/inet.h>
+#include <net/bpf.h>
+#include <net/ethertypes.h>
#include <net/if.h>
+#include <net/if_ether.h>
#include <net/route.h>
+#include <netinet/in_systm.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include <err.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -66,12 +73,14 @@
*
* The usability is likely to be improved later.
*/
-#define MYADDR "10.181.181.11"
+#define MYADDR "10.181.181.0"
#define MYBCAST "10.181.181.255"
#define MYMASK "255.255.255.0"
#define MYGW "10.181.181.1"
#define IFNAME "virt0" /* XXX: hardcoded */
+static in_addr_t myaddr, youraddr;
+
static void
configure_interface(void)
{
@@ -97,13 +106,18 @@
if (s == -1)
err(1, "configuration socket");
+ srandom(time(NULL));
+ myaddr = inet_addr(MYADDR);
+ myaddr = htonl(ntohl(myaddr) + (random() % 126 + 1));
+
/* fill out struct ifaliasreq */
memset(&ia, 0, sizeof(ia));
strcpy(ia.ifra_name, IFNAME);
sin = (struct sockaddr_in *)&ia.ifra_addr;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
- sin->sin_addr.s_addr = inet_addr(MYADDR);
+ sin->sin_addr.s_addr = myaddr;
+ printf("using address %s\n", inet_ntoa(sin->sin_addr));
sin = (struct sockaddr_in *)&ia.ifra_broadaddr;
sin->sin_family = AF_INET;
@@ -190,6 +204,118 @@
printf("total mbufs: %d\n", totalmbuf);
}
+static void
+dobpfread(void)
+{
+ struct bpf_program bpf_prog;
+ struct bpf_insn bpf_ins;
+ struct bpf_hdr *bhdr;
+ void *buf;
+ struct ifreq ifr;
+ int bpfd;
+ u_int bpflen, x;
+
+ bpfd = rump_sys_open("/dev/bpf", O_RDWR);
+ if (bpfd == -1)
+ err(1, "bpf open");
+
+ if (rump_sys_ioctl(bpfd, BIOCGBLEN, &bpflen) == -1)
+ err(1, "BIOCGBLEN");
+
+ buf = malloc(bpflen);
+ if (buf == NULL)
+ err(1, "malloc bpfbuf");
+
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, IFNAME);
+
+ if (rump_sys_ioctl(bpfd, BIOCSETIF, &ifr) == -1)
+ err(1, "BIOCSETIF");
+
+ /* accept all packets up to 9000 bytes */
+ memset(&bpf_ins, 0, sizeof(bpf_ins));
+ bpf_ins.code = BPF_RET + BPF_K;
+ bpf_ins.k = 9000;
+ bpf_prog.bf_len = 1;
+ bpf_prog.bf_insns = &bpf_ins;
+ if (rump_sys_ioctl(bpfd, BIOCSETF, &bpf_prog) == -1)
+ err(1, "BIOCSETF");
+
+ /* we want all packets delivered immediately */
+ x = 1;
+ if (rump_sys_ioctl(bpfd, BIOCIMMEDIATE, &x) == -1)
+ err(1, "BIOCIMMEDIATE");
+
+
+ for (;;) {
+ char fmt[64];
+ struct ether_header *ehdr;
+ struct ip *ip;
+ struct tcphdr *tcph;
+ ssize_t n;
+
+ memset(buf, 0, bpflen);
+ n = rump_sys_read(bpfd, buf, bpflen);
+ if (n == 0) {
+ printf("EOF\n");
+ exit(0);
+ } else if (n == -1) {
+ err(1, "read");
+ }
+
+ bhdr = buf;
+ while (bhdr->bh_caplen) {
+ printf("got packet, caplen %d\n", bhdr->bh_caplen);
+ ehdr = (void *)((uint8_t *)bhdr + bhdr->bh_hdrlen);
+ switch (ntohs(ehdr->ether_type)) {
+ case ETHERTYPE_ARP:
+ printf("ARP\n");
+ break;
+ case ETHERTYPE_IP:
+ printf("IP, ");
+ ip = (void *)((uint8_t *)ehdr + sizeof(*ehdr));
+ printf("version %d, proto ", ip->ip_v);
+ if (ip->ip_p == IPPROTO_TCP)
+ printf("TCP");
+ else if (ip->ip_p == IPPROTO_UDP)
+ printf("UDP");
+ else
+ printf("unknown");
+ printf("\n");
+
+ /*
+ * if it's the droids we're looking for,
+ * print segment contents.
+ */
+ if (ip->ip_src.s_addr != youraddr ||
+ ip->ip_dst.s_addr != myaddr ||
+ ip->ip_p != IPPROTO_TCP)
+ break;
+ tcph = (void *)((uint8_t *)ip + (ip->ip_hl<<2));
+ if (ntohs(tcph->th_sport) != 80)
+ break;
+
+ printf("requested data:\n");
+ sprintf(fmt, "%%%ds\n",
+ ntohs(ip->ip_len) - (ip->ip_hl<<2));
+ printf(fmt, (char *)tcph + (tcph->th_off<<2));
+
+ break;
+ case ETHERTYPE_IPV6:
+ printf("IPv6\n");
+ break;
+ default:
+ printf("unknown type 0x%04x\n",
+ ntohs(ehdr->ether_type));
+ break;
+ }
+
+ bhdr = (void *)((uint8_t *)bhdr +
+ BPF_WORDALIGN(bhdr->bh_hdrlen + bhdr->bh_caplen));
+ }
+ }
+}
+
int
main(int argc, char *argv[])
{
@@ -220,7 +346,7 @@
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(DEST_PORT);
- sin.sin_addr.s_addr = inet_addr(DEST_ADDR);
+ sin.sin_addr.s_addr = youraddr = inet_addr(DEST_ADDR);
if (rump_sys_connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
err(1, "connect failed");
@@ -236,6 +362,11 @@
err(1, "wrote only %zd vs. %zu\n",
n, strlen(buf));
+#ifdef FULL_NETWORK_STACK
+ if (argc > 1)
+ dobpfread();
+#endif
+
/* wait for mbufs to accumulate. hacky, but serves purpose. */
sleep(1);
printstats();
@@ -250,5 +381,8 @@
printf("read %zd (max %zu):\n", off, sizeof(buf));
printf("%s", buf);
+ rump_sys_close(s);
+ sleep(1);
+
return 0;
}
Home |
Main Index |
Thread Index |
Old Index