npf_table_test.c revision 1.8.8.1 1 1.8.8.1 pgoyette /* $NetBSD: npf_table_test.c,v 1.8.8.1 2017/01/07 08:57:00 pgoyette Exp $ */
2 1.1 rmind
3 1.1 rmind /*
4 1.1 rmind * NPF tableset test.
5 1.1 rmind *
6 1.1 rmind * Public Domain.
7 1.1 rmind */
8 1.1 rmind
9 1.8.8.1 pgoyette #ifdef _KERNEL
10 1.1 rmind #include <sys/types.h>
11 1.8 rmind #include <sys/malloc.h>
12 1.8.8.1 pgoyette #endif
13 1.8.8.1 pgoyette
14 1.8.8.1 pgoyette #ifdef __linux__
15 1.8.8.1 pgoyette #include <endian.h>
16 1.8.8.1 pgoyette #else
17 1.8.8.1 pgoyette #include <sys/endian.h>
18 1.8.8.1 pgoyette #endif
19 1.1 rmind
20 1.1 rmind #include "npf_impl.h"
21 1.1 rmind #include "npf_test.h"
22 1.1 rmind
23 1.1 rmind static const char *ip_list[] = {
24 1.1 rmind "192.168.1.1",
25 1.1 rmind "10.0.0.1",
26 1.1 rmind "192.168.2.1",
27 1.1 rmind "10.1.0.1",
28 1.1 rmind "192.168.100.253",
29 1.1 rmind "10.0.5.1",
30 1.1 rmind "192.168.128.127",
31 1.1 rmind "10.0.0.2",
32 1.1 rmind };
33 1.1 rmind
34 1.8.8.1 pgoyette #if __BYTE_ORDER == __LITTLE_ENDIAN
35 1.8.8.1 pgoyette #define U16_TO_LE(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
36 1.8.8.1 pgoyette #else
37 1.8.8.1 pgoyette #define U16_TO_LE(x) (x)
38 1.8.8.1 pgoyette #endif
39 1.8.8.1 pgoyette
40 1.5 rmind static const uint16_t ip6_list[][8] = {
41 1.5 rmind {
42 1.8.8.1 pgoyette U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
43 1.8.8.1 pgoyette U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff),
44 1.8.8.1 pgoyette U16_TO_LE(0xfe10), U16_TO_LE(0x1234)
45 1.5 rmind },
46 1.5 rmind {
47 1.8.8.1 pgoyette U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
48 1.8.8.1 pgoyette U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff), 0x00, 0x0
49 1.5 rmind },
50 1.5 rmind {
51 1.8.8.1 pgoyette U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
52 1.5 rmind 0x0, 0x0, 0x0, 0x0
53 1.5 rmind },
54 1.5 rmind {
55 1.8.8.1 pgoyette U16_TO_LE(0xfe80), 0x0, 0x0, 0x0,
56 1.8.8.1 pgoyette U16_TO_LE(0x2a0), U16_TO_LE(0xc0ff),
57 1.8.8.1 pgoyette U16_TO_LE(0xfe10), U16_TO_LE(0x1230)
58 1.5 rmind }
59 1.4 rmind };
60 1.4 rmind
61 1.8.8.1 pgoyette #define check_ok(x) \
62 1.8.8.1 pgoyette ((x) ? true : (printf("fail at line %d\n", __LINE__), false))
63 1.8.8.1 pgoyette
64 1.7 rmind #define HASH_TID "hash-table"
65 1.7 rmind #define TREE_TID "tree-table"
66 1.8 rmind #define CDB_TID "cdb-table"
67 1.1 rmind
68 1.6 rmind static bool
69 1.6 rmind npf_table_test_fill4(npf_tableset_t *tblset, npf_addr_t *addr)
70 1.6 rmind {
71 1.6 rmind const int alen = sizeof(struct in_addr);
72 1.6 rmind const int nm = NPF_NO_NETMASK;
73 1.6 rmind bool fail = false;
74 1.6 rmind
75 1.6 rmind /* Fill both tables with IP addresses. */
76 1.6 rmind for (unsigned i = 0; i < __arraycount(ip_list); i++) {
77 1.7 rmind npf_table_t *t;
78 1.6 rmind int error;
79 1.6 rmind
80 1.8.8.1 pgoyette addr->word32[0] = inet_addr(ip_list[i]);
81 1.6 rmind
82 1.7 rmind t = npf_tableset_getbyname(tblset, HASH_TID);
83 1.7 rmind error = npf_table_insert(t, alen, addr, nm);
84 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
85 1.7 rmind error = npf_table_insert(t, alen, addr, nm);
86 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
87 1.6 rmind
88 1.7 rmind t = npf_tableset_getbyname(tblset, TREE_TID);
89 1.7 rmind error = npf_table_insert(t, alen, addr, nm);
90 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
91 1.7 rmind error = npf_table_insert(t, alen, addr, nm);
92 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
93 1.6 rmind }
94 1.6 rmind return fail;
95 1.6 rmind }
96 1.6 rmind
97 1.1 rmind bool
98 1.8 rmind npf_table_test(bool verbose, void *blob, size_t size)
99 1.1 rmind {
100 1.1 rmind npf_addr_t addr_storage, *addr = &addr_storage;
101 1.4 rmind const int nm = NPF_NO_NETMASK;
102 1.8 rmind npf_table_t *t, *t1, *t2, *t3;
103 1.1 rmind npf_tableset_t *tblset;
104 1.4 rmind int error, alen;
105 1.5 rmind bool fail = false;
106 1.8 rmind void *cdb;
107 1.1 rmind u_int i;
108 1.1 rmind
109 1.8 rmind tblset = npf_tableset_create(3);
110 1.8.8.1 pgoyette fail |= !check_ok(tblset != NULL);
111 1.1 rmind
112 1.1 rmind /* Table ID 1, using hash table with 256 lists. */
113 1.8 rmind t1 = npf_table_create(HASH_TID, 0, NPF_TABLE_HASH, NULL, 256);
114 1.8.8.1 pgoyette fail |= !check_ok(t1 != NULL);
115 1.1 rmind error = npf_tableset_insert(tblset, t1);
116 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
117 1.1 rmind
118 1.1 rmind /* Check for double-insert. */
119 1.1 rmind error = npf_tableset_insert(tblset, t1);
120 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
121 1.1 rmind
122 1.7 rmind /* Table ID 2, using a prefix tree. */
123 1.8 rmind t2 = npf_table_create(TREE_TID, 1, NPF_TABLE_TREE, NULL, 0);
124 1.5 rmind fail |= !(t2 != NULL);
125 1.1 rmind error = npf_tableset_insert(tblset, t2);
126 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
127 1.1 rmind
128 1.8 rmind /* Table ID 3, using a CDB. */
129 1.8 rmind cdb = malloc(size, M_TEMP, M_WAITOK);
130 1.8 rmind memcpy(cdb, blob, size);
131 1.8 rmind
132 1.8 rmind t3 = npf_table_create(CDB_TID, 2, NPF_TABLE_CDB, cdb, size);
133 1.8 rmind fail |= !(t3 != NULL);
134 1.8 rmind error = npf_tableset_insert(tblset, t3);
135 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
136 1.8 rmind
137 1.2 rmind /* Attempt to match non-existing entries - should fail. */
138 1.8.8.1 pgoyette addr->word32[0] = inet_addr(ip_list[0]);
139 1.4 rmind alen = sizeof(struct in_addr);
140 1.2 rmind
141 1.7 rmind t = npf_tableset_getbyname(tblset, HASH_TID);
142 1.7 rmind error = npf_table_lookup(t, alen, addr);
143 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
144 1.2 rmind
145 1.7 rmind t = npf_tableset_getbyname(tblset, TREE_TID);
146 1.7 rmind error = npf_table_lookup(t, alen, addr);
147 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
148 1.2 rmind
149 1.1 rmind /* Fill both tables with IP addresses. */
150 1.6 rmind fail |= npf_table_test_fill4(tblset, addr);
151 1.1 rmind
152 1.1 rmind /* Attempt to add duplicates - should fail. */
153 1.8.8.1 pgoyette addr->word32[0] = inet_addr(ip_list[0]);
154 1.4 rmind alen = sizeof(struct in_addr);
155 1.1 rmind
156 1.7 rmind t = npf_tableset_getbyname(tblset, HASH_TID);
157 1.7 rmind error = npf_table_insert(t, alen, addr, nm);
158 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
159 1.1 rmind
160 1.7 rmind t = npf_tableset_getbyname(tblset, TREE_TID);
161 1.7 rmind error = npf_table_insert(t, alen, addr, nm);
162 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
163 1.1 rmind
164 1.1 rmind /* Match (validate) each IP entry. */
165 1.1 rmind for (i = 0; i < __arraycount(ip_list); i++) {
166 1.8.8.1 pgoyette addr->word32[0] = inet_addr(ip_list[i]);
167 1.1 rmind
168 1.7 rmind t = npf_tableset_getbyname(tblset, HASH_TID);
169 1.7 rmind error = npf_table_lookup(t, alen, addr);
170 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
171 1.1 rmind
172 1.7 rmind t = npf_tableset_getbyname(tblset, TREE_TID);
173 1.7 rmind error = npf_table_lookup(t, alen, addr);
174 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
175 1.1 rmind }
176 1.1 rmind
177 1.4 rmind /* IPv6 addresses. */
178 1.4 rmind memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
179 1.4 rmind alen = sizeof(struct in6_addr);
180 1.4 rmind
181 1.7 rmind t = npf_tableset_getbyname(tblset, HASH_TID);
182 1.7 rmind error = npf_table_insert(t, alen, addr, nm);
183 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
184 1.7 rmind error = npf_table_lookup(t, alen, addr);
185 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
186 1.7 rmind error = npf_table_remove(t, alen, addr, nm);
187 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
188 1.4 rmind
189 1.7 rmind t = npf_tableset_getbyname(tblset, TREE_TID);
190 1.7 rmind error = npf_table_insert(t, alen, addr, nm);
191 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
192 1.7 rmind error = npf_table_lookup(t, alen, addr);
193 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
194 1.7 rmind error = npf_table_remove(t, alen, addr, nm);
195 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
196 1.4 rmind
197 1.4 rmind /*
198 1.4 rmind * Masking: 96, 32, 127.
199 1.4 rmind */
200 1.4 rmind
201 1.4 rmind memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
202 1.7 rmind error = npf_table_insert(t, alen, addr, 96);
203 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
204 1.4 rmind
205 1.4 rmind memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
206 1.7 rmind error = npf_table_lookup(t, alen, addr);
207 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
208 1.4 rmind
209 1.4 rmind memcpy(addr, ip6_list[1], sizeof(ip6_list[1]));
210 1.7 rmind error = npf_table_remove(t, alen, addr, 96);
211 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
212 1.4 rmind
213 1.4 rmind
214 1.4 rmind memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
215 1.7 rmind error = npf_table_insert(t, alen, addr, 32);
216 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
217 1.4 rmind
218 1.4 rmind memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
219 1.7 rmind error = npf_table_lookup(t, alen, addr);
220 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
221 1.4 rmind
222 1.4 rmind memcpy(addr, ip6_list[2], sizeof(ip6_list[2]));
223 1.7 rmind error = npf_table_remove(t, alen, addr, 32);
224 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
225 1.4 rmind
226 1.4 rmind
227 1.4 rmind memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
228 1.7 rmind error = npf_table_insert(t, alen, addr, 126);
229 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
230 1.4 rmind
231 1.4 rmind memcpy(addr, ip6_list[0], sizeof(ip6_list[0]));
232 1.7 rmind error = npf_table_lookup(t, alen, addr);
233 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
234 1.4 rmind
235 1.4 rmind memcpy(addr, ip6_list[3], sizeof(ip6_list[3]));
236 1.7 rmind error = npf_table_remove(t, alen, addr, 126);
237 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
238 1.4 rmind
239 1.4 rmind
240 1.4 rmind alen = sizeof(struct in_addr);
241 1.4 rmind
242 1.4 rmind /* Remove all IPv4 entries. */
243 1.1 rmind for (i = 0; i < __arraycount(ip_list); i++) {
244 1.8.8.1 pgoyette addr->word32[0] = inet_addr(ip_list[i]);
245 1.1 rmind
246 1.7 rmind t = npf_tableset_getbyname(tblset, HASH_TID);
247 1.7 rmind error = npf_table_remove(t, alen, addr, nm);
248 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
249 1.1 rmind
250 1.7 rmind t = npf_tableset_getbyname(tblset, TREE_TID);
251 1.7 rmind error = npf_table_remove(t, alen, addr, nm);
252 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
253 1.1 rmind }
254 1.1 rmind
255 1.8 rmind /* Test CDB. */
256 1.8.8.1 pgoyette addr->word32[0] = inet_addr(ip_list[0]);
257 1.8 rmind alen = sizeof(struct in_addr);
258 1.8 rmind error = npf_table_lookup(t3, alen, addr);
259 1.8.8.1 pgoyette fail |= !check_ok(error == 0);
260 1.8 rmind
261 1.8 rmind for (i = 1; i < __arraycount(ip_list) - 1; i++) {
262 1.8.8.1 pgoyette addr->word32[0] = inet_addr(ip_list[i]);
263 1.8 rmind alen = sizeof(struct in_addr);
264 1.8 rmind error = npf_table_lookup(t3, alen, addr);
265 1.8.8.1 pgoyette fail |= !check_ok(error != 0);
266 1.8 rmind }
267 1.8 rmind
268 1.1 rmind npf_tableset_destroy(tblset);
269 1.1 rmind
270 1.5 rmind return !fail;
271 1.1 rmind }
272