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