Add initial NPF regression tests integrated with RUMP framework (running the
kernel part of NPF in userland). Other tests will be added once converted to RUMP framework. All tests are in the public domain. Some Makefile fixes from christos@.
This commit is contained in:
parent
16bec229c7
commit
9ffbe6bd3d
|
@ -0,0 +1,27 @@
|
|||
# $NetBSD: Makefile,v 1.1 2012/04/14 21:57:29 rmind Exp $
|
||||
#
|
||||
# Public Domain
|
||||
#
|
||||
|
||||
PROG= npftest
|
||||
|
||||
SRCS= npftest.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
|
||||
|
||||
WARNS= 4
|
||||
NOMAN= # no man page
|
||||
NOLINT= # disabled (note: deliberately)
|
||||
|
||||
SUBDIR+= libnpftest
|
||||
|
||||
${LIBNPFTEST}/libnpftest.a: all-libnpftest
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
.include <bsd.prog.mk>
|
|
@ -0,0 +1,24 @@
|
|||
# $NetBSD: Makefile,v 1.1 2012/04/14 21:57:29 rmind Exp $
|
||||
#
|
||||
# Public Domain
|
||||
#
|
||||
|
||||
RUMPTOP= ${.CURDIR}/../../../../sys/rump
|
||||
|
||||
LIB= npftest
|
||||
LIBISPRIVATE= yes
|
||||
|
||||
SRCS+= npf_mbuf_subr.c
|
||||
|
||||
SRCS+= npf_nbuf_test.c
|
||||
SRCS+= npf_processor_test.c
|
||||
SRCS+= npf_table_test.c
|
||||
|
||||
CPPFLAGS+= -I${.CURDIR}/../../../../sys/net/npf
|
||||
CPPFLAGS+= -I${RUMPTOP}/librump/rumpkern
|
||||
|
||||
WARNS= 4
|
||||
|
||||
.include "${RUMPTOP}/Makefile.rump"
|
||||
.include <bsd.lib.mk>
|
||||
.include <bsd.klinks.mk>
|
|
@ -0,0 +1,110 @@
|
|||
/* $NetBSD: npf_mbuf_subr.c,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF testing - helper routines.
|
||||
*
|
||||
* Public Domain.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/kmem.h>
|
||||
|
||||
#include "npf_impl.h"
|
||||
#include "npf_test.h"
|
||||
|
||||
struct mbuf *
|
||||
mbuf_getwithdata(void *data, size_t len)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
m = kmem_zalloc(sizeof(struct mbuf), KM_SLEEP);
|
||||
assert(m != NULL);
|
||||
m->m_data = data;
|
||||
m->m_len = len;
|
||||
return m;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mbuf_construct_ether(int proto)
|
||||
{
|
||||
struct mbuf *m0, *m1;
|
||||
struct ether_header *ethdr;
|
||||
|
||||
m0 = m_gethdr(M_WAITOK, MT_HEADER);
|
||||
ethdr = mtod(m0, struct ether_header *);
|
||||
ethdr->ether_type = htons(ETHERTYPE_IP);
|
||||
m0->m_len = sizeof(struct ether_header);
|
||||
|
||||
m1 = mbuf_construct(proto);
|
||||
m0->m_next = m1;
|
||||
m1->m_next = NULL;
|
||||
return m0;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mbuf_construct(int proto)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct ip *iphdr;
|
||||
struct tcphdr *th;
|
||||
int size;
|
||||
|
||||
m = m_gethdr(M_WAITOK, MT_HEADER);
|
||||
iphdr = mtod(m, struct ip *);
|
||||
|
||||
iphdr->ip_v = IPVERSION;
|
||||
iphdr->ip_hl = sizeof(struct ip) >> 2;
|
||||
iphdr->ip_off = 0;
|
||||
iphdr->ip_ttl = 64;
|
||||
iphdr->ip_p = proto;
|
||||
|
||||
size = sizeof(struct ip);
|
||||
|
||||
switch (proto) {
|
||||
case IPPROTO_TCP:
|
||||
th = (void *)(iphdr + 1);
|
||||
th->th_off = sizeof(struct tcphdr) >> 2;
|
||||
size += sizeof(struct tcphdr);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
size += sizeof(struct udphdr);
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
size += offsetof(struct icmp, icmp_data);
|
||||
break;
|
||||
}
|
||||
iphdr->ip_len = htons(size);
|
||||
|
||||
m->m_len = size;
|
||||
m->m_next = NULL;
|
||||
return m;
|
||||
}
|
||||
|
||||
void *
|
||||
mbuf_return_hdrs(struct mbuf *m, bool ether, struct ip **ip)
|
||||
{
|
||||
struct ip *iphdr;
|
||||
|
||||
if (ether) {
|
||||
struct mbuf *mn = m->m_next;
|
||||
iphdr = mtod(mn, struct ip *);
|
||||
} else {
|
||||
iphdr = mtod(m, struct ip *);
|
||||
}
|
||||
*ip = iphdr;
|
||||
return (void *)(iphdr + 1);
|
||||
}
|
||||
|
||||
void
|
||||
mbuf_icmp_append(struct mbuf *m, struct mbuf *m_orig)
|
||||
{
|
||||
struct ip *iphdr = mtod(m, struct ip *);
|
||||
const size_t hlen = iphdr->ip_hl << 2;
|
||||
struct icmp *ic = (struct icmp *)((uint8_t *)iphdr + hlen);
|
||||
const size_t addlen = m_orig->m_len;
|
||||
|
||||
iphdr->ip_len = htons(ntohs(iphdr->ip_len) + addlen);
|
||||
memcpy(&ic->icmp_ip, mtod(m_orig, struct ip *), addlen);
|
||||
m->m_len += addlen;
|
||||
m_freem(m_orig);
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
/* $NetBSD: npf_nbuf_test.c,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF nbuf interface test.
|
||||
*
|
||||
* Public Domain.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/kmem.h>
|
||||
|
||||
#include "npf_impl.h"
|
||||
#include "npf_test.h"
|
||||
|
||||
#define MBUF_CHAIN_LEN 128
|
||||
|
||||
CTASSERT((MBUF_CHAIN_LEN % sizeof(uint32_t)) == 0);
|
||||
|
||||
static char *
|
||||
parse_nbuf_chain(void *nbuf, void *n_ptr)
|
||||
{
|
||||
char *s = kmem_zalloc(MBUF_CHAIN_LEN + 1, KM_SLEEP);
|
||||
int n, error;
|
||||
|
||||
for (n = 0; ; ) {
|
||||
char d[4 + 1];
|
||||
|
||||
error = nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint32_t), d);
|
||||
if (error) {
|
||||
return NULL;
|
||||
}
|
||||
d[sizeof(d) - 1] = '\0';
|
||||
strcat(s, d);
|
||||
|
||||
if (n + sizeof(uint32_t) == MBUF_CHAIN_LEN) {
|
||||
assert(nbuf_advance(&nbuf, n_ptr,
|
||||
sizeof(uint32_t) - 1));
|
||||
break;
|
||||
}
|
||||
n_ptr = nbuf_advance(&nbuf, n_ptr, sizeof(uint32_t));
|
||||
if (n_ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
n += sizeof(uint32_t);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static char *
|
||||
mbuf_getstring(struct mbuf *m)
|
||||
{
|
||||
char *s = kmem_zalloc(MBUF_CHAIN_LEN + 1, KM_SLEEP);
|
||||
u_int tlen = 0;
|
||||
|
||||
while (m) {
|
||||
int len = m->m_len;
|
||||
char *d = m->m_data;
|
||||
while (len--) {
|
||||
s[tlen++] = *d++;
|
||||
}
|
||||
m = m->m_next;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
mbuf_alloc_with_off(size_t off, int len)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
m = kmem_zalloc(sizeof(struct mbuf) + off + len, KM_SLEEP);
|
||||
m->m_data = (char *)m + sizeof(struct mbuf) + off;
|
||||
m->m_len = len;
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an mbuf chain, each of 1 byte size.
|
||||
*/
|
||||
static struct mbuf *
|
||||
mbuf_bytesize(size_t clen)
|
||||
{
|
||||
struct mbuf *m0 = NULL, *m = NULL;
|
||||
u_int i, n;
|
||||
|
||||
/* Chain of clen (e.g. 128) mbufs, each storing 1 byte of data. */
|
||||
for (i = 0, n = 0; i < clen; i++) {
|
||||
/* Range of offset: 0 .. 15. */
|
||||
m0 = mbuf_alloc_with_off(n & 0xf, 1);
|
||||
|
||||
/* Fill data with letters from 'a' to 'z'. */
|
||||
memset(m0->m_data, 'a' + n, 1);
|
||||
n = ('a' + n) != 'z' ? n + 1 : 0;
|
||||
|
||||
/* Next mbuf.. */
|
||||
m0->m_next = m;
|
||||
m = m0;
|
||||
}
|
||||
return m0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate random amount of mbufs, with random offsets and lengths.
|
||||
*/
|
||||
static struct mbuf *
|
||||
mbuf_random_len(size_t chain_len)
|
||||
{
|
||||
struct mbuf *m0 = NULL, *m = NULL;
|
||||
u_int tlen = 0, n = 0;
|
||||
|
||||
while (tlen < chain_len) {
|
||||
u_int off, len;
|
||||
char *d;
|
||||
|
||||
/* Random offset and length range: 1 .. 16. */
|
||||
off = (random() % 16) + 1;
|
||||
len = (random() % 16) + 1;
|
||||
|
||||
/* Do not exceed 128 bytes of total length. */
|
||||
if (tlen + len > chain_len) {
|
||||
len = chain_len - tlen;
|
||||
}
|
||||
tlen += len;
|
||||
|
||||
/* Consistently fill data with letters from 'a' to 'z'. */
|
||||
m0 = mbuf_alloc_with_off(off, len);
|
||||
d = m0->m_data;
|
||||
while (len--) {
|
||||
*d++ = ('a' + n);
|
||||
n = ('a' + n) != 'z' ? n + 1 : 0;
|
||||
}
|
||||
|
||||
/* Next mbuf.. */
|
||||
m0->m_next = m;
|
||||
m = m0;
|
||||
}
|
||||
assert(tlen == chain_len);
|
||||
return m0;
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_mbuf_data(struct mbuf *m, bool verbose, char *bufa, char *bufb)
|
||||
{
|
||||
bool ret = (strcmp(bufa, bufb) == 0);
|
||||
|
||||
if (verbose) {
|
||||
printf("Buffer A: %s\nBuffer B: %s\n", bufa, bufb);
|
||||
}
|
||||
/* XXX free m */
|
||||
kmem_free(bufa, MBUF_CHAIN_LEN + 1);
|
||||
kmem_free(bufb, MBUF_CHAIN_LEN + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
npf_nbuf_test(bool verbose)
|
||||
{
|
||||
struct mbuf *m1, *m2;
|
||||
char *bufa, *bufb;
|
||||
|
||||
m1 = mbuf_random_len(MBUF_CHAIN_LEN);
|
||||
bufa = mbuf_getstring(m1);
|
||||
bufb = parse_nbuf_chain(m1, m1->m_data);
|
||||
if (!validate_mbuf_data(m1, verbose, bufa, bufb)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m2 = mbuf_bytesize(MBUF_CHAIN_LEN);
|
||||
bufa = mbuf_getstring(m2);
|
||||
bufb = parse_nbuf_chain(m2, m2->m_data);
|
||||
if (!validate_mbuf_data(m2, verbose, bufa, bufb)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/* $NetBSD: npf_processor_test.c,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF n-code processor test.
|
||||
*
|
||||
* Public Domain.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "npf_impl.h"
|
||||
#include "npf_ncode.h"
|
||||
#include "npf_test.h"
|
||||
|
||||
/*
|
||||
* In network byte order:
|
||||
* 192.168.2.0 == 0x0002a8c0
|
||||
* 192.168.2.1 == 0x0102a8c0
|
||||
* 192.168.2.100 == 0x6402a8c0
|
||||
* htons(ETHERTYPE_IP) == 0x08
|
||||
* (htons(80) << 16) | htons(80) == 0x50005000
|
||||
* (htons(80) << 16) | htons(15000) == 0x5000983a
|
||||
*/
|
||||
|
||||
static uint32_t nc_match[ ] __aligned(4) = {
|
||||
NPF_OPCODE_CMP, NPF_LAYER_3, 0,
|
||||
NPF_OPCODE_BEQ, 0x0c,
|
||||
NPF_OPCODE_ETHER, 0x00, 0x00, 0x08,
|
||||
NPF_OPCODE_BEQ, 0x04,
|
||||
NPF_OPCODE_RET, 0xff,
|
||||
NPF_OPCODE_ADVR, 3,
|
||||
NPF_OPCODE_IP4MASK, 0x01, 0x0002a8c0, 24,
|
||||
NPF_OPCODE_BEQ, 0x04,
|
||||
NPF_OPCODE_RET, 0xff,
|
||||
NPF_OPCODE_TCP_PORTS, 0x00, 0x50005000,
|
||||
NPF_OPCODE_BEQ, 0x04,
|
||||
NPF_OPCODE_RET, 0xff,
|
||||
NPF_OPCODE_RET, 0x00
|
||||
};
|
||||
|
||||
static uint32_t nc_nmatch[ ] __aligned(4) = {
|
||||
NPF_OPCODE_CMP, NPF_LAYER_3, 0,
|
||||
NPF_OPCODE_BEQ, 0x0c,
|
||||
NPF_OPCODE_ETHER, 0x00, 0x00, 0x08,
|
||||
NPF_OPCODE_BEQ, 0x04,
|
||||
NPF_OPCODE_RET, 0xff,
|
||||
NPF_OPCODE_ADVR, 3,
|
||||
NPF_OPCODE_IP4MASK, 0x01, 0x0102a8c0, 32,
|
||||
NPF_OPCODE_BEQ, 0x04,
|
||||
NPF_OPCODE_RET, 0xff,
|
||||
NPF_OPCODE_RET, 0x00
|
||||
};
|
||||
|
||||
static uint32_t nc_rmatch[ ] __aligned(4) = {
|
||||
NPF_OPCODE_MOVE, offsetof(struct ip, ip_src), 1,
|
||||
NPF_OPCODE_ADVR, 1,
|
||||
NPF_OPCODE_LW, sizeof(in_addr_t), 0,
|
||||
NPF_OPCODE_CMP, 0x6402a8c0, 0,
|
||||
NPF_OPCODE_BEQ, 0x04,
|
||||
NPF_OPCODE_RET, 0xff,
|
||||
NPF_OPCODE_MOVE, sizeof(struct ip) - offsetof(struct ip, ip_src)
|
||||
+ offsetof(struct tcphdr, th_sport), 1,
|
||||
NPF_OPCODE_ADVR, 1,
|
||||
NPF_OPCODE_LW, 2 * sizeof(in_port_t), 0,
|
||||
NPF_OPCODE_CMP, 0x5000983a, 0,
|
||||
NPF_OPCODE_BEQ, 0x04,
|
||||
NPF_OPCODE_RET, 0xff,
|
||||
NPF_OPCODE_RET, 0x01
|
||||
};
|
||||
|
||||
static uint32_t nc_inval[ ] __aligned(4) = {
|
||||
NPF_OPCODE_BEQ, 0x05,
|
||||
NPF_OPCODE_RET, 0xff,
|
||||
NPF_OPCODE_RET, 0x01
|
||||
};
|
||||
|
||||
static void
|
||||
fill_packet(struct mbuf *m, bool ether)
|
||||
{
|
||||
struct ip *ip;
|
||||
struct tcphdr *th;
|
||||
|
||||
th = mbuf_return_hdrs(m, ether, &ip);
|
||||
ip->ip_src.s_addr = inet_addr("192.168.2.100");
|
||||
ip->ip_dst.s_addr = inet_addr("10.0.0.1");
|
||||
th->th_sport = htons(15000);
|
||||
th->th_dport = htons(80);
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_retcode(const char *msg, bool verbose, int ret, int expected)
|
||||
{
|
||||
bool ok = (ret == expected);
|
||||
|
||||
if (verbose) {
|
||||
printf("%-25s\t%-4d == %4d\t-> %s\n",
|
||||
msg, ret, expected, ok ? "ok" : "fail");
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
npf_processor_test(bool verbose)
|
||||
{
|
||||
npf_cache_t npc;
|
||||
struct mbuf *m;
|
||||
int errat, ret;
|
||||
|
||||
/* Layer 2 (Ethernet + IP + TCP). */
|
||||
m = mbuf_construct_ether(IPPROTO_TCP);
|
||||
fill_packet(m, true);
|
||||
ret = npf_ncode_validate(nc_match, sizeof(nc_match), &errat);
|
||||
if (!validate_retcode("Ether validation", verbose, ret, 0)) {
|
||||
return false;
|
||||
}
|
||||
memset(&npc, 0, sizeof(npf_cache_t));
|
||||
ret = npf_ncode_process(&npc, nc_match, m, NPF_LAYER_2);
|
||||
if (!validate_retcode("Ether", verbose, ret, 0)) {
|
||||
return false;
|
||||
}
|
||||
m_freem(m);
|
||||
|
||||
/* Layer 3 (IP + TCP). */
|
||||
m = mbuf_construct(IPPROTO_TCP);
|
||||
fill_packet(m, false);
|
||||
memset(&npc, 0, sizeof(npf_cache_t));
|
||||
ret = npf_ncode_process(&npc, nc_match, m, NPF_LAYER_3);
|
||||
if (!validate_retcode("IPv4 mask 1", verbose, ret, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Non-matching IPv4 case. */
|
||||
ret = npf_ncode_validate(nc_nmatch, sizeof(nc_nmatch), &errat);
|
||||
if (!validate_retcode("IPv4 mask 2 validation", verbose, ret, 0)) {
|
||||
return false;
|
||||
}
|
||||
memset(&npc, 0, sizeof(npf_cache_t));
|
||||
ret = npf_ncode_process(&npc, nc_nmatch, m, NPF_LAYER_3);
|
||||
if (!validate_retcode("IPv4 mask 2", verbose, ret, 255)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Invalid n-code case. */
|
||||
ret = npf_ncode_validate(nc_inval, sizeof(nc_inval), &errat);
|
||||
if (!validate_retcode("Invalid n-code", verbose, ret, NPF_ERR_JUMP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* RISC-like insns. */
|
||||
ret = npf_ncode_validate(nc_rmatch, sizeof(nc_rmatch), &errat);
|
||||
if (!validate_retcode("RISC-like n-code validation", verbose, ret, 0)) {
|
||||
return false;
|
||||
}
|
||||
memset(&npc, 0, sizeof(npf_cache_t));
|
||||
ret = npf_ncode_process(&npc, nc_rmatch, m, NPF_LAYER_3);
|
||||
if (!validate_retcode("RISC-like n-code", verbose, ret, 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_freem(m);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/* $NetBSD: npf_table_test.c,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF tableset test.
|
||||
*
|
||||
* Public Domain.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "npf_impl.h"
|
||||
#include "npf_test.h"
|
||||
|
||||
static const char *ip_list[] = {
|
||||
"192.168.1.1",
|
||||
"10.0.0.1",
|
||||
"192.168.2.1",
|
||||
"10.1.0.1",
|
||||
"192.168.100.253",
|
||||
"10.0.5.1",
|
||||
"192.168.128.127",
|
||||
"10.0.0.2",
|
||||
};
|
||||
|
||||
#define HASH_TID 1
|
||||
#define TREE_TID 2
|
||||
|
||||
bool
|
||||
npf_table_test(bool verbose)
|
||||
{
|
||||
npf_addr_t addr_storage, *addr = &addr_storage;
|
||||
npf_tableset_t *tblset;
|
||||
npf_table_t *t1, *t2;
|
||||
int error;
|
||||
u_int i;
|
||||
|
||||
npf_tableset_sysinit();
|
||||
|
||||
tblset = npf_tableset_create();
|
||||
assert(tblset != NULL);
|
||||
|
||||
/* Table ID 1, using hash table with 256 lists. */
|
||||
t1 = npf_table_create(HASH_TID, NPF_TABLE_HASH, 256);
|
||||
assert(t1 != NULL);
|
||||
error = npf_tableset_insert(tblset, t1);
|
||||
assert(error == 0);
|
||||
|
||||
/* Check for double-insert. */
|
||||
error = npf_tableset_insert(tblset, t1);
|
||||
assert(error != 0);
|
||||
|
||||
/* Table ID 2, using RB-tree. */
|
||||
t2 = npf_table_create(TREE_TID, NPF_TABLE_TREE, 0);
|
||||
assert(t2 != NULL);
|
||||
error = npf_tableset_insert(tblset, t2);
|
||||
assert(error == 0);
|
||||
|
||||
/* Fill both tables with IP addresses. */
|
||||
for (i = 0; i < __arraycount(ip_list); i++) {
|
||||
addr->s6_addr32[0] = inet_addr(ip_list[i]);
|
||||
|
||||
error = npf_table_add_cidr(tblset, HASH_TID, addr, 32);
|
||||
assert(error == 0);
|
||||
error = npf_table_add_cidr(tblset, HASH_TID, addr, 32);
|
||||
assert(error != 0);
|
||||
|
||||
error = npf_table_add_cidr(tblset, TREE_TID, addr, 32);
|
||||
assert(error == 0);
|
||||
error = npf_table_add_cidr(tblset, TREE_TID, addr, 32);
|
||||
assert(error != 0);
|
||||
}
|
||||
|
||||
/* Attempt to add duplicates - should fail. */
|
||||
addr->s6_addr32[0] = inet_addr(ip_list[0]);
|
||||
|
||||
error = npf_table_add_cidr(tblset, HASH_TID, addr, 32);
|
||||
assert(error != 0);
|
||||
|
||||
error = npf_table_add_cidr(tblset, TREE_TID, addr, 32);
|
||||
assert(error != 0);
|
||||
|
||||
/* Reference checks. */
|
||||
t1 = npf_table_get(tblset, HASH_TID);
|
||||
assert(t1 != NULL);
|
||||
npf_table_put(t1);
|
||||
|
||||
t2 = npf_table_get(tblset, TREE_TID);
|
||||
assert(t2 != NULL);
|
||||
npf_table_put(t2);
|
||||
|
||||
/* Match (validate) each IP entry. */
|
||||
for (i = 0; i < __arraycount(ip_list); i++) {
|
||||
addr->s6_addr32[0] = inet_addr(ip_list[i]);
|
||||
|
||||
error = npf_table_match_addr(tblset, HASH_TID, addr);
|
||||
assert(error == 0);
|
||||
|
||||
error = npf_table_match_addr(tblset, TREE_TID, addr);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
/* Remove all entries. */
|
||||
for (i = 0; i < __arraycount(ip_list); i++) {
|
||||
addr->s6_addr32[0] = inet_addr(ip_list[i]);
|
||||
|
||||
error = npf_table_rem_cidr(tblset, HASH_TID, addr, 32);
|
||||
assert(error == 0);
|
||||
|
||||
error = npf_table_rem_cidr(tblset, TREE_TID, addr, 32);
|
||||
assert(error == 0);
|
||||
}
|
||||
|
||||
npf_tableset_destroy(tblset);
|
||||
npf_tableset_sysfini();
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/* $NetBSD: npf_test.h,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain.
|
||||
*/
|
||||
|
||||
#ifndef _LIB_NPF_TEST_H_
|
||||
#define _LIB_NPF_TEST_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mbuf.h>
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet6/in6.h>
|
||||
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_ether.h>
|
||||
#include <net/ethertypes.h>
|
||||
|
||||
struct mbuf * mbuf_getwithdata(void *, size_t);
|
||||
struct mbuf * mbuf_construct_ether(int);
|
||||
struct mbuf * mbuf_construct(int);
|
||||
void * mbuf_return_hdrs(struct mbuf *, bool, struct ip **);
|
||||
void mbuf_icmp_append(struct mbuf *, struct mbuf *);
|
||||
|
||||
bool npf_nbuf_test(bool);
|
||||
bool npf_processor_test(bool);
|
||||
bool npf_table_test(bool);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,87 @@
|
|||
/* $NetBSD: npftest.c,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* NPF testing framework.
|
||||
*
|
||||
* Public Domain.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
|
||||
#include "npftest.h"
|
||||
|
||||
static bool benchmark, verbose, quiet;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
printf("%s: [ -b ] [ -v ]\n", getprogname());
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
result(const char *test, bool ok)
|
||||
{
|
||||
if (!quiet) {
|
||||
printf("NPF %-10s\t%s\n", test, ok ? "OK" : "fail");
|
||||
}
|
||||
if (verbose) {
|
||||
puts("-----");
|
||||
}
|
||||
if (!ok) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
bool ok;
|
||||
int ch;
|
||||
|
||||
benchmark = false;
|
||||
verbose = false;
|
||||
quiet = false;
|
||||
|
||||
while ((ch = getopt(argc, argv, "bqv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
benchmark = true;
|
||||
break;
|
||||
case 'q':
|
||||
quiet = true;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX rn_init */
|
||||
extern int rumpns_max_keylen;
|
||||
rumpns_max_keylen = 1;
|
||||
|
||||
rump_init();
|
||||
rump_schedule();
|
||||
|
||||
ok = rumpns_npf_nbuf_test(verbose);
|
||||
result("nbuf", ok);
|
||||
|
||||
ok = rumpns_npf_processor_test(verbose);
|
||||
result("processor", ok);
|
||||
|
||||
ok = rumpns_npf_table_test(verbose);
|
||||
result("table", ok);
|
||||
|
||||
rump_unschedule();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* $NetBSD: npftest.h,v 1.1 2012/04/14 21:57:29 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain.
|
||||
*/
|
||||
|
||||
#ifndef _NPF_TEST_H_
|
||||
#define _NPF_TEST_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool rumpns_npf_nbuf_test(bool);
|
||||
bool rumpns_npf_processor_test(bool);
|
||||
bool rumpns_npf_table_test(bool);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue