npf_table_test.c revision 1.1.2.3 1 /* $NetBSD: npf_table_test.c,v 1.1.2.3 2012/10/30 19:00:48 yamt 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