xref: /netbsd-src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c (revision ba65fde2d7fefa7d39838fa5fa855e62bd606b5e)
1 /*	$NetBSD: npf_table_test.c,v 1.6 2012/10/29 02:27:11 rmind Exp $	*/
2 
3 /*
4  * NPF tableset test.
5  *
6  * Public Domain.
7  */
8 
9 #include <sys/types.h>
10 
11 #include "npf_impl.h"
12 #include "npf_test.h"
13 
14 static const char *ip_list[] = {
15 	"192.168.1.1",
16 	"10.0.0.1",
17 	"192.168.2.1",
18 	"10.1.0.1",
19 	"192.168.100.253",
20 	"10.0.5.1",
21 	"192.168.128.127",
22 	"10.0.0.2",
23 };
24 
25 static const uint16_t ip6_list[][8] = {
26 	{
27 	    htons(0xfe80), 0x0, 0x0, 0x0,
28 	    htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1234)
29 	},
30 	{
31 	    htons(0xfe80), 0x0, 0x0, 0x0,
32 	    htons(0x2a0), htons(0xc0ff), 0x00, 0x0
33 	},
34 	{
35 	    htons(0xfe80), 0x0, 0x0, 0x0,
36 	    0x0, 0x0, 0x0, 0x0
37 	},
38 	{
39 	    htons(0xfe80), 0x0, 0x0, 0x0,
40 	    htons(0x2a0), htons(0xc0ff), htons(0xfe10), htons(0x1230)
41 	}
42 };
43 
44 #define	HASH_TID		1
45 #define	TREE_TID		2
46 
47 static bool
48 npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr)
49 {
50 	const int alen = sizeof(struct in_addr);
51 	const int nm = NPF_NO_NETMASK;
52 	bool fail = false;
53 
54 	/* Fill both tables with IP addresses. */
55 	for (unsigned i = 0; i < __arraycount(ip_list); i++) {
56 		int error;
57 
58 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
59 
60 		error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
61 		fail |= !(error == 0);
62 		error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
63 		fail |= !(error != 0);
64 
65 		error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
66 		fail |= !(error == 0);
67 		error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
68 		fail |= !(error != 0);
69 	}
70 	return fail;
71 }
72 
73 bool
74 npf_table_test(bool verbose)
75 {
76 	npf_addr_t addr_storage, *addr = &addr_storage;
77 	const int nm = NPF_NO_NETMASK;
78 	npf_tableset_t *tblset;
79 	npf_table_t *t1, *t2;
80 	int error, alen;
81 	bool fail = false;
82 	u_int i;
83 
84 	tblset = npf_tableset_create();
85 	fail |= !(tblset != NULL);
86 
87 	/* Table ID 1, using hash table with 256 lists. */
88 	t1 = npf_table_create(HASH_TID, NPF_TABLE_HASH, 256);
89 	fail |= !(t1 != NULL);
90 	error = npf_tableset_insert(tblset, t1);
91 	fail |= !(error == 0);
92 
93 	/* Check for double-insert. */
94 	error = npf_tableset_insert(tblset, t1);
95 	fail |= !(error != 0);
96 
97 	/* Table ID 2, using RB-tree. */
98 	t2 = npf_table_create(TREE_TID, NPF_TABLE_TREE, 0);
99 	fail |= !(t2 != NULL);
100 	error = npf_tableset_insert(tblset, t2);
101 	fail |= !(error == 0);
102 
103 	/* Attempt to match non-existing entries - should fail. */
104 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
105 	alen = sizeof(struct in_addr);
106 
107 	error = npf_table_lookup(tblset, HASH_TID, alen, addr);
108 	fail |= !(error != 0);
109 
110 	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
111 	fail |= !(error != 0);
112 
113 	/* Fill both tables with IP addresses. */
114 	fail |= npf_table_test_fill4(tblset, addr);
115 
116 	/* Attempt to add duplicates - should fail. */
117 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
118 	alen = sizeof(struct in_addr);
119 
120 	error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
121 	fail |= !(error != 0);
122 
123 	error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
124 	fail |= !(error != 0);
125 
126 	/* Match (validate) each IP entry. */
127 	for (i = 0; i < __arraycount(ip_list); i++) {
128 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
129 
130 		error = npf_table_lookup(tblset, HASH_TID, alen, addr);
131 		fail |= !(error == 0);
132 
133 		error = npf_table_lookup(tblset, TREE_TID, alen, addr);
134 		fail |= !(error == 0);
135 	}
136 
137 	/* IPv6 addresses. */
138 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
139 	alen = sizeof(struct in6_addr);
140 
141 	error = npf_table_insert(tblset, HASH_TID, alen, addr, nm);
142 	fail |= !(error == 0);
143 	error = npf_table_lookup(tblset, HASH_TID, alen, addr);
144 	fail |= !(error == 0);
145 	error = npf_table_remove(tblset, HASH_TID, alen, addr, nm);
146 	fail |= !(error == 0);
147 
148 	error = npf_table_insert(tblset, TREE_TID, alen, addr, nm);
149 	fail |= !(error == 0);
150 	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
151 	fail |= !(error == 0);
152 	error = npf_table_remove(tblset, TREE_TID, alen, addr, nm);
153 	fail |= !(error == 0);
154 
155 	/*
156 	 * Masking: 96, 32, 127.
157 	 */
158 
159 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
160 	error = npf_table_insert(tblset, TREE_TID, alen, addr, 96);
161 	fail |= !(error == 0);
162 
163 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
164 	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
165 	fail |= !(error == 0);
166 
167 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
168 	error = npf_table_remove(tblset, TREE_TID, alen, addr, 96);
169 	fail |= !(error == 0);
170 
171 
172 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
173 	error = npf_table_insert(tblset, TREE_TID, alen, addr, 32);
174 	fail |= !(error == 0);
175 
176 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
177 	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
178 	fail |= !(error == 0);
179 
180 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
181 	error = npf_table_remove(tblset, TREE_TID, alen, addr, 32);
182 	fail |= !(error == 0);
183 
184 
185 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
186 	error = npf_table_insert(tblset, TREE_TID, alen, addr, 126);
187 	fail |= !(error == 0);
188 
189 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
190 	error = npf_table_lookup(tblset, TREE_TID, alen, addr);
191 	fail |= !(error != 0);
192 
193 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
194 	error = npf_table_remove(tblset, TREE_TID, alen, addr, 126);
195 	fail |= !(error == 0);
196 
197 
198 	alen = sizeof(struct in_addr);
199 
200 	/* Remove all IPv4 entries. */
201 	for (i = 0; i < __arraycount(ip_list); i++) {
202 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
203 
204 		error = npf_table_remove(tblset, HASH_TID, alen, addr, nm);
205 		fail |= !(error == 0);
206 
207 		error = npf_table_remove(tblset, TREE_TID, alen, addr, nm);
208 		fail |= !(error == 0);
209 	}
210 
211 	npf_tableset_destroy(tblset);
212 
213 	return !fail;
214 }
215