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