Home | History | Annotate | Line # | Download | only in tests
      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);
     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 }
     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);
     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 }
    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);
    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 }
    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);
    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 }
    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);
    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 }
    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);
    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 }
    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);
    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 }
    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);
    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 }
    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);
    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 }
    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);
    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 }
    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);
    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 }
    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 
    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