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