1 /* $NetBSD: mdb6_unittest.c,v 1.2 2018/04/07 22:37:30 christos Exp $ */
2
3 /*
4 * Copyright (C) 2007-2017 by Internet Systems Consortium, Inc. ("ISC")
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include "config.h"
20
21 #include <sys/types.h>
22 #include <time.h>
23 #include <netinet/in.h>
24
25 #include <stdarg.h>
26 #include "dhcpd.h"
27 #include "omapip/omapip.h"
28 #include "omapip/hash.h"
29 #include <isc/md5.h>
30
31 #include <atf-c.h>
32
33 #include <stdlib.h>
34
35 void build_prefix6(struct in6_addr *pref, const struct in6_addr *net_start_pref,
36 int pool_bits, int pref_bits,
37 const struct data_string *input);
38
39 /*
40 * Basic iaaddr manipulation.
41 * Verify construction and referencing of an iaaddr.
42 */
43
44 ATF_TC(iaaddr_basic);
ATF_TC_HEAD(iaaddr_basic,tc)45 ATF_TC_HEAD(iaaddr_basic, tc)
46 {
47 atf_tc_set_md_var(tc, "descr", "This test case checks that basic "
48 "IAADDR manipulation is possible.");
49 }
ATF_TC_BODY(iaaddr_basic,tc)50 ATF_TC_BODY(iaaddr_basic, tc)
51 {
52 struct iasubopt *iaaddr;
53 struct iasubopt *iaaddr_copy;
54
55 /* set up dhcp globals */
56 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
57 NULL, NULL);
58
59 /* and other common arguments */
60 iaaddr = NULL;
61 iaaddr_copy = NULL;
62
63 /* tests */
64 if (iasubopt_allocate(&iaaddr, MDL) != ISC_R_SUCCESS) {
65 atf_tc_fail("ERROR: iasubopt_allocate() %s:%d", MDL);
66 }
67 if (iaaddr->state != FTS_FREE) {
68 atf_tc_fail("ERROR: bad state %s:%d", MDL);
69 }
70 if (iaaddr->active_index != 0) {
71 atf_tc_fail("ERROR: bad active_index :%d %s:%d",
72 iaaddr->active_index, MDL);
73 }
74 if (iaaddr->inactive_index != 0) {
75 atf_tc_fail("ERROR: bad inactive_index %d %s:%d",
76 iaaddr->inactive_index, MDL);
77 }
78 if (iasubopt_reference(&iaaddr_copy, iaaddr, MDL) != ISC_R_SUCCESS) {
79 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
80 }
81 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
82 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
83 }
84 if (iasubopt_dereference(&iaaddr_copy, MDL) != ISC_R_SUCCESS) {
85 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
86 }
87 }
88
89 /*
90 * Basic iaaddr sanity checks.
91 * Verify that the iaaddr code does some sanity checking.
92 */
93
94 ATF_TC(iaaddr_negative);
ATF_TC_HEAD(iaaddr_negative,tc)95 ATF_TC_HEAD(iaaddr_negative, tc)
96 {
97 atf_tc_set_md_var(tc, "descr", "This test case checks that IAADDR "
98 "option code can handle various negative scenarios.");
99 }
ATF_TC_BODY(iaaddr_negative,tc)100 ATF_TC_BODY(iaaddr_negative, tc)
101 {
102 struct iasubopt *iaaddr;
103 struct iasubopt *iaaddr_copy;
104
105 /* set up dhcp globals */
106 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
107 NULL, NULL);
108
109 /* tests */
110 /* bogus allocate arguments */
111 if (iasubopt_allocate(NULL, MDL) != DHCP_R_INVALIDARG) {
112 atf_tc_fail("ERROR: iasubopt_allocate() %s:%d", MDL);
113 }
114 iaaddr = (struct iasubopt *)1;
115 if (iasubopt_allocate(&iaaddr, MDL) != DHCP_R_INVALIDARG) {
116 atf_tc_fail("ERROR: iasubopt_allocate() %s:%d", MDL);
117 }
118
119 /* bogus reference arguments */
120 iaaddr = NULL;
121 if (iasubopt_allocate(&iaaddr, MDL) != ISC_R_SUCCESS) {
122 atf_tc_fail("ERROR: iasubopt_allocate() %s:%d", MDL);
123 }
124 if (iasubopt_reference(NULL, iaaddr, MDL) != DHCP_R_INVALIDARG) {
125 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
126 }
127 iaaddr_copy = (struct iasubopt *)1;
128 if (iasubopt_reference(&iaaddr_copy, iaaddr,
129 MDL) != DHCP_R_INVALIDARG) {
130 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
131 }
132 iaaddr_copy = NULL;
133 if (iasubopt_reference(&iaaddr_copy, NULL, MDL) != DHCP_R_INVALIDARG) {
134 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
135 }
136 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
137 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
138 }
139
140 /* bogus dereference arguments */
141 if (iasubopt_dereference(NULL, MDL) != DHCP_R_INVALIDARG) {
142 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
143 }
144 iaaddr = NULL;
145 if (iasubopt_dereference(&iaaddr, MDL) != DHCP_R_INVALIDARG) {
146 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
147 }
148 }
149
150 /*
151 * Basic ia_na manipulation.
152 */
153
154 ATF_TC(ia_na_basic);
ATF_TC_HEAD(ia_na_basic,tc)155 ATF_TC_HEAD(ia_na_basic, tc)
156 {
157 atf_tc_set_md_var(tc, "descr", "This test case checks that IA_NA code can "
158 "handle various basic scenarios.");
159 }
ATF_TC_BODY(ia_na_basic,tc)160 ATF_TC_BODY(ia_na_basic, tc)
161 {
162 uint32_t iaid;
163 struct ia_xx *ia_na;
164 struct ia_xx *ia_na_copy;
165 struct iasubopt *iaaddr;
166
167 /* set up dhcp globals */
168 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
169 NULL, NULL);
170
171 /* and other common arguments */
172 iaid = 666;
173 ia_na = NULL;
174 ia_na_copy = NULL;
175 iaaddr = NULL;
176
177 /* tests */
178 if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) {
179 atf_tc_fail("ERROR: ia_allocate() %s:%d", MDL);
180 }
181 if (memcmp(ia_na->iaid_duid.data, &iaid, sizeof(iaid)) != 0) {
182 atf_tc_fail("ERROR: bad IAID_DUID %s:%d", MDL);
183 }
184 if (memcmp(ia_na->iaid_duid.data+sizeof(iaid), "TestDUID", 8) != 0) {
185 atf_tc_fail("ERROR: bad IAID_DUID %s:%d", MDL);
186 }
187 if (ia_na->num_iasubopt != 0) {
188 atf_tc_fail("ERROR: bad num_iasubopt %s:%d", MDL);
189 }
190 if (ia_reference(&ia_na_copy, ia_na, MDL) != ISC_R_SUCCESS) {
191 atf_tc_fail("ERROR: ia_reference() %s:%d", MDL);
192 }
193 if (iasubopt_allocate(&iaaddr, MDL) != ISC_R_SUCCESS) {
194 atf_tc_fail("ERROR: iasubopt_allocate() %s:%d", MDL);
195 }
196 if (ia_add_iasubopt(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) {
197 atf_tc_fail("ERROR: ia_add_iasubopt() %s:%d", MDL);
198 }
199 ia_remove_iasubopt(ia_na, iaaddr, MDL);
200 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
201 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
202 }
203 if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) {
204 atf_tc_fail("ERROR: ia_dereference() %s:%d", MDL);
205 }
206 if (ia_dereference(&ia_na_copy, MDL) != ISC_R_SUCCESS) {
207 atf_tc_fail("ERROR: ia_dereference() %s:%d", MDL);
208 }
209 }
210
211 /*
212 * Lots of iaaddr in our ia_na.
213 * Create many iaaddrs and attach them to an ia_na
214 * then clean up by removing them one at a time and
215 * all at once by dereferencing the ia_na.
216 */
217
218 ATF_TC(ia_na_manyaddrs);
ATF_TC_HEAD(ia_na_manyaddrs,tc)219 ATF_TC_HEAD(ia_na_manyaddrs, tc)
220 {
221 atf_tc_set_md_var(tc, "descr", "This test case checks that IA_NA can "
222 "handle lots of addresses.");
223 }
ATF_TC_BODY(ia_na_manyaddrs,tc)224 ATF_TC_BODY(ia_na_manyaddrs, tc)
225 {
226 uint32_t iaid;
227 struct ia_xx *ia_na;
228 struct iasubopt *iaaddr;
229 int i;
230
231 /* set up dhcp globals */
232 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
233 NULL, NULL);
234
235 /* tests */
236 /* lots of iaaddr that we delete */
237 iaid = 666;
238 ia_na = NULL;
239 if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) {
240 atf_tc_fail("ERROR: ia_allocate() %s:%d", MDL);
241 }
242 for (i=0; i<100; i++) {
243 iaaddr = NULL;
244 if (iasubopt_allocate(&iaaddr, MDL) != ISC_R_SUCCESS) {
245 atf_tc_fail("ERROR: iasubopt_allocate() %s:%d", MDL);
246 }
247 if (ia_add_iasubopt(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) {
248 atf_tc_fail("ERROR: ia_add_iasubopt() %s:%d", MDL);
249 }
250 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
251 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
252 }
253 }
254
255 #if 0
256 for (i=0; i<100; i++) {
257 iaaddr = ia_na->iasubopt[random() % ia_na->num_iasubopt];
258 ia_remove_iasubopt(ia_na, iaaddr, MDL);
259 /* TODO: valgrind reports problem here: Invalid read of size 8
260 * Address 0x51e6258 is 56 bytes inside a block of size 88 free'd */
261 }
262 #endif
263 if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) {
264 atf_tc_fail("ERROR: ia_dereference() %s:%d", MDL);
265 }
266
267 /* lots of iaaddr, let dereference cleanup */
268 iaid = 666;
269 ia_na = NULL;
270 if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) {
271 atf_tc_fail("ERROR: ia_allocate() %s:%d", MDL);
272 }
273 for (i=0; i<100; i++) {
274 iaaddr = NULL;
275 if (iasubopt_allocate(&iaaddr, MDL) != ISC_R_SUCCESS) {
276 atf_tc_fail("ERROR: iasubopt_allocate() %s:%d", MDL);
277 }
278 if (ia_add_iasubopt(ia_na, iaaddr, MDL) != ISC_R_SUCCESS) {
279 atf_tc_fail("ERROR: ia_add_iasubopt() %s:%d", MDL);
280 }
281 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
282 atf_tc_fail("ERROR: iasubopt_reference() %s:%d", MDL);
283 }
284 }
285 if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) {
286 atf_tc_fail("ERROR: ia_dereference() %s:%d", MDL);
287 }
288 }
289
290 /*
291 * Basic ia_na sanity checks.
292 * Verify that the ia_na code does some sanity checking.
293 */
294
295 ATF_TC(ia_na_negative);
ATF_TC_HEAD(ia_na_negative,tc)296 ATF_TC_HEAD(ia_na_negative, tc)
297 {
298 atf_tc_set_md_var(tc, "descr", "This test case checks that IA_NA option "
299 "code can handle various negative scenarios.");
300 }
ATF_TC_BODY(ia_na_negative,tc)301 ATF_TC_BODY(ia_na_negative, tc)
302 {
303 uint32_t iaid;
304 struct ia_xx *ia_na;
305 struct ia_xx *ia_na_copy;
306
307 /* set up dhcp globals */
308 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
309 NULL, NULL);
310
311 /* tests */
312 /* bogus allocate arguments */
313 if (ia_allocate(NULL, 123, "", 0, MDL) != DHCP_R_INVALIDARG) {
314 atf_tc_fail("ERROR: ia_allocate() %s:%d", MDL);
315 }
316 ia_na = (struct ia_xx *)1;
317 if (ia_allocate(&ia_na, 456, "", 0, MDL) != DHCP_R_INVALIDARG) {
318 atf_tc_fail("ERROR: ia_allocate() %s:%d", MDL);
319 }
320
321 /* bogus reference arguments */
322 iaid = 666;
323 ia_na = NULL;
324 if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) {
325 atf_tc_fail("ERROR: ia_allocate() %s:%d", MDL);
326 }
327 if (ia_reference(NULL, ia_na, MDL) != DHCP_R_INVALIDARG) {
328 atf_tc_fail("ERROR: ia_reference() %s:%d", MDL);
329 }
330 ia_na_copy = (struct ia_xx *)1;
331 if (ia_reference(&ia_na_copy, ia_na, MDL) != DHCP_R_INVALIDARG) {
332 atf_tc_fail("ERROR: ia_reference() %s:%d", MDL);
333 }
334 ia_na_copy = NULL;
335 if (ia_reference(&ia_na_copy, NULL, MDL) != DHCP_R_INVALIDARG) {
336 atf_tc_fail("ERROR: ia_reference() %s:%d", MDL);
337 }
338 if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) {
339 atf_tc_fail("ERROR: ia_dereference() %s:%d", MDL);
340 }
341
342 /* bogus dereference arguments */
343 if (ia_dereference(NULL, MDL) != DHCP_R_INVALIDARG) {
344 atf_tc_fail("ERROR: ia_dereference() %s:%d", MDL);
345 }
346
347 /* bogus remove */
348 iaid = 666;
349 ia_na = NULL;
350 if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) {
351 atf_tc_fail("ERROR: ia_allocate() %s:%d", MDL);
352 }
353 ia_remove_iasubopt(ia_na, NULL, MDL);
354 if (ia_dereference(&ia_na, MDL) != ISC_R_SUCCESS) {
355 atf_tc_fail("ERROR: ia_dereference() %s:%d", MDL);
356 }
357 }
358
359 /*
360 * Basic ipv6_pool manipulation.
361 * Verify that basic pool operations work properly.
362 * The operations include creating a pool and creating,
363 * renewing, expiring, releasing and declining addresses.
364 */
365
366 ATF_TC(ipv6_pool_basic);
ATF_TC_HEAD(ipv6_pool_basic,tc)367 ATF_TC_HEAD(ipv6_pool_basic, tc)
368 {
369 atf_tc_set_md_var(tc, "descr", "This test case checks that IPv6 pool "
370 "manipulation is possible.");
371 }
ATF_TC_BODY(ipv6_pool_basic,tc)372 ATF_TC_BODY(ipv6_pool_basic, tc)
373 {
374 struct iasubopt *iaaddr;
375 struct in6_addr addr;
376 struct ipv6_pool *pool;
377 struct ipv6_pool *pool_copy;
378 char addr_buf[INET6_ADDRSTRLEN];
379 char *uid;
380 struct data_string ds;
381 struct iasubopt *expired_iaaddr;
382 unsigned int attempts;
383
384 /* set up dhcp globals */
385 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
386 NULL, NULL);
387
388 /* and other common arguments */
389 inet_pton(AF_INET6, "1:2:3:4::", &addr);
390
391 uid = "client0";
392 memset(&ds, 0, sizeof(ds));
393 ds.len = strlen(uid);
394 if (!buffer_allocate(&ds.buffer, ds.len, MDL)) {
395 atf_tc_fail("Out of memory");
396 }
397 ds.data = ds.buffer->data;
398 memcpy((char *)ds.data, uid, ds.len);
399
400 /* tests */
401 /* allocate, reference */
402 pool = NULL;
403 if (ipv6_pool_allocate(&pool, D6O_IA_NA, &addr,
404 64, 128, MDL) != ISC_R_SUCCESS) {
405 atf_tc_fail("ERROR: ipv6_pool_allocate() %s:%d", MDL);
406 }
407 if (pool->num_active != 0) {
408 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
409 }
410 if (pool->bits != 64) {
411 atf_tc_fail("ERROR: bad bits %s:%d", MDL);
412 }
413 inet_ntop(AF_INET6, &pool->start_addr, addr_buf, sizeof(addr_buf));
414 if (strcmp(inet_ntop(AF_INET6, &pool->start_addr, addr_buf,
415 sizeof(addr_buf)), "1:2:3:4::") != 0) {
416 atf_tc_fail("ERROR: bad start_addr %s:%d", MDL);
417 }
418 pool_copy = NULL;
419 if (ipv6_pool_reference(&pool_copy, pool, MDL) != ISC_R_SUCCESS) {
420 atf_tc_fail("ERROR: ipv6_pool_reference() %s:%d", MDL);
421 }
422
423 /* create_lease6, renew_lease6, expire_lease6 */
424 iaaddr = NULL;
425 if (create_lease6(pool, &iaaddr,
426 &attempts, &ds, 1) != ISC_R_SUCCESS) {
427 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
428 }
429 if (pool->num_inactive != 1) {
430 atf_tc_fail("ERROR: bad num_inactive %s:%d", MDL);
431 }
432 if (renew_lease6(pool, iaaddr) != ISC_R_SUCCESS) {
433 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
434 }
435 if (pool->num_active != 1) {
436 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
437 }
438 expired_iaaddr = NULL;
439 if (expire_lease6(&expired_iaaddr, pool, 0) != ISC_R_SUCCESS) {
440 atf_tc_fail("ERROR: expire_lease6() %s:%d", MDL);
441 }
442 if (expired_iaaddr != NULL) {
443 atf_tc_fail("ERROR: should not have expired a lease %s:%d", MDL);
444 }
445 if (pool->num_active != 1) {
446 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
447 }
448 if (expire_lease6(&expired_iaaddr, pool, 1000) != ISC_R_SUCCESS) {
449 atf_tc_fail("ERROR: expire_lease6() %s:%d", MDL);
450 }
451 if (expired_iaaddr == NULL) {
452 atf_tc_fail("ERROR: should have expired a lease %s:%d", MDL);
453 }
454 if (iasubopt_dereference(&expired_iaaddr, MDL) != ISC_R_SUCCESS) {
455 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
456 }
457 if (pool->num_active != 0) {
458 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
459 }
460 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
461 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
462 }
463
464 /* release_lease6, decline_lease6 */
465 if (create_lease6(pool, &iaaddr, &attempts,
466 &ds, 1) != ISC_R_SUCCESS) {
467 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
468 }
469 if (renew_lease6(pool, iaaddr) != ISC_R_SUCCESS) {
470 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
471 }
472 if (pool->num_active != 1) {
473 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
474 }
475 if (release_lease6(pool, iaaddr) != ISC_R_SUCCESS) {
476 atf_tc_fail("ERROR: decline_lease6() %s:%d", MDL);
477 }
478 if (pool->num_active != 0) {
479 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
480 }
481 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
482 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
483 }
484 if (create_lease6(pool, &iaaddr, &attempts,
485 &ds, 1) != ISC_R_SUCCESS) {
486 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
487 }
488 if (renew_lease6(pool, iaaddr) != ISC_R_SUCCESS) {
489 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
490 }
491 if (pool->num_active != 1) {
492 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
493 }
494 if (decline_lease6(pool, iaaddr) != ISC_R_SUCCESS) {
495 atf_tc_fail("ERROR: decline_lease6() %s:%d", MDL);
496 }
497 if (pool->num_active != 1) {
498 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
499 }
500 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
501 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
502 }
503
504 /* dereference */
505 if (ipv6_pool_dereference(&pool, MDL) != ISC_R_SUCCESS) {
506 atf_tc_fail("ERROR: ipv6_pool_reference() %s:%d", MDL);
507 }
508 if (ipv6_pool_dereference(&pool_copy, MDL) != ISC_R_SUCCESS) {
509 atf_tc_fail("ERROR: ipv6_pool_reference() %s:%d", MDL);
510 }
511 }
512
513 /*
514 * Basic ipv6_pool sanity checks.
515 * Verify that the ipv6_pool code does some sanity checking.
516 */
517
518 ATF_TC(ipv6_pool_negative);
ATF_TC_HEAD(ipv6_pool_negative,tc)519 ATF_TC_HEAD(ipv6_pool_negative, tc)
520 {
521 atf_tc_set_md_var(tc, "descr", "This test case checks that IPv6 pool "
522 "can handle negative cases.");
523 }
ATF_TC_BODY(ipv6_pool_negative,tc)524 ATF_TC_BODY(ipv6_pool_negative, tc)
525 {
526 struct in6_addr addr;
527 struct ipv6_pool *pool;
528 struct ipv6_pool *pool_copy;
529
530 /* set up dhcp globals */
531 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
532 NULL, NULL);
533
534 /* and other common arguments */
535 inet_pton(AF_INET6, "1:2:3:4::", &addr);
536
537 /* tests */
538 if (ipv6_pool_allocate(NULL, D6O_IA_NA, &addr,
539 64, 128, MDL) != DHCP_R_INVALIDARG) {
540 atf_tc_fail("ERROR: ipv6_pool_allocate() %s:%d", MDL);
541 }
542 pool = (struct ipv6_pool *)1;
543 if (ipv6_pool_allocate(&pool, D6O_IA_NA, &addr,
544 64, 128, MDL) != DHCP_R_INVALIDARG) {
545 atf_tc_fail("ERROR: ipv6_pool_allocate() %s:%d", MDL);
546 }
547 if (ipv6_pool_reference(NULL, pool, MDL) != DHCP_R_INVALIDARG) {
548 atf_tc_fail("ERROR: ipv6_pool_reference() %s:%d", MDL);
549 }
550 pool_copy = (struct ipv6_pool *)1;
551 if (ipv6_pool_reference(&pool_copy, pool, MDL) != DHCP_R_INVALIDARG) {
552 atf_tc_fail("ERROR: ipv6_pool_reference() %s:%d", MDL);
553 }
554 pool_copy = NULL;
555 if (ipv6_pool_reference(&pool_copy, NULL, MDL) != DHCP_R_INVALIDARG) {
556 atf_tc_fail("ERROR: ipv6_pool_reference() %s:%d", MDL);
557 }
558 if (ipv6_pool_dereference(NULL, MDL) != DHCP_R_INVALIDARG) {
559 atf_tc_fail("ERROR: ipv6_pool_dereference() %s:%d", MDL);
560 }
561 if (ipv6_pool_dereference(&pool_copy, MDL) != DHCP_R_INVALIDARG) {
562 atf_tc_fail("ERROR: ipv6_pool_dereference() %s:%d", MDL);
563 }
564 }
565
566
567 /*
568 * Order of expiration.
569 * Add several addresses to a pool and check that
570 * they expire in the proper order.
571 */
572
573 ATF_TC(expire_order);
ATF_TC_HEAD(expire_order,tc)574 ATF_TC_HEAD(expire_order, tc)
575 {
576 atf_tc_set_md_var(tc, "descr", "This test case checks that order "
577 "of lease expiration is handled properly.");
578 }
ATF_TC_BODY(expire_order,tc)579 ATF_TC_BODY(expire_order, tc)
580 {
581 struct iasubopt *iaaddr;
582 struct ipv6_pool *pool;
583 struct in6_addr addr;
584 int i;
585 char *uid;
586 struct data_string ds;
587 struct iasubopt *expired_iaaddr;
588 unsigned int attempts;
589
590 /* set up dhcp globals */
591 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
592 NULL, NULL);
593
594 /* and other common arguments */
595 inet_pton(AF_INET6, "1:2:3:4::", &addr);
596
597 uid = "client0";
598 memset(&ds, 0, sizeof(ds));
599 ds.len = strlen(uid);
600 if (!buffer_allocate(&ds.buffer, ds.len, MDL)) {
601 atf_tc_fail("Out of memory");
602 }
603 ds.data = ds.buffer->data;
604 memcpy((char *)ds.data, uid, ds.len);
605
606 iaaddr = NULL;
607 expired_iaaddr = NULL;
608
609 /* tests */
610 pool = NULL;
611 if (ipv6_pool_allocate(&pool, D6O_IA_NA, &addr,
612 64, 128, MDL) != ISC_R_SUCCESS) {
613 atf_tc_fail("ERROR: ipv6_pool_allocate() %s:%d", MDL);
614 }
615
616 for (i=10; i<100; i+=10) {
617 if (create_lease6(pool, &iaaddr, &attempts,
618 &ds, i) != ISC_R_SUCCESS) {
619 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
620 }
621 if (renew_lease6(pool, iaaddr) != ISC_R_SUCCESS) {
622 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
623 }
624 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
625 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
626 }
627 if (pool->num_active != (i / 10)) {
628 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
629 }
630 }
631 if (pool->num_active != 9) {
632 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
633 }
634
635 for (i=10; i<100; i+=10) {
636 if (expire_lease6(&expired_iaaddr,
637 pool, 1000) != ISC_R_SUCCESS) {
638 atf_tc_fail("ERROR: expire_lease6() %s:%d", MDL);
639 }
640 if (expired_iaaddr == NULL) {
641 atf_tc_fail("ERROR: should have expired a lease %s:%d",
642 MDL);
643 }
644 if (pool->num_active != (9 - (i / 10))) {
645 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
646 }
647 if (expired_iaaddr->hard_lifetime_end_time != i) {
648 atf_tc_fail("ERROR: bad hard_lifetime_end_time %s:%d",
649 MDL);
650 }
651 if (iasubopt_dereference(&expired_iaaddr, MDL) !=
652 ISC_R_SUCCESS) {
653 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
654 }
655 }
656 if (pool->num_active != 0) {
657 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
658 }
659 expired_iaaddr = NULL;
660 if (expire_lease6(&expired_iaaddr, pool, 1000) != ISC_R_SUCCESS) {
661 atf_tc_fail("ERROR: expire_lease6() %s:%d", MDL);
662 }
663 if (ipv6_pool_dereference(&pool, MDL) != ISC_R_SUCCESS) {
664 atf_tc_fail("ERROR: ipv6_pool_dereference() %s:%d", MDL);
665 }
666 }
667
668 /*
669 * Reduce the expiration period of a lease.
670 * This test reduces the expiration period of
671 * a lease to verify we process reductions
672 * properly.
673 */
674 ATF_TC(expire_order_reduce);
ATF_TC_HEAD(expire_order_reduce,tc)675 ATF_TC_HEAD(expire_order_reduce, tc)
676 {
677 atf_tc_set_md_var(tc, "descr", "This test case checks that reducing "
678 "the expiration time of a lease works properly.");
679 }
ATF_TC_BODY(expire_order_reduce,tc)680 ATF_TC_BODY(expire_order_reduce, tc)
681 {
682 struct iasubopt *iaaddr1, *iaaddr2;
683 struct ipv6_pool *pool;
684 struct in6_addr addr;
685 char *uid;
686 struct data_string ds;
687 struct iasubopt *expired_iaaddr;
688 unsigned int attempts;
689
690 /* set up dhcp globals */
691 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
692 NULL, NULL);
693
694 /* and other common arguments */
695 inet_pton(AF_INET6, "1:2:3:4::", &addr);
696
697 uid = "client0";
698 memset(&ds, 0, sizeof(ds));
699 ds.len = strlen(uid);
700 if (!buffer_allocate(&ds.buffer, ds.len, MDL)) {
701 atf_tc_fail("Out of memory");
702 }
703 ds.data = ds.buffer->data;
704 memcpy((char *)ds.data, uid, ds.len);
705
706 pool = NULL;
707 iaaddr1 = NULL;
708 iaaddr2 = NULL;
709 expired_iaaddr = NULL;
710
711 /*
712 * Add two leases iaaddr1 with expire time of 200
713 * and iaaddr2 with expire time of 300. Then update
714 * iaaddr2 to expire in 100 instead. This should cause
715 * iaaddr2 to move with the hash list.
716 */
717 /* create pool and add iaaddr1 and iaaddr2 */
718 if (ipv6_pool_allocate(&pool, D6O_IA_NA, &addr,
719 64, 128, MDL) != ISC_R_SUCCESS) {
720 atf_tc_fail("ERROR: ipv6_pool_allocate() %s:%d", MDL);
721 }
722 if (create_lease6(pool, &iaaddr1, &attempts, &ds, 200) != ISC_R_SUCCESS) {
723 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
724 }
725 if (renew_lease6(pool, iaaddr1) != ISC_R_SUCCESS) {
726 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
727 }
728 if (create_lease6(pool, &iaaddr2, &attempts, &ds, 300) != ISC_R_SUCCESS) {
729 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
730 }
731 if (renew_lease6(pool, iaaddr2) != ISC_R_SUCCESS) {
732 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
733 }
734
735 /* verify pool */
736 if (pool->num_active != 2) {
737 atf_tc_fail("ERROR: bad num_active %s:%d", MDL);
738 }
739
740 /* reduce lease for iaaddr2 */
741 iaaddr2->soft_lifetime_end_time = 100;
742 if (renew_lease6(pool, iaaddr2) != ISC_R_SUCCESS) {
743 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
744 }
745
746 /* expire a lease, it should be iaaddr2 with an expire time of 100 */
747 if (expire_lease6(&expired_iaaddr, pool, 1000) != ISC_R_SUCCESS) {
748 atf_tc_fail("ERROR: expire_lease6() %s:%d", MDL);
749 }
750 if (expired_iaaddr == NULL) {
751 atf_tc_fail("ERROR: should have expired a lease %s:%d", MDL);
752 }
753 if (expired_iaaddr != iaaddr2) {
754 atf_tc_fail("Error: incorrect lease expired %s:%d", MDL);
755 }
756 if (expired_iaaddr->hard_lifetime_end_time != 100) {
757 atf_tc_fail("ERROR: bad hard_lifetime_end_time %s:%d", MDL);
758 }
759 if (iasubopt_dereference(&expired_iaaddr, MDL) != ISC_R_SUCCESS) {
760 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
761 }
762
763 /* expire a lease, it should be iaaddr1 with an expire time of 200 */
764 if (expire_lease6(&expired_iaaddr, pool, 1000) != ISC_R_SUCCESS) {
765 atf_tc_fail("ERROR: expire_lease6() %s:%d", MDL);
766 }
767 if (expired_iaaddr == NULL) {
768 atf_tc_fail("ERROR: should have expired a lease %s:%d", MDL);
769 }
770 if (expired_iaaddr != iaaddr1) {
771 atf_tc_fail("Error: incorrect lease expired %s:%d", MDL);
772 }
773 if (expired_iaaddr->hard_lifetime_end_time != 200) {
774 atf_tc_fail("ERROR: bad hard_lifetime_end_time %s:%d", MDL);
775 }
776 if (iasubopt_dereference(&expired_iaaddr, MDL) != ISC_R_SUCCESS) {
777 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
778 }
779
780 /* cleanup */
781 if (iasubopt_dereference(&iaaddr1, MDL) != ISC_R_SUCCESS) {
782 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
783 }
784 if (iasubopt_dereference(&iaaddr2, MDL) != ISC_R_SUCCESS) {
785 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
786 }
787 if (ipv6_pool_dereference(&pool, MDL) != ISC_R_SUCCESS) {
788 atf_tc_fail("ERROR: ipv6_pool_dereference() %s:%d", MDL);
789 }
790 }
791
792 /*
793 * Small pool.
794 * check that a small pool behaves properly.
795 */
796
797 ATF_TC(small_pool);
ATF_TC_HEAD(small_pool,tc)798 ATF_TC_HEAD(small_pool, tc)
799 {
800 atf_tc_set_md_var(tc, "descr", "This test case checks that small pool "
801 "is handled properly.");
802 }
ATF_TC_BODY(small_pool,tc)803 ATF_TC_BODY(small_pool, tc)
804 {
805 struct in6_addr addr;
806 struct ipv6_pool *pool;
807 struct iasubopt *iaaddr;
808 char *uid;
809 struct data_string ds;
810 unsigned int attempts;
811
812 /* set up dhcp globals */
813 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
814 NULL, NULL);
815
816 /* and other common arguments */
817 inet_pton(AF_INET6, "1:2:3:4::", &addr);
818 addr.s6_addr[14] = 0x81;
819
820 uid = "client0";
821 memset(&ds, 0, sizeof(ds));
822 ds.len = strlen(uid);
823 if (!buffer_allocate(&ds.buffer, ds.len, MDL)) {
824 atf_tc_fail("Out of memory");
825 }
826 ds.data = ds.buffer->data;
827 memcpy((char *)ds.data, uid, ds.len);
828
829 pool = NULL;
830 iaaddr = NULL;
831
832 /* tests */
833 if (ipv6_pool_allocate(&pool, D6O_IA_NA, &addr,
834 127, 128, MDL) != ISC_R_SUCCESS) {
835 atf_tc_fail("ERROR: ipv6_pool_allocate() %s:%d", MDL);
836 }
837
838 if (create_lease6(pool, &iaaddr, &attempts,
839 &ds, 42) != ISC_R_SUCCESS) {
840 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
841 }
842 if (renew_lease6(pool, iaaddr) != ISC_R_SUCCESS) {
843 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
844 }
845 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
846 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
847 }
848 if (create_lease6(pool, &iaaddr, &attempts,
849 &ds, 11) != ISC_R_SUCCESS) {
850 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
851 }
852 if (renew_lease6(pool, iaaddr) != ISC_R_SUCCESS) {
853 atf_tc_fail("ERROR: renew_lease6() %s:%d", MDL);
854 }
855 if (iasubopt_dereference(&iaaddr, MDL) != ISC_R_SUCCESS) {
856 atf_tc_fail("ERROR: iasubopt_dereference() %s:%d", MDL);
857 }
858 if (create_lease6(pool, &iaaddr, &attempts,
859 &ds, 11) != ISC_R_NORESOURCES) {
860 atf_tc_fail("ERROR: create_lease6() %s:%d", MDL);
861 }
862 if (ipv6_pool_dereference(&pool, MDL) != ISC_R_SUCCESS) {
863 atf_tc_fail("ERROR: ipv6_pool_dereference() %s:%d", MDL);
864 }
865 }
866
867 /*
868 * Address to pool mapping.
869 * Verify that we find the proper pool for an address
870 * or don't find a pool if we don't have one for the given
871 * address.
872 */
873 ATF_TC(many_pools);
ATF_TC_HEAD(many_pools,tc)874 ATF_TC_HEAD(many_pools, tc)
875 {
876 atf_tc_set_md_var(tc, "descr", "This test case checks that functions "
877 "across all pools are working correctly.");
878 }
ATF_TC_BODY(many_pools,tc)879 ATF_TC_BODY(many_pools, tc)
880 {
881 struct in6_addr addr;
882 struct ipv6_pool *pool;
883
884 /* set up dhcp globals */
885 dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
886 NULL, NULL);
887
888 /* and other common arguments */
889 inet_pton(AF_INET6, "1:2:3:4::", &addr);
890
891 /* tests */
892
893 pool = NULL;
894 if (ipv6_pool_allocate(&pool, D6O_IA_NA, &addr,
895 64, 128, MDL) != ISC_R_SUCCESS) {
896 atf_tc_fail("ERROR: ipv6_pool_allocate() %s:%d", MDL);
897 }
898 if (add_ipv6_pool(pool) != ISC_R_SUCCESS) {
899 atf_tc_fail("ERROR: add_ipv6_pool() %s:%d", MDL);
900 }
901 if (ipv6_pool_dereference(&pool, MDL) != ISC_R_SUCCESS) {
902 atf_tc_fail("ERROR: ipv6_pool_dereference() %s:%d", MDL);
903 }
904 pool = NULL;
905 if (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != ISC_R_SUCCESS) {
906 atf_tc_fail("ERROR: find_ipv6_pool() %s:%d", MDL);
907 }
908 if (ipv6_pool_dereference(&pool, MDL) != ISC_R_SUCCESS) {
909 atf_tc_fail("ERROR: ipv6_pool_dereference() %s:%d", MDL);
910 }
911 inet_pton(AF_INET6, "1:2:3:4:ffff:ffff:ffff:ffff", &addr);
912 pool = NULL;
913 if (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != ISC_R_SUCCESS) {
914 atf_tc_fail("ERROR: find_ipv6_pool() %s:%d", MDL);
915 }
916 if (ipv6_pool_dereference(&pool, MDL) != ISC_R_SUCCESS) {
917 atf_tc_fail("ERROR: ipv6_pool_dereference() %s:%d", MDL);
918 }
919 inet_pton(AF_INET6, "1:2:3:5::", &addr);
920 pool = NULL;
921 if (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != ISC_R_NOTFOUND) {
922 atf_tc_fail("ERROR: find_ipv6_pool() %s:%d", MDL);
923 }
924 inet_pton(AF_INET6, "1:2:3:3:ffff:ffff:ffff:ffff", &addr);
925 pool = NULL;
926 if (find_ipv6_pool(&pool, D6O_IA_NA, &addr) != ISC_R_NOTFOUND) {
927 atf_tc_fail("ERROR: find_ipv6_pool() %s:%d", MDL);
928 }
929
930 /* iaid = 666;
931 ia_na = NULL;
932 if (ia_allocate(&ia_na, iaid, "TestDUID", 8, MDL) != ISC_R_SUCCESS) {
933 atf_tc_fail("ERROR: ia_allocate() %s:%d", MDL);
934 }*/
935
936 {
937 struct in6_addr r;
938 struct data_string ds;
939 u_char data[16];
940 char buf[64];
941 int i, j;
942
943 memset(&ds, 0, sizeof(ds));
944 memset(data, 0xaa, sizeof(data));
945 ds.len = 16;
946 ds.data = data;
947
948 inet_pton(AF_INET6, "3ffe:501:ffff:100::", &addr);
949 for (i = 32; i < 42; i++)
950 for (j = i + 1; j < 49; j++) {
951 memset(&r, 0, sizeof(r));
952 memset(buf, 0, 64);
953 build_prefix6(&r, &addr, i, j, &ds);
954 inet_ntop(AF_INET6, &r, buf, 64);
955 printf("%d,%d-> %s/%d\n", i, j, buf, j);
956 }
957 }
958 }
959
ATF_TP_ADD_TCS(tp)960 ATF_TP_ADD_TCS(tp)
961 {
962 ATF_TP_ADD_TC(tp, iaaddr_basic);
963 ATF_TP_ADD_TC(tp, iaaddr_negative);
964 ATF_TP_ADD_TC(tp, ia_na_basic);
965 ATF_TP_ADD_TC(tp, ia_na_manyaddrs);
966 ATF_TP_ADD_TC(tp, ia_na_negative);
967 ATF_TP_ADD_TC(tp, ipv6_pool_basic);
968 ATF_TP_ADD_TC(tp, ipv6_pool_negative);
969 ATF_TP_ADD_TC(tp, expire_order);
970 ATF_TP_ADD_TC(tp, expire_order_reduce);
971 ATF_TP_ADD_TC(tp, small_pool);
972 ATF_TP_ADD_TC(tp, many_pools);
973
974 return (atf_no_error());
975 }
976