Module Name: src
Committed By: rmind
Date: Wed May 30 21:38:04 UTC 2012
Modified Files:
src/sys/net/npf: npf_ctl.c npf_handler.c npf_impl.h npf_state.c
npf_state_tcp.c
src/sys/rump/dev/lib/libnpf: Makefile
src/usr.sbin/npf/npftest: Makefile npftest.c npftest.h
src/usr.sbin/npf/npftest/libnpftest: Makefile npf_mbuf_subr.c
npf_test.h
Added Files:
src/usr.sbin/npf/npftest: npfstream.c
src/usr.sbin/npf/npftest/libnpftest: npf_test_subr.c
Log Message:
npftest: add a stream processor, which prints out the TCP state information.
A tool for debugging connection tracking from tcpdump -w captured data.
To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/net/npf/npf_ctl.c \
src/sys/net/npf/npf_impl.h
cvs rdiff -u -r1.16 -r1.17 src/sys/net/npf/npf_handler.c
cvs rdiff -u -r1.6 -r1.7 src/sys/net/npf/npf_state.c
cvs rdiff -u -r1.4 -r1.5 src/sys/net/npf/npf_state_tcp.c
cvs rdiff -u -r1.2 -r1.3 src/sys/rump/dev/lib/libnpf/Makefile
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/npf/npftest/Makefile \
src/usr.sbin/npf/npftest/npftest.c src/usr.sbin/npf/npftest/npftest.h
cvs rdiff -u -r0 -r1.1 src/usr.sbin/npf/npftest/npfstream.c
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/npf/npftest/libnpftest/Makefile \
src/usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c \
src/usr.sbin/npf/npftest/libnpftest/npf_test.h
cvs rdiff -u -r0 -r1.1 src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/net/npf/npf_ctl.c
diff -u src/sys/net/npf/npf_ctl.c:1.14 src/sys/net/npf/npf_ctl.c:1.15
--- src/sys/net/npf/npf_ctl.c:1.14 Sun Mar 11 18:27:59 2012
+++ src/sys/net/npf/npf_ctl.c Wed May 30 21:38:03 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_ctl.c,v 1.14 2012/03/11 18:27:59 rmind Exp $ */
+/* $NetBSD: npf_ctl.c,v 1.15 2012/05/30 21:38:03 rmind Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.14 2012/03/11 18:27:59 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.15 2012/05/30 21:38:03 rmind Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -434,15 +434,14 @@ npfctl_reload(u_long cmd, void *data)
int error;
/* Retrieve the dictionary. */
-#ifdef _KERNEL
+#ifndef _NPF_TESTING
error = prop_dictionary_copyin_ioctl(pref, cmd, &npf_dict);
if (error)
return error;
#else
- npf_dict = prop_dictionary_internalize_from_file(data);
- if (npf_dict == NULL)
- return EINVAL;
+ npf_dict = (prop_dictionary_t)pref;
#endif
+
/* Dictionary for error reporting. */
errdict = prop_dictionary_create();
@@ -507,7 +506,7 @@ fail:
/* Error report. */
prop_dictionary_set_int32(errdict, "errno", error);
-#ifdef _KERNEL
+#ifndef _NPF_TESTING
prop_dictionary_copyout_ioctl(pref, cmd, errdict);
#endif
prop_object_release(errdict);
@@ -544,17 +543,11 @@ npfctl_update_rule(u_long cmd, void *dat
const char *name;
int error;
-#ifdef _KERNEL
/* Retrieve and construct the rule. */
error = prop_dictionary_copyin_ioctl(pref, cmd, &dict);
if (error) {
return error;
}
-#else
- dict = prop_dictionary_internalize_from_file(data);
- if (dict == NULL)
- return EINVAL;
-#endif
/* Dictionary for error reporting. */
errdict = prop_dictionary_create();
@@ -580,9 +573,7 @@ out: /* Error path. */
/* Error report. */
prop_dictionary_set_int32(errdict, "errno", error);
-#ifdef _KERNEL
prop_dictionary_copyout_ioctl(pref, cmd, errdict);
-#endif
prop_object_release(errdict);
return error;
}
@@ -612,11 +603,7 @@ npfctl_sessions_save(u_long cmd, void *d
/* Set the session list, NAT policy list and export the dictionary. */
prop_dictionary_set(sesdict, "session-list", selist);
prop_dictionary_set(sesdict, "nat-policy-list", nplist);
-#ifdef _KERNEL
error = prop_dictionary_copyout_ioctl(pref, cmd, sesdict);
-#else
- error = prop_dictionary_externalize_to_file(sesdict, data) ? 0 : errno;
-#endif
fail:
prop_object_release(sesdict);
return error;
@@ -636,15 +623,10 @@ npfctl_sessions_load(u_long cmd, void *d
int error;
/* Retrieve the dictionary containing session and NAT policy lists. */
-#ifdef _KERNEL
error = prop_dictionary_copyin_ioctl(pref, cmd, &sesdict);
if (error)
return error;
-#else
- sesdict = prop_dictionary_internalize_from_file(data);
- if (sesdict == NULL)
- return EINVAL;
-#endif
+
/*
* Note: session objects contain the references to the NAT policy
* entries. Therefore, no need to directly access it.
Index: src/sys/net/npf/npf_impl.h
diff -u src/sys/net/npf/npf_impl.h:1.14 src/sys/net/npf/npf_impl.h:1.15
--- src/sys/net/npf/npf_impl.h:1.14 Sun May 6 02:45:25 2012
+++ src/sys/net/npf/npf_impl.h Wed May 30 21:38:03 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_impl.h,v 1.14 2012/05/06 02:45:25 rmind Exp $ */
+/* $NetBSD: npf_impl.h,v 1.15 2012/05/30 21:38:03 rmind Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -115,6 +115,13 @@ typedef struct {
npf_tcpstate_t nst_tcpst[2];
} npf_state_t;
+#if defined(_NPF_TESTING)
+void npf_state_sample(npf_state_t *, bool);
+#define NPF_TCP_STATE_SAMPLE(n, r) npf_state_sample(n, r)
+#else
+#define NPF_TCP_STATE_SAMPLE(n, r)
+#endif
+
/*
* INTERFACES.
*/
@@ -149,6 +156,7 @@ void npf_stats_dec(npf_stats_t);
int npf_pfil_register(void);
void npf_pfil_unregister(void);
bool npf_pfil_registered_p(void);
+int npf_packet_handler(void *, struct mbuf **, ifnet_t *, int);
void npf_log_packet(npf_cache_t *, nbuf_t *, int);
/* Protocol helpers. */
Index: src/sys/net/npf/npf_handler.c
diff -u src/sys/net/npf/npf_handler.c:1.16 src/sys/net/npf/npf_handler.c:1.17
--- src/sys/net/npf/npf_handler.c:1.16 Sun May 6 02:45:25 2012
+++ src/sys/net/npf/npf_handler.c Wed May 30 21:38:03 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_handler.c,v 1.16 2012/05/06 02:45:25 rmind Exp $ */
+/* $NetBSD: npf_handler.c,v 1.17 2012/05/30 21:38:03 rmind Exp $ */
/*-
* Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.16 2012/05/06 02:45:25 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.17 2012/05/30 21:38:03 rmind Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -61,8 +61,6 @@ static struct pfil_head * npf_ph_if = NU
static struct pfil_head * npf_ph_inet = NULL;
static struct pfil_head * npf_ph_inet6 = NULL;
-int npf_packet_handler(void *, struct mbuf **, ifnet_t *, int);
-
/*
* npf_ifhook: hook handling interface changes.
*/
Index: src/sys/net/npf/npf_state.c
diff -u src/sys/net/npf/npf_state.c:1.6 src/sys/net/npf/npf_state.c:1.7
--- src/sys/net/npf/npf_state.c:1.6 Tue Nov 29 20:05:30 2011
+++ src/sys/net/npf/npf_state.c Wed May 30 21:38:03 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_state.c,v 1.6 2011/11/29 20:05:30 rmind Exp $ */
+/* $NetBSD: npf_state.c,v 1.7 2012/05/30 21:38:03 rmind Exp $ */
/*-
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.6 2011/11/29 20:05:30 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.7 2012/05/30 21:38:03 rmind Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -134,6 +134,7 @@ npf_state_inspect(const npf_cache_t *npc
default:
ret = false;
}
+ NPF_TCP_STATE_SAMPLE(nst, ret);
mutex_exit(&nst->nst_lock);
if (__predict_false(!ret)) {
Index: src/sys/net/npf/npf_state_tcp.c
diff -u src/sys/net/npf/npf_state_tcp.c:1.4 src/sys/net/npf/npf_state_tcp.c:1.5
--- src/sys/net/npf/npf_state_tcp.c:1.4 Tue Apr 3 22:14:12 2012
+++ src/sys/net/npf/npf_state_tcp.c Wed May 30 21:38:03 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_state_tcp.c,v 1.4 2012/04/03 22:14:12 rmind Exp $ */
+/* $NetBSD: npf_state_tcp.c,v 1.5 2012/05/30 21:38:03 rmind Exp $ */
/*-
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.4 2012/04/03 22:14:12 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.5 2012/05/30 21:38:03 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -50,13 +50,6 @@ __KERNEL_RCSID(0, "$NetBSD: npf_state_tc
#include "npf_impl.h"
-#if defined(_NPF_TESTING)
-void npf_state_sample(npf_state_t *);
-#define NPF_TCP_STATE_SAMPLE(nst) npf_state_sample(nst)
-#else
-#define NPF_TCP_STATE_SAMPLE(nst)
-#endif
-
/*
* NPF TCP states. Note: these states are different from the TCP FSM
* states of RFC 793. The packet filter is a man-in-the-middle.
@@ -389,8 +382,6 @@ npf_tcp_inwindow(const npf_cache_t *npc,
end = fstate->nst_end;
seq = end;
}
-
- NPF_TCP_STATE_SAMPLE(nst);
#if 0
/* Strict in-order sequence for RST packets. */
if (((tcpfl & TH_RST) != 0) && (fstate->nst_end - seq) > 1) {
@@ -463,6 +454,7 @@ npf_state_tcp(const npf_cache_t *npc, nb
} else {
nstate = NPF_TCPS_CLOSED;
}
+
/* Determine whether TCP packet really belongs to this connection. */
if (!npf_tcp_inwindow(npc, nbuf, nst, di)) {
return false;
@@ -470,6 +462,7 @@ npf_state_tcp(const npf_cache_t *npc, nb
if (__predict_true(nstate == NPF_TCPS_OK)) {
return true;
}
+
nst->nst_state = nstate;
return true;
}
Index: src/sys/rump/dev/lib/libnpf/Makefile
diff -u src/sys/rump/dev/lib/libnpf/Makefile:1.2 src/sys/rump/dev/lib/libnpf/Makefile:1.3
--- src/sys/rump/dev/lib/libnpf/Makefile:1.2 Sat Apr 14 19:01:22 2012
+++ src/sys/rump/dev/lib/libnpf/Makefile Wed May 30 21:38:03 2012
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.2 2012/04/14 19:01:22 rmind Exp $
+# $NetBSD: Makefile,v 1.3 2012/05/30 21:38:03 rmind Exp $
#
# Public Domain.
#
@@ -16,6 +16,7 @@ SRCS+= component.c
WARNS= 4
+CPPFLAGS+= -D_NPF_TESTING
CPPFLAGS+= -I${.CURDIR}/../../../librump/rumpvfs
.include <bsd.lib.mk>
Index: src/usr.sbin/npf/npftest/Makefile
diff -u src/usr.sbin/npf/npftest/Makefile:1.1 src/usr.sbin/npf/npftest/Makefile:1.2
--- src/usr.sbin/npf/npftest/Makefile:1.1 Sat Apr 14 21:57:29 2012
+++ src/usr.sbin/npf/npftest/Makefile Wed May 30 21:38:04 2012
@@ -1,19 +1,20 @@
-# $NetBSD: Makefile,v 1.1 2012/04/14 21:57:29 rmind Exp $
+# $NetBSD: Makefile,v 1.2 2012/05/30 21:38:04 rmind Exp $
#
# Public Domain
#
PROG= npftest
-SRCS= npftest.c
+SRCS= npftest.c npfstream.c
CPPFLAGS+= -I${.CURDIR}
LIBNPFTEST!= cd ${.CURDIR}/libnpftest && ${MAKE} -V .OBJDIR
DPADD+= ${LIBNPFTEST}/libnpftest.a
LDADD+= -L${LIBNPFTEST} -lnpftest
-LDADD+= -lrump -lrumpvfs -lrumpnet -lrump -lrumpnet_net
-LDADD+= -lrumpnet_virtif -lrumpdev_npf -lpthread
+LDADD+= -lrump -lrumpvfs -lrumpnet -lrumpnet_net -lrumpdev_npf
+
+LDADD+= -lpcap -lprop -lpthread
WARNS= 4
NOMAN= # no man page
Index: src/usr.sbin/npf/npftest/npftest.c
diff -u src/usr.sbin/npf/npftest/npftest.c:1.1 src/usr.sbin/npf/npftest/npftest.c:1.2
--- src/usr.sbin/npf/npftest/npftest.c:1.1 Sat Apr 14 21:57:29 2012
+++ src/usr.sbin/npf/npftest/npftest.c Wed May 30 21:38:04 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npftest.c,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
+/* $NetBSD: npftest.c,v 1.2 2012/05/30 21:38:04 rmind Exp $ */
/*
* NPF testing framework.
@@ -9,27 +9,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <string.h>
#include <unistd.h>
#include <assert.h>
+#include <fcntl.h>
+#include <err.h>
+
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <arpa/inet.h>
#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
#include "npftest.h"
-static bool benchmark, verbose, quiet;
+static bool verbose, quiet;
static void
usage(void)
{
- printf("%s: [ -b ] [ -v ]\n", getprogname());
- exit(EXIT_SUCCESS);
+ printf("usage: %s: [ -q | -v ] [ -c <config> ] "
+ "[ -i 'interfaces' ] < -b | -t | -s file >\n"
+ "\t-b: benchmark\n"
+ "\t-t: regression test\n"
+ "\t-c <config>: NPF configuration file\n"
+ "\t-i 'interfaces': interfaces to create\n"
+ "\t-q: quiet mode\n"
+ "\t-s <file>: pcap stream\n"
+ "\t-v: verbose mode\n",
+ getprogname());
+ exit(EXIT_FAILURE);
}
static void
-result(const char *test, bool ok)
+result(const char *testcase, bool ok)
{
if (!quiet) {
- printf("NPF %-10s\t%s\n", test, ok ? "OK" : "fail");
+ printf("NPF %-10s\t%s\n", testcase, ok ? "OK" : "fail");
}
if (verbose) {
puts("-----");
@@ -39,17 +56,77 @@ result(const char *test, bool ok)
}
}
+#if 0
+static void
+construct_interfaces(char *ifs)
+{
+ char *ifname, *addr, *mask, *sptr;
+
+ /*
+ * Format: ifname0[,ip0,mask1];ifname1,...
+ */
+ ifname = strtok_r(ifs, ";", &sptr);
+ while (ifname) {
+ /* Address and netmask. */
+ addr = strchr(ifname, ',');
+ if (addr) {
+ *addr++ = '\0';
+ }
+ mask = strchr(addr, ',');
+ if (mask) {
+ *mask++ = '\0';
+ }
+
+ /* Construct; next.. */
+ setup_rump_if(ifname, addr, mask);
+ ifname = strtok_r(NULL, ";", &sptr);
+ }
+}
+#endif
+
+static void
+load_npf_config(const char *config)
+{
+ prop_dictionary_t npf_dict;
+ void *xml;
+ int error;
+
+ npf_dict = prop_dictionary_internalize_from_file(config);
+ if (!npf_dict) {
+ err(EXIT_FAILURE, "prop_dictionary_internalize_from_file");
+ }
+ xml = prop_dictionary_externalize(npf_dict);
+ prop_object_release(npf_dict);
+
+ error = rumpns_npf_test_load(xml);
+ if (error) {
+ errx(EXIT_FAILURE, "npf_test_load: %s\n", strerror(error));
+ }
+ free(xml);
+
+ if (verbose) {
+ printf("Loaded NPF config at '%s'\n", config);
+ }
+}
+
int
main(int argc, char **argv)
{
- bool ok;
+ bool benchmark, test, ok;
+ char *config, *interfaces, *stream;
int ch;
benchmark = false;
+ test = false;
+
+ config = NULL;
+ interfaces = NULL;
+ stream = NULL;
+
verbose = false;
quiet = false;
- while ((ch = getopt(argc, argv, "bqv")) != -1) {
+ while ((ch = getopt(argc, argv, "bqvc:i:s:t")) != -1) {
switch (ch) {
case 'b':
benchmark = true;
@@ -60,11 +137,28 @@ main(int argc, char **argv)
case 'v':
verbose = true;
break;
+ case 'c':
+ config = optarg;
+ break;
+ case 'i':
+ interfaces = optarg;
+ break;
+ case 's':
+ stream = optarg;
+ break;
+ case 't':
+ test = true;
+ break;
default:
usage();
}
}
+ /* Either benchmark or test. */
+ if (benchmark == test && (!stream || !interfaces)) {
+ usage();
+ }
+
/* XXX rn_init */
extern int rumpns_max_keylen;
rumpns_max_keylen = 1;
@@ -72,14 +166,30 @@ main(int argc, char **argv)
rump_init();
rump_schedule();
- ok = rumpns_npf_nbuf_test(verbose);
- result("nbuf", ok);
+ if (config) {
+ load_npf_config(config);
+ }
+
+ if (test) {
+ ok = rumpns_npf_nbuf_test(verbose);
+ result("nbuf", ok);
- ok = rumpns_npf_processor_test(verbose);
- result("processor", ok);
+ ok = rumpns_npf_processor_test(verbose);
+ result("processor", ok);
- ok = rumpns_npf_table_test(verbose);
- result("table", ok);
+ ok = rumpns_npf_table_test(verbose);
+ result("table", ok);
+ }
+
+ if (stream) {
+ unsigned idx = if_nametoindex(interfaces);
+ if (idx == 0) {
+ err(EXIT_FAILURE, "if_nametoindex");
+ } else if (verbose) {
+ printf("Interface %s index %u\n", interfaces, idx);
+ }
+ process_stream(stream, NULL, idx);
+ }
rump_unschedule();
Index: src/usr.sbin/npf/npftest/npftest.h
diff -u src/usr.sbin/npf/npftest/npftest.h:1.1 src/usr.sbin/npf/npftest/npftest.h:1.2
--- src/usr.sbin/npf/npftest/npftest.h:1.1 Sat Apr 14 21:57:29 2012
+++ src/usr.sbin/npf/npftest/npftest.h Wed May 30 21:38:04 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npftest.h,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
+/* $NetBSD: npftest.h,v 1.2 2012/05/30 21:38:04 rmind Exp $ */
/*
* Public Domain.
@@ -7,10 +7,17 @@
#ifndef _NPF_TEST_H_
#define _NPF_TEST_H_
+#include <stdint.h>
#include <stdbool.h>
+int rumpns_npf_test_load(const void *);
+int rumpns_npf_test_handlepkt(const void *, size_t,
+ unsigned, bool, int64_t *);
+
bool rumpns_npf_nbuf_test(bool);
bool rumpns_npf_processor_test(bool);
bool rumpns_npf_table_test(bool);
+int process_stream(const char *, const char *, unsigned);
+
#endif
Index: src/usr.sbin/npf/npftest/libnpftest/Makefile
diff -u src/usr.sbin/npf/npftest/libnpftest/Makefile:1.1 src/usr.sbin/npf/npftest/libnpftest/Makefile:1.2
--- src/usr.sbin/npf/npftest/libnpftest/Makefile:1.1 Sat Apr 14 21:57:29 2012
+++ src/usr.sbin/npf/npftest/libnpftest/Makefile Wed May 30 21:38:04 2012
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.1 2012/04/14 21:57:29 rmind Exp $
+# $NetBSD: Makefile,v 1.2 2012/05/30 21:38:04 rmind Exp $
#
# Public Domain
#
@@ -8,12 +8,14 @@ RUMPTOP= ${.CURDIR}/../../../../sys/rump
LIB= npftest
LIBISPRIVATE= yes
+SRCS+= npf_test_subr.c
SRCS+= npf_mbuf_subr.c
SRCS+= npf_nbuf_test.c
SRCS+= npf_processor_test.c
SRCS+= npf_table_test.c
+CPPFLAGS+= -D_NPF_TESTING
CPPFLAGS+= -I${.CURDIR}/../../../../sys/net/npf
CPPFLAGS+= -I${RUMPTOP}/librump/rumpkern
Index: src/usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c:1.1 src/usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c:1.2
--- src/usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c:1.1 Sat Apr 14 21:57:29 2012
+++ src/usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c Wed May 30 21:38:04 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_mbuf_subr.c,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
+/* $NetBSD: npf_mbuf_subr.c,v 1.2 2012/05/30 21:38:04 rmind Exp $ */
/*
* NPF testing - helper routines.
@@ -13,13 +13,15 @@
#include "npf_test.h"
struct mbuf *
-mbuf_getwithdata(void *data, size_t len)
+mbuf_getwithdata(const void *data, size_t len)
{
struct mbuf *m;
+ void *dst;
- m = kmem_zalloc(sizeof(struct mbuf), KM_SLEEP);
+ m = m_gethdr(M_WAITOK, MT_HEADER);
assert(m != NULL);
- m->m_data = data;
+ dst = mtod(m, void *);
+ memcpy(dst, data, len);
m->m_len = len;
return m;
}
Index: src/usr.sbin/npf/npftest/libnpftest/npf_test.h
diff -u src/usr.sbin/npf/npftest/libnpftest/npf_test.h:1.1 src/usr.sbin/npf/npftest/libnpftest/npf_test.h:1.2
--- src/usr.sbin/npf/npftest/libnpftest/npf_test.h:1.1 Sat Apr 14 21:57:29 2012
+++ src/usr.sbin/npf/npftest/libnpftest/npf_test.h Wed May 30 21:38:04 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_test.h,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
+/* $NetBSD: npf_test.h,v 1.2 2012/05/30 21:38:04 rmind Exp $ */
/*
* Public Domain.
@@ -24,7 +24,11 @@
#include <net/if_ether.h>
#include <net/ethertypes.h>
-struct mbuf * mbuf_getwithdata(void *, size_t);
+int npf_test_load(const void *);
+int npf_test_handlepkt(const void *, size_t, unsigned,
+ bool, int64_t *);
+
+struct mbuf * mbuf_getwithdata(const void *, size_t);
struct mbuf * mbuf_construct_ether(int);
struct mbuf * mbuf_construct(int);
void * mbuf_return_hdrs(struct mbuf *, bool, struct ip **);
Added files:
Index: src/usr.sbin/npf/npftest/npfstream.c
diff -u /dev/null src/usr.sbin/npf/npftest/npfstream.c:1.1
--- /dev/null Wed May 30 21:38:04 2012
+++ src/usr.sbin/npf/npftest/npfstream.c Wed May 30 21:38:04 2012
@@ -0,0 +1,117 @@
+/* $NetBSD: npfstream.c,v 1.1 2012/05/30 21:38:04 rmind Exp $ */
+
+/*
+ * NPF stream processor.
+ *
+ * Public Domain.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <inttypes.h>
+#include <err.h>
+#include <pcap.h>
+
+#include <arpa/inet.h>
+
+#include <net/if.h>
+#include <net/ethertypes.h>
+#include <net/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <rump/rump.h>
+
+#include "npftest.h"
+
+static struct in_addr initial_ip;
+static int snd_packet_no = 0;
+static int rcv_packet_no = 0;
+
+static void
+process_tcpip(const void *data, size_t len, FILE *fp, unsigned idx)
+{
+ const struct ether_header *eth = data;
+ const struct ip *ip;
+ const struct tcphdr *th;
+ unsigned hlen, tcpdlen;
+ int error, packetno;
+ tcp_seq seq;
+ bool forw;
+
+ if (ntohs(eth->ether_type) != ETHERTYPE_IP) {
+ errx(EXIT_FAILURE, "process_tcpip: not IP protocol (%d)",
+ eth->ether_type);
+ }
+ ip = (const struct ip *)(eth + 1);
+ hlen = ip->ip_hl << 2;
+ th = (const struct tcphdr *)((const uint8_t *)ip + hlen);
+
+ tcpdlen = ntohs(ip->ip_len) - hlen - (th->th_off << 2);
+ if (th->th_flags & TH_SYN) {
+ tcpdlen++;
+ }
+ if (th->th_flags & TH_FIN) {
+ tcpdlen++;
+ }
+ seq = ntohl(th->th_seq);
+
+ if (snd_packet_no == 0) {
+ memcpy(&initial_ip, &ip->ip_src, sizeof(struct in_addr));
+ }
+
+ forw = (initial_ip.s_addr == ip->ip_src.s_addr);
+ packetno = forw ? ++snd_packet_no : ++rcv_packet_no;
+
+ int64_t result[9];
+ memset(result, 0, sizeof(result));
+
+ len = ntohs(ip->ip_len);
+ error = rumpns_npf_test_handlepkt(ip, len, idx, forw, result);
+
+ fprintf(fp, "%s%2x %5d %3d %11u %11u %11u %11u %12lx",
+ forw ? ">" : "<", (th->th_flags & (TH_SYN | TH_ACK | TH_FIN)),
+ packetno, error, (u_int)seq, (u_int)ntohl(th->th_ack),
+ (u_int)(seq + tcpdlen), ntohs(th->th_win), (uintptr_t)result[0]);
+
+ for (unsigned i = 1; i < __arraycount(result); i++) {
+ fprintf(fp, "%11" PRIu64 " ", result[i]);
+ }
+ fputs("\n", fp);
+}
+
+int
+process_stream(const char *input, const char *output, unsigned idx)
+{
+ pcap_t *pcap;
+ char pcap_errbuf[PCAP_ERRBUF_SIZE];
+ struct pcap_pkthdr *phdr;
+ const uint8_t *data;
+ FILE *fp;
+
+ pcap = pcap_open_offline(input, pcap_errbuf);
+ if (pcap == NULL) {
+ errx(EXIT_FAILURE, "pcap_open_offline failed: %s", pcap_errbuf);
+ }
+ fp = output ? fopen(output, "w") : stdout;
+ if (fp == NULL) {
+ err(EXIT_FAILURE, "fopen");
+ }
+ fprintf(fp, "# %5s %3s %11s %11s %11s %11s %11s %11s %11s\n",
+ "No", "Err", "Seq", "Ack", "TCP Len", "Win",
+ "Stream", "RetVal", "State");
+ while (pcap_next_ex(pcap, &phdr, &data) > 0) {
+ if (phdr->len != phdr->caplen) {
+ warnx("process_stream: truncated packet");
+ }
+ process_tcpip(data, phdr->caplen, fp, idx);
+ }
+ pcap_close(pcap);
+ fclose(fp);
+
+ return 0;
+}
Index: src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c
diff -u /dev/null src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c:1.1
--- /dev/null Wed May 30 21:38:04 2012
+++ src/usr.sbin/npf/npftest/libnpftest/npf_test_subr.c Wed May 30 21:38:04 2012
@@ -0,0 +1,74 @@
+/* $NetBSD: npf_test_subr.c,v 1.1 2012/05/30 21:38:04 rmind Exp $ */
+
+/*
+ * NPF initialisation and handler routines.
+ *
+ * Public Domain.
+ */
+
+#include <sys/types.h>
+#include <net/if.h>
+#include <net/if_types.h>
+
+#include "npf_impl.h"
+#include "npf_test.h"
+
+/* State of the current stream. */
+static npf_state_t cstream_state;
+static void * cstream_ptr;
+static bool cstream_retval;
+
+int
+npf_test_load(const void *xml)
+{
+ prop_dictionary_t npf_dict = prop_dictionary_internalize(xml);
+ return npfctl_reload(0, npf_dict);
+}
+
+/*
+ * State sampler - this routine is called from inside of NPF state engine.
+ */
+void
+npf_state_sample(npf_state_t *nst, bool retval)
+{
+ /* Pointer will serve as an ID. */
+ cstream_ptr = nst;
+ memcpy(&cstream_state, nst, sizeof(npf_state_t));
+ cstream_retval = retval;
+}
+
+int
+npf_test_handlepkt(const void *data, size_t len, unsigned idx,
+ bool forw, int64_t *result)
+{
+ ifnet_t ifp = { .if_index = idx };
+ struct mbuf *m;
+ int i = 0, error;
+
+ m = mbuf_getwithdata(data, len);
+ error = npf_packet_handler(NULL, &m, &ifp, forw ? PFIL_OUT : PFIL_IN);
+ if (error) {
+ assert(m == NULL);
+ return error;
+ }
+ assert(m != NULL);
+ m_freem(m);
+
+ const int di = forw ? NPF_FLOW_FORW : NPF_FLOW_BACK;
+ npf_tcpstate_t *fstate = &cstream_state.nst_tcpst[di];
+ npf_tcpstate_t *tstate = &cstream_state.nst_tcpst[!di];
+
+ result[i++] = (intptr_t)cstream_ptr;
+ result[i++] = cstream_retval;
+ result[i++] = cstream_state.nst_state;
+
+ result[i++] = fstate->nst_end;
+ result[i++] = fstate->nst_maxend;
+ result[i++] = fstate->nst_maxwin;
+
+ result[i++] = tstate->nst_end;
+ result[i++] = tstate->nst_maxend;
+ result[i++] = tstate->nst_maxwin;
+
+ return 0;
+}