xref: /netbsd-src/usr.sbin/npf/npftest/libnpftest/npf_table_test.c (revision 6d322f2f4598f0d8a138f10ea648ec4fabe41f8b)
1 /*	$NetBSD: npf_table_test.c,v 1.7 2013/11/12 00:46:34 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		"hash-table"
45 #define	TREE_TID		"tree-table"
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 		npf_table_t *t;
57 		int error;
58 
59 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
60 
61 		t = npf_tableset_getbyname(tblset, HASH_TID);
62 		error = npf_table_insert(t, alen, addr, nm);
63 		fail |= !(error == 0);
64 		error = npf_table_insert(t, alen, addr, nm);
65 		fail |= !(error != 0);
66 
67 		t = npf_tableset_getbyname(tblset, TREE_TID);
68 		error = npf_table_insert(t, alen, addr, nm);
69 		fail |= !(error == 0);
70 		error = npf_table_insert(t, alen, addr, nm);
71 		fail |= !(error != 0);
72 	}
73 	return fail;
74 }
75 
76 bool
77 npf_table_test(bool verbose)
78 {
79 	npf_addr_t addr_storage, *addr = &addr_storage;
80 	const int nm = NPF_NO_NETMASK;
81 	npf_tableset_t *tblset;
82 	npf_table_t *t, *t1, *t2;
83 	int error, alen;
84 	bool fail = false;
85 	u_int i;
86 
87 	tblset = npf_tableset_create(2);
88 	fail |= !(tblset != NULL);
89 
90 	/* Table ID 1, using hash table with 256 lists. */
91 	t1 = npf_table_create(HASH_TID, 0, NPF_TABLE_HASH, 256);
92 	fail |= !(t1 != NULL);
93 	error = npf_tableset_insert(tblset, t1);
94 	fail |= !(error == 0);
95 
96 	/* Check for double-insert. */
97 	error = npf_tableset_insert(tblset, t1);
98 	fail |= !(error != 0);
99 
100 	/* Table ID 2, using a prefix tree. */
101 	t2 = npf_table_create(TREE_TID, 1, NPF_TABLE_TREE, 0);
102 	fail |= !(t2 != NULL);
103 	error = npf_tableset_insert(tblset, t2);
104 	fail |= !(error == 0);
105 
106 	/* Attempt to match non-existing entries - should fail. */
107 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
108 	alen = sizeof(struct in_addr);
109 
110 	t = npf_tableset_getbyname(tblset, HASH_TID);
111 	error = npf_table_lookup(t, alen, addr);
112 	fail |= !(error != 0);
113 
114 	t = npf_tableset_getbyname(tblset, TREE_TID);
115 	error = npf_table_lookup(t, alen, addr);
116 	fail |= !(error != 0);
117 
118 	/* Fill both tables with IP addresses. */
119 	fail |= npf_table_test_fill4(tblset, addr);
120 
121 	/* Attempt to add duplicates - should fail. */
122 	addr->s6_addr32[0] = inet_addr(ip_list[0]);
123 	alen = sizeof(struct in_addr);
124 
125 	t = npf_tableset_getbyname(tblset, HASH_TID);
126 	error = npf_table_insert(t, alen, addr, nm);
127 	fail |= !(error != 0);
128 
129 	t = npf_tableset_getbyname(tblset, TREE_TID);
130 	error = npf_table_insert(t, alen, addr, nm);
131 	fail |= !(error != 0);
132 
133 	/* Match (validate) each IP entry. */
134 	for (i = 0; i < __arraycount(ip_list); i++) {
135 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
136 
137 		t = npf_tableset_getbyname(tblset, HASH_TID);
138 		error = npf_table_lookup(t, alen, addr);
139 		fail |= !(error == 0);
140 
141 		t = npf_tableset_getbyname(tblset, TREE_TID);
142 		error = npf_table_lookup(t, alen, addr);
143 		fail |= !(error == 0);
144 	}
145 
146 	/* IPv6 addresses. */
147 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
148 	alen = sizeof(struct in6_addr);
149 
150 	t = npf_tableset_getbyname(tblset, HASH_TID);
151 	error = npf_table_insert(t, alen, addr, nm);
152 	fail |= !(error == 0);
153 	error = npf_table_lookup(t, alen, addr);
154 	fail |= !(error == 0);
155 	error = npf_table_remove(t, alen, addr, nm);
156 	fail |= !(error == 0);
157 
158 	t = npf_tableset_getbyname(tblset, TREE_TID);
159 	error = npf_table_insert(t, alen, addr, nm);
160 	fail |= !(error == 0);
161 	error = npf_table_lookup(t, alen, addr);
162 	fail |= !(error == 0);
163 	error = npf_table_remove(t, alen, addr, nm);
164 	fail |= !(error == 0);
165 
166 	/*
167 	 * Masking: 96, 32, 127.
168 	 */
169 
170 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
171 	error = npf_table_insert(t, alen, addr, 96);
172 	fail |= !(error == 0);
173 
174 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
175 	error = npf_table_lookup(t, alen, addr);
176 	fail |= !(error == 0);
177 
178 	memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
179 	error = npf_table_remove(t, alen, addr, 96);
180 	fail |= !(error == 0);
181 
182 
183 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
184 	error = npf_table_insert(t, alen, addr, 32);
185 	fail |= !(error == 0);
186 
187 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
188 	error = npf_table_lookup(t, alen, addr);
189 	fail |= !(error == 0);
190 
191 	memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
192 	error = npf_table_remove(t, alen, addr, 32);
193 	fail |= !(error == 0);
194 
195 
196 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
197 	error = npf_table_insert(t, alen, addr, 126);
198 	fail |= !(error == 0);
199 
200 	memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
201 	error = npf_table_lookup(t, alen, addr);
202 	fail |= !(error != 0);
203 
204 	memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
205 	error = npf_table_remove(t, alen, addr, 126);
206 	fail |= !(error == 0);
207 
208 
209 	alen = sizeof(struct in_addr);
210 
211 	/* Remove all IPv4 entries. */
212 	for (i = 0; i < __arraycount(ip_list); i++) {
213 		addr->s6_addr32[0] = inet_addr(ip_list[i]);
214 
215 		t = npf_tableset_getbyname(tblset, HASH_TID);
216 		error = npf_table_remove(t, alen, addr, nm);
217 		fail |= !(error == 0);
218 
219 		t = npf_tableset_getbyname(tblset, TREE_TID);
220 		error = npf_table_remove(t, alen, addr, nm);
221 		fail |= !(error == 0);
222 	}
223 
224 	npf_tableset_destroy(tblset);
225 
226 	return !fail;
227 }
228