Home | History | Annotate | Line # | Download | only in libnpftest
npf_rule_test.c revision 1.2
      1  1.2  rmind /*	$NetBSD: npf_rule_test.c,v 1.2 2012/08/21 20:52:11 rmind Exp $	*/
      2  1.1  rmind 
      3  1.1  rmind /*
      4  1.1  rmind  * NPF ruleset test.
      5  1.1  rmind  *
      6  1.1  rmind  * Public Domain.
      7  1.1  rmind  */
      8  1.1  rmind 
      9  1.1  rmind #include <sys/types.h>
     10  1.1  rmind 
     11  1.1  rmind #include "npf_impl.h"
     12  1.1  rmind #include "npf_test.h"
     13  1.1  rmind 
     14  1.1  rmind #define	IFNAME_EXT	"npftest0"
     15  1.1  rmind #define	IFNAME_INT	"npftest1"
     16  1.1  rmind 
     17  1.1  rmind #define	RESULT_PASS	0
     18  1.1  rmind #define	RESULT_BLOCK	ENETUNREACH
     19  1.1  rmind 
     20  1.1  rmind static const struct test_case {
     21  1.1  rmind 	const char *	src;
     22  1.1  rmind 	const char *	dst;
     23  1.1  rmind 	const char *	ifname;
     24  1.1  rmind 	int		di;
     25  1.1  rmind 	int		stateful_ret;
     26  1.1  rmind 	int		ret;
     27  1.1  rmind } test_cases[] = {
     28  1.1  rmind 
     29  1.1  rmind 	/* Stateful pass. */
     30  1.1  rmind 	{
     31  1.1  rmind 		.src = "10.1.1.1",		.dst = "10.1.1.2",
     32  1.1  rmind 		.ifname = IFNAME_INT,		.di = PFIL_OUT,
     33  1.1  rmind 		.stateful_ret = RESULT_PASS,	.ret = RESULT_PASS
     34  1.1  rmind 	},
     35  1.1  rmind 	{
     36  1.1  rmind 		.src = "10.1.1.2",		.dst = "10.1.1.1",
     37  1.1  rmind 		.ifname = IFNAME_INT,		.di = PFIL_IN,
     38  1.1  rmind 		.stateful_ret = RESULT_PASS,	.ret = RESULT_BLOCK
     39  1.1  rmind 	},
     40  1.1  rmind 
     41  1.1  rmind 	/* Pass forwards stream only. */
     42  1.1  rmind 	{
     43  1.1  rmind 		.src = "10.1.1.1",		.dst = "10.1.1.3",
     44  1.1  rmind 		.ifname = IFNAME_INT,		.di = PFIL_OUT,
     45  1.1  rmind 		.stateful_ret = RESULT_PASS,	.ret = RESULT_PASS
     46  1.1  rmind 	},
     47  1.1  rmind 	{
     48  1.1  rmind 		.src = "10.1.1.3",		.dst = "10.1.1.1",
     49  1.1  rmind 		.ifname = IFNAME_INT,		.di = PFIL_IN,
     50  1.1  rmind 		.stateful_ret = RESULT_BLOCK,	.ret = RESULT_BLOCK
     51  1.1  rmind 	},
     52  1.1  rmind 
     53  1.1  rmind 	/* Block. */
     54  1.1  rmind 	{	.src = "10.1.1.1",		.dst = "10.1.1.4",
     55  1.1  rmind 		.ifname = IFNAME_INT,		.di = PFIL_OUT,
     56  1.1  rmind 		.stateful_ret = RESULT_BLOCK,	.ret = RESULT_BLOCK
     57  1.1  rmind 	},
     58  1.1  rmind 
     59  1.1  rmind };
     60  1.1  rmind 
     61  1.1  rmind static struct mbuf *
     62  1.1  rmind fill_packet(const struct test_case *t)
     63  1.1  rmind {
     64  1.1  rmind 	struct mbuf *m;
     65  1.1  rmind 	struct ip *ip;
     66  1.1  rmind 	struct udphdr *uh;
     67  1.1  rmind 
     68  1.1  rmind 	m = mbuf_construct(IPPROTO_UDP);
     69  1.1  rmind 	uh = mbuf_return_hdrs(m, false, &ip);
     70  1.1  rmind 	ip->ip_src.s_addr = inet_addr(t->src);
     71  1.1  rmind 	ip->ip_dst.s_addr = inet_addr(t->dst);
     72  1.1  rmind 	uh->uh_sport = htons(9000);
     73  1.1  rmind 	uh->uh_dport = htons(9000);
     74  1.1  rmind 	return m;
     75  1.1  rmind }
     76  1.1  rmind 
     77  1.1  rmind static int
     78  1.1  rmind npf_rule_raw_test(bool verbose, struct mbuf *m, ifnet_t *ifp, int di)
     79  1.1  rmind {
     80  1.1  rmind 	npf_cache_t npc = { .npc_info = 0 };
     81  1.1  rmind 	npf_rule_t *rl;
     82  1.1  rmind 	int retfl, error;
     83  1.1  rmind 
     84  1.1  rmind 	npf_core_enter();
     85  1.1  rmind 	rl = npf_ruleset_inspect(&npc, m, npf_core_ruleset(),
     86  1.1  rmind 	    ifp, di, NPF_LAYER_3);
     87  1.1  rmind 	if (rl) {
     88  1.1  rmind 		if (verbose) {
     89  1.1  rmind 			npf_rulenc_dump(rl);
     90  1.1  rmind 		}
     91  1.1  rmind 		error = npf_rule_apply(&npc, m, rl, &retfl);
     92  1.1  rmind 	} else {
     93  1.1  rmind 		npf_core_exit();
     94  1.1  rmind 		error = ENOENT;
     95  1.1  rmind 	}
     96  1.1  rmind 	return error;
     97  1.1  rmind }
     98  1.1  rmind 
     99  1.1  rmind bool
    100  1.1  rmind npf_rule_test(bool verbose)
    101  1.1  rmind {
    102  1.2  rmind 	bool fail = false;
    103  1.2  rmind 
    104  1.1  rmind 	for (unsigned i = 0; i < __arraycount(test_cases); i++) {
    105  1.1  rmind 		const struct test_case *t = &test_cases[i];
    106  1.1  rmind 		ifnet_t *ifp = ifunit(t->ifname);
    107  1.1  rmind 		int serror, error;
    108  1.1  rmind 
    109  1.1  rmind 		if (ifp == NULL) {
    110  1.1  rmind 			printf("Interface %s is not configured.\n", t->ifname);
    111  1.1  rmind 			return false;
    112  1.1  rmind 		}
    113  1.1  rmind 
    114  1.2  rmind 		struct mbuf *m = fill_packet(t);
    115  1.1  rmind 		error = npf_rule_raw_test(verbose, m, ifp, t->di);
    116  1.1  rmind 		serror = npf_packet_handler(NULL, &m, ifp, t->di);
    117  1.1  rmind 
    118  1.1  rmind 		if (m) {
    119  1.1  rmind 			m_freem(m);
    120  1.1  rmind 		}
    121  1.1  rmind 
    122  1.1  rmind 		if (verbose) {
    123  1.1  rmind 			printf("Rule test %d, expected %d (stateful) and %d \n"
    124  1.1  rmind 			    "-> returned %d and %d.\n",
    125  1.1  rmind 			    i + 1, t->stateful_ret, t->ret, serror, error);
    126  1.1  rmind 		}
    127  1.2  rmind 		fail |= (serror != t->stateful_ret || error != t->ret);
    128  1.1  rmind 	}
    129  1.2  rmind 	return !fail;
    130  1.1  rmind }
    131