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