xref: /netbsd-src/external/mpl/dhcp/dist/server/tests/mdb6_unittest.c (revision ce893c7eea48d62b6f0d8ef9958789ad27d03f6f)
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