Annotation of embedaddon/dhcp/client/dhc6.c, revision 1.1.1.1

1.1       misho       1: /* dhc6.c - DHCPv6 client routines. */
                      2: 
                      3: /*
1.1.1.1 ! misho       4:  * Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC")
1.1       misho       5:  * Copyright (c) 2006-2010 by Internet Systems Consortium, Inc. ("ISC")
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     17:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  *
                     19:  *   Internet Systems Consortium, Inc.
                     20:  *   950 Charter Street
                     21:  *   Redwood City, CA 94063
                     22:  *   <info@isc.org>
                     23:  *   https://www.isc.org/
                     24:  */
                     25: 
                     26: #include "dhcpd.h"
                     27: 
                     28: #ifdef DHCPv6
                     29: 
                     30: struct sockaddr_in6 DHCPv6DestAddr;
                     31: 
                     32: /*
                     33:  * Option definition structures that are used by the software - declared
                     34:  * here once and assigned at startup to save lookups.
                     35:  */
                     36: struct option *clientid_option = NULL;
                     37: struct option *elapsed_option = NULL;
                     38: struct option *ia_na_option = NULL;
                     39: struct option *ia_ta_option = NULL;
                     40: struct option *ia_pd_option = NULL;
                     41: struct option *iaaddr_option = NULL;
                     42: struct option *iaprefix_option = NULL;
                     43: struct option *oro_option = NULL;
                     44: struct option *irt_option = NULL;
                     45: 
                     46: static struct dhc6_lease *dhc6_dup_lease(struct dhc6_lease *lease,
                     47:                                         const char *file, int line);
                     48: static struct dhc6_ia *dhc6_dup_ia(struct dhc6_ia *ia,
                     49:                                   const char *file, int line);
                     50: static struct dhc6_addr *dhc6_dup_addr(struct dhc6_addr *addr,
                     51:                                       const char *file, int line);
                     52: static void dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line);
                     53: static isc_result_t dhc6_parse_ia_na(struct dhc6_ia **pia,
                     54:                                     struct packet *packet,
                     55:                                     struct option_state *options);
                     56: static isc_result_t dhc6_parse_ia_ta(struct dhc6_ia **pia,
                     57:                                     struct packet *packet,
                     58:                                     struct option_state *options);
                     59: static isc_result_t dhc6_parse_ia_pd(struct dhc6_ia **pia,
                     60:                                     struct packet *packet,
                     61:                                     struct option_state *options);
                     62: static isc_result_t dhc6_parse_addrs(struct dhc6_addr **paddr,
                     63:                                     struct packet *packet,
                     64:                                     struct option_state *options);
                     65: static isc_result_t dhc6_parse_prefixes(struct dhc6_addr **ppref,
                     66:                                        struct packet *packet,
                     67:                                        struct option_state *options);
                     68: static struct dhc6_ia *find_ia(struct dhc6_ia *head,
                     69:                               u_int16_t type, const char *id);
                     70: static struct dhc6_addr *find_addr(struct dhc6_addr *head,
                     71:                                   struct iaddr *address);
                     72: static struct dhc6_addr *find_pref(struct dhc6_addr *head,
                     73:                                   struct iaddr *prefix, u_int8_t plen);
                     74: void init_handler(struct packet *packet, struct client_state *client);
                     75: void info_request_handler(struct packet *packet, struct client_state *client);
                     76: void rapid_commit_handler(struct packet *packet, struct client_state *client);
                     77: void do_init6(void *input);
                     78: void do_info_request6(void *input);
                     79: void do_confirm6(void *input);
                     80: void reply_handler(struct packet *packet, struct client_state *client);
                     81: static isc_result_t dhc6_add_ia_na(struct client_state *client,
                     82:                                   struct data_string *packet,
                     83:                                   struct dhc6_lease *lease,
                     84:                                   u_int8_t message);
                     85: static isc_result_t dhc6_add_ia_ta(struct client_state *client,
                     86:                                   struct data_string *packet,
                     87:                                   struct dhc6_lease *lease,
                     88:                                   u_int8_t message);
                     89: static isc_result_t dhc6_add_ia_pd(struct client_state *client,
                     90:                                   struct data_string *packet,
                     91:                                   struct dhc6_lease *lease,
                     92:                                   u_int8_t message);
                     93: static isc_boolean_t stopping_finished(void);
                     94: static void dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst);
                     95: void do_select6(void *input);
                     96: void do_refresh6(void *input);
                     97: static void do_release6(void *input);
                     98: static void start_bound(struct client_state *client);
                     99: static void start_informed(struct client_state *client);
                    100: void informed_handler(struct packet *packet, struct client_state *client);
                    101: void bound_handler(struct packet *packet, struct client_state *client);
                    102: void start_renew6(void *input);
                    103: void start_rebind6(void *input);
                    104: void do_depref(void *input);
                    105: void do_expire(void *input);
                    106: static void make_client6_options(struct client_state *client,
                    107:                                 struct option_state **op,
                    108:                                 struct dhc6_lease *lease, u_int8_t message);
                    109: static void script_write_params6(struct client_state *client,
                    110:                                 const char *prefix,
                    111:                                 struct option_state *options);
                    112: static isc_boolean_t active_prefix(struct client_state *client);
                    113: 
                    114: static int check_timing6(struct client_state *client, u_int8_t msg_type, 
                    115:                         char *msg_str, struct dhc6_lease *lease,
                    116:                         struct data_string *ds);
                    117: 
                    118: extern int onetry;
                    119: extern int stateless;
                    120: 
                    121: /*
                    122:  * The "best" default DUID, since we cannot predict any information
                    123:  * about the system (such as whether or not the hardware addresses are
                    124:  * integrated into the motherboard or similar), is the "LLT", link local
                    125:  * plus time, DUID. For real stateless "LL" is better.
                    126:  *
                    127:  * Once generated, this duid is stored into the state database, and
                    128:  * retained across restarts.
                    129:  *
                    130:  * For the time being, there is probably a different state database for
                    131:  * every daemon, so this winds up being a per-interface identifier...which
                    132:  * is not how it is intended.  Upcoming rearchitecting the client should
                    133:  * address this "one daemon model."
                    134:  */
                    135: void
                    136: form_duid(struct data_string *duid, const char *file, int line)
                    137: {
                    138:        struct interface_info *ip;
                    139:        int len;
                    140: 
                    141:        /* For now, just use the first interface on the list. */
                    142:        ip = interfaces;
                    143: 
                    144:        if (ip == NULL)
                    145:                log_fatal("Impossible condition at %s:%d.", MDL);
                    146: 
                    147:        if ((ip->hw_address.hlen == 0) ||
                    148:            (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
                    149:                log_fatal("Impossible hardware address length at %s:%d.", MDL);
                    150: 
                    151:        /*
                    152:         * 2 bytes for the 'duid type' field.
                    153:         * 2 bytes for the 'htype' field.
                    154:         * (not stateless) 4 bytes for the 'current time'.
                    155:         * enough bytes for the hardware address (note that hw_address has
                    156:         * the 'htype' on byte zero).
                    157:         */
                    158:        len = 4 + (ip->hw_address.hlen - 1);
                    159:        if (!stateless)
                    160:                len += 4;
                    161:        if (!buffer_allocate(&duid->buffer, len, MDL))
                    162:                log_fatal("no memory for default DUID!");
                    163:        duid->data = duid->buffer->data;
                    164:        duid->len = len;
                    165: 
                    166:        /* Basic Link Local Address type of DUID. */
                    167:        if (!stateless) {
                    168:                putUShort(duid->buffer->data, DUID_LLT);
                    169:                putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
                    170:                putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH);
                    171:                memcpy(duid->buffer->data + 8, ip->hw_address.hbuf + 1,
                    172:                       ip->hw_address.hlen - 1);
                    173:        } else {
                    174:                putUShort(duid->buffer->data, DUID_LL);
                    175:                putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
                    176:                memcpy(duid->buffer->data + 4, ip->hw_address.hbuf + 1,
                    177:                       ip->hw_address.hlen - 1);
                    178:        }
                    179: }
                    180: 
                    181: /*
                    182:  * Assign DHCPv6 port numbers as a client.
                    183:  */
                    184: void
                    185: dhcpv6_client_assignments(void)
                    186: {
                    187:        struct servent *ent;
                    188:        unsigned code;
                    189: 
                    190:        if (path_dhclient_pid == NULL)
                    191:                path_dhclient_pid = _PATH_DHCLIENT6_PID;
                    192:        if (path_dhclient_db == NULL)
                    193:                path_dhclient_db = _PATH_DHCLIENT6_DB;
                    194: 
                    195:        if (local_port == 0) {
                    196:                ent = getservbyname("dhcpv6-client", "udp");
                    197:                if (ent == NULL)
                    198:                        local_port = htons(546);
                    199:                else
                    200:                        local_port = ent->s_port;
                    201:        }
                    202: 
                    203:        if (remote_port == 0) {
                    204:                ent = getservbyname("dhcpv6-server", "udp");
                    205:                if (ent == NULL)
                    206:                        remote_port = htons(547);
                    207:                else
                    208:                        remote_port = ent->s_port;
                    209:        }
                    210: 
                    211:        memset(&DHCPv6DestAddr, 0, sizeof(DHCPv6DestAddr));
                    212:        DHCPv6DestAddr.sin6_family = AF_INET6;
                    213:        DHCPv6DestAddr.sin6_port = remote_port;
                    214:        inet_pton(AF_INET6, All_DHCP_Relay_Agents_and_Servers,
                    215:                  &DHCPv6DestAddr.sin6_addr);
                    216: 
                    217:        code = D6O_CLIENTID;
                    218:        if (!option_code_hash_lookup(&clientid_option,
                    219:                                     dhcpv6_universe.code_hash, &code, 0, MDL))
                    220:                log_fatal("Unable to find the CLIENTID option definition.");
                    221: 
                    222:        code = D6O_ELAPSED_TIME;
                    223:        if (!option_code_hash_lookup(&elapsed_option,
                    224:                                     dhcpv6_universe.code_hash, &code, 0, MDL))
                    225:                log_fatal("Unable to find the ELAPSED_TIME option definition.");
                    226: 
                    227:        code = D6O_IA_NA;
                    228:        if (!option_code_hash_lookup(&ia_na_option, dhcpv6_universe.code_hash,
                    229:                                     &code, 0, MDL))
                    230:                log_fatal("Unable to find the IA_NA option definition.");
                    231: 
                    232:        code = D6O_IA_TA;
                    233:        if (!option_code_hash_lookup(&ia_ta_option, dhcpv6_universe.code_hash,
                    234:                                     &code, 0, MDL))
                    235:                log_fatal("Unable to find the IA_TA option definition.");
                    236: 
                    237:        code = D6O_IA_PD;
                    238:        if (!option_code_hash_lookup(&ia_pd_option, dhcpv6_universe.code_hash,
                    239:                                     &code, 0, MDL))
                    240:                log_fatal("Unable to find the IA_PD option definition.");
                    241: 
                    242:        code = D6O_IAADDR;
                    243:        if (!option_code_hash_lookup(&iaaddr_option, dhcpv6_universe.code_hash,
                    244:                                     &code, 0, MDL))
                    245:                log_fatal("Unable to find the IAADDR option definition.");
                    246: 
                    247:        code = D6O_IAPREFIX;
                    248:        if (!option_code_hash_lookup(&iaprefix_option,
                    249:                                     dhcpv6_universe.code_hash,
                    250:                                     &code, 0, MDL))
                    251:                log_fatal("Unable to find the IAPREFIX option definition.");
                    252: 
                    253:        code = D6O_ORO;
                    254:        if (!option_code_hash_lookup(&oro_option, dhcpv6_universe.code_hash,
                    255:                                     &code, 0, MDL))
                    256:                log_fatal("Unable to find the ORO option definition.");
                    257: 
                    258:        code = D6O_INFORMATION_REFRESH_TIME;
                    259:        if (!option_code_hash_lookup(&irt_option, dhcpv6_universe.code_hash,
                    260:                                     &code, 0, MDL))
                    261:                log_fatal("Unable to find the IRT option definition.");
                    262: 
                    263: #ifndef __CYGWIN32__ /* XXX */
                    264:        endservent();
                    265: #endif
                    266: }
                    267: 
                    268: /*
                    269:  * Instead of implementing RFC3315 RAND (section 14) as a float "between"
                    270:  * -0.1 and 0.1 non-inclusive, we implement it as an integer.
                    271:  *
                    272:  * The result is expected to follow this table:
                    273:  *
                    274:  *             split range answer
                    275:  *                 - ERROR -                 base <= 0
                    276:  *             0       1   0..0         1 <= base <= 10
                    277:  *             1       3  -1..1        11 <= base <= 20
                    278:  *             2       5  -2..2        21 <= base <= 30
                    279:  *             3       7  -3..3        31 <= base <= 40
                    280:  *             ...
                    281:  *
                    282:  * XXX: For this to make sense, we really need to do timing on a
                    283:  * XXX: usec scale...we currently can assume zero for any value less than
                    284:  * XXX: 11, which are very common in early stages of transmission for most
                    285:  * XXX: messages.
                    286:  */
                    287: static TIME
                    288: dhc6_rand(TIME base)
                    289: {
                    290:        TIME rval;
                    291:        TIME range;
                    292:        TIME split;
                    293: 
                    294:        /*
                    295:         * A zero or less timeout is a bad thing...we don't want to
                    296:         * DHCP-flood anyone.
                    297:         */
                    298:        if (base <= 0)
                    299:                log_fatal("Impossible condition at %s:%d.", MDL);
                    300: 
                    301:        /*
                    302:         * The first thing we do is count how many random integers we want
                    303:         * in either direction (best thought of as the maximum negative
                    304:         * integer, as we will subtract this potentially from a random 0).
                    305:         */
                    306:        split = (base - 1) / 10;
                    307: 
                    308:        /* Don't bother with the rest of the math if we know we'll get 0. */
                    309:        if (split == 0)
                    310:                return 0;
                    311: 
                    312:        /*
                    313:         * Then we count the total number of integers in this set.  This
                    314:         * is twice the number of integers in positive and negative
                    315:         * directions, plus zero (-1, 0, 1 is 3, -2..2 adds 2 to 5, so forth).
                    316:         */
                    317:        range = (split * 2) + 1;
                    318: 
                    319:        /* Take a random number from [0..(range-1)]. */
                    320:        rval = random();
                    321:        rval %= range;
                    322: 
                    323:        /* Offset it to uncover potential negative values. */
                    324:        rval -= split;
                    325: 
                    326:        return rval;
                    327: }
                    328: 
                    329: /* Initialize message exchange timers (set RT from Initial-RT). */
                    330: static void
                    331: dhc6_retrans_init(struct client_state *client)
                    332: {
                    333:        int xid;
                    334: 
                    335:        /* Initialize timers. */
                    336:        client->txcount = 0;
                    337:        client->RT = client->IRT + dhc6_rand(client->IRT);
                    338: 
                    339:        /* Generate a new random 24-bit transaction ID for this exchange. */
                    340: 
                    341: #if (RAND_MAX >= 0x00ffffff)
                    342:        xid = random();
                    343: #elif (RAND_MAX >= 0x0000ffff)
                    344:        xid = (random() << 16) ^ random();
                    345: #elif (RAND_MAX >= 0x000000ff)
                    346:        xid = (random() << 16) ^ (random() << 8) ^ random();
                    347: #else
                    348: # error "Random number generator of less than 8 bits not supported."
                    349: #endif
                    350: 
                    351:        client->dhcpv6_transaction_id[0] = (xid >> 16) & 0xff;
                    352:        client->dhcpv6_transaction_id[1] = (xid >>  8) & 0xff;
                    353:        client->dhcpv6_transaction_id[2] =  xid        & 0xff;
                    354: }
                    355: 
                    356: /* Advance the DHCPv6 retransmission state once. */
                    357: static void
                    358: dhc6_retrans_advance(struct client_state *client)
                    359: {
                    360:        struct timeval elapsed;
                    361: 
                    362:        /* elapsed = cur - start */
                    363:        elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
                    364:        elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
                    365:        if (elapsed.tv_usec < 0) {
                    366:                elapsed.tv_sec -= 1;
                    367:                elapsed.tv_usec += 1000000;
                    368:        }
                    369:        /* retrans_advance is called after consuming client->RT. */
                    370:        /* elapsed += RT */
                    371:        elapsed.tv_sec += client->RT / 100;
                    372:        elapsed.tv_usec += (client->RT % 100) * 10000;
                    373:        if (elapsed.tv_usec >= 1000000) {
                    374:                elapsed.tv_sec += 1;
                    375:                elapsed.tv_usec -= 1000000;
                    376:        }
                    377: 
                    378:        /*
                    379:         * RT for each subsequent message transmission is based on the previous
                    380:         * value of RT:
                    381:         *
                    382:         *    RT = 2*RTprev + RAND*RTprev
                    383:         */
                    384:        client->RT += client->RT + dhc6_rand(client->RT);
                    385: 
                    386:        /*
                    387:         * MRT specifies an upper bound on the value of RT (disregarding the
                    388:         * randomization added by the use of RAND).  If MRT has a value of 0,
                    389:         * there is no upper limit on the value of RT.  Otherwise:
                    390:         *
                    391:         *    if (RT > MRT)
                    392:         *       RT = MRT + RAND*MRT
                    393:         */
                    394:        if ((client->MRT != 0) && (client->RT > client->MRT))
                    395:                client->RT = client->MRT + dhc6_rand(client->MRT);
                    396: 
                    397:        /*
                    398:         * Further, if there's an MRD, we should wake up upon reaching
                    399:         * the MRD rather than at some point after it.
                    400:         */
                    401:        if (client->MRD == 0) {
                    402:                /* Done. */
                    403:                client->txcount++;
                    404:                return;
                    405:        }
                    406:        /* elapsed += client->RT */
                    407:        elapsed.tv_sec += client->RT / 100;
                    408:        elapsed.tv_usec += (client->RT % 100) * 10000;
                    409:        if (elapsed.tv_usec >= 1000000) {
                    410:                elapsed.tv_sec += 1;
                    411:                elapsed.tv_usec -= 1000000;
                    412:        }
                    413:        if (elapsed.tv_sec >= client->MRD) {
                    414:                /*
                    415:                 * wake at RT + cur = start + MRD
                    416:                 */
                    417:                client->RT = client->MRD +
                    418:                        (client->start_time.tv_sec - cur_tv.tv_sec);
                    419:                client->RT = client->RT * 100 +
                    420:                        (client->start_time.tv_usec - cur_tv.tv_usec) / 10000;
                    421:        }
                    422:        client->txcount++;
                    423: }
                    424: 
                    425: /* Quick validation of DHCPv6 ADVERTISE packet contents. */
                    426: static int
                    427: valid_reply(struct packet *packet, struct client_state *client)
                    428: {
                    429:        struct data_string sid, cid;
                    430:        struct option_cache *oc;
                    431:        int rval = ISC_TRUE;
                    432: 
                    433:        memset(&sid, 0, sizeof(sid));
                    434:        memset(&cid, 0, sizeof(cid));
                    435: 
                    436:        if (!lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID)) {
                    437:                log_error("Response without a server identifier received.");
                    438:                rval = ISC_FALSE;
                    439:        }
                    440: 
                    441:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
                    442:        if (!oc ||
                    443:            !evaluate_option_cache(&sid, packet, NULL, client, packet->options,
                    444:                                   client->sent_options, &global_scope, oc,
                    445:                                   MDL)) {
                    446:                log_error("Response without a client identifier.");
                    447:                rval = ISC_FALSE;
                    448:        }
                    449: 
                    450:        oc = lookup_option(&dhcpv6_universe, client->sent_options,
                    451:                           D6O_CLIENTID);
                    452:        if (!oc ||
                    453:            !evaluate_option_cache(&cid, packet, NULL, client,
                    454:                                   client->sent_options, NULL, &global_scope,
                    455:                                   oc, MDL)) {
                    456:                log_error("Local client identifier is missing!");
                    457:                rval = ISC_FALSE;
                    458:        }
                    459: 
                    460:        if (sid.len == 0 ||
                    461:            sid.len != cid.len ||
                    462:            memcmp(sid.data, cid.data, sid.len)) {
                    463:                log_error("Advertise with matching transaction ID, but "
                    464:                          "mismatching client id.");
                    465:                rval = ISC_FALSE;
                    466:        }
                    467: 
                    468:        return rval;
                    469: }
                    470: 
                    471: /*
                    472:  * Create a complete copy of a DHCPv6 lease structure.
                    473:  */
                    474: static struct dhc6_lease *
                    475: dhc6_dup_lease(struct dhc6_lease *lease, const char *file, int line)
                    476: {
                    477:        struct dhc6_lease *copy;
                    478:        struct dhc6_ia **insert_ia, *ia;
                    479: 
                    480:        copy = dmalloc(sizeof(*copy), file, line);
                    481:        if (copy == NULL) {
                    482:                log_error("Out of memory for v6 lease structure.");
                    483:                return NULL;
                    484:        }
                    485: 
                    486:        data_string_copy(&copy->server_id, &lease->server_id, file, line);
                    487:        copy->pref = lease->pref;
                    488: 
                    489:        memcpy(copy->dhcpv6_transaction_id, lease->dhcpv6_transaction_id,
                    490:               sizeof(copy->dhcpv6_transaction_id));
                    491: 
                    492:        option_state_reference(&copy->options, lease->options, file, line);
                    493: 
                    494:        insert_ia = &copy->bindings;
                    495:        for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
                    496:                *insert_ia = dhc6_dup_ia(ia, file, line);
                    497: 
                    498:                if (*insert_ia == NULL) {
                    499:                        dhc6_lease_destroy(&copy, file, line);
                    500:                        return NULL;
                    501:                }
                    502: 
                    503:                insert_ia = &(*insert_ia)->next;
                    504:        }
                    505: 
                    506:        return copy;
                    507: }
                    508: 
                    509: /*
                    510:  * Duplicate an IA structure.
                    511:  */
                    512: static struct dhc6_ia *
                    513: dhc6_dup_ia(struct dhc6_ia *ia, const char *file, int line)
                    514: {
                    515:        struct dhc6_ia *copy;
                    516:        struct dhc6_addr **insert_addr, *addr;
                    517: 
                    518:        copy = dmalloc(sizeof(*ia), file, line);
                    519: 
                    520:        memcpy(copy->iaid, ia->iaid, sizeof(copy->iaid));
                    521: 
                    522:        copy->ia_type = ia->ia_type;
                    523:        copy->starts = ia->starts;
                    524:        copy->renew = ia->renew;
                    525:        copy->rebind = ia->rebind;
                    526: 
                    527:        insert_addr = &copy->addrs;
                    528:        for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                    529:                *insert_addr = dhc6_dup_addr(addr, file, line);
                    530: 
                    531:                if (*insert_addr == NULL) {
                    532:                        dhc6_ia_destroy(&copy, file, line);
                    533:                        return NULL;
                    534:                }
                    535: 
                    536:                insert_addr = &(*insert_addr)->next;
                    537:        }
                    538: 
                    539:        if (ia->options != NULL)
                    540:                option_state_reference(&copy->options, ia->options,
                    541:                                       file, line);
                    542: 
                    543:        return copy;
                    544: }
                    545: 
                    546: /*
                    547:  * Duplicate an IAADDR or IAPREFIX structure.
                    548:  */
                    549: static struct dhc6_addr *
                    550: dhc6_dup_addr(struct dhc6_addr *addr, const char *file, int line)
                    551: {
                    552:        struct dhc6_addr *copy;
                    553: 
                    554:        copy = dmalloc(sizeof(*addr), file, line);
                    555: 
                    556:        if (copy == NULL)
                    557:                return NULL;
                    558: 
                    559:        memcpy(&copy->address, &addr->address, sizeof(copy->address));
                    560: 
                    561:        copy->plen = addr->plen;
                    562:        copy->flags = addr->flags;
                    563:        copy->starts = addr->starts;
                    564:        copy->preferred_life = addr->preferred_life;
                    565:        copy->max_life = addr->max_life;
                    566: 
                    567:        if (addr->options != NULL)
                    568:                option_state_reference(&copy->options, addr->options,
                    569:                                       file, line);
                    570: 
                    571:        return copy;
                    572: }
                    573: 
                    574: /*
                    575:  * Form a DHCPv6 lease structure based upon packet contents.  Creates and
                    576:  * populates IA's and any IAADDR/IAPREFIX's they contain.
                    577:  * Parsed options are deleted in order to not save them in the lease file.
                    578:  */
                    579: static struct dhc6_lease *
                    580: dhc6_leaseify(struct packet *packet)
                    581: {
                    582:        struct data_string ds;
                    583:        struct dhc6_lease *lease;
                    584:        struct option_cache *oc;
                    585: 
                    586:        lease = dmalloc(sizeof(*lease), MDL);
                    587:        if (lease == NULL) {
                    588:                log_error("Out of memory for v6 lease structure.");
                    589:                return NULL;
                    590:        }
                    591: 
                    592:        memcpy(lease->dhcpv6_transaction_id, packet->dhcpv6_transaction_id, 3);
                    593:        option_state_reference(&lease->options, packet->options, MDL);
                    594: 
                    595:        memset(&ds, 0, sizeof(ds));
                    596: 
                    597:        /* Determine preference (default zero). */
                    598:        oc = lookup_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE);
                    599:        if (oc &&
                    600:            evaluate_option_cache(&ds, packet, NULL, NULL, lease->options,
                    601:                                  NULL, &global_scope, oc, MDL)) {
                    602:                if (ds.len != 1) {
                    603:                        log_error("Invalid length of DHCPv6 Preference option "
                    604:                                  "(%d != 1)", ds.len);
                    605:                        data_string_forget(&ds, MDL);
                    606:                        dhc6_lease_destroy(&lease, MDL);
                    607:                        return NULL;
                    608:                } else {
                    609:                        lease->pref = ds.data[0];
                    610:                        log_debug("RCV:  X-- Preference %u.",
                    611:                                  (unsigned)lease->pref);
                    612:                }
                    613: 
                    614:                data_string_forget(&ds, MDL);
                    615:        }
                    616:        delete_option(&dhcpv6_universe, lease->options, D6O_PREFERENCE);
                    617: 
                    618:        /*
                    619:         * Dig into recursive DHCPv6 pockets for IA_NA and contained IAADDR
                    620:         * options.
                    621:         */
                    622:        if (dhc6_parse_ia_na(&lease->bindings, packet,
                    623:                             lease->options) != ISC_R_SUCCESS) {
                    624:                /* Error conditions are logged by the caller. */
                    625:                dhc6_lease_destroy(&lease, MDL);
                    626:                return NULL;
                    627:        }
                    628:        /*
                    629:         * Dig into recursive DHCPv6 pockets for IA_TA and contained IAADDR
                    630:         * options.
                    631:         */
                    632:        if (dhc6_parse_ia_ta(&lease->bindings, packet,
                    633:                             lease->options) != ISC_R_SUCCESS) {
                    634:                /* Error conditions are logged by the caller. */
                    635:                dhc6_lease_destroy(&lease, MDL);
                    636:                return NULL;
                    637:        }
                    638:        /*
                    639:         * Dig into recursive DHCPv6 pockets for IA_PD and contained IAPREFIX
                    640:         * options.
                    641:         */
                    642:        if (dhc6_parse_ia_pd(&lease->bindings, packet,
                    643:                             lease->options) != ISC_R_SUCCESS) {
                    644:                /* Error conditions are logged by the caller. */
                    645:                dhc6_lease_destroy(&lease, MDL);
                    646:                return NULL;
                    647:        }
                    648: 
                    649:        /*
                    650:         * This is last because in the future we may want to make a different
                    651:         * key based upon additional information from the packet (we may need
                    652:         * to allow multiple leases in one client state per server, but we're
                    653:         * not sure based on what additional keys now).
                    654:         */
                    655:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
                    656:        if (!evaluate_option_cache(&lease->server_id, packet, NULL, NULL,
                    657:                                   lease->options, NULL, &global_scope,
                    658:                                   oc, MDL) ||
                    659:            lease->server_id.len == 0) {
                    660:                /* This should be impossible due to validation checks earlier.
                    661:                 */
                    662:                log_error("Invalid SERVERID option cache.");
                    663:                dhc6_lease_destroy(&lease, MDL);
                    664:                return NULL;
                    665:        } else {
                    666:                log_debug("RCV:  X-- Server ID: %s",
                    667:                          print_hex_1(lease->server_id.len,
                    668:                                      lease->server_id.data, 52));
                    669:        }
                    670: 
                    671:        return lease;
                    672: }
                    673: 
                    674: static isc_result_t
                    675: dhc6_parse_ia_na(struct dhc6_ia **pia, struct packet *packet,
                    676:                 struct option_state *options)
                    677: {
                    678:        struct data_string ds;
                    679:        struct dhc6_ia *ia;
                    680:        struct option_cache *oc;
                    681:        isc_result_t result;
                    682: 
                    683:        memset(&ds, 0, sizeof(ds));
                    684: 
                    685:        oc = lookup_option(&dhcpv6_universe, options, D6O_IA_NA);
                    686:        for ( ; oc != NULL ; oc = oc->next) {
                    687:                ia = dmalloc(sizeof(*ia), MDL);
                    688:                if (ia == NULL) {
                    689:                        log_error("Out of memory allocating IA_NA structure.");
                    690:                        return ISC_R_NOMEMORY;
                    691:                } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
                    692:                                                 options, NULL,
                    693:                                                 &global_scope, oc, MDL) &&
                    694:                           ds.len >= 12) {
                    695:                        memcpy(ia->iaid, ds.data, 4);
                    696:                        ia->ia_type = D6O_IA_NA;
                    697:                        ia->starts = cur_time;
                    698:                        ia->renew = getULong(ds.data + 4);
                    699:                        ia->rebind = getULong(ds.data + 8);
                    700: 
                    701:                        log_debug("RCV:  X-- IA_NA %s",
                    702:                                  print_hex_1(4, ia->iaid, 59));
                    703:                        /* XXX: This should be the printed time I think. */
                    704:                        log_debug("RCV:  | X-- starts %u",
                    705:                                  (unsigned)ia->starts);
                    706:                        log_debug("RCV:  | X-- t1 - renew  +%u", ia->renew);
                    707:                        log_debug("RCV:  | X-- t2 - rebind +%u", ia->rebind);
                    708: 
                    709:                        /*
                    710:                         * RFC3315 section 22.4, discard IA_NA's that
                    711:                         * have t1 greater than t2, and both not zero.
                    712:                         * Since RFC3315 defines this behaviour, it is not
                    713:                         * an error - just normal operation.
                    714:                         *
                    715:                         * Note that RFC3315 says we MUST honor these values
                    716:                         * if they are not zero.  So insane values are
                    717:                         * totally OK.
                    718:                         */
                    719:                        if ((ia->renew > 0) && (ia->rebind > 0) &&
                    720:                            (ia->renew > ia->rebind)) {
                    721:                                log_debug("RCV:  | !-- INVALID renew/rebind "
                    722:                                          "times, IA_NA discarded.");
                    723:                                dfree(ia, MDL);
                    724:                                data_string_forget(&ds, MDL);
                    725:                                continue;
                    726:                        }
                    727: 
                    728:                        if (ds.len > 12) {
                    729:                                log_debug("RCV:  | X-- [Options]");
                    730: 
                    731:                                if (!option_state_allocate(&ia->options,
                    732:                                                           MDL)) {
                    733:                                        log_error("Out of memory allocating "
                    734:                                                  "IA_NA option state.");
                    735:                                        dfree(ia, MDL);
                    736:                                        data_string_forget(&ds, MDL);
                    737:                                        return ISC_R_NOMEMORY;
                    738:                                }
                    739: 
                    740:                                if (!parse_option_buffer(ia->options,
                    741:                                                         ds.data + 12,
                    742:                                                         ds.len - 12,
                    743:                                                         &dhcpv6_universe)) {
                    744:                                        log_error("Corrupt IA_NA options.");
                    745:                                        option_state_dereference(&ia->options,
                    746:                                                                 MDL);
                    747:                                        dfree(ia, MDL);
                    748:                                        data_string_forget(&ds, MDL);
                    749:                                        return ISC_R_BADPARSE;
                    750:                                }
                    751:                        }
                    752:                        data_string_forget(&ds, MDL);
                    753: 
                    754:                        if (ia->options != NULL) {
                    755:                                result = dhc6_parse_addrs(&ia->addrs, packet,
                    756:                                                          ia->options);
                    757:                                if (result != ISC_R_SUCCESS) {
                    758:                                        option_state_dereference(&ia->options,
                    759:                                                                 MDL);
                    760:                                        dfree(ia, MDL);
                    761:                                        return result;
                    762:                                }
                    763:                        }
                    764: 
                    765:                        while (*pia != NULL)
                    766:                                pia = &(*pia)->next;
                    767:                        *pia = ia;
                    768:                        pia = &ia->next;
                    769:                } else {
                    770:                        log_error("Invalid IA_NA option cache.");
                    771:                        dfree(ia, MDL);
                    772:                        if (ds.len != 0)
                    773:                                data_string_forget(&ds, MDL);
                    774:                        return ISC_R_UNEXPECTED;
                    775:                }
                    776:        }
                    777:        delete_option(&dhcpv6_universe, options, D6O_IA_NA);
                    778: 
                    779:        return ISC_R_SUCCESS;
                    780: }
                    781: 
                    782: static isc_result_t
                    783: dhc6_parse_ia_ta(struct dhc6_ia **pia, struct packet *packet,
                    784:                 struct option_state *options)
                    785: {
                    786:        struct data_string ds;
                    787:        struct dhc6_ia *ia;
                    788:        struct option_cache *oc;
                    789:        isc_result_t result;
                    790: 
                    791:        memset(&ds, 0, sizeof(ds));
                    792: 
                    793:        oc = lookup_option(&dhcpv6_universe, options, D6O_IA_TA);
                    794:        for ( ; oc != NULL ; oc = oc->next) {
                    795:                ia = dmalloc(sizeof(*ia), MDL);
                    796:                if (ia == NULL) {
                    797:                        log_error("Out of memory allocating IA_TA structure.");
                    798:                        return ISC_R_NOMEMORY;
                    799:                } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
                    800:                                                 options, NULL,
                    801:                                                 &global_scope, oc, MDL) &&
                    802:                           ds.len >= 4) {
                    803:                        memcpy(ia->iaid, ds.data, 4);
                    804:                        ia->ia_type = D6O_IA_TA;
                    805:                        ia->starts = cur_time;
                    806: 
                    807:                        log_debug("RCV:  X-- IA_TA %s",
                    808:                                  print_hex_1(4, ia->iaid, 59));
                    809:                        /* XXX: This should be the printed time I think. */
                    810:                        log_debug("RCV:  | X-- starts %u",
                    811:                                  (unsigned)ia->starts);
                    812: 
                    813:                        if (ds.len > 4) {
                    814:                                log_debug("RCV:  | X-- [Options]");
                    815: 
                    816:                                if (!option_state_allocate(&ia->options,
                    817:                                                           MDL)) {
                    818:                                        log_error("Out of memory allocating "
                    819:                                                  "IA_TA option state.");
                    820:                                        dfree(ia, MDL);
                    821:                                        data_string_forget(&ds, MDL);
                    822:                                        return ISC_R_NOMEMORY;
                    823:                                }
                    824: 
                    825:                                if (!parse_option_buffer(ia->options,
                    826:                                                         ds.data + 4,
                    827:                                                         ds.len - 4,
                    828:                                                         &dhcpv6_universe)) {
                    829:                                        log_error("Corrupt IA_TA options.");
                    830:                                        option_state_dereference(&ia->options,
                    831:                                                                 MDL);
                    832:                                        dfree(ia, MDL);
                    833:                                        data_string_forget(&ds, MDL);
                    834:                                        return ISC_R_BADPARSE;
                    835:                                }
                    836:                        }
                    837:                        data_string_forget(&ds, MDL);
                    838: 
                    839:                        if (ia->options != NULL) {
                    840:                                result = dhc6_parse_addrs(&ia->addrs, packet,
                    841:                                                          ia->options);
                    842:                                if (result != ISC_R_SUCCESS) {
                    843:                                        option_state_dereference(&ia->options,
                    844:                                                                 MDL);
                    845:                                        dfree(ia, MDL);
                    846:                                        return result;
                    847:                                }
                    848:                        }
                    849: 
                    850:                        while (*pia != NULL)
                    851:                                pia = &(*pia)->next;
                    852:                        *pia = ia;
                    853:                        pia = &ia->next;
                    854:                } else {
                    855:                        log_error("Invalid IA_TA option cache.");
                    856:                        dfree(ia, MDL);
                    857:                        if (ds.len != 0)
                    858:                                data_string_forget(&ds, MDL);
                    859:                        return ISC_R_UNEXPECTED;
                    860:                }
                    861:        }
                    862:        delete_option(&dhcpv6_universe, options, D6O_IA_TA);
                    863: 
                    864:        return ISC_R_SUCCESS;
                    865: }
                    866: 
                    867: static isc_result_t
                    868: dhc6_parse_ia_pd(struct dhc6_ia **pia, struct packet *packet,
                    869:                 struct option_state *options)
                    870: {
                    871:        struct data_string ds;
                    872:        struct dhc6_ia *ia;
                    873:        struct option_cache *oc;
                    874:        isc_result_t result;
                    875: 
                    876:        memset(&ds, 0, sizeof(ds));
                    877: 
                    878:        oc = lookup_option(&dhcpv6_universe, options, D6O_IA_PD);
                    879:        for ( ; oc != NULL ; oc = oc->next) {
                    880:                ia = dmalloc(sizeof(*ia), MDL);
                    881:                if (ia == NULL) {
                    882:                        log_error("Out of memory allocating IA_PD structure.");
                    883:                        return ISC_R_NOMEMORY;
                    884:                } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
                    885:                                                 options, NULL,
                    886:                                                 &global_scope, oc, MDL) &&
                    887:                           ds.len >= 12) {
                    888:                        memcpy(ia->iaid, ds.data, 4);
                    889:                        ia->ia_type = D6O_IA_PD;
                    890:                        ia->starts = cur_time;
                    891:                        ia->renew = getULong(ds.data + 4);
                    892:                        ia->rebind = getULong(ds.data + 8);
                    893: 
                    894:                        log_debug("RCV:  X-- IA_PD %s",
                    895:                                  print_hex_1(4, ia->iaid, 59));
                    896:                        /* XXX: This should be the printed time I think. */
                    897:                        log_debug("RCV:  | X-- starts %u",
                    898:                                  (unsigned)ia->starts);
                    899:                        log_debug("RCV:  | X-- t1 - renew  +%u", ia->renew);
                    900:                        log_debug("RCV:  | X-- t2 - rebind +%u", ia->rebind);
                    901: 
                    902:                        /*
                    903:                         * RFC3633 section 9, discard IA_PD's that
                    904:                         * have t1 greater than t2, and both not zero.
                    905:                         * Since RFC3633 defines this behaviour, it is not
                    906:                         * an error - just normal operation.
                    907:                         */
                    908:                        if ((ia->renew > 0) && (ia->rebind > 0) &&
                    909:                            (ia->renew > ia->rebind)) {
                    910:                                log_debug("RCV:  | !-- INVALID renew/rebind "
                    911:                                          "times, IA_PD discarded.");
                    912:                                dfree(ia, MDL);
                    913:                                data_string_forget(&ds, MDL);
                    914:                                continue;
                    915:                        }
                    916: 
                    917:                        if (ds.len > 12) {
                    918:                                log_debug("RCV:  | X-- [Options]");
                    919: 
                    920:                                if (!option_state_allocate(&ia->options,
                    921:                                                           MDL)) {
                    922:                                        log_error("Out of memory allocating "
                    923:                                                  "IA_PD option state.");
                    924:                                        dfree(ia, MDL);
                    925:                                        data_string_forget(&ds, MDL);
                    926:                                        return ISC_R_NOMEMORY;
                    927:                                }
                    928: 
                    929:                                if (!parse_option_buffer(ia->options,
                    930:                                                         ds.data + 12,
                    931:                                                         ds.len - 12,
                    932:                                                         &dhcpv6_universe)) {
                    933:                                        log_error("Corrupt IA_PD options.");
                    934:                                        option_state_dereference(&ia->options,
                    935:                                                                 MDL);
                    936:                                        dfree(ia, MDL);
                    937:                                        data_string_forget(&ds, MDL);
                    938:                                        return ISC_R_BADPARSE;
                    939:                                }
                    940:                        }
                    941:                        data_string_forget(&ds, MDL);
                    942: 
                    943:                        if (ia->options != NULL) {
                    944:                                result = dhc6_parse_prefixes(&ia->addrs,
                    945:                                                             packet,
                    946:                                                             ia->options);
                    947:                                if (result != ISC_R_SUCCESS) {
                    948:                                        option_state_dereference(&ia->options,
                    949:                                                                 MDL);
                    950:                                        dfree(ia, MDL);
                    951:                                        return result;
                    952:                                }
                    953:                        }
                    954: 
                    955:                        while (*pia != NULL)
                    956:                                pia = &(*pia)->next;
                    957:                        *pia = ia;
                    958:                        pia = &ia->next;
                    959:                } else {
                    960:                        log_error("Invalid IA_PD option cache.");
                    961:                        dfree(ia, MDL);
                    962:                        if (ds.len != 0)
                    963:                                data_string_forget(&ds, MDL);
                    964:                        return ISC_R_UNEXPECTED;
                    965:                }
                    966:        }
                    967:        delete_option(&dhcpv6_universe, options, D6O_IA_PD);
                    968: 
                    969:        return ISC_R_SUCCESS;
                    970: }
                    971: 
                    972: 
                    973: static isc_result_t
                    974: dhc6_parse_addrs(struct dhc6_addr **paddr, struct packet *packet,
                    975:                 struct option_state *options)
                    976: {
                    977:        struct data_string ds;
                    978:        struct option_cache *oc;
                    979:        struct dhc6_addr *addr;
                    980: 
                    981:        memset(&ds, 0, sizeof(ds));
                    982: 
                    983:        oc = lookup_option(&dhcpv6_universe, options, D6O_IAADDR);
                    984:        for ( ; oc != NULL ; oc = oc->next) {
                    985:                addr = dmalloc(sizeof(*addr), MDL);
                    986:                if (addr == NULL) {
                    987:                        log_error("Out of memory allocating "
                    988:                                  "address structure.");
                    989:                        return ISC_R_NOMEMORY;
                    990:                } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
                    991:                                                 options, NULL, &global_scope,
                    992:                                                 oc, MDL) &&
                    993:                           (ds.len >= 24)) {
                    994: 
                    995:                        addr->address.len = 16;
                    996:                        memcpy(addr->address.iabuf, ds.data, 16);
                    997:                        addr->starts = cur_time;
                    998:                        addr->preferred_life = getULong(ds.data + 16);
                    999:                        addr->max_life = getULong(ds.data + 20);
                   1000: 
                   1001:                        log_debug("RCV:  | | X-- IAADDR %s",
                   1002:                                  piaddr(addr->address));
                   1003:                        log_debug("RCV:  | | | X-- Preferred lifetime %u.",
                   1004:                                  addr->preferred_life);
                   1005:                        log_debug("RCV:  | | | X-- Max lifetime %u.",
                   1006:                                  addr->max_life);
                   1007: 
                   1008:                        /*
                   1009:                         * RFC 3315 section 22.6 says we must discard
                   1010:                         * addresses whose pref is later than valid.
                   1011:                         */
                   1012:                        if ((addr->preferred_life > addr->max_life)) {
                   1013:                                log_debug("RCV:  | | | !-- INVALID lifetimes, "
                   1014:                                          "IAADDR discarded.  Check your "
                   1015:                                          "server configuration.");
                   1016:                                dfree(addr, MDL);
                   1017:                                data_string_forget(&ds, MDL);
                   1018:                                continue;
                   1019:                        }
                   1020: 
                   1021:                        /*
                   1022:                         * Fortunately this is the last recursion in the
                   1023:                         * protocol.
                   1024:                         */
                   1025:                        if (ds.len > 24) {
                   1026:                                if (!option_state_allocate(&addr->options,
                   1027:                                                           MDL)) {
                   1028:                                        log_error("Out of memory allocating "
                   1029:                                                  "IAADDR option state.");
                   1030:                                        dfree(addr, MDL);
                   1031:                                        data_string_forget(&ds, MDL);
                   1032:                                        return ISC_R_NOMEMORY;
                   1033:                                }
                   1034: 
                   1035:                                if (!parse_option_buffer(addr->options,
                   1036:                                                         ds.data + 24,
                   1037:                                                         ds.len - 24,
                   1038:                                                         &dhcpv6_universe)) {
                   1039:                                        log_error("Corrupt IAADDR options.");
                   1040:                                        option_state_dereference(&addr->options,
                   1041:                                                                 MDL);
                   1042:                                        dfree(addr, MDL);
                   1043:                                        data_string_forget(&ds, MDL);
                   1044:                                        return ISC_R_BADPARSE;
                   1045:                                }
                   1046:                        }
                   1047: 
                   1048:                        if (addr->options != NULL)
                   1049:                                log_debug("RCV:  | | | X-- "
                   1050:                                          "[Options]");
                   1051: 
                   1052:                        data_string_forget(&ds, MDL);
                   1053: 
                   1054:                        *paddr = addr;
                   1055:                        paddr = &addr->next;
                   1056:                } else {
                   1057:                        log_error("Invalid IAADDR option cache.");
                   1058:                        dfree(addr, MDL);
                   1059:                        if (ds.len != 0)
                   1060:                                data_string_forget(&ds, MDL);
                   1061:                        return ISC_R_UNEXPECTED;
                   1062:                }
                   1063:        }
                   1064:        delete_option(&dhcpv6_universe, options, D6O_IAADDR);
                   1065: 
                   1066:        return ISC_R_SUCCESS;
                   1067: }
                   1068: 
                   1069: static isc_result_t
                   1070: dhc6_parse_prefixes(struct dhc6_addr **ppfx, struct packet *packet,
                   1071:                    struct option_state *options)
                   1072: {
                   1073:        struct data_string ds;
                   1074:        struct option_cache *oc;
                   1075:        struct dhc6_addr *pfx;
                   1076: 
                   1077:        memset(&ds, 0, sizeof(ds));
                   1078: 
                   1079:        oc = lookup_option(&dhcpv6_universe, options, D6O_IAPREFIX);
                   1080:        for ( ; oc != NULL ; oc = oc->next) {
                   1081:                pfx = dmalloc(sizeof(*pfx), MDL);
                   1082:                if (pfx == NULL) {
                   1083:                        log_error("Out of memory allocating "
                   1084:                                  "prefix structure.");
                   1085:                        return ISC_R_NOMEMORY;
                   1086:                } else if (evaluate_option_cache(&ds, packet, NULL, NULL,
                   1087:                                                 options, NULL, &global_scope,
                   1088:                                                 oc, MDL) &&
                   1089:                           (ds.len >= 25)) {
                   1090: 
                   1091:                        pfx->preferred_life = getULong(ds.data);
                   1092:                        pfx->max_life = getULong(ds.data + 4);
                   1093:                        pfx->plen = getUChar(ds.data + 8);
                   1094:                        pfx->address.len = 16;
                   1095:                        memcpy(pfx->address.iabuf, ds.data + 9, 16);
                   1096:                        pfx->starts = cur_time;
                   1097: 
                   1098:                        log_debug("RCV:  | | X-- IAPREFIX %s/%d",
                   1099:                                  piaddr(pfx->address), (int)pfx->plen);
                   1100:                        log_debug("RCV:  | | | X-- Preferred lifetime %u.",
                   1101:                                  pfx->preferred_life);
                   1102:                        log_debug("RCV:  | | | X-- Max lifetime %u.",
                   1103:                                  pfx->max_life);
                   1104: 
                   1105:                        /* Sanity check over the prefix length */
                   1106:                        if ((pfx->plen < 4) || (pfx->plen > 128)) {
                   1107:                                log_debug("RCV:  | | | !-- INVALID prefix "
                   1108:                                          "length, IAPREFIX discarded.  "
                   1109:                                          "Check your server configuration.");
                   1110:                                dfree(pfx, MDL);
                   1111:                                data_string_forget(&ds, MDL);
                   1112:                                continue;
                   1113:                        }
                   1114:                        /*
                   1115:                         * RFC 3633 section 10 says we must discard
                   1116:                         * prefixes whose pref is later than valid.
                   1117:                         */
                   1118:                        if ((pfx->preferred_life > pfx->max_life)) {
                   1119:                                log_debug("RCV:  | | | !-- INVALID lifetimes, "
                   1120:                                          "IAPREFIX discarded.  Check your "
                   1121:                                          "server configuration.");
                   1122:                                dfree(pfx, MDL);
                   1123:                                data_string_forget(&ds, MDL);
                   1124:                                continue;
                   1125:                        }
                   1126: 
                   1127:                        /*
                   1128:                         * Fortunately this is the last recursion in the
                   1129:                         * protocol.
                   1130:                         */
                   1131:                        if (ds.len > 25) {
                   1132:                                if (!option_state_allocate(&pfx->options,
                   1133:                                                           MDL)) {
                   1134:                                        log_error("Out of memory allocating "
                   1135:                                                  "IAPREFIX option state.");
                   1136:                                        dfree(pfx, MDL);
                   1137:                                        data_string_forget(&ds, MDL);
                   1138:                                        return ISC_R_NOMEMORY;
                   1139:                                }
                   1140: 
                   1141:                                if (!parse_option_buffer(pfx->options,
                   1142:                                                         ds.data + 25,
                   1143:                                                         ds.len - 25,
                   1144:                                                         &dhcpv6_universe)) {
                   1145:                                        log_error("Corrupt IAPREFIX options.");
                   1146:                                        option_state_dereference(&pfx->options,
                   1147:                                                                 MDL);
                   1148:                                        dfree(pfx, MDL);
                   1149:                                        data_string_forget(&ds, MDL);
                   1150:                                        return ISC_R_BADPARSE;
                   1151:                                }
                   1152:                        }
                   1153: 
                   1154:                        if (pfx->options != NULL)
                   1155:                                log_debug("RCV:  | | | X-- "
                   1156:                                          "[Options]");
                   1157: 
                   1158:                        data_string_forget(&ds, MDL);
                   1159: 
                   1160:                        *ppfx = pfx;
                   1161:                        ppfx = &pfx->next;
                   1162:                } else {
                   1163:                        log_error("Invalid IAPREFIX option cache.");
                   1164:                        dfree(pfx, MDL);
                   1165:                        if (ds.len != 0)
                   1166:                                data_string_forget(&ds, MDL);
                   1167:                        return ISC_R_UNEXPECTED;
                   1168:                }
                   1169:        }
                   1170:        delete_option(&dhcpv6_universe, options, D6O_IAPREFIX);
                   1171: 
                   1172:        return ISC_R_SUCCESS;
                   1173: }
                   1174: 
                   1175: /* Clean up a lease object, deallocate all its parts, and set it to NULL. */
                   1176: void
                   1177: dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line)
                   1178: {
                   1179:        struct dhc6_ia *ia, *nia;
                   1180:        struct dhc6_lease *lease;
                   1181: 
                   1182:        if (src == NULL || *src == NULL) {
                   1183:                log_error("Attempt to destroy null lease.");
                   1184:                return;
                   1185:        }
                   1186:        lease = *src;
                   1187: 
                   1188:        if (lease->server_id.len != 0)
                   1189:                data_string_forget(&lease->server_id, file, line);
                   1190: 
                   1191:        for (ia = lease->bindings ; ia != NULL ; ia = nia) {
                   1192:                nia = ia->next;
                   1193: 
                   1194:                dhc6_ia_destroy(&ia, file, line);
                   1195:        }
                   1196: 
                   1197:        if (lease->options != NULL)
                   1198:                option_state_dereference(&lease->options, file, line);
                   1199: 
                   1200:        dfree(lease, file, line);
                   1201:        *src = NULL;
                   1202: }
                   1203: 
                   1204: /*
                   1205:  * Traverse the addresses list, and destroy their contents, and NULL the
                   1206:  * list pointer.
                   1207:  */
                   1208: static void
                   1209: dhc6_ia_destroy(struct dhc6_ia **src, const char *file, int line)
                   1210: {
                   1211:        struct dhc6_addr *addr, *naddr;
                   1212:        struct dhc6_ia *ia;
                   1213: 
                   1214:        if (src == NULL || *src == NULL) {
                   1215:                log_error("Attempt to destroy null IA.");
                   1216:                return;
                   1217:        }
                   1218:        ia = *src;
                   1219: 
                   1220:        for (addr = ia->addrs ; addr != NULL ; addr = naddr) {
                   1221:                naddr = addr->next;
                   1222: 
                   1223:                if (addr->options != NULL)
                   1224:                        option_state_dereference(&addr->options, file, line);
                   1225: 
                   1226:                dfree(addr, file, line);
                   1227:        }
                   1228: 
                   1229:        if (ia->options != NULL)
                   1230:                option_state_dereference(&ia->options, file, line);
                   1231: 
                   1232:        dfree(ia, file, line);
                   1233:        *src = NULL;
                   1234: }
                   1235: 
                   1236: /*
                   1237:  * For a given lease, insert it into the tail of the lease list.  Upon
                   1238:  * finding a duplicate by server id, remove it and take over its position.
                   1239:  */
                   1240: static void
                   1241: insert_lease(struct dhc6_lease **head, struct dhc6_lease *new)
                   1242: {
                   1243:        while (*head != NULL) {
                   1244:                if ((*head)->server_id.len == new->server_id.len &&
                   1245:                    memcmp((*head)->server_id.data, new->server_id.data,
                   1246:                           new->server_id.len) == 0) {
                   1247:                        new->next = (*head)->next;
                   1248:                        dhc6_lease_destroy(head, MDL);
                   1249:                        break;
                   1250:                }
                   1251: 
                   1252:                head= &(*head)->next;
                   1253:        }
                   1254: 
                   1255:        *head = new;
                   1256:        return;
                   1257: }
                   1258: 
                   1259: /*
                   1260:  * Not really clear what to do here yet.
                   1261:  */
                   1262: static int
                   1263: dhc6_score_lease(struct client_state *client, struct dhc6_lease *lease)
                   1264: {
                   1265:        struct dhc6_ia *ia;
                   1266:        struct dhc6_addr *addr;
                   1267:        struct option **req;
                   1268:        int i;
                   1269: 
                   1270:        if (lease->score)
                   1271:                return lease->score;
                   1272: 
                   1273:        lease->score = 1;
                   1274: 
                   1275:        /* If this lease lacks a required option, dump it. */
                   1276:        /* XXX: we should be able to cache the failure... */
                   1277:        req = client->config->required_options;
                   1278:        if (req != NULL) {
                   1279:                for (i = 0 ; req[i] != NULL ; i++) {
                   1280:                        if (lookup_option(&dhcpv6_universe, lease->options,
                   1281:                                          req[i]->code) == NULL) {
                   1282:                                lease->score = 0;
                   1283:                                return lease->score;
                   1284:                        }
                   1285:                }
                   1286:        }
                   1287: 
                   1288:        /* If this lease contains a requested option, improve its score. */
                   1289:        req = client->config->requested_options;
                   1290:        if (req != NULL) {
                   1291:                for (i = 0 ; req[i] != NULL ; i++) {
                   1292:                        if (lookup_option(&dhcpv6_universe, lease->options,
                   1293:                                          req[i]->code) != NULL)
                   1294:                                lease->score++;
                   1295:                }
                   1296:        }
                   1297: 
                   1298:        for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
                   1299:                lease->score += 50;
                   1300: 
                   1301:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   1302:                        lease->score += 100;
                   1303:                }
                   1304:        }
                   1305: 
                   1306:        return lease->score;
                   1307: }
                   1308: 
                   1309: /*
                   1310:  * start_init6() kicks off the process, transmitting a packet and
                   1311:  * scheduling a retransmission event.
                   1312:  */
                   1313: void
                   1314: start_init6(struct client_state *client)
                   1315: {
                   1316:        struct timeval tv;
                   1317: 
                   1318:        log_debug("PRC: Soliciting for leases (INIT).");
                   1319:        client->state = S_INIT;
                   1320: 
                   1321:        /* Initialize timers, RFC3315 section 17.1.2. */
                   1322:        client->IRT = SOL_TIMEOUT * 100;
                   1323:        client->MRT = SOL_MAX_RT * 100;
                   1324:        client->MRC = 0;
                   1325:        /* Default is 0 (no max) but -1 changes this. */
                   1326:        if (!onetry)
                   1327:                client->MRD = 0;
                   1328:        else
                   1329:                client->MRD = client->config->timeout;
                   1330: 
                   1331:        dhc6_retrans_init(client);
                   1332: 
                   1333:        /*
                   1334:         * RFC3315 section 17.1.2 goes out of its way:
                   1335:         * Also, the first RT MUST be selected to be strictly greater than IRT
                   1336:         * by choosing RAND to be strictly greater than 0.
                   1337:         */
                   1338:        /* if RAND < 0 then RAND = -RAND */
                   1339:        if (client->RT <= client->IRT)
                   1340:                client->RT = client->IRT + (client->IRT - client->RT);
                   1341:        /* if RAND == 0 then RAND = 1 */
                   1342:        if (client->RT <= client->IRT)
                   1343:                client->RT = client->IRT + 1;
                   1344: 
                   1345:        client->v6_handler = init_handler;
                   1346: 
                   1347:        /*
                   1348:         * RFC3315 section 17.1.2 says we MUST start the first packet
                   1349:         * between 0 and SOL_MAX_DELAY seconds.  The good news is
                   1350:         * SOL_MAX_DELAY is 1.
                   1351:         */
                   1352:        tv.tv_sec = cur_tv.tv_sec;
                   1353:        tv.tv_usec = cur_tv.tv_usec;
                   1354:        tv.tv_usec += (random() % (SOL_MAX_DELAY * 100)) * 10000;
                   1355:        if (tv.tv_usec >= 1000000) {
                   1356:                tv.tv_sec += 1;
                   1357:                tv.tv_usec -= 1000000;
                   1358:        }
                   1359:        add_timeout(&tv, do_init6, client, NULL, NULL);
                   1360: 
                   1361:        if (nowait)
                   1362:                go_daemon();
                   1363: }
                   1364: 
                   1365: /*
                   1366:  * start_info_request6() kicks off the process, transmitting an info
                   1367:  * request packet and scheduling a retransmission event.
                   1368:  */
                   1369: void
                   1370: start_info_request6(struct client_state *client)
                   1371: {
                   1372:        struct timeval tv;
                   1373: 
                   1374:        log_debug("PRC: Requesting information (INIT).");
                   1375:        client->state = S_INIT;
                   1376: 
                   1377:        /* Initialize timers, RFC3315 section 18.1.5. */
                   1378:        client->IRT = INF_TIMEOUT * 100;
                   1379:        client->MRT = INF_MAX_RT * 100;
                   1380:        client->MRC = 0;
                   1381:        /* Default is 0 (no max) but -1 changes this. */
                   1382:        if (!onetry)
                   1383:                client->MRD = 0;
                   1384:        else
                   1385:                client->MRD = client->config->timeout;
                   1386: 
                   1387:        dhc6_retrans_init(client);
                   1388: 
                   1389:        client->v6_handler = info_request_handler;
                   1390: 
                   1391:        /*
                   1392:         * RFC3315 section 18.1.5 says we MUST start the first packet
                   1393:         * between 0 and INF_MAX_DELAY seconds.  The good news is
                   1394:         * INF_MAX_DELAY is 1.
                   1395:         */
                   1396:        tv.tv_sec = cur_tv.tv_sec;
                   1397:        tv.tv_usec = cur_tv.tv_usec;
                   1398:        tv.tv_usec += (random() % (INF_MAX_DELAY * 100)) * 10000;
                   1399:        if (tv.tv_usec >= 1000000) {
                   1400:                tv.tv_sec += 1;
                   1401:                tv.tv_usec -= 1000000;
                   1402:        }
                   1403:        add_timeout(&tv, do_info_request6, client, NULL, NULL);
                   1404: 
                   1405:        if (nowait)
                   1406:                go_daemon();
                   1407: }
                   1408: 
                   1409: /*
                   1410:  * start_confirm6() kicks off an "init-reboot" version of the process, at
                   1411:  * startup to find out if old bindings are 'fair' and at runtime whenever
                   1412:  * a link cycles state we'll eventually want to do this.
                   1413:  */
                   1414: void
                   1415: start_confirm6(struct client_state *client)
                   1416: {
                   1417:        struct timeval tv;
                   1418: 
                   1419:        /* If there is no active lease, there is nothing to check. */
                   1420:        if ((client->active_lease == NULL) ||
                   1421:            !active_prefix(client) ||
                   1422:            client->active_lease->released) {
                   1423:                start_init6(client);
                   1424:                return;
                   1425:        }
                   1426: 
                   1427:        log_debug("PRC: Confirming active lease (INIT-REBOOT).");
                   1428:        client->state = S_REBOOTING;
                   1429: 
                   1430:        /* Initialize timers, RFC3315 section 17.1.3. */
                   1431:        client->IRT = CNF_TIMEOUT * 100;
                   1432:        client->MRT = CNF_MAX_RT * 100;
                   1433:        client->MRC = 0;
                   1434:        client->MRD = CNF_MAX_RD;
                   1435: 
                   1436:        dhc6_retrans_init(client);
                   1437: 
                   1438:        client->v6_handler = reply_handler;
                   1439: 
                   1440:        /*
                   1441:         * RFC3315 section 18.1.2 says we MUST start the first packet
                   1442:         * between 0 and CNF_MAX_DELAY seconds.  The good news is
                   1443:         * CNF_MAX_DELAY is 1.
                   1444:         */
                   1445:        tv.tv_sec = cur_tv.tv_sec;
                   1446:        tv.tv_usec = cur_tv.tv_usec;
                   1447:        tv.tv_usec += (random() % (CNF_MAX_DELAY * 100)) * 10000;
                   1448:        if (tv.tv_usec >= 1000000) {
                   1449:                tv.tv_sec += 1;
                   1450:                tv.tv_usec -= 1000000;
                   1451:        }
                   1452:        if (wanted_ia_pd != 0) {
                   1453:                client->state = S_REBINDING;
                   1454:                client->refresh_type = DHCPV6_REBIND;
                   1455:                add_timeout(&tv, do_refresh6, client, NULL, NULL);
                   1456:        } else
                   1457:                add_timeout(&tv, do_confirm6, client, NULL, NULL);
                   1458: }
                   1459: 
                   1460: /*
                   1461:  * check_timing6() check on the timing for sending a v6 message
                   1462:  * and then do the basic initialization for a v6 message.
                   1463:  */
                   1464: #define CHK_TIM_SUCCESS                0
                   1465: #define CHK_TIM_MRC_EXCEEDED   1
                   1466: #define CHK_TIM_MRD_EXCEEDED   2
                   1467: #define CHK_TIM_ALLOC_FAILURE  3
                   1468: 
                   1469: int
                   1470: check_timing6 (struct client_state *client, u_int8_t msg_type, 
                   1471:               char *msg_str, struct dhc6_lease *lease,
                   1472:               struct data_string *ds)
                   1473: {
                   1474:        struct timeval elapsed;
                   1475: 
                   1476:        /*
                   1477:         * Start_time starts at the first transmission.
                   1478:         */
                   1479:        if (client->txcount == 0) {
                   1480:                client->start_time.tv_sec = cur_tv.tv_sec;
                   1481:                client->start_time.tv_usec = cur_tv.tv_usec;
                   1482:        } else if ((client->MRC != 0) && (client->txcount > client->MRC)) {
                   1483:                log_info("Max retransmission count exceeded.");
                   1484:                return(CHK_TIM_MRC_EXCEEDED);
                   1485:        }
                   1486: 
                   1487:        /* elapsed = cur - start */
                   1488:        elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
                   1489:        elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
                   1490:        if (elapsed.tv_usec < 0) {
                   1491:                elapsed.tv_sec -= 1;
                   1492:                elapsed.tv_usec += 1000000;
                   1493:        }
                   1494: 
                   1495:        /* Check if finished (-1 argument). */
                   1496:        if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
                   1497:                log_info("Max retransmission duration exceeded.");
                   1498:                return(CHK_TIM_MRD_EXCEEDED);
                   1499:        }
                   1500: 
                   1501:        memset(ds, 0, sizeof(*ds));
                   1502:        if (!buffer_allocate(&(ds->buffer), 4, MDL)) {
                   1503:                log_error("Unable to allocate memory for %s.", msg_str);
                   1504:                return(CHK_TIM_ALLOC_FAILURE);
                   1505:        }
                   1506:        ds->data = ds->buffer->data;
                   1507:        ds->len = 4;
                   1508: 
                   1509:        ds->buffer->data[0] = msg_type;
                   1510:        memcpy(ds->buffer->data + 1, client->dhcpv6_transaction_id, 3);
                   1511: 
                   1512:        /* Form an elapsed option. */
                   1513:        /* Maximum value is 65535 1/100s coded as 0xffff. */
                   1514:        if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
                   1515:            ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
                   1516:                client->elapsed = 0xffff;
                   1517:        } else {
                   1518:                client->elapsed = elapsed.tv_sec * 100;
                   1519:                client->elapsed += elapsed.tv_usec / 10000;
                   1520:        }
                   1521: 
                   1522:        if (client->elapsed == 0)
                   1523:                log_debug("XMT: Forming %s, 0 ms elapsed.", msg_str);
                   1524:        else
                   1525:                log_debug("XMT: Forming %s, %u0 ms elapsed.", msg_str,
                   1526:                          (unsigned)client->elapsed);
                   1527: 
                   1528:        client->elapsed = htons(client->elapsed);
                   1529: 
                   1530:        make_client6_options(client, &client->sent_options, lease, msg_type);
                   1531: 
                   1532:        return(CHK_TIM_SUCCESS);
                   1533: }
                   1534: 
                   1535: /*
                   1536:  * do_init6() marshals and transmits a solicit.
                   1537:  */
                   1538: void
                   1539: do_init6(void *input)
                   1540: {
                   1541:        struct client_state *client;
                   1542:        struct dhc6_ia *old_ia;
                   1543:        struct dhc6_addr *old_addr;
                   1544:        struct data_string ds;
                   1545:        struct data_string ia;
                   1546:        struct data_string addr;
                   1547:        struct timeval tv;
                   1548:        u_int32_t t1, t2;
                   1549:        int i, idx, len, send_ret;
                   1550: 
                   1551:        client = input;
                   1552: 
                   1553:        /*
                   1554:         * In RFC3315 section 17.1.2, the retransmission timer is
                   1555:         * used as the selecting timer.
                   1556:         */
                   1557:        if (client->advertised_leases != NULL) {
                   1558:                start_selecting6(client);
                   1559:                return;
                   1560:        }
                   1561: 
                   1562:        switch(check_timing6(client, DHCPV6_SOLICIT, "Solicit", NULL, &ds)) {
                   1563:              case CHK_TIM_MRC_EXCEEDED:
                   1564:              case CHK_TIM_ALLOC_FAILURE:
                   1565:                return;
                   1566:              case CHK_TIM_MRD_EXCEEDED:
                   1567:                client->state = S_STOPPED;
                   1568:                if (client->active_lease != NULL) {
                   1569:                        dhc6_lease_destroy(&client->active_lease, MDL);
                   1570:                        client->active_lease = NULL;
                   1571:                }
                   1572:                /* Stop if and only if this is the last client. */
                   1573:                if (stopping_finished())
                   1574:                        exit(2);
                   1575:                return;
                   1576:        }
                   1577: 
                   1578:        /*
                   1579:         * Fetch any configured 'sent' options (includes DUID) in wire format.
                   1580:         */
                   1581:        dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
                   1582:                                    NULL, client->sent_options, &global_scope,
                   1583:                                    &dhcpv6_universe);
                   1584: 
                   1585:        /* Use a specific handler with rapid-commit. */
                   1586:        if (lookup_option(&dhcpv6_universe, client->sent_options,
                   1587:                          D6O_RAPID_COMMIT) != NULL) {
                   1588:                client->v6_handler = rapid_commit_handler;
                   1589:        }
                   1590: 
                   1591:        /* Append IA_NA. */
                   1592:        for (i = 0; i < wanted_ia_na; i++) {
                   1593:                /*
                   1594:                 * XXX: maybe the IA_NA('s) should be put into the sent_options
                   1595:                 * cache.  They'd have to be pulled down as they also contain
                   1596:                 * different option caches in the same universe...
                   1597:                 */
                   1598:                memset(&ia, 0, sizeof(ia));
                   1599:                if (!buffer_allocate(&ia.buffer, 12, MDL)) {
                   1600:                        log_error("Unable to allocate memory for IA_NA.");
                   1601:                        data_string_forget(&ds, MDL);
                   1602:                        return;
                   1603:                }
                   1604:                ia.data = ia.buffer->data;
                   1605:                ia.len = 12;
                   1606: 
                   1607:                /*
                   1608:                 * A simple IAID is the last 4 bytes
                   1609:                 * of the hardware address.
                   1610:                 */
                   1611:                if (client->interface->hw_address.hlen > 4) {
                   1612:                        idx = client->interface->hw_address.hlen - 4;
                   1613:                        len = 4;
                   1614:                } else {
                   1615:                        idx = 0;
                   1616:                        len = client->interface->hw_address.hlen;
                   1617:                }
                   1618:                memcpy(ia.buffer->data,
                   1619:                       client->interface->hw_address.hbuf + idx,
                   1620:                       len);
                   1621:                if (i)
                   1622:                        ia.buffer->data[3] += i;
                   1623: 
                   1624:                t1 = client->config->requested_lease / 2;
                   1625:                t2 = t1 + (t1 / 2);
                   1626:                putULong(ia.buffer->data + 4, t1);
                   1627:                putULong(ia.buffer->data + 8, t2);
                   1628: 
                   1629:                log_debug("XMT:  X-- IA_NA %s",
                   1630:                          print_hex_1(4, ia.buffer->data, 55));
                   1631:                log_debug("XMT:  | X-- Request renew in  +%u", (unsigned)t1);
                   1632:                log_debug("XMT:  | X-- Request rebind in +%u", (unsigned)t2);
                   1633: 
                   1634:                if ((client->active_lease != NULL) &&
                   1635:                    ((old_ia = find_ia(client->active_lease->bindings,
                   1636:                                       D6O_IA_NA,
                   1637:                                       (char *)ia.buffer->data)) != NULL)) {
                   1638:                        /*
                   1639:                         * For each address in the old IA_NA,
                   1640:                         * request a binding.
                   1641:                         */
                   1642:                        memset(&addr, 0, sizeof(addr));
                   1643:                        for (old_addr = old_ia->addrs ; old_addr != NULL ;
                   1644:                             old_addr = old_addr->next) {
                   1645:                                if (old_addr->address.len != 16) {
                   1646:                                        log_error("Invalid IPv6 address "
                   1647:                                                  "length %d.  "
                   1648:                                                  "Ignoring.  (%s:%d)",
                   1649:                                                  old_addr->address.len,
                   1650:                                                  MDL);
                   1651:                                        continue;
                   1652:                                }
                   1653: 
                   1654:                                if (!buffer_allocate(&addr.buffer, 24, MDL)) {
                   1655:                                        log_error("Unable to allocate memory "
                   1656:                                                  "for IAADDR.");
                   1657:                                        data_string_forget(&ia, MDL);
                   1658:                                        data_string_forget(&ds, MDL);
                   1659:                                        return;
                   1660:                                }
                   1661:                                addr.data = addr.buffer->data;
                   1662:                                addr.len = 24;
                   1663: 
                   1664:                                memcpy(addr.buffer->data,
                   1665:                                       old_addr->address.iabuf,
                   1666:                                       16);
                   1667: 
                   1668:                                t1 = client->config->requested_lease;
                   1669:                                t2 = t1 + (t1 / 2);
                   1670:                                putULong(addr.buffer->data + 16, t1);
                   1671:                                putULong(addr.buffer->data + 20, t2);
                   1672: 
                   1673:                                log_debug("XMT:  | X-- Request address %s.",
                   1674:                                          piaddr(old_addr->address));
                   1675:                                log_debug("XMT:  | | X-- Request "
                   1676:                                          "preferred in +%u",
                   1677:                                          (unsigned)t1);
                   1678:                                log_debug("XMT:  | | X-- Request valid "
                   1679:                                          "in     +%u",
                   1680:                                          (unsigned)t2);
                   1681: 
                   1682:                                append_option(&ia, &dhcpv6_universe,
                   1683:                                              iaaddr_option,
                   1684:                                              &addr);
                   1685: 
                   1686:                                data_string_forget(&addr, MDL);
                   1687:                        }
                   1688:                }
                   1689: 
                   1690:                append_option(&ds, &dhcpv6_universe, ia_na_option, &ia);
                   1691:                data_string_forget(&ia, MDL);
                   1692:        }
                   1693: 
                   1694:        /* Append IA_TA. */
                   1695:        for (i = 0; i < wanted_ia_ta; i++) {
                   1696:                /*
                   1697:                 * XXX: maybe the IA_TA('s) should be put into the sent_options
                   1698:                 * cache.  They'd have to be pulled down as they also contain
                   1699:                 * different option caches in the same universe...
                   1700:                 */
                   1701:                memset(&ia, 0, sizeof(ia));
                   1702:                if (!buffer_allocate(&ia.buffer, 4, MDL)) {
                   1703:                        log_error("Unable to allocate memory for IA_TA.");
                   1704:                        data_string_forget(&ds, MDL);
                   1705:                        return;
                   1706:                }
                   1707:                ia.data = ia.buffer->data;
                   1708:                ia.len = 4;
                   1709: 
                   1710:                /*
                   1711:                 * A simple IAID is the last 4 bytes
                   1712:                 * of the hardware address.
                   1713:                 */
                   1714:                if (client->interface->hw_address.hlen > 4) {
                   1715:                        idx = client->interface->hw_address.hlen - 4;
                   1716:                        len = 4;
                   1717:                } else {
                   1718:                        idx = 0;
                   1719:                        len = client->interface->hw_address.hlen;
                   1720:                }
                   1721:                memcpy(ia.buffer->data,
                   1722:                       client->interface->hw_address.hbuf + idx,
                   1723:                       len);
                   1724:                if (i)
                   1725:                        ia.buffer->data[3] += i;
                   1726: 
                   1727:                log_debug("XMT:  X-- IA_TA %s",
                   1728:                          print_hex_1(4, ia.buffer->data, 55));
                   1729: 
                   1730:                if ((client->active_lease != NULL) &&
                   1731:                    ((old_ia = find_ia(client->active_lease->bindings,
                   1732:                                       D6O_IA_TA,
                   1733:                                       (char *)ia.buffer->data)) != NULL)) {
                   1734:                        /*
                   1735:                         * For each address in the old IA_TA,
                   1736:                         * request a binding.
                   1737:                         */
                   1738:                        memset(&addr, 0, sizeof(addr));
                   1739:                        for (old_addr = old_ia->addrs ; old_addr != NULL ;
                   1740:                             old_addr = old_addr->next) {
                   1741:                                if (old_addr->address.len != 16) {
                   1742:                                        log_error("Invalid IPv6 address "
                   1743:                                                  "length %d.  "
                   1744:                                                  "Ignoring.  (%s:%d)",
                   1745:                                                  old_addr->address.len,
                   1746:                                                  MDL);
                   1747:                                        continue;
                   1748:                                }
                   1749: 
                   1750:                                if (!buffer_allocate(&addr.buffer, 24, MDL)) {
                   1751:                                        log_error("Unable to allocate memory "
                   1752:                                                  "for IAADDR.");
                   1753:                                        data_string_forget(&ia, MDL);
                   1754:                                        data_string_forget(&ds, MDL);
                   1755:                                        return;
                   1756:                                }
                   1757:                                addr.data = addr.buffer->data;
                   1758:                                addr.len = 24;
                   1759: 
                   1760:                                memcpy(addr.buffer->data,
                   1761:                                       old_addr->address.iabuf,
                   1762:                                       16);
                   1763: 
                   1764:                                t1 = client->config->requested_lease;
                   1765:                                t2 = t1 + (t1 / 2);
                   1766:                                putULong(addr.buffer->data + 16, t1);
                   1767:                                putULong(addr.buffer->data + 20, t2);
                   1768: 
                   1769:                                log_debug("XMT:  | X-- Request address %s.",
                   1770:                                          piaddr(old_addr->address));
                   1771:                                log_debug("XMT:  | | X-- Request "
                   1772:                                          "preferred in +%u",
                   1773:                                          (unsigned)t1);
                   1774:                                log_debug("XMT:  | | X-- Request valid "
                   1775:                                          "in     +%u",
                   1776:                                          (unsigned)t2);
                   1777: 
                   1778:                                append_option(&ia, &dhcpv6_universe,
                   1779:                                              iaaddr_option,
                   1780:                                              &addr);
                   1781: 
                   1782:                                data_string_forget(&addr, MDL);
                   1783:                        }
                   1784:                }
                   1785: 
                   1786:                append_option(&ds, &dhcpv6_universe, ia_ta_option, &ia);
                   1787:                data_string_forget(&ia, MDL);
                   1788:        }
                   1789: 
                   1790:        /* Append IA_PD. */
                   1791:        for (i = 0; i < wanted_ia_pd; i++) {
                   1792:                /*
                   1793:                 * XXX: maybe the IA_PD('s) should be put into the sent_options
                   1794:                 * cache.  They'd have to be pulled down as they also contain
                   1795:                 * different option caches in the same universe...
                   1796:                 */
                   1797:                memset(&ia, 0, sizeof(ia));
                   1798:                if (!buffer_allocate(&ia.buffer, 12, MDL)) {
                   1799:                        log_error("Unable to allocate memory for IA_PD.");
                   1800:                        data_string_forget(&ds, MDL);
                   1801:                        return;
                   1802:                }
                   1803:                ia.data = ia.buffer->data;
                   1804:                ia.len = 12;
                   1805: 
                   1806:                /*
                   1807:                 * A simple IAID is the last 4 bytes
                   1808:                 * of the hardware address.
                   1809:                 */
                   1810:                if (client->interface->hw_address.hlen > 4) {
                   1811:                        idx = client->interface->hw_address.hlen - 4;
                   1812:                        len = 4;
                   1813:                } else {
                   1814:                        idx = 0;
                   1815:                        len = client->interface->hw_address.hlen;
                   1816:                }
                   1817:                memcpy(ia.buffer->data,
                   1818:                       client->interface->hw_address.hbuf + idx,
                   1819:                       len);
                   1820:                if (i)
                   1821:                        ia.buffer->data[3] += i;
                   1822: 
                   1823:                t1 = client->config->requested_lease / 2;
                   1824:                t2 = t1 + (t1 / 2);
                   1825:                putULong(ia.buffer->data + 4, t1);
                   1826:                putULong(ia.buffer->data + 8, t2);
                   1827: 
                   1828:                log_debug("XMT:  X-- IA_PD %s",
                   1829:                          print_hex_1(4, ia.buffer->data, 55));
                   1830:                log_debug("XMT:  | X-- Request renew in  +%u", (unsigned)t1);
                   1831:                log_debug("XMT:  | X-- Request rebind in +%u", (unsigned)t2);
                   1832: 
                   1833:                if ((client->active_lease != NULL) &&
                   1834:                    ((old_ia = find_ia(client->active_lease->bindings,
                   1835:                                       D6O_IA_PD,
                   1836:                                       (char *)ia.buffer->data)) != NULL)) {
                   1837:                        /*
                   1838:                         * For each prefix in the old IA_PD,
                   1839:                         * request a binding.
                   1840:                         */
                   1841:                        memset(&addr, 0, sizeof(addr));
                   1842:                        for (old_addr = old_ia->addrs ; old_addr != NULL ;
                   1843:                             old_addr = old_addr->next) {
                   1844:                                if (old_addr->address.len != 16) {
                   1845:                                        log_error("Invalid IPv6 prefix, "
                   1846:                                                  "Ignoring.  (%s:%d)",
                   1847:                                                  MDL);
                   1848:                                        continue;
                   1849:                                }
                   1850: 
                   1851:                                if (!buffer_allocate(&addr.buffer, 25, MDL)) {
                   1852:                                        log_error("Unable to allocate memory "
                   1853:                                                  "for IAPREFIX.");
                   1854:                                        data_string_forget(&ia, MDL);
                   1855:                                        data_string_forget(&ds, MDL);
                   1856:                                        return;
                   1857:                                }
                   1858:                                addr.data = addr.buffer->data;
                   1859:                                addr.len = 25;
                   1860: 
                   1861:                                t1 = client->config->requested_lease;
                   1862:                                t2 = t1 + (t1 / 2);
                   1863:                                putULong(addr.buffer->data, t1);
                   1864:                                putULong(addr.buffer->data + 4, t2);
                   1865: 
                   1866:                                putUChar(addr.buffer->data + 8,
                   1867:                                         old_addr->plen);
                   1868:                                memcpy(addr.buffer->data + 9,
                   1869:                                       old_addr->address.iabuf,
                   1870:                                       16);
                   1871: 
                   1872:                                log_debug("XMT:  | X-- Request prefix %s/%u.",
                   1873:                                          piaddr(old_addr->address),
                   1874:                                          (unsigned) old_addr->plen);
                   1875:                                log_debug("XMT:  | | X-- Request "
                   1876:                                          "preferred in +%u",
                   1877:                                          (unsigned)t1);
                   1878:                                log_debug("XMT:  | | X-- Request valid "
                   1879:                                          "in     +%u",
                   1880:                                          (unsigned)t2);
                   1881: 
                   1882:                                append_option(&ia, &dhcpv6_universe,
                   1883:                                              iaprefix_option,
                   1884:                                              &addr);
                   1885: 
                   1886:                                data_string_forget(&addr, MDL);
                   1887:                        }
                   1888:                }
                   1889: 
                   1890:                append_option(&ds, &dhcpv6_universe, ia_pd_option, &ia);
                   1891:                data_string_forget(&ia, MDL);
                   1892:        }
                   1893: 
                   1894:        /* Transmit and wait. */
                   1895: 
                   1896:        log_info("XMT: Solicit on %s, interval %ld0ms.",
                   1897:                 client->name ? client->name : client->interface->name,
                   1898:                 (long int)client->RT);
                   1899: 
                   1900:        send_ret = send_packet6(client->interface,
                   1901:                                ds.data, ds.len, &DHCPv6DestAddr);
                   1902:        if (send_ret != ds.len) {
                   1903:                log_error("dhc6: send_packet6() sent %d of %d bytes",
                   1904:                          send_ret, ds.len);
                   1905:        }
                   1906: 
                   1907:        data_string_forget(&ds, MDL);
                   1908: 
                   1909:        /* Wait RT */
                   1910:        tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
                   1911:        tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
                   1912:        if (tv.tv_usec >= 1000000) {
                   1913:                tv.tv_sec += 1;
                   1914:                tv.tv_usec -= 1000000;
                   1915:        }
                   1916:        add_timeout(&tv, do_init6, client, NULL, NULL);
                   1917: 
                   1918:        dhc6_retrans_advance(client);
                   1919: }
                   1920: 
                   1921: /* do_info_request6() marshals and transmits an information-request. */
                   1922: void
                   1923: do_info_request6(void *input)
                   1924: {
                   1925:        struct client_state *client;
                   1926:        struct data_string ds;
                   1927:        struct timeval tv;
                   1928:        int send_ret;
                   1929: 
                   1930:        client = input;
                   1931: 
                   1932:        switch(check_timing6(client, DHCPV6_INFORMATION_REQUEST,
                   1933:                             "Info-Request", NULL, &ds)) {
                   1934:              case CHK_TIM_MRC_EXCEEDED:
                   1935:              case CHK_TIM_ALLOC_FAILURE:
                   1936:                return;
                   1937:              case CHK_TIM_MRD_EXCEEDED:
                   1938:                exit(2);
                   1939:              case CHK_TIM_SUCCESS:
                   1940:                break;
                   1941:        }
                   1942: 
                   1943:        /* Fetch any configured 'sent' options (includes DUID) in wire format.
                   1944:         */
                   1945:        dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
                   1946:                                    NULL, client->sent_options, &global_scope,
                   1947:                                    &dhcpv6_universe);
                   1948: 
                   1949:        /* Transmit and wait. */
                   1950: 
                   1951:        log_info("XMT: Info-Request on %s, interval %ld0ms.",
                   1952:                 client->name ? client->name : client->interface->name,
                   1953:                 (long int)client->RT);
                   1954: 
                   1955:        send_ret = send_packet6(client->interface,
                   1956:                                ds.data, ds.len, &DHCPv6DestAddr);
                   1957:        if (send_ret != ds.len) {
                   1958:                log_error("dhc6: send_packet6() sent %d of %d bytes",
                   1959:                          send_ret, ds.len);
                   1960:        }
                   1961: 
                   1962:        data_string_forget(&ds, MDL);
                   1963: 
                   1964:        /* Wait RT */
                   1965:        tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
                   1966:        tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
                   1967:        if (tv.tv_usec >= 1000000) {
                   1968:                tv.tv_sec += 1;
                   1969:                tv.tv_usec -= 1000000;
                   1970:        }
                   1971:        add_timeout(&tv, do_info_request6, client, NULL, NULL);
                   1972: 
                   1973:        dhc6_retrans_advance(client);
                   1974: }
                   1975: 
                   1976: /* do_confirm6() creates a Confirm packet and transmits it.  This function
                   1977:  * is called on every timeout to (re)transmit.
                   1978:  */
                   1979: void
                   1980: do_confirm6(void *input)
                   1981: {
                   1982:        struct client_state *client;
                   1983:        struct data_string ds;
                   1984:        int send_ret;
                   1985:        struct timeval tv;
                   1986: 
                   1987:        client = input;
                   1988: 
                   1989:        if (client->active_lease == NULL)
                   1990:                log_fatal("Impossible condition at %s:%d.", MDL);
                   1991: 
                   1992:        /* In section 17.1.3, it is said:
                   1993:         *
                   1994:         *   If the client receives no responses before the message
                   1995:         *   transmission process terminates, as described in section 14,
                   1996:         *   the client SHOULD continue to use any IP addresses, using the
                   1997:         *   last known lifetimes for those addresses, and SHOULD continue
                   1998:         *   to use any other previously obtained configuration parameters.
                   1999:         *
                   2000:         * So if confirm times out, we go active.
                   2001:         *
                   2002:         * XXX: Should we reduce all IA's t1 to 0, so that we renew and
                   2003:         * stick there until we get a reply?
                   2004:         */
                   2005: 
                   2006:        switch(check_timing6(client, DHCPV6_CONFIRM, "Confirm",
                   2007:                             client->active_lease, &ds)) {
                   2008:              case CHK_TIM_MRC_EXCEEDED:
                   2009:              case CHK_TIM_MRD_EXCEEDED:
                   2010:                start_bound(client);
                   2011:                return;
                   2012:              case CHK_TIM_ALLOC_FAILURE:
                   2013:                return;
                   2014:              case CHK_TIM_SUCCESS:
                   2015:                break;
                   2016:        }
                   2017: 
                   2018:        /* Fetch any configured 'sent' options (includes DUID') in wire format.
                   2019:         */
                   2020:        dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
                   2021:                                    client->sent_options, &global_scope,
                   2022:                                    &dhcpv6_universe);
                   2023: 
                   2024:        /* Append IA's. */
                   2025:        if (wanted_ia_na &&
                   2026:            dhc6_add_ia_na(client, &ds, client->active_lease,
                   2027:                           DHCPV6_CONFIRM) != ISC_R_SUCCESS) {
                   2028:                data_string_forget(&ds, MDL);
                   2029:                return;
                   2030:        }
                   2031:        if (wanted_ia_ta &&
                   2032:            dhc6_add_ia_ta(client, &ds, client->active_lease,
                   2033:                           DHCPV6_CONFIRM) != ISC_R_SUCCESS) {
                   2034:                data_string_forget(&ds, MDL);
                   2035:                return;
                   2036:        }
                   2037: 
                   2038:        /* Transmit and wait. */
                   2039: 
                   2040:        log_info("XMT: Confirm on %s, interval %ld0ms.",
                   2041:                 client->name ? client->name : client->interface->name,
                   2042:                 (long int)client->RT);
                   2043: 
                   2044:        send_ret = send_packet6(client->interface, ds.data, ds.len,
                   2045:                                &DHCPv6DestAddr);
                   2046:        if (send_ret != ds.len) {
                   2047:                log_error("dhc6: sendpacket6() sent %d of %d bytes",
                   2048:                          send_ret, ds.len);
                   2049:        }
                   2050: 
                   2051:        data_string_forget(&ds, MDL);
                   2052: 
                   2053:        /* Wait RT */
                   2054:        tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
                   2055:        tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
                   2056:        if (tv.tv_usec >= 1000000) {
                   2057:                tv.tv_sec += 1;
                   2058:                tv.tv_usec -= 1000000;
                   2059:        }
                   2060:        add_timeout(&tv, do_confirm6, client, NULL, NULL);
                   2061: 
                   2062:        dhc6_retrans_advance(client);
                   2063: }
                   2064: 
                   2065: /*
                   2066:  * Release addresses.
                   2067:  */
                   2068: void
                   2069: start_release6(struct client_state *client)
                   2070: {
                   2071:        /* Cancel any pending transmissions */
                   2072:        cancel_timeout(do_confirm6, client);
                   2073:        cancel_timeout(do_select6, client);
                   2074:        cancel_timeout(do_refresh6, client);
                   2075:        cancel_timeout(do_release6, client);
                   2076:        client->state = S_STOPPED;
                   2077: 
                   2078:        /*
                   2079:         * It is written:  "The client MUST NOT use any of the addresses it
                   2080:         * is releasing as the source address in the Release message or in
                   2081:         * any subsequently transmitted message."  So unconfigure now.
                   2082:         */
                   2083:        unconfigure6(client, "RELEASE6");
                   2084: 
                   2085:        /* Note this in the lease file. */
                   2086:        if (client->active_lease == NULL)
                   2087:                return;
                   2088:        client->active_lease->released = ISC_TRUE;
                   2089:        write_client6_lease(client, client->active_lease, 0, 1);
                   2090: 
                   2091:        /* Set timers per RFC3315 section 18.1.6. */
                   2092:        client->IRT = REL_TIMEOUT * 100;
                   2093:        client->MRT = 0;
                   2094:        client->MRC = REL_MAX_RC;
                   2095:        client->MRD = 0;
                   2096: 
                   2097:        dhc6_retrans_init(client);
                   2098:        client->v6_handler = reply_handler;
                   2099: 
                   2100:        do_release6(client);
                   2101: }
                   2102: /*
                   2103:  * do_release6() creates a Release packet and transmits it.
                   2104:  */
                   2105: static void
                   2106: do_release6(void *input)
                   2107: {
                   2108:        struct client_state *client;
                   2109:        struct data_string ds;
                   2110:        int send_ret;
                   2111:        struct timeval tv;
                   2112: 
                   2113:        client = input;
                   2114: 
                   2115:        if ((client->active_lease == NULL) || !active_prefix(client))
                   2116:                return;
                   2117: 
                   2118:        switch(check_timing6(client, DHCPV6_RELEASE, "Release", 
                   2119:                             client->active_lease, &ds)) {
                   2120:              case CHK_TIM_MRC_EXCEEDED:
                   2121:              case CHK_TIM_ALLOC_FAILURE:
                   2122:              case CHK_TIM_MRD_EXCEEDED:
                   2123:                goto release_done;
                   2124:              case CHK_TIM_SUCCESS:
                   2125:                break;
                   2126:        }
                   2127: 
                   2128:        /*
                   2129:         * Don't use unicast as we don't know if we still have an
                   2130:         * available address with enough scope.
                   2131:         */
                   2132: 
                   2133:        dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
                   2134:                                    client->sent_options, &global_scope,
                   2135:                                    &dhcpv6_universe);
                   2136: 
                   2137:        /* Append IA's (but don't release temporary addresses). */
                   2138:        if (wanted_ia_na &&
                   2139:            dhc6_add_ia_na(client, &ds, client->active_lease,
                   2140:                           DHCPV6_RELEASE) != ISC_R_SUCCESS) {
                   2141:                data_string_forget(&ds, MDL);
                   2142:                goto release_done;
                   2143:        }
                   2144:        if (wanted_ia_pd &&
                   2145:            dhc6_add_ia_pd(client, &ds, client->active_lease,
                   2146:                           DHCPV6_RELEASE) != ISC_R_SUCCESS) {
                   2147:                data_string_forget(&ds, MDL);
                   2148:                goto release_done;
                   2149:        }
                   2150: 
                   2151:        /* Transmit and wait. */
                   2152:        log_info("XMT: Release on %s, interval %ld0ms.",
                   2153:                 client->name ? client->name : client->interface->name,
                   2154:                 (long int)client->RT);
                   2155: 
                   2156:        send_ret = send_packet6(client->interface, ds.data, ds.len,
                   2157:                                &DHCPv6DestAddr);
                   2158:        if (send_ret != ds.len) {
                   2159:                log_error("dhc6: sendpacket6() sent %d of %d bytes",
                   2160:                          send_ret, ds.len);
                   2161:        }
                   2162: 
                   2163:        data_string_forget(&ds, MDL);
                   2164: 
                   2165:        /* Wait RT */
                   2166:        tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
                   2167:        tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
                   2168:        if (tv.tv_usec >= 1000000) {
                   2169:                tv.tv_sec += 1;
                   2170:                tv.tv_usec -= 1000000;
                   2171:        }
                   2172:        add_timeout(&tv, do_release6, client, NULL, NULL);
                   2173:        dhc6_retrans_advance(client);
                   2174:        return;
                   2175: 
                   2176:       release_done:
                   2177:        dhc6_lease_destroy(&client->active_lease, MDL);
                   2178:        client->active_lease = NULL;
                   2179:        if (stopping_finished())
                   2180:                exit(0);
                   2181: }
                   2182: 
                   2183: /* status_log() just puts a status code into displayable form and logs it
                   2184:  * to info level.
                   2185:  */
                   2186: static void
                   2187: status_log(int code, const char *scope, const char *additional, int len)
                   2188: {
                   2189:        const char *msg = NULL;
                   2190: 
                   2191:        switch(code) {
                   2192:              case STATUS_Success:
                   2193:                msg = "Success";
                   2194:                break;
                   2195: 
                   2196:              case STATUS_UnspecFail:
                   2197:                msg = "UnspecFail";
                   2198:                break;
                   2199: 
                   2200:              case STATUS_NoAddrsAvail:
                   2201:                msg = "NoAddrsAvail";
                   2202:                break;
                   2203: 
                   2204:              case STATUS_NoBinding:
                   2205:                msg = "NoBinding";
                   2206:                break;
                   2207: 
                   2208:              case STATUS_NotOnLink:
                   2209:                msg = "NotOnLink";
                   2210:                break;
                   2211: 
                   2212:              case STATUS_UseMulticast:
                   2213:                msg = "UseMulticast";
                   2214:                break;
                   2215: 
                   2216:              case STATUS_NoPrefixAvail:
                   2217:                msg = "NoPrefixAvail";
                   2218:                break;
                   2219: 
                   2220:              default:
                   2221:                msg = "UNKNOWN";
                   2222:                break;
                   2223:        }
                   2224: 
                   2225:        if (len > 0)
                   2226:                log_info("%s status code %s: %s", scope, msg,
                   2227:                         print_hex_1(len,
                   2228:                                     (const unsigned char *)additional, 50));
                   2229:        else
                   2230:                log_info("%s status code %s.", scope, msg);
                   2231: }
                   2232: 
                   2233: /* Acquire a status code.
                   2234:  */
                   2235: static isc_result_t
                   2236: dhc6_get_status_code(struct option_state *options, unsigned *code,
                   2237:                     struct data_string *msg)
                   2238: {
                   2239:        struct option_cache *oc;
                   2240:        struct data_string ds;
                   2241:        isc_result_t rval = ISC_R_SUCCESS;
                   2242: 
                   2243:        if ((options == NULL) || (code == NULL))
                   2244:                return ISC_R_INVALIDARG;
                   2245: 
                   2246:        if ((msg != NULL) && (msg->len != 0))
                   2247:                return ISC_R_INVALIDARG;
                   2248: 
                   2249:        memset(&ds, 0, sizeof(ds));
                   2250: 
                   2251:        /* Assume success if there is no option. */
                   2252:        *code = STATUS_Success;
                   2253: 
                   2254:        oc = lookup_option(&dhcpv6_universe, options, D6O_STATUS_CODE);
                   2255:        if ((oc != NULL) &&
                   2256:            evaluate_option_cache(&ds, NULL, NULL, NULL, options,
                   2257:                                  NULL, &global_scope, oc, MDL)) {
                   2258:                if (ds.len < 2) {
                   2259:                        log_error("Invalid status code length %d.", ds.len);
                   2260:                        rval = ISC_R_FORMERR;
                   2261:                } else
                   2262:                        *code = getUShort(ds.data);
                   2263: 
                   2264:                if ((msg != NULL) && (ds.len > 2)) {
                   2265:                        data_string_copy(msg, &ds, MDL);
                   2266:                        msg->data += 2;
                   2267:                        msg->len -= 2;
                   2268:                }
                   2269: 
                   2270:                data_string_forget(&ds, MDL);
                   2271:                return rval;
                   2272:        }
                   2273: 
                   2274:        return ISC_R_NOTFOUND;
                   2275: }
                   2276: 
                   2277: /* Look at status codes in an advertise, and reform the return value.
                   2278:  */
                   2279: static isc_result_t
                   2280: dhc6_check_status(isc_result_t rval, struct option_state *options,
                   2281:                  const char *scope, unsigned *code)
                   2282: {
                   2283:        struct data_string msg;
                   2284:        isc_result_t status;
                   2285: 
                   2286:        if ((scope == NULL) || (code == NULL))
                   2287:                return ISC_R_INVALIDARG;
                   2288: 
                   2289:        /* If we don't find a code, we assume success. */
                   2290:        *code = STATUS_Success;
                   2291: 
                   2292:        /* If there is no options cache, then there is no code. */
                   2293:        if (options != NULL) {
                   2294:                memset(&msg, 0, sizeof(msg));
                   2295:                status = dhc6_get_status_code(options, code, &msg);
                   2296: 
                   2297:                if (status == ISC_R_SUCCESS) {
                   2298:                        status_log(*code, scope, (char *)msg.data, msg.len);
                   2299:                        data_string_forget(&msg, MDL);
                   2300: 
                   2301:                        if (*code != STATUS_Success)
                   2302:                                rval = ISC_R_FAILURE;
                   2303: 
                   2304:                } else if (status != ISC_R_NOTFOUND)
                   2305:                        rval = status;
                   2306:        }
                   2307: 
                   2308:        return rval;
                   2309: }
                   2310: 
                   2311: /* Look in the packet, any IA's, and any IAADDR's within those IA's to find
                   2312:  * status code options that are not SUCCESS.
                   2313:  */
                   2314: static isc_result_t
                   2315: dhc6_check_advertise(struct dhc6_lease *lease)
                   2316: {
                   2317:        struct dhc6_ia *ia;
                   2318:        struct dhc6_addr *addr;
                   2319:        isc_result_t rval = ISC_R_SUCCESS;
                   2320:        int have_addrs = ISC_FALSE;
                   2321:        unsigned code;
                   2322:        const char *scope;
                   2323: 
                   2324:        rval = dhc6_check_status(rval, lease->options, "message", &code);
                   2325: 
                   2326:        for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
                   2327:                switch (ia->ia_type) {
                   2328:                        case D6O_IA_NA:
                   2329:                                scope = "IA_NA";
                   2330:                                break;
                   2331:                        case D6O_IA_TA:
                   2332:                                scope = "IA_TA";
                   2333:                                break;
                   2334:                        case D6O_IA_PD:
                   2335:                                scope = "IA_PD";
                   2336:                                break;
                   2337:                        default:
                   2338:                                log_error("dhc6_check_advertise: no type.");
                   2339:                                return ISC_R_FAILURE;
                   2340:                }
                   2341:                rval = dhc6_check_status(rval, ia->options, scope, &code);
                   2342: 
                   2343:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   2344:                        if (ia->ia_type != D6O_IA_PD)
                   2345:                                scope = "IAADDR";
                   2346:                        else
                   2347:                                scope = "IAPREFIX";
                   2348:                        rval = dhc6_check_status(rval, addr->options,
                   2349:                                                 scope, &code);
                   2350:                        have_addrs = ISC_TRUE;
                   2351:                }
                   2352:        }
                   2353: 
                   2354:        if (have_addrs != ISC_TRUE)
                   2355:                rval = ISC_R_ADDRNOTAVAIL;
                   2356: 
                   2357:        return rval;
                   2358: }
                   2359: 
                   2360: /* status code <-> action matrix for the client in INIT state
                   2361:  * (rapid/commit).  Returns always false as no action is defined.
                   2362:  */
                   2363: static isc_boolean_t
                   2364: dhc6_init_action(struct client_state *client, isc_result_t *rvalp,
                   2365:                 unsigned code)
                   2366: {
                   2367:        if (rvalp == NULL)
                   2368:                log_fatal("Impossible condition at %s:%d.", MDL);
                   2369: 
                   2370:        if (client == NULL) {
                   2371:                *rvalp = ISC_R_INVALIDARG;
                   2372:                return ISC_FALSE;
                   2373:        }
                   2374: 
                   2375:        if (*rvalp == ISC_R_SUCCESS)
                   2376:                return ISC_FALSE;
                   2377: 
                   2378:        /* No possible action in any case... */
                   2379:        return ISC_FALSE;
                   2380: }
                   2381: 
                   2382: /* status code <-> action matrix for the client in SELECT state
                   2383:  * (request/reply).  Returns true if action was taken (and the
                   2384:  * packet should be ignored), or false if no action was taken.
                   2385:  */
                   2386: static isc_boolean_t
                   2387: dhc6_select_action(struct client_state *client, isc_result_t *rvalp,
                   2388:                   unsigned code)
                   2389: {
                   2390:        struct dhc6_lease *lease;
                   2391:        isc_result_t rval;
                   2392: 
                   2393:        if (rvalp == NULL)
                   2394:                log_fatal("Impossible condition at %s:%d.", MDL);
                   2395: 
                   2396:        if (client == NULL) {
                   2397:                *rvalp = ISC_R_INVALIDARG;
                   2398:                return ISC_FALSE;
                   2399:        }
                   2400:        rval = *rvalp;
                   2401: 
                   2402:        if (rval == ISC_R_SUCCESS)
                   2403:                return ISC_FALSE;
                   2404: 
                   2405:        switch (code) {
                   2406:                /* We may have an earlier failure status code (so no
                   2407:                 * success rval), and a success code now.  This
                   2408:                 * doesn't upgrade the rval to success, but it does
                   2409:                 * mean we take no action here.
                   2410:                 */
                   2411:              case STATUS_Success:
                   2412:                /* Gimpy server, or possibly an attacker. */
                   2413:              case STATUS_NoBinding:
                   2414:              case STATUS_UseMulticast:
                   2415:                /* Take no action. */
                   2416:                return ISC_FALSE;
                   2417: 
                   2418:                /* If the server can't deal with us, either try the
                   2419:                 * next advertised server, or continue retrying if there
                   2420:                 * weren't any.
                   2421:                 */
                   2422:              default:
                   2423:              case STATUS_UnspecFail:
                   2424:                if (client->advertised_leases != NULL) {
                   2425:                        dhc6_lease_destroy(&client->selected_lease, MDL);
                   2426:                        client->selected_lease = NULL;
                   2427: 
                   2428:                        start_selecting6(client);
                   2429: 
                   2430:                        break;
                   2431:                } else /* Take no action - continue to retry. */
                   2432:                        return ISC_FALSE;
                   2433: 
                   2434:                /* If the server has no addresses, try other servers if
                   2435:                 * we got some, otherwise go to INIT to hope for more
                   2436:                 * servers.
                   2437:                 */
                   2438:              case STATUS_NoAddrsAvail:
                   2439:              case STATUS_NoPrefixAvail:
                   2440:                if (client->state == S_REBOOTING)
                   2441:                        return ISC_FALSE;
                   2442: 
                   2443:                if (client->selected_lease == NULL)
                   2444:                        log_fatal("Impossible case at %s:%d.", MDL);
                   2445: 
                   2446:                dhc6_lease_destroy(&client->selected_lease, MDL);
                   2447:                client->selected_lease = NULL;
                   2448: 
                   2449:                if (client->advertised_leases != NULL)
                   2450:                        start_selecting6(client);
                   2451:                else
                   2452:                        start_init6(client);
                   2453: 
                   2454:                break;
                   2455: 
                   2456:                /* If we got a NotOnLink from a Confirm, then we're not
                   2457:                 * on link.  Kill the old-active binding and start over.
                   2458:                 *
                   2459:                 * If we got a NotOnLink from our Request, something weird
                   2460:                 * happened.  Start over from scratch anyway.
                   2461:                 */
                   2462:              case STATUS_NotOnLink:
                   2463:                if (client->state == S_REBOOTING) {
                   2464:                        if (client->active_lease == NULL)
                   2465:                                log_fatal("Impossible case at %s:%d.", MDL);
                   2466: 
                   2467:                        dhc6_lease_destroy(&client->active_lease, MDL);
                   2468:                } else {
                   2469:                        if (client->selected_lease == NULL)
                   2470:                                log_fatal("Impossible case at %s:%d.", MDL);
                   2471: 
                   2472:                        dhc6_lease_destroy(&client->selected_lease, MDL);
                   2473:                        client->selected_lease = NULL;
                   2474: 
                   2475:                        while (client->advertised_leases != NULL) {
                   2476:                                lease = client->advertised_leases;
                   2477:                                client->advertised_leases = lease->next;
                   2478: 
                   2479:                                dhc6_lease_destroy(&lease, MDL);
                   2480:                        }
                   2481:                }
                   2482: 
                   2483:                start_init6(client);
                   2484:                break;
                   2485:        }
                   2486: 
                   2487:        return ISC_TRUE;
                   2488: }
                   2489: 
                   2490: static void
                   2491: dhc6_withdraw_lease(struct client_state *client)
                   2492: {
                   2493:        struct dhc6_ia *ia;
                   2494:        struct dhc6_addr *addr;
                   2495: 
                   2496:        if ((client == NULL) || (client->active_lease == NULL))
                   2497:                return;
                   2498: 
                   2499:        for (ia = client->active_lease->bindings ; ia != NULL ;
                   2500:             ia = ia->next) {
                   2501:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   2502:                        addr->max_life = addr->preferred_life = 0;
                   2503:                }
                   2504:        }
                   2505: 
                   2506:        /* Perform expiry. */
                   2507:        do_expire(client);
                   2508: }
                   2509: 
                   2510: /* status code <-> action matrix for the client in BOUND state
                   2511:  * (request/reply).  Returns true if action was taken (and the
                   2512:  * packet should be ignored), or false if no action was taken.
                   2513:  */
                   2514: static isc_boolean_t
                   2515: dhc6_reply_action(struct client_state *client, isc_result_t *rvalp,
                   2516:                  unsigned code)
                   2517: {
                   2518:        isc_result_t rval;
                   2519: 
                   2520:        if (rvalp == NULL)
                   2521:                log_fatal("Impossible condition at %s:%d.", MDL);
                   2522: 
                   2523:        if (client == NULL) {
                   2524:                *rvalp = ISC_R_INVALIDARG;
                   2525:                return ISC_FALSE;
                   2526:        }
                   2527:        rval = *rvalp;
                   2528: 
                   2529:        if (rval == ISC_R_SUCCESS)
                   2530:                return ISC_FALSE;
                   2531: 
                   2532:        switch (code) {
                   2533:                /* It's possible an earlier status code set rval to a failure
                   2534:                 * code, and we've encountered a later success.
                   2535:                 */
                   2536:              case STATUS_Success:
                   2537:                /* In "refreshes" (where we get replies), we probably
                   2538:                 * still have a valid lease.  So "take no action" and
                   2539:                 * the upper levels will keep retrying until the lease
                   2540:                 * expires (or we rebind).
                   2541:                 */
                   2542:              case STATUS_UnspecFail:
                   2543:                /* For unknown codes...it's a soft (retryable) error. */
                   2544:              default:
                   2545:                return ISC_FALSE;
                   2546: 
                   2547:                /* The server is telling us to use a multicast address, so
                   2548:                 * we have to delete the unicast option from the active
                   2549:                 * lease, then allow retransmission to occur normally.
                   2550:                 * (XXX: It might be preferable in this case to retransmit
                   2551:                 * sooner than the current interval, but for now we don't.)
                   2552:                 */
                   2553:              case STATUS_UseMulticast:
                   2554:                if (client->active_lease != NULL)
                   2555:                        delete_option(&dhcp_universe,
                   2556:                                      client->active_lease->options,
                   2557:                                      D6O_UNICAST);
                   2558:                return ISC_FALSE;
                   2559: 
                   2560:                /* "When the client receives a NotOnLink status from the
                   2561:                 *  server in response to a Request, the client can either
                   2562:                 *  re-issue the Request without specifying any addresses
                   2563:                 *  or restart the DHCP server discovery process."
                   2564:                 *
                   2565:                 * This is strange.  If competing server evaluation is
                   2566:                 * useful (and therefore in the protocol), then why would
                   2567:                 * a client's first reaction be to request from the same
                   2568:                 * server on a different link?  Surely you'd want to
                   2569:                 * re-evaluate your server selection.
                   2570:                 *
                   2571:                 * Well, I guess that's the answer.
                   2572:                 */
                   2573:              case STATUS_NotOnLink:
                   2574:                /* In this case, we need to rescind all current active
                   2575:                 * bindings (just 'expire' them all normally, if early).
                   2576:                 * They're no use to us on the wrong link.  Then head back
                   2577:                 * to init, redo server selection and get new addresses.
                   2578:                 */
                   2579:                dhc6_withdraw_lease(client);
                   2580:                break;
                   2581: 
                   2582:                /* "If the status code is NoAddrsAvail, the client has
                   2583:                 *  received no usable addresses in the IA and may choose
                   2584:                 *  to try obtaining addresses for the IA from another
                   2585:                 *  server."
                   2586:                 */
                   2587:              case STATUS_NoAddrsAvail:
                   2588:              case STATUS_NoPrefixAvail:
                   2589:                /* Head back to init, keeping any active bindings (!). */
                   2590:                start_init6(client);
                   2591:                break;
                   2592: 
                   2593:                /* -  sends a Request message if the IA contained a Status
                   2594:                 *    Code option with the NoBinding status (and does not
                   2595:                 *    send any additional Renew/Rebind messages)
                   2596:                 */
                   2597:              case STATUS_NoBinding:
                   2598:                if (client->advertised_leases != NULL)
                   2599:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   2600: 
                   2601:                client->advertised_leases =
                   2602:                                dhc6_dup_lease(client->active_lease, MDL);
                   2603:                start_selecting6(client);
                   2604:                break;
                   2605:        }
                   2606: 
                   2607:        return ISC_TRUE;
                   2608: }
                   2609: 
                   2610: /* status code <-> action matrix for the client in STOPPED state
                   2611:  * (release/decline).  Returns true if action was taken (and the
                   2612:  * packet should be ignored), or false if no action was taken.
                   2613:  * NoBinding is translated into Success.
                   2614:  */
                   2615: static isc_boolean_t
                   2616: dhc6_stop_action(struct client_state *client, isc_result_t *rvalp,
                   2617:                  unsigned code)
                   2618: {
                   2619:        isc_result_t rval;
                   2620: 
                   2621:        if (rvalp == NULL)
                   2622:                log_fatal("Impossible condition at %s:%d.", MDL);
                   2623: 
                   2624:        if (client == NULL) {
                   2625:                *rvalp = ISC_R_INVALIDARG;
                   2626:                return ISC_FALSE;
                   2627:        }
                   2628:        rval = *rvalp;
                   2629: 
                   2630:        if (rval == ISC_R_SUCCESS)
                   2631:                return ISC_FALSE;
                   2632: 
                   2633:        switch (code) {
                   2634:                /* It's possible an earlier status code set rval to a failure
                   2635:                 * code, and we've encountered a later success.
                   2636:                 */
                   2637:              case STATUS_Success:
                   2638:                /* For unknown codes...it's a soft (retryable) error. */
                   2639:              case STATUS_UnspecFail:
                   2640:              default:
                   2641:                return ISC_FALSE;
                   2642: 
                   2643:                /* NoBinding is not an error */
                   2644:              case STATUS_NoBinding:
                   2645:                if (rval == ISC_R_FAILURE)
                   2646:                        *rvalp = ISC_R_SUCCESS;
                   2647:                return ISC_FALSE;
                   2648: 
                   2649:                /* Should not happen */
                   2650:              case STATUS_NoAddrsAvail:
                   2651:              case STATUS_NoPrefixAvail:
                   2652:                break;
                   2653: 
                   2654:                /* Give up on it */
                   2655:              case STATUS_NotOnLink:
                   2656:                break;
                   2657: 
                   2658:                /* The server is telling us to use a multicast address, so
                   2659:                 * we have to delete the unicast option from the active
                   2660:                 * lease, then allow retransmission to occur normally.
                   2661:                 * (XXX: It might be preferable in this case to retransmit
                   2662:                 * sooner than the current interval, but for now we don't.)
                   2663:                 */
                   2664:              case STATUS_UseMulticast:
                   2665:                if (client->active_lease != NULL)
                   2666:                        delete_option(&dhcp_universe,
                   2667:                                      client->active_lease->options,
                   2668:                                      D6O_UNICAST);
                   2669:                return ISC_FALSE;
                   2670:        }
                   2671: 
                   2672:        return ISC_TRUE;
                   2673: }
                   2674: 
                   2675: /* Look at a new and old lease, and make sure the new information is not
                   2676:  * losing us any state.
                   2677:  */
                   2678: static isc_result_t
                   2679: dhc6_check_reply(struct client_state *client, struct dhc6_lease *new)
                   2680: {
                   2681:        isc_boolean_t (*action)(struct client_state *,
                   2682:                                isc_result_t *, unsigned);
                   2683:        struct dhc6_ia *ia;
                   2684:        struct dhc6_addr *addr;
                   2685:        isc_result_t rval = ISC_R_SUCCESS;
                   2686:        unsigned code;
                   2687:        const char *scope;
                   2688:        int nscore, sscore;
                   2689: 
                   2690:        if ((client == NULL) || (new == NULL))
                   2691:                return ISC_R_INVALIDARG;
                   2692: 
                   2693:        switch (client->state) {
                   2694:              case S_INIT:
                   2695:                action = dhc6_init_action;
                   2696:                break;
                   2697: 
                   2698:              case S_SELECTING:
                   2699:              case S_REBOOTING:
                   2700:                action = dhc6_select_action;
                   2701:                break;
                   2702: 
                   2703:              case S_RENEWING:
                   2704:              case S_REBINDING:
                   2705:                action = dhc6_reply_action;
                   2706:                break;
                   2707: 
                   2708:              case S_STOPPED:
                   2709:                action = dhc6_stop_action;
                   2710:                break;
                   2711: 
                   2712:              default:
                   2713:                log_fatal("Impossible condition at %s:%d.", MDL);
                   2714:                return ISC_R_CANCELED;
                   2715:        }
                   2716: 
                   2717:        /* If there is a code to extract, and if there is some
                   2718:         * action to take based on that code, then take the action
                   2719:         * and do not continue.
                   2720:         */
                   2721:        rval = dhc6_check_status(rval, new->options, "message", &code);
                   2722:        if (action(client, &rval, code))
                   2723:                return ISC_R_CANCELED;
                   2724: 
                   2725:        for (ia = new->bindings ; ia != NULL ; ia = ia->next) {
                   2726:                switch (ia->ia_type) {
                   2727:                        case D6O_IA_NA:
                   2728:                                scope = "IA_NA";
                   2729:                                break;
                   2730:                        case D6O_IA_TA:
                   2731:                                scope = "IA_TA";
                   2732:                                break;
                   2733:                        case D6O_IA_PD:
                   2734:                                scope = "IA_PD";
                   2735:                                break;
                   2736:                        default:
                   2737:                                log_error("dhc6_check_reply: no type.");
                   2738:                                return ISC_R_INVALIDARG;
                   2739:                }
                   2740:                rval = dhc6_check_status(rval, ia->options,
                   2741:                                         scope, &code);
                   2742:                if (action(client, &rval, code))
                   2743:                        return ISC_R_CANCELED;
                   2744: 
                   2745:                for (addr = ia->addrs ; addr != NULL ;
                   2746:                     addr = addr->next) {
                   2747:                        if (ia->ia_type != D6O_IA_PD)
                   2748:                                scope = "IAADDR";
                   2749:                        else
                   2750:                                scope = "IAPREFIX";
                   2751:                        rval = dhc6_check_status(rval, addr->options,
                   2752:                                                 scope, &code);
                   2753:                        if (action(client, &rval, code))
                   2754:                                return ISC_R_CANCELED;
                   2755:                }
                   2756:        }
                   2757: 
                   2758:        /* A Confirm->Reply is unsuitable for comparison to the old lease. */
                   2759:        if (client->state == S_REBOOTING)
                   2760:                return rval;
                   2761: 
                   2762:        /* No old lease in rapid-commit. */
                   2763:        if (client->state == S_INIT)
                   2764:                return rval;
                   2765: 
                   2766:        switch (client->state) {
                   2767:              case S_SELECTING:
                   2768:                /* Compare the new lease with the selected lease to make
                   2769:                 * sure there is no risky business.
                   2770:                 */
                   2771:                nscore = dhc6_score_lease(client, new);
                   2772:                sscore = dhc6_score_lease(client, client->selected_lease);
                   2773:                if ((client->advertised_leases != NULL) &&
                   2774:                    (nscore < (sscore / 2))) {
                   2775:                        /* XXX: An attacker might reply this way to make
                   2776:                         * XXX: sure we latch onto their configuration.
                   2777:                         * XXX: We might want to ignore the packet and
                   2778:                         * XXX: schedule re-selection at the next timeout?
                   2779:                         */
                   2780:                        log_error("PRC: BAIT AND SWITCH detected.  Score of "
                   2781:                                  "supplied lease (%d) is substantially "
                   2782:                                  "smaller than the advertised score (%d).  "
                   2783:                                  "Trying other servers.",
                   2784:                                  nscore, sscore);
                   2785: 
                   2786:                        dhc6_lease_destroy(&client->selected_lease, MDL);
                   2787:                        client->selected_lease = NULL;
                   2788: 
                   2789:                        start_selecting6(client);
                   2790: 
                   2791:                        return ISC_R_CANCELED;
                   2792:                }
                   2793:                break;
                   2794: 
                   2795:              case S_RENEWING:
                   2796:              case S_REBINDING:
                   2797:                /* This leaves one RFC3315 status check unimplemented:
                   2798:                 *
                   2799:                 * -  sends a Renew/Rebind if the IA is not in the Reply
                   2800:                 *    message
                   2801:                 *
                   2802:                 * We rely on the scheduling system to note that the IA has
                   2803:                 * not left Renewal/Rebinding/whatever since it still carries
                   2804:                 * old times from the last successful binding.  So this is
                   2805:                 * implemented actually, just not explicitly.
                   2806:                 */
                   2807:                break;
                   2808: 
                   2809:              case S_STOPPED:
                   2810:                /* Nothing critical to do at this stage. */
                   2811:                break;
                   2812: 
                   2813:              default:
                   2814:                log_fatal("REALLY impossible condition at %s:%d.", MDL);
                   2815:                return ISC_R_CANCELED;
                   2816:        }
                   2817: 
                   2818:        return rval;
                   2819: }
                   2820: 
                   2821: /* While in init state, we only collect advertisements.  If there happens
                   2822:  * to be an advertisement with a preference option of 255, that's an
                   2823:  * automatic exit.  Otherwise, we collect advertisements until our timeout
                   2824:  * expires (client->RT).
                   2825:  */
                   2826: void
                   2827: init_handler(struct packet *packet, struct client_state *client)
                   2828: {
                   2829:        struct dhc6_lease *lease;
                   2830: 
                   2831:        /* In INIT state, we send solicits, we only expect to get
                   2832:         * advertises (rapid commit has its own handler).
                   2833:         */
                   2834:        if (packet->dhcpv6_msg_type != DHCPV6_ADVERTISE)
                   2835:                return;
                   2836: 
                   2837:        /* RFC3315 section 15.3 validation (same as 15.10 since we
                   2838:         * always include a client id).
                   2839:         */
                   2840:        if (!valid_reply(packet, client)) {
                   2841:                log_error("Invalid Advertise - rejecting.");
                   2842:                return;
                   2843:        }
                   2844: 
                   2845:        lease = dhc6_leaseify(packet);
                   2846: 
                   2847:        if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
                   2848:                log_debug("PRC: Lease failed to satisfy.");
                   2849:                dhc6_lease_destroy(&lease, MDL);
                   2850:                return;
                   2851:        }
                   2852: 
                   2853:        insert_lease(&client->advertised_leases, lease);
                   2854: 
                   2855:        /* According to RFC3315 section 17.1.2, the client MUST wait for
                   2856:         * the first RT before selecting a lease.  But on the 400th RT,
                   2857:         * we dont' want to wait the full timeout if we finally get an
                   2858:         * advertise.  We could probably wait a second, but ohwell,
                   2859:         * RFC3315 doesn't say so.
                   2860:         *
                   2861:         * If the lease is highest possible preference, 255, RFC3315 claims
                   2862:         * we should continue immediately even on the first RT.  We probably
                   2863:         * should not if the advertise contains less than one IA and address.
                   2864:         */
                   2865:        if ((client->txcount > 1) ||
                   2866:            ((lease->pref == 255) &&
                   2867:            (dhc6_score_lease(client, lease) > 150))) {
                   2868:                log_debug("RCV:  Advertisement immediately selected.");
                   2869:                cancel_timeout(do_init6, client);
                   2870:                start_selecting6(client);
                   2871:        } else
                   2872:                log_debug("RCV:  Advertisement recorded.");
                   2873: }
                   2874: 
                   2875: /* info_request_handler() accepts a Reply to an Info-request.
                   2876:  */
                   2877: void
                   2878: info_request_handler(struct packet *packet, struct client_state *client)
                   2879: {
                   2880:        isc_result_t check_status;
                   2881:        unsigned code;
                   2882: 
                   2883:        if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
                   2884:                return;
                   2885: 
                   2886:        /* RFC3315 section 15.10 validation (same as 15.3 since we
                   2887:         * always include a client id).
                   2888:         */
                   2889:        if (!valid_reply(packet, client)) {
                   2890:                log_error("Invalid Reply - rejecting.");
                   2891:                return;
                   2892:        }
                   2893: 
                   2894:        check_status = dhc6_check_status(ISC_R_SUCCESS, packet->options,
                   2895:                                         "message", &code);
                   2896:        if (check_status != ISC_R_SUCCESS) {
                   2897:                /* If no action was taken, but there is an error, then
                   2898:                 * we wait for a retransmission.
                   2899:                 */
                   2900:                if (check_status != ISC_R_CANCELED)
                   2901:                        return;
                   2902:        }
                   2903: 
                   2904:        /* We're done retransmitting at this point. */
                   2905:        cancel_timeout(do_info_request6, client);
                   2906: 
                   2907:        /* Action was taken, so now that we've torn down our scheduled
                   2908:         * retransmissions, return.
                   2909:         */
                   2910:        if (check_status == ISC_R_CANCELED)
                   2911:                return;
                   2912: 
                   2913:        /* Cleanup if a previous attempt to go bound failed. */
                   2914:        if (client->old_lease != NULL) {
                   2915:                dhc6_lease_destroy(&client->old_lease, MDL);
                   2916:                client->old_lease = NULL;
                   2917:        }
                   2918: 
                   2919:        /* Cache options in the active_lease. */
                   2920:        if (client->active_lease != NULL)
                   2921:                client->old_lease = client->active_lease;
                   2922:        client->active_lease = dmalloc(sizeof(struct dhc6_lease), MDL);
                   2923:        if (client->active_lease == NULL)
                   2924:                log_fatal("Out of memory for v6 lease structure.");
                   2925:        option_state_reference(&client->active_lease->options,
                   2926:                               packet->options, MDL);
                   2927: 
                   2928:        start_informed(client);
                   2929: }
                   2930: 
                   2931: /* Specific version of init_handler() for rapid-commit.
                   2932:  */
                   2933: void
                   2934: rapid_commit_handler(struct packet *packet, struct client_state *client)
                   2935: {
                   2936:        struct dhc6_lease *lease;
                   2937:        isc_result_t check_status;
                   2938: 
                   2939:        /* On ADVERTISE just fall back to the init_handler().
                   2940:         */
                   2941:        if (packet->dhcpv6_msg_type == DHCPV6_ADVERTISE) {
                   2942:                init_handler(packet, client);
                   2943:                return;
                   2944:        } else if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
                   2945:                return;
                   2946: 
                   2947:        /* RFC3315 section 15.10 validation (same as 15.3 since we
                   2948:         * always include a client id).
                   2949:         */
                   2950:        if (!valid_reply(packet, client)) {
                   2951:                log_error("Invalid Reply - rejecting.");
                   2952:                return;
                   2953:        }
                   2954: 
                   2955:        /* A rapid-commit option MUST be here. */
                   2956:        if (lookup_option(&dhcpv6_universe, packet->options,
                   2957:                          D6O_RAPID_COMMIT) == 0) {
                   2958:                log_error("Reply without Rapid-Commit - rejecting.");
                   2959:                return;
                   2960:        }
                   2961: 
                   2962:        lease = dhc6_leaseify(packet);
                   2963: 
                   2964:        /* This is an out of memory condition...hopefully a temporary
                   2965:         * problem.  Returning now makes us try to retransmit later.
                   2966:         */
                   2967:        if (lease == NULL)
                   2968:                return;
                   2969: 
                   2970:        check_status = dhc6_check_reply(client, lease);
                   2971:        if (check_status != ISC_R_SUCCESS) {
                   2972:                dhc6_lease_destroy(&lease, MDL);
                   2973:                return;
                   2974:        }
                   2975: 
                   2976:        /* Jump to the selecting state. */
                   2977:        cancel_timeout(do_init6, client);
                   2978:        client->state = S_SELECTING;
                   2979: 
                   2980:        /* Merge any bindings in the active lease (if there is one) into
                   2981:         * the new active lease.
                   2982:         */
                   2983:        dhc6_merge_lease(client->active_lease, lease);
                   2984: 
                   2985:        /* Cleanup if a previous attempt to go bound failed. */
                   2986:        if (client->old_lease != NULL) {
                   2987:                dhc6_lease_destroy(&client->old_lease, MDL);
                   2988:                client->old_lease = NULL;
                   2989:        }
                   2990: 
                   2991:        /* Make this lease active and BIND to it. */
                   2992:        if (client->active_lease != NULL)
                   2993:                client->old_lease = client->active_lease;
                   2994:        client->active_lease = lease;
                   2995: 
                   2996:        /* We're done with the ADVERTISEd leases, if any. */
                   2997:        while(client->advertised_leases != NULL) {
                   2998:                lease = client->advertised_leases;
                   2999:                client->advertised_leases = lease->next;
                   3000: 
                   3001:                dhc6_lease_destroy(&lease, MDL);
                   3002:        }
                   3003: 
                   3004:        start_bound(client);
                   3005: }
                   3006: 
                   3007: /* Find the 'best' lease in the cache of advertised leases (usually).  From
                   3008:  * RFC3315 Section 17.1.3:
                   3009:  *
                   3010:  *   Upon receipt of one or more valid Advertise messages, the client
                   3011:  *   selects one or more Advertise messages based upon the following
                   3012:  *   criteria.
                   3013:  *
                   3014:  *   -  Those Advertise messages with the highest server preference value
                   3015:  *      are preferred over all other Advertise messages.
                   3016:  *
                   3017:  *   -  Within a group of Advertise messages with the same server
                   3018:  *      preference value, a client MAY select those servers whose
                   3019:  *      Advertise messages advertise information of interest to the
                   3020:  *      client.  For example, the client may choose a server that returned
                   3021:  *      an advertisement with configuration options of interest to the
                   3022:  *      client.
                   3023:  *
                   3024:  *   -  The client MAY choose a less-preferred server if that server has a
                   3025:  *      better set of advertised parameters, such as the available
                   3026:  *      addresses advertised in IAs.
                   3027:  *
                   3028:  * Note that the first and third contradict each other.  The third should
                   3029:  * probably be taken to mean that the client should prefer answers that
                   3030:  * offer bindings, even if that violates the preference rule.
                   3031:  *
                   3032:  * The above also isn't deterministic where there are ties.  So the final
                   3033:  * tiebreaker we add, if all other values are equal, is to compare the
                   3034:  * server identifiers and to select the numerically lower one.
                   3035:  */
                   3036: static struct dhc6_lease *
                   3037: dhc6_best_lease(struct client_state *client, struct dhc6_lease **head)
                   3038: {
                   3039:        struct dhc6_lease **rpos, *rval, **candp, *cand;
                   3040:        int cscore, rscore;
                   3041: 
                   3042:        if (head == NULL || *head == NULL)
                   3043:                return NULL;
                   3044: 
                   3045:        rpos = head;
                   3046:        rval = *rpos;
                   3047:        rscore = dhc6_score_lease(client, rval);
                   3048:        candp = &rval->next;
                   3049:        cand = *candp;
                   3050: 
                   3051:        log_debug("PRC: Considering best lease.");
                   3052:        log_debug("PRC:  X-- Initial candidate %s (s: %d, p: %u).",
                   3053:                  print_hex_1(rval->server_id.len,
                   3054:                              rval->server_id.data, 48),
                   3055:                  rscore, (unsigned)rval->pref);
                   3056: 
                   3057:        for (; cand != NULL ; candp = &cand->next, cand = *candp) {
                   3058:                cscore = dhc6_score_lease(client, cand);
                   3059: 
                   3060:                log_debug("PRC:  X-- Candidate %s (s: %d, p: %u).",
                   3061:                          print_hex_1(cand->server_id.len,
                   3062:                                      cand->server_id.data, 48),
                   3063:                          cscore, (unsigned)cand->pref);
                   3064: 
                   3065:                /* Above you'll find quoted RFC3315 Section 17.1.3.
                   3066:                 *
                   3067:                 * The third clause tells us to give up on leases that
                   3068:                 * have no bindings even if their preference is better.
                   3069:                 * So where our 'selected' lease's score is less than 150
                   3070:                 * (1 ia + 1 addr), choose any candidate >= 150.
                   3071:                 *
                   3072:                 * The first clause tells us to make preference the primary
                   3073:                 * deciding factor.  So if it's lower, reject, if it's
                   3074:                 * higher, select.
                   3075:                 *
                   3076:                 * The second clause tells us where the preference is
                   3077:                 * equal, we should use 'our judgement' of what we like
                   3078:                 * to see in an advertisement primarily.
                   3079:                 *
                   3080:                 * But there can still be a tie.  To make this deterministic,
                   3081:                 * we compare the server identifiers and select the binary
                   3082:                 * lowest.
                   3083:                 *
                   3084:                 * Since server id's are unique in this list, there is
                   3085:                 * no further tie to break.
                   3086:                 */
                   3087:                if ((rscore < 150) && (cscore >= 150)) {
                   3088:                        log_debug("PRC:  | X-- Selected, has bindings.");
                   3089:                } else if (cand->pref < rval->pref) {
                   3090:                        log_debug("PRC:  | X-- Rejected, lower preference.");
                   3091:                        continue;
                   3092:                } else if (cand->pref > rval->pref) {
                   3093:                        log_debug("PRC:  | X-- Selected, higher preference.");
                   3094:                } else if (cscore > rscore) {
                   3095:                        log_debug("PRC:  | X-- Selected, equal preference, "
                   3096:                                  "higher score.");
                   3097:                } else if (cscore < rscore) {
                   3098:                        log_debug("PRC:  | X-- Rejected, equal preference, "
                   3099:                                  "lower score.");
                   3100:                        continue;
                   3101:                } else if ((cand->server_id.len < rval->server_id.len) ||
                   3102:                           ((cand->server_id.len == rval->server_id.len) &&
                   3103:                            (memcmp(cand->server_id.data,
                   3104:                                    rval->server_id.data,
                   3105:                                    cand->server_id.len) < 0))) {
                   3106:                        log_debug("PRC:  | X-- Selected, equal preference, "
                   3107:                                  "equal score, binary lesser server ID.");
                   3108:                } else {
                   3109:                        log_debug("PRC:  | X-- Rejected, equal preference, "
                   3110:                                  "equal score, binary greater server ID.");
                   3111:                        continue;
                   3112:                }
                   3113: 
                   3114:                rpos = candp;
                   3115:                rval = cand;
                   3116:                rscore = cscore;
                   3117:        }
                   3118: 
                   3119:        /* Remove the selected lease from the chain. */
                   3120:        *rpos = rval->next;
                   3121: 
                   3122:        return rval;
                   3123: }
                   3124: 
                   3125: /* Select a lease out of the advertised leases and setup state to try and
                   3126:  * acquire that lease.
                   3127:  */
                   3128: void
                   3129: start_selecting6(struct client_state *client)
                   3130: {
                   3131:        struct dhc6_lease *lease;
                   3132: 
                   3133:        if (client->advertised_leases == NULL) {
                   3134:                log_error("Can not enter DHCPv6 SELECTING state with no "
                   3135:                          "leases to select from!");
                   3136:                return;
                   3137:        }
                   3138: 
                   3139:        log_debug("PRC: Selecting best advertised lease.");
                   3140:        client->state = S_SELECTING;
                   3141: 
                   3142:        lease = dhc6_best_lease(client, &client->advertised_leases);
                   3143: 
                   3144:        if (lease == NULL)
                   3145:                log_fatal("Impossible error at %s:%d.", MDL);
                   3146: 
                   3147:        client->selected_lease = lease;
                   3148: 
                   3149:        /* Set timers per RFC3315 section 18.1.1. */
                   3150:        client->IRT = REQ_TIMEOUT * 100;
                   3151:        client->MRT = REQ_MAX_RT * 100;
                   3152:        client->MRC = REQ_MAX_RC;
                   3153:        client->MRD = 0;
                   3154: 
                   3155:        dhc6_retrans_init(client);
                   3156: 
                   3157:        client->v6_handler = reply_handler;
                   3158: 
                   3159:        /* ("re")transmit the first packet. */
                   3160:        do_select6(client);
                   3161: }
                   3162: 
                   3163: /* Transmit a Request to select a lease offered in Advertisements.  In
                   3164:  * the event of failure, either move on to the next-best advertised lease,
                   3165:  * or head back to INIT state if there are none.
                   3166:  */
                   3167: void
                   3168: do_select6(void *input)
                   3169: {
                   3170:        struct client_state *client;
                   3171:        struct dhc6_lease *lease;
                   3172:        struct data_string ds;
                   3173:        struct timeval tv;
                   3174:        int send_ret;
                   3175: 
                   3176:        client = input;
                   3177: 
                   3178:        /* 'lease' is fewer characters to type. */
                   3179:        lease = client->selected_lease;
                   3180:        if (lease == NULL || lease->bindings == NULL) {
                   3181:                log_error("Illegal to attempt selection without selecting "
                   3182:                          "a lease.");
                   3183:                return;
                   3184:        }
                   3185: 
                   3186:        switch(check_timing6(client, DHCPV6_REQUEST, "Request", lease, &ds)) {
                   3187:              case CHK_TIM_MRC_EXCEEDED:
                   3188:              case CHK_TIM_MRD_EXCEEDED:
                   3189:                log_debug("PRC: Lease %s failed.",
                   3190:                          print_hex_1(lease->server_id.len,
                   3191:                                      lease->server_id.data, 56));
                   3192: 
                   3193:                /* Get rid of the lease that timed/counted out. */
                   3194:                dhc6_lease_destroy(&lease, MDL);
                   3195:                client->selected_lease = NULL;
                   3196: 
                   3197:                /* If there are more leases great.  If not, get more. */
                   3198:                if (client->advertised_leases != NULL)
                   3199:                        start_selecting6(client);
                   3200:                else
                   3201:                        start_init6(client);
                   3202:                return;
                   3203:              case CHK_TIM_ALLOC_FAILURE:
                   3204:                return;
                   3205:              case CHK_TIM_SUCCESS:
                   3206:                break;
                   3207:        }
                   3208: 
                   3209:        /* Now make a packet that looks suspiciously like the one we
                   3210:         * got from the server.  But different.
                   3211:         *
                   3212:         * XXX: I guess IAID is supposed to be something the client
                   3213:         * indicates and uses as a key to its internal state.  It is
                   3214:         * kind of odd to ask the server for IA's whose IAID the client
                   3215:         * did not manufacture.  We first need a formal dhclient.conf
                   3216:         * construct for the iaid, then we can delve into this matter
                   3217:         * more properly.  In the time being, this will work.
                   3218:         */
                   3219: 
                   3220:        /* Fetch any configured 'sent' options (includes DUID) in wire format.
                   3221:         */
                   3222:        dhcpv6_universe.encapsulate(&ds, NULL, NULL, client,
                   3223:                                    NULL, client->sent_options, &global_scope,
                   3224:                                    &dhcpv6_universe);
                   3225: 
                   3226:        /* Now append any IA's, and within them any IAADDR/IAPREFIXs. */
                   3227:        if (wanted_ia_na &&
                   3228:            dhc6_add_ia_na(client, &ds, lease,
                   3229:                           DHCPV6_REQUEST) != ISC_R_SUCCESS) {
                   3230:                data_string_forget(&ds, MDL);
                   3231:                return;
                   3232:        }
                   3233:        if (wanted_ia_ta &&
                   3234:            dhc6_add_ia_ta(client, &ds, lease,
                   3235:                           DHCPV6_REQUEST) != ISC_R_SUCCESS) {
                   3236:                data_string_forget(&ds, MDL);
                   3237:                return;
                   3238:        }
                   3239:        if (wanted_ia_pd &&
                   3240:            dhc6_add_ia_pd(client, &ds, lease,
                   3241:                           DHCPV6_REQUEST) != ISC_R_SUCCESS) {
                   3242:                data_string_forget(&ds, MDL);
                   3243:                return;
                   3244:        }
                   3245: 
                   3246:        log_info("XMT: Request on %s, interval %ld0ms.",
                   3247:                 client->name ? client->name : client->interface->name,
                   3248:                 (long int)client->RT);
                   3249: 
                   3250:        send_ret = send_packet6(client->interface,
                   3251:                                ds.data, ds.len, &DHCPv6DestAddr);
                   3252:        if (send_ret != ds.len) {
                   3253:                log_error("dhc6: send_packet6() sent %d of %d bytes",
                   3254:                          send_ret, ds.len);
                   3255:        }
                   3256: 
                   3257:        data_string_forget(&ds, MDL);
                   3258: 
                   3259:        /* Wait RT */
                   3260:        tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
                   3261:        tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
                   3262:        if (tv.tv_usec >= 1000000) {
                   3263:                tv.tv_sec += 1;
                   3264:                tv.tv_usec -= 1000000;
                   3265:        }
                   3266:        add_timeout(&tv, do_select6, client, NULL, NULL);
                   3267: 
                   3268:        dhc6_retrans_advance(client);
                   3269: }
                   3270: 
                   3271: /* For each IA_NA in the lease, for each address in the IA_NA,
                   3272:  * append that information onto the packet-so-far.
                   3273:  */
                   3274: static isc_result_t
                   3275: dhc6_add_ia_na(struct client_state *client, struct data_string *packet,
                   3276:               struct dhc6_lease *lease, u_int8_t message)
                   3277: {
                   3278:        struct data_string iads;
                   3279:        struct data_string addrds;
                   3280:        struct dhc6_addr *addr;
                   3281:        struct dhc6_ia *ia;
                   3282:        isc_result_t rval = ISC_R_SUCCESS;
                   3283:        TIME t1, t2;
                   3284: 
                   3285:        memset(&iads, 0, sizeof(iads));
                   3286:        memset(&addrds, 0, sizeof(addrds));
                   3287:        for (ia = lease->bindings;
                   3288:             ia != NULL && rval == ISC_R_SUCCESS;
                   3289:             ia = ia->next) {
                   3290:                if (ia->ia_type != D6O_IA_NA)
                   3291:                        continue;
                   3292: 
                   3293:                if (!buffer_allocate(&iads.buffer, 12, MDL)) {
                   3294:                        log_error("Unable to allocate memory for IA_NA.");
                   3295:                        rval = ISC_R_NOMEMORY;
                   3296:                        break;
                   3297:                }
                   3298: 
                   3299:                /* Copy the IAID into the packet buffer. */
                   3300:                memcpy(iads.buffer->data, ia->iaid, 4);
                   3301:                iads.data = iads.buffer->data;
                   3302:                iads.len = 12;
                   3303: 
                   3304:                switch (message) {
                   3305:                      case DHCPV6_REQUEST:
                   3306:                      case DHCPV6_RENEW:
                   3307:                      case DHCPV6_REBIND:
                   3308: 
                   3309:                        t1 = client->config->requested_lease / 2;
                   3310:                        t2 = t1 + (t1 / 2);
                   3311: #if MAX_TIME > 0xffffffff
                   3312:                        if (t1 > 0xffffffff)
                   3313:                                t1 = 0xffffffff;
                   3314:                        if (t2 > 0xffffffff)
                   3315:                                t2 = 0xffffffff;
                   3316: #endif
                   3317:                        putULong(iads.buffer->data + 4, t1);
                   3318:                        putULong(iads.buffer->data + 8, t2);
                   3319: 
                   3320:                        log_debug("XMT:  X-- IA_NA %s",
                   3321:                                  print_hex_1(4, iads.data, 59));
                   3322:                        log_debug("XMT:  | X-- Requested renew  +%u",
                   3323:                                  (unsigned) t1);
                   3324:                        log_debug("XMT:  | X-- Requested rebind +%u",
                   3325:                                  (unsigned) t2);
                   3326:                        break;
                   3327: 
                   3328:                      case DHCPV6_CONFIRM:
                   3329:                      case DHCPV6_RELEASE:
                   3330:                      case DHCPV6_DECLINE:
                   3331:                        /* Set t1 and t2 to zero; server will ignore them */
                   3332:                        memset(iads.buffer->data + 4, 0, 8);
                   3333:                        log_debug("XMT:  X-- IA_NA %s",
                   3334:                                  print_hex_1(4, iads.buffer->data, 55));
                   3335: 
                   3336:                        break;
                   3337: 
                   3338:                      default:
                   3339:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   3340:                }
                   3341: 
                   3342:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   3343:                        /*
                   3344:                         * Do not confirm expired addresses, do not request
                   3345:                         * expired addresses (but we keep them around for
                   3346:                         * solicit).
                   3347:                         */
                   3348:                        if (addr->flags & DHC6_ADDR_EXPIRED)
                   3349:                                continue;
                   3350: 
                   3351:                        if (addr->address.len != 16) {
                   3352:                                log_error("Illegal IPv6 address length (%d), "
                   3353:                                          "ignoring.  (%s:%d)",
                   3354:                                          addr->address.len, MDL);
                   3355:                                continue;
                   3356:                        }
                   3357: 
                   3358:                        if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
                   3359:                                log_error("Unable to allocate memory for "
                   3360:                                          "IAADDR.");
                   3361:                                rval = ISC_R_NOMEMORY;
                   3362:                                break;
                   3363:                        }
                   3364: 
                   3365:                        addrds.data = addrds.buffer->data;
                   3366:                        addrds.len = 24;
                   3367: 
                   3368:                        /* Copy the address into the packet buffer. */
                   3369:                        memcpy(addrds.buffer->data, addr->address.iabuf, 16);
                   3370: 
                   3371:                        /* Copy in additional information as appropriate */
                   3372:                        switch (message) {
                   3373:                              case DHCPV6_REQUEST:
                   3374:                              case DHCPV6_RENEW:
                   3375:                              case DHCPV6_REBIND:
                   3376:                                t1 = client->config->requested_lease;
                   3377:                                t2 = t1 + 300;
                   3378:                                putULong(addrds.buffer->data + 16, t1);
                   3379:                                putULong(addrds.buffer->data + 20, t2);
                   3380: 
                   3381:                                log_debug("XMT:  | | X-- IAADDR %s",
                   3382:                                          piaddr(addr->address));
                   3383:                                log_debug("XMT:  | | | X-- Preferred "
                   3384:                                          "lifetime +%u", (unsigned)t1);
                   3385:                                log_debug("XMT:  | | | X-- Max lifetime +%u",
                   3386:                                          (unsigned)t2);
                   3387: 
                   3388:                                break;
                   3389: 
                   3390:                              case DHCPV6_CONFIRM:
                   3391:                                /*
                   3392:                                 * Set preferred and max life to zero,
                   3393:                                 * per 17.1.3.
                   3394:                                 */
                   3395:                                memset(addrds.buffer->data + 16, 0, 8);
                   3396:                                log_debug("XMT:  | X-- Confirm Address %s",
                   3397:                                          piaddr(addr->address));
                   3398:                                break;
                   3399: 
                   3400:                              case DHCPV6_RELEASE:
                   3401:                                /* Preferred and max life are irrelevant */
                   3402:                                memset(addrds.buffer->data + 16, 0, 8);
                   3403:                                log_debug("XMT:  | X-- Release Address %s",
                   3404:                                          piaddr(addr->address));
                   3405:                                break;
                   3406: 
                   3407:                              case DHCPV6_DECLINE:
                   3408:                                /* Preferred and max life are irrelevant */
                   3409:                                memset(addrds.buffer->data + 16, 0, 8);
                   3410:                                log_debug("XMT:  | X-- Decline Address %s",
                   3411:                                          piaddr(addr->address));
                   3412:                                break;
                   3413: 
                   3414:                              default:
                   3415:                                log_fatal("Impossible condition at %s:%d.",
                   3416:                                          MDL);
                   3417:                        }
                   3418: 
                   3419:                        append_option(&iads, &dhcpv6_universe, iaaddr_option,
                   3420:                                      &addrds);
                   3421:                        data_string_forget(&addrds, MDL);
                   3422:                }
                   3423: 
                   3424:                /*
                   3425:                 * It doesn't make sense to make a request without an
                   3426:                 * address.
                   3427:                 */
                   3428:                if (ia->addrs == NULL) {
                   3429:                        log_debug("!!!:  V IA_NA has no IAADDRs - removed.");
                   3430:                        rval = ISC_R_FAILURE;
                   3431:                } else if (rval == ISC_R_SUCCESS) {
                   3432:                        log_debug("XMT:  V IA_NA appended.");
                   3433:                        append_option(packet, &dhcpv6_universe, ia_na_option,
                   3434:                                      &iads);
                   3435:                }
                   3436: 
                   3437:                data_string_forget(&iads, MDL);
                   3438:        }
                   3439: 
                   3440:        return rval;
                   3441: }
                   3442: 
                   3443: /* For each IA_TA in the lease, for each address in the IA_TA,
                   3444:  * append that information onto the packet-so-far.
                   3445:  */
                   3446: static isc_result_t
                   3447: dhc6_add_ia_ta(struct client_state *client, struct data_string *packet,
                   3448:               struct dhc6_lease *lease, u_int8_t message)
                   3449: {
                   3450:        struct data_string iads;
                   3451:        struct data_string addrds;
                   3452:        struct dhc6_addr *addr;
                   3453:        struct dhc6_ia *ia;
                   3454:        isc_result_t rval = ISC_R_SUCCESS;
                   3455:        TIME t1, t2;
                   3456: 
                   3457:        memset(&iads, 0, sizeof(iads));
                   3458:        memset(&addrds, 0, sizeof(addrds));
                   3459:        for (ia = lease->bindings;
                   3460:             ia != NULL && rval == ISC_R_SUCCESS;
                   3461:             ia = ia->next) {
                   3462:                if (ia->ia_type != D6O_IA_TA)
                   3463:                        continue;
                   3464: 
                   3465:                if (!buffer_allocate(&iads.buffer, 4, MDL)) {
                   3466:                        log_error("Unable to allocate memory for IA_TA.");
                   3467:                        rval = ISC_R_NOMEMORY;
                   3468:                        break;
                   3469:                }
                   3470: 
                   3471:                /* Copy the IAID into the packet buffer. */
                   3472:                memcpy(iads.buffer->data, ia->iaid, 4);
                   3473:                iads.data = iads.buffer->data;
                   3474:                iads.len = 4;
                   3475: 
                   3476:                log_debug("XMT:  X-- IA_TA %s",
                   3477:                          print_hex_1(4, iads.buffer->data, 55));
                   3478: 
                   3479:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   3480:                        /*
                   3481:                         * Do not confirm expired addresses, do not request
                   3482:                         * expired addresses (but we keep them around for
                   3483:                         * solicit).
                   3484:                         */
                   3485:                        if (addr->flags & DHC6_ADDR_EXPIRED)
                   3486:                                continue;
                   3487: 
                   3488:                        if (addr->address.len != 16) {
                   3489:                                log_error("Illegal IPv6 address length (%d), "
                   3490:                                          "ignoring.  (%s:%d)",
                   3491:                                          addr->address.len, MDL);
                   3492:                                continue;
                   3493:                        }
                   3494: 
                   3495:                        if (!buffer_allocate(&addrds.buffer, 24, MDL)) {
                   3496:                                log_error("Unable to allocate memory for "
                   3497:                                          "IAADDR.");
                   3498:                                rval = ISC_R_NOMEMORY;
                   3499:                                break;
                   3500:                        }
                   3501: 
                   3502:                        addrds.data = addrds.buffer->data;
                   3503:                        addrds.len = 24;
                   3504: 
                   3505:                        /* Copy the address into the packet buffer. */
                   3506:                        memcpy(addrds.buffer->data, addr->address.iabuf, 16);
                   3507: 
                   3508:                        /* Copy in additional information as appropriate */
                   3509:                        switch (message) {
                   3510:                              case DHCPV6_REQUEST:
                   3511:                              case DHCPV6_RENEW:
                   3512:                              case DHCPV6_REBIND:
                   3513:                                t1 = client->config->requested_lease;
                   3514:                                t2 = t1 + 300;
                   3515:                                putULong(addrds.buffer->data + 16, t1);
                   3516:                                putULong(addrds.buffer->data + 20, t2);
                   3517: 
                   3518:                                log_debug("XMT:  | | X-- IAADDR %s",
                   3519:                                          piaddr(addr->address));
                   3520:                                log_debug("XMT:  | | | X-- Preferred "
                   3521:                                          "lifetime +%u", (unsigned)t1);
                   3522:                                log_debug("XMT:  | | | X-- Max lifetime +%u",
                   3523:                                          (unsigned)t2);
                   3524: 
                   3525:                                break;
                   3526: 
                   3527:                              case DHCPV6_CONFIRM:
                   3528:                                /*
                   3529:                                 * Set preferred and max life to zero,
                   3530:                                 * per 17.1.3.
                   3531:                                 */
                   3532:                                memset(addrds.buffer->data + 16, 0, 8);
                   3533:                                log_debug("XMT:  | X-- Confirm Address %s",
                   3534:                                          piaddr(addr->address));
                   3535:                                break;
                   3536: 
                   3537:                              case DHCPV6_RELEASE:
                   3538:                                /* Preferred and max life are irrelevant */
                   3539:                                memset(addrds.buffer->data + 16, 0, 8);
                   3540:                                log_debug("XMT:  | X-- Release Address %s",
                   3541:                                          piaddr(addr->address));
                   3542:                                break;
                   3543: 
                   3544:                              default:
                   3545:                                log_fatal("Impossible condition at %s:%d.",
                   3546:                                          MDL);
                   3547:                        }
                   3548: 
                   3549:                        append_option(&iads, &dhcpv6_universe, iaaddr_option,
                   3550:                                      &addrds);
                   3551:                        data_string_forget(&addrds, MDL);
                   3552:                }
                   3553: 
                   3554:                /*
                   3555:                 * It doesn't make sense to make a request without an
                   3556:                 * address.
                   3557:                 */
                   3558:                if (ia->addrs == NULL) {
                   3559:                        log_debug("!!!:  V IA_TA has no IAADDRs - removed.");
                   3560:                        rval = ISC_R_FAILURE;
                   3561:                } else if (rval == ISC_R_SUCCESS) {
                   3562:                        log_debug("XMT:  V IA_TA appended.");
                   3563:                        append_option(packet, &dhcpv6_universe, ia_ta_option,
                   3564:                                      &iads);
                   3565:                }
                   3566: 
                   3567:                data_string_forget(&iads, MDL);
                   3568:        }
                   3569: 
                   3570:        return rval;
                   3571: }
                   3572: 
                   3573: /* For each IA_PD in the lease, for each prefix in the IA_PD,
                   3574:  * append that information onto the packet-so-far.
                   3575:  */
                   3576: static isc_result_t
                   3577: dhc6_add_ia_pd(struct client_state *client, struct data_string *packet,
                   3578:               struct dhc6_lease *lease, u_int8_t message)
                   3579: {
                   3580:        struct data_string iads;
                   3581:        struct data_string prefds;
                   3582:        struct dhc6_addr *pref;
                   3583:        struct dhc6_ia *ia;
                   3584:        isc_result_t rval = ISC_R_SUCCESS;
                   3585:        TIME t1, t2;
                   3586: 
                   3587:        memset(&iads, 0, sizeof(iads));
                   3588:        memset(&prefds, 0, sizeof(prefds));
                   3589:        for (ia = lease->bindings;
                   3590:             ia != NULL && rval == ISC_R_SUCCESS;
                   3591:             ia = ia->next) {
                   3592:                if (ia->ia_type != D6O_IA_PD)
                   3593:                        continue;
                   3594: 
                   3595:                if (!buffer_allocate(&iads.buffer, 12, MDL)) {
                   3596:                        log_error("Unable to allocate memory for IA_PD.");
                   3597:                        rval = ISC_R_NOMEMORY;
                   3598:                        break;
                   3599:                }
                   3600: 
                   3601:                /* Copy the IAID into the packet buffer. */
                   3602:                memcpy(iads.buffer->data, ia->iaid, 4);
                   3603:                iads.data = iads.buffer->data;
                   3604:                iads.len = 12;
                   3605: 
                   3606:                switch (message) {
                   3607:                      case DHCPV6_REQUEST:
                   3608:                      case DHCPV6_RENEW:
                   3609:                      case DHCPV6_REBIND:
                   3610: 
                   3611:                        t1 = client->config->requested_lease / 2;
                   3612:                        t2 = t1 + (t1 / 2);
                   3613: #if MAX_TIME > 0xffffffff
                   3614:                        if (t1 > 0xffffffff)
                   3615:                                t1 = 0xffffffff;
                   3616:                        if (t2 > 0xffffffff)
                   3617:                                t2 = 0xffffffff;
                   3618: #endif
                   3619:                        putULong(iads.buffer->data + 4, t1);
                   3620:                        putULong(iads.buffer->data + 8, t2);
                   3621: 
                   3622:                        log_debug("XMT:  X-- IA_PD %s",
                   3623:                                  print_hex_1(4, iads.data, 59));
                   3624:                        log_debug("XMT:  | X-- Requested renew  +%u",
                   3625:                                  (unsigned) t1);
                   3626:                        log_debug("XMT:  | X-- Requested rebind +%u",
                   3627:                                  (unsigned) t2);
                   3628:                        break;
                   3629: 
                   3630:                      case DHCPV6_RELEASE:
                   3631:                        /* Set t1 and t2 to zero; server will ignore them */
                   3632:                        memset(iads.buffer->data + 4, 0, 8);
                   3633:                        log_debug("XMT:  X-- IA_PD %s",
                   3634:                                  print_hex_1(4, iads.buffer->data, 55));
                   3635: 
                   3636:                        break;
                   3637: 
                   3638:                      default:
                   3639:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   3640:                }
                   3641: 
                   3642:                for (pref = ia->addrs ; pref != NULL ; pref = pref->next) {
                   3643:                        /*
                   3644:                         * Do not confirm expired prefixes, do not request
                   3645:                         * expired prefixes (but we keep them around for
                   3646:                         * solicit).
                   3647:                         */
                   3648:                        if (pref->flags & DHC6_ADDR_EXPIRED)
                   3649:                                continue;
                   3650: 
                   3651:                        if (pref->address.len != 16) {
                   3652:                                log_error("Illegal IPv6 prefix "
                   3653:                                          "ignoring.  (%s:%d)",
                   3654:                                          MDL);
                   3655:                                continue;
                   3656:                        }
                   3657: 
                   3658:                        if (pref->plen == 0) {
                   3659:                                log_info("Null IPv6 prefix, "
                   3660:                                         "ignoring. (%s:%d)",
                   3661:                                         MDL);
                   3662:                        }
                   3663: 
                   3664:                        if (!buffer_allocate(&prefds.buffer, 25, MDL)) {
                   3665:                                log_error("Unable to allocate memory for "
                   3666:                                          "IAPREFIX.");
                   3667:                                rval = ISC_R_NOMEMORY;
                   3668:                                break;
                   3669:                        }
                   3670: 
                   3671:                        prefds.data = prefds.buffer->data;
                   3672:                        prefds.len = 25;
                   3673: 
                   3674:                        /* Copy the prefix into the packet buffer. */
                   3675:                        putUChar(prefds.buffer->data + 8, pref->plen);
                   3676:                        memcpy(prefds.buffer->data + 9,
                   3677:                               pref->address.iabuf,
                   3678:                               16);
                   3679: 
                   3680:                        /* Copy in additional information as appropriate */
                   3681:                        switch (message) {
                   3682:                              case DHCPV6_REQUEST:
                   3683:                              case DHCPV6_RENEW:
                   3684:                              case DHCPV6_REBIND:
                   3685:                                t1 = client->config->requested_lease;
                   3686:                                t2 = t1 + 300;
                   3687:                                putULong(prefds.buffer->data, t1);
                   3688:                                putULong(prefds.buffer->data + 4, t2);
                   3689: 
                   3690:                                log_debug("XMT:  | | X-- IAPREFIX %s/%u",
                   3691:                                          piaddr(pref->address),
                   3692:                                          (unsigned) pref->plen);
                   3693:                                log_debug("XMT:  | | | X-- Preferred "
                   3694:                                          "lifetime +%u", (unsigned)t1);
                   3695:                                log_debug("XMT:  | | | X-- Max lifetime +%u",
                   3696:                                          (unsigned)t2);
                   3697: 
                   3698:                                break;
                   3699: 
                   3700:                              case DHCPV6_RELEASE:
                   3701:                                /* Preferred and max life are irrelevant */
                   3702:                                memset(prefds.buffer->data, 0, 8);
                   3703:                                log_debug("XMT:  | X-- Release Prefix %s/%u",
                   3704:                                          piaddr(pref->address),
                   3705:                                          (unsigned) pref->plen);
                   3706:                                break;
                   3707: 
                   3708:                              default:
                   3709:                                log_fatal("Impossible condition at %s:%d.",
                   3710:                                          MDL);
                   3711:                        }
                   3712: 
                   3713:                        append_option(&iads, &dhcpv6_universe,
                   3714:                                      iaprefix_option, &prefds);
                   3715:                        data_string_forget(&prefds, MDL);
                   3716:                }
                   3717: 
                   3718:                /*
                   3719:                 * It doesn't make sense to make a request without an
                   3720:                 * address.
                   3721:                 */
                   3722:                if (ia->addrs == NULL) {
                   3723:                        log_debug("!!!:  V IA_PD has no IAPREFIXs - removed.");
                   3724:                        rval = ISC_R_FAILURE;
                   3725:                } else if (rval == ISC_R_SUCCESS) {
                   3726:                        log_debug("XMT:  V IA_PD appended.");
                   3727:                        append_option(packet, &dhcpv6_universe,
                   3728:                                      ia_pd_option, &iads);
                   3729:                }
                   3730: 
                   3731:                data_string_forget(&iads, MDL);
                   3732:        }
                   3733: 
                   3734:        return rval;
                   3735: }
                   3736: 
                   3737: /* stopping_finished() checks if there is a remaining work to do.
                   3738:  */
                   3739: static isc_boolean_t
                   3740: stopping_finished(void)
                   3741: {
                   3742:        struct interface_info *ip;
                   3743:        struct client_state *client;
                   3744: 
                   3745:        for (ip = interfaces; ip; ip = ip -> next) {
                   3746:                for (client = ip -> client; client; client = client -> next) {
                   3747:                        if (client->state != S_STOPPED)
                   3748:                                return ISC_FALSE;
                   3749:                        if (client->active_lease != NULL)
                   3750:                                return ISC_FALSE;
                   3751:                }
                   3752:        }
                   3753:        return ISC_TRUE;
                   3754: }
                   3755: 
                   3756: /* reply_handler() accepts a Reply while we're attempting Select or Renew or
                   3757:  * Rebind.  Basically any Reply packet.
                   3758:  */
                   3759: void
                   3760: reply_handler(struct packet *packet, struct client_state *client)
                   3761: {
                   3762:        struct dhc6_lease *lease;
                   3763:        isc_result_t check_status;
                   3764: 
                   3765:        if (packet->dhcpv6_msg_type != DHCPV6_REPLY)
                   3766:                return;
                   3767: 
                   3768:        /* RFC3315 section 15.10 validation (same as 15.3 since we
                   3769:         * always include a client id).
                   3770:         */
                   3771:        if (!valid_reply(packet, client)) {
                   3772:                log_error("Invalid Reply - rejecting.");
                   3773:                return;
                   3774:        }
                   3775: 
                   3776:        lease = dhc6_leaseify(packet);
                   3777: 
                   3778:        /* This is an out of memory condition...hopefully a temporary
                   3779:         * problem.  Returning now makes us try to retransmit later.
                   3780:         */
                   3781:        if (lease == NULL)
                   3782:                return;
                   3783: 
                   3784:        check_status = dhc6_check_reply(client, lease);
                   3785:        if (check_status != ISC_R_SUCCESS) {
                   3786:                dhc6_lease_destroy(&lease, MDL);
                   3787: 
                   3788:                /* If no action was taken, but there is an error, then
                   3789:                 * we wait for a retransmission.
                   3790:                 */
                   3791:                if (check_status != ISC_R_CANCELED)
                   3792:                        return;
                   3793:        }
                   3794: 
                   3795:        /* We're done retransmitting at this point. */
                   3796:        cancel_timeout(do_confirm6, client);
                   3797:        cancel_timeout(do_select6, client);
                   3798:        cancel_timeout(do_refresh6, client);
                   3799:        cancel_timeout(do_release6, client);
                   3800: 
                   3801:        /* If this is in response to a Release/Decline, clean up and return. */
                   3802:        if (client->state == S_STOPPED) {
                   3803:                if (client->active_lease == NULL)
                   3804:                        return;
                   3805: 
                   3806:                dhc6_lease_destroy(&client->active_lease, MDL);
                   3807:                client->active_lease = NULL;
                   3808:                /* We should never wait for nothing!? */
                   3809:                if (stopping_finished())
                   3810:                        exit(0);
                   3811:                return;
                   3812:        }
                   3813: 
                   3814:        /* Action was taken, so now that we've torn down our scheduled
                   3815:         * retransmissions, return.
                   3816:         */
                   3817:        if (check_status == ISC_R_CANCELED)
                   3818:                return;
                   3819: 
                   3820:        if (client->selected_lease != NULL) {
                   3821:                dhc6_lease_destroy(&client->selected_lease, MDL);
                   3822:                client->selected_lease = NULL;
                   3823:        }
                   3824: 
                   3825:        /* If this is in response to a confirm, we use the lease we've
                   3826:         * already got, not the reply we were sent.
                   3827:         */
                   3828:        if (client->state == S_REBOOTING) {
                   3829:                if (client->active_lease == NULL)
                   3830:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   3831: 
                   3832:                dhc6_lease_destroy(&lease, MDL);
                   3833:                start_bound(client);
                   3834:                return;
                   3835:        }
                   3836: 
                   3837:        /* Merge any bindings in the active lease (if there is one) into
                   3838:         * the new active lease.
                   3839:         */
                   3840:        dhc6_merge_lease(client->active_lease, lease);
                   3841: 
                   3842:        /* Cleanup if a previous attempt to go bound failed. */
                   3843:        if (client->old_lease != NULL) {
                   3844:                dhc6_lease_destroy(&client->old_lease, MDL);
                   3845:                client->old_lease = NULL;
                   3846:        }
                   3847: 
                   3848:        /* Make this lease active and BIND to it. */
                   3849:        if (client->active_lease != NULL)
                   3850:                client->old_lease = client->active_lease;
                   3851:        client->active_lease = lease;
                   3852: 
                   3853:        /* We're done with the ADVERTISEd leases, if any. */
                   3854:        while(client->advertised_leases != NULL) {
                   3855:                lease = client->advertised_leases;
                   3856:                client->advertised_leases = lease->next;
                   3857: 
                   3858:                dhc6_lease_destroy(&lease, MDL);
                   3859:        }
                   3860: 
                   3861:        start_bound(client);
                   3862: }
                   3863: 
                   3864: /* DHCPv6 packets are a little sillier than they needed to be - the root
                   3865:  * packet contains options, then IA's which contain options, then within
                   3866:  * that IAADDR's which contain options.
                   3867:  *
                   3868:  * To sort this out at dhclient-script time (which fetches config parameters
                   3869:  * in environment variables), start_bound() iterates over each IAADDR, and
                   3870:  * calls this function to marshall an environment variable set that includes
                   3871:  * the most-specific option values related to that IAADDR in particular.
                   3872:  *
                   3873:  * To achieve this, we load environment variables for the root options space,
                   3874:  * then the IA, then the IAADDR.  Any duplicate option names will be
                   3875:  * over-written by the later versions.
                   3876:  */
                   3877: static void
                   3878: dhc6_marshall_values(const char *prefix, struct client_state *client,
                   3879:                     struct dhc6_lease *lease, struct dhc6_ia *ia,
                   3880:                     struct dhc6_addr *addr)
                   3881: {
                   3882:        /* Option cache contents, in descending order of
                   3883:         * scope.
                   3884:         */
                   3885:        if ((lease != NULL) && (lease->options != NULL))
                   3886:                script_write_params6(client, prefix, lease->options);
                   3887:        if ((ia != NULL) && (ia->options != NULL))
                   3888:                script_write_params6(client, prefix, ia->options);
                   3889:        if ((addr != NULL) && (addr->options != NULL))
                   3890:                script_write_params6(client, prefix, addr->options);
                   3891: 
                   3892:        /* addr fields. */
                   3893:        if (addr != NULL) {
                   3894:                if ((ia != NULL) && (ia->ia_type == D6O_IA_PD)) {
                   3895:                        client_envadd(client, prefix,
                   3896:                                      "ip6_prefix", "%s/%u",
                   3897:                                      piaddr(addr->address),
                   3898:                                      (unsigned) addr->plen);
                   3899:                } else {
                   3900:                        /* Current practice is that all subnets are /64's, but
                   3901:                         * some suspect this may not be permanent.
                   3902:                         */
                   3903:                        client_envadd(client, prefix, "ip6_prefixlen",
                   3904:                                      "%d", 64);
                   3905:                        client_envadd(client, prefix, "ip6_address",
                   3906:                                      "%s", piaddr(addr->address));
                   3907:                }
                   3908:                if ((ia != NULL) && (ia->ia_type == D6O_IA_TA)) {
                   3909:                        client_envadd(client, prefix,
                   3910:                                      "ip6_type", "temporary");
                   3911:                }
                   3912:                client_envadd(client, prefix, "life_starts", "%d",
                   3913:                              (int)(addr->starts));
                   3914:                client_envadd(client, prefix, "preferred_life", "%d",
                   3915:                              (int)(addr->preferred_life));
                   3916:                client_envadd(client, prefix, "max_life", "%d",
                   3917:                              (int)(addr->max_life));
                   3918:        }
                   3919: 
                   3920:        /* ia fields. */
                   3921:        if (ia != NULL) {
                   3922:                client_envadd(client, prefix, "iaid", "%s",
                   3923:                              print_hex_1(4, ia->iaid, 12));
                   3924:                client_envadd(client, prefix, "starts", "%d",
                   3925:                              (int)(ia->starts));
                   3926:                client_envadd(client, prefix, "renew", "%u", ia->renew);
                   3927:                client_envadd(client, prefix, "rebind", "%u", ia->rebind);
                   3928:        }
                   3929: }
                   3930: 
                   3931: /* Look at where the client's active lease is sitting.  If it's looking to
                   3932:  * time out on renew, rebind, depref, or expiration, do those things.
                   3933:  */
                   3934: static void
                   3935: dhc6_check_times(struct client_state *client)
                   3936: {
                   3937:        struct dhc6_lease *lease;
                   3938:        struct dhc6_ia *ia;
                   3939:        struct dhc6_addr *addr;
                   3940:        TIME renew=MAX_TIME, rebind=MAX_TIME, depref=MAX_TIME,
                   3941:             lo_expire=MAX_TIME, hi_expire=0, tmp;
                   3942:        int has_addrs = ISC_FALSE;
                   3943:        struct timeval tv;
                   3944: 
                   3945:        lease = client->active_lease;
                   3946: 
                   3947:        /* Bit spammy.  We should probably keep record of scheduled
                   3948:         * events instead.
                   3949:         */
                   3950:        cancel_timeout(start_renew6, client);
                   3951:        cancel_timeout(start_rebind6, client);
                   3952:        cancel_timeout(do_depref, client);
                   3953:        cancel_timeout(do_expire, client);
                   3954: 
                   3955:        for(ia = lease->bindings ; ia != NULL ; ia = ia->next) {
                   3956:                TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
                   3957: 
                   3958:                this_ia_lo_expire = MAX_TIME;
                   3959:                this_ia_hi_expire = 0;
                   3960: 
                   3961:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   3962:                        if(!(addr->flags & DHC6_ADDR_DEPREFFED)) {
                   3963:                                if (addr->preferred_life == 0xffffffff)
                   3964:                                        tmp = MAX_TIME;
                   3965:                                else
                   3966:                                        tmp = addr->starts +
                   3967:                                              addr->preferred_life;
                   3968: 
                   3969:                                if (tmp < depref)
                   3970:                                        depref = tmp;
                   3971:                        }
                   3972: 
                   3973:                        if (!(addr->flags & DHC6_ADDR_EXPIRED)) {
                   3974:                                /* Find EPOCH-relative expiration. */
                   3975:                                if (addr->max_life == 0xffffffff)
                   3976:                                        tmp = MAX_TIME;
                   3977:                                else
                   3978:                                        tmp = addr->starts + addr->max_life;
                   3979: 
                   3980:                                /* Make the times ia->starts relative. */
                   3981:                                tmp -= ia->starts;
                   3982: 
                   3983:                                if (tmp > this_ia_hi_expire)
                   3984:                                        this_ia_hi_expire = tmp;
                   3985:                                if (tmp < this_ia_lo_expire)
                   3986:                                        this_ia_lo_expire = tmp;
                   3987: 
                   3988:                                has_addrs = ISC_TRUE;
                   3989:                        }
                   3990:                }
                   3991: 
                   3992:                /* These times are ia->starts relative. */
                   3993:                if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
                   3994:                        use_expire = this_ia_hi_expire;
                   3995:                else
                   3996:                        use_expire = this_ia_lo_expire;
                   3997: 
                   3998:                /*
                   3999:                 * If the auto-selected expiration time is "infinite", or
                   4000:                 * zero, assert a reasonable default.
                   4001:                 */
                   4002:                if ((use_expire == MAX_TIME) || (use_expire <= 1))
                   4003:                        use_expire = client->config->requested_lease / 2;
                   4004:                else
                   4005:                        use_expire /= 2;
                   4006: 
                   4007:                /* Don't renew/rebind temporary addresses. */
                   4008:                if (ia->ia_type != D6O_IA_TA) {
                   4009: 
                   4010:                        if (ia->renew == 0) {
                   4011:                                tmp = ia->starts + use_expire;
                   4012:                        } else if (ia->renew == 0xffffffff)
                   4013:                                tmp = MAX_TIME;
                   4014:                        else
                   4015:                                tmp = ia->starts + ia->renew;
                   4016: 
                   4017:                        if (tmp < renew)
                   4018:                                renew = tmp;
                   4019: 
                   4020:                        if (ia->rebind == 0) {
                   4021:                                /* Set rebind to 3/4 expiration interval. */
                   4022:                                tmp = ia->starts;
                   4023:                                tmp += use_expire + (use_expire / 2);
1.1.1.1 ! misho    4024:                        } else if (ia->rebind == 0xffffffff)
1.1       misho    4025:                                tmp = MAX_TIME;
                   4026:                        else
                   4027:                                tmp = ia->starts + ia->rebind;
                   4028: 
                   4029:                        if (tmp < rebind)
                   4030:                                rebind = tmp;
                   4031:                }
                   4032: 
                   4033:                /*
                   4034:                 * Return expiration ranges to EPOCH relative for event
                   4035:                 * scheduling (add_timeout()).
                   4036:                 */
                   4037:                this_ia_hi_expire += ia->starts;
                   4038:                this_ia_lo_expire += ia->starts;
                   4039: 
                   4040:                if (this_ia_hi_expire > hi_expire)
                   4041:                        hi_expire = this_ia_hi_expire;
                   4042:                if (this_ia_lo_expire < lo_expire)
                   4043:                        lo_expire = this_ia_lo_expire;
                   4044:        }
                   4045: 
                   4046:        /* If there are no addresses, give up, go to INIT.
                   4047:         * Note that if an address is unexpired with a date in the past,
                   4048:         * we're scheduling an expiration event to ocurr in the past.  We
                   4049:         * could probably optimize this to expire now (but then there's
                   4050:         * recursion).
                   4051:         *
                   4052:         * In the future, we may decide that we're done here, or to
                   4053:         * schedule a future request (using 4-pkt info-request model).
                   4054:         */
                   4055:        if (has_addrs == ISC_FALSE) {
                   4056:                dhc6_lease_destroy(&client->active_lease, MDL);
                   4057:                client->active_lease = NULL;
                   4058: 
                   4059:                /* Go back to the beginning. */
                   4060:                start_init6(client);
                   4061:                return;
                   4062:        }
                   4063: 
                   4064:        switch(client->state) {
                   4065:              case S_BOUND:
                   4066:                /* We'd like to hit renewing, but if rebinding has already
                   4067:                 * passed (time warp), head straight there.
                   4068:                 */
                   4069:                if ((rebind > cur_time) && (renew < rebind)) {
                   4070:                        log_debug("PRC: Renewal event scheduled in %d seconds, "
                   4071:                                  "to run for %u seconds.",
                   4072:                                  (int)(renew - cur_time),
                   4073:                                  (unsigned)(rebind - renew));
                   4074:                        client->next_MRD = rebind;
                   4075:                        tv.tv_sec = renew;
                   4076:                        tv.tv_usec = 0;
                   4077:                        add_timeout(&tv, start_renew6, client, NULL, NULL);
                   4078: 
                   4079:                        break;
                   4080:                }
                   4081:                /* FALL THROUGH */
                   4082:              case S_RENEWING:
                   4083:                /* While actively renewing, MRD is bounded by the time
                   4084:                 * we stop renewing and start rebinding.  This helps us
                   4085:                 * process the state change on time.
                   4086:                 */
                   4087:                client->MRD = rebind - cur_time;
                   4088:                if (rebind != MAX_TIME) {
                   4089:                        log_debug("PRC: Rebind event scheduled in %d seconds, "
                   4090:                                  "to run for %d seconds.",
                   4091:                                  (int)(rebind - cur_time),
                   4092:                                  (int)(hi_expire - rebind));
                   4093:                        client->next_MRD = hi_expire;
                   4094:                        tv.tv_sec = rebind;
                   4095:                        tv.tv_usec = 0;
                   4096:                        add_timeout(&tv, start_rebind6, client, NULL, NULL);
                   4097:                }
                   4098:                break;
                   4099: 
                   4100:              case S_REBINDING:
                   4101:                /* For now, we rebind up until the last lease expires.  In
                   4102:                 * the future, we might want to start SOLICITing when we've
                   4103:                 * depreffed an address.
                   4104:                 */
                   4105:                client->MRD = hi_expire - cur_time;
                   4106:                break;
                   4107: 
                   4108:              default:
                   4109:                log_fatal("Impossible condition at %s:%d.", MDL);
                   4110:        }
                   4111: 
                   4112:        /* Separately, set a time at which we will depref and expire
                   4113:         * leases.  This might happen with multiple addresses while we
                   4114:         * keep trying to refresh.
                   4115:         */
                   4116:        if (depref != MAX_TIME) {
                   4117:                log_debug("PRC: Depreference scheduled in %d seconds.",
                   4118:                          (int)(depref - cur_time));
                   4119:                tv.tv_sec = depref;
                   4120:                tv.tv_usec = 0;
                   4121:                add_timeout(&tv, do_depref, client, NULL, NULL);
                   4122:        }
                   4123:        if (lo_expire != MAX_TIME) {
                   4124:                log_debug("PRC: Expiration scheduled in %d seconds.",
                   4125:                          (int)(lo_expire - cur_time));
                   4126:                tv.tv_sec = lo_expire;
                   4127:                tv.tv_usec = 0;
                   4128:                add_timeout(&tv, do_expire, client, NULL, NULL);
                   4129:        }
                   4130: }
                   4131: 
                   4132: /* In a given IA chain, find the IA with the same type and 'iaid'. */
                   4133: static struct dhc6_ia *
                   4134: find_ia(struct dhc6_ia *head, u_int16_t type, const char *id)
                   4135: {
                   4136:        struct dhc6_ia *ia;
                   4137: 
                   4138:        for (ia = head ; ia != NULL ; ia = ia->next) {
                   4139:                if (ia->ia_type != type)
                   4140:                        continue;
                   4141:                if (memcmp(ia->iaid, id, 4) == 0)
                   4142:                        return ia;
                   4143:        }
                   4144: 
                   4145:        return NULL;
                   4146: }
                   4147: 
                   4148: /* In a given address chain, find a matching address. */
                   4149: static struct dhc6_addr *
                   4150: find_addr(struct dhc6_addr *head, struct iaddr *address)
                   4151: {
                   4152:        struct dhc6_addr *addr;
                   4153: 
                   4154:        for (addr = head ; addr != NULL ; addr = addr->next) {
                   4155:                if ((addr->address.len == address->len) &&
                   4156:                    (memcmp(addr->address.iabuf, address->iabuf,
                   4157:                            address->len) == 0))
                   4158:                        return addr;
                   4159:        }
                   4160: 
                   4161:        return NULL;
                   4162: }
                   4163: 
                   4164: /* In a given prefix chain, find a matching prefix. */
                   4165: static struct dhc6_addr *
                   4166: find_pref(struct dhc6_addr *head, struct iaddr *prefix, u_int8_t plen)
                   4167: {
                   4168:        struct dhc6_addr *pref;
                   4169: 
                   4170:        for (pref = head ; pref != NULL ; pref = pref->next) {
                   4171:                if ((pref->address.len == prefix->len) &&
                   4172:                    (pref->plen == plen) &&
                   4173:                    (memcmp(pref->address.iabuf, prefix->iabuf,
                   4174:                            prefix->len) == 0))
                   4175:                        return pref;
                   4176:        }
                   4177: 
                   4178:        return NULL;
                   4179: }
                   4180: 
                   4181: /* Merge the bindings from the source lease into the destination lease
                   4182:  * structure, where they are missing.  We have to copy the stateful
                   4183:  * objects rather than move them over, because later code needs to be
                   4184:  * able to compare new versus old if they contain any bindings.
                   4185:  */
                   4186: static void
                   4187: dhc6_merge_lease(struct dhc6_lease *src, struct dhc6_lease *dst)
                   4188: {
                   4189:        struct dhc6_ia *sia, *dia, *tia;
                   4190:        struct dhc6_addr *saddr, *daddr, *taddr;
                   4191:        int changes = 0;
                   4192: 
                   4193:        if ((dst == NULL) || (src == NULL))
                   4194:                return;
                   4195: 
                   4196:        for (sia = src->bindings ; sia != NULL ; sia = sia->next) {
                   4197:                dia = find_ia(dst->bindings, sia->ia_type, (char *)sia->iaid);
                   4198: 
                   4199:                if (dia == NULL) {
                   4200:                        tia = dhc6_dup_ia(sia, MDL);
                   4201: 
                   4202:                        if (tia == NULL)
                   4203:                                log_fatal("Out of memory merging lease - "
                   4204:                                          "Unable to continue without losing "
                   4205:                                          "state! (%s:%d)", MDL);
                   4206: 
                   4207:                        /* XXX: consider sorting? */
                   4208:                        tia->next = dst->bindings;
                   4209:                        dst->bindings = tia;
                   4210:                        changes = 1;
                   4211:                } else {
                   4212:                        for (saddr = sia->addrs ; saddr != NULL ;
                   4213:                             saddr = saddr->next) {
                   4214:                                if (sia->ia_type != D6O_IA_PD)
                   4215:                                        daddr = find_addr(dia->addrs,
                   4216:                                                          &saddr->address);
                   4217:                                else
                   4218:                                        daddr = find_pref(dia->addrs,
                   4219:                                                          &saddr->address,
                   4220:                                                          saddr->plen);
                   4221: 
                   4222:                                if (daddr == NULL) {
                   4223:                                        taddr = dhc6_dup_addr(saddr, MDL);
                   4224: 
                   4225:                                        if (taddr == NULL)
                   4226:                                                log_fatal("Out of memory "
                   4227:                                                          "merging lease - "
                   4228:                                                          "Unable to continue "
                   4229:                                                          "without losing "
                   4230:                                                          "state! (%s:%d)",
                   4231:                                                          MDL);
                   4232: 
                   4233:                                        /* XXX: consider sorting? */
                   4234:                                        taddr->next = dia->addrs;
                   4235:                                        dia->addrs = taddr;
                   4236:                                        changes = 1;
                   4237:                                }
                   4238:                        }
                   4239:                }
                   4240:        }
                   4241: 
                   4242:        /* If we made changes, reset the score to 0 so it is recalculated. */
                   4243:        if (changes)
                   4244:                dst->score = 0;
                   4245: }
                   4246: 
                   4247: /* We've either finished selecting or succeeded in Renew or Rebinding our
                   4248:  * lease.  In all cases we got a Reply.  Give dhclient-script a tickle
                   4249:  * to inform it about the new values, and then lay in wait for the next
                   4250:  * event.
                   4251:  */
                   4252: static void
                   4253: start_bound(struct client_state *client)
                   4254: {
                   4255:        struct dhc6_ia *ia, *oldia;
                   4256:        struct dhc6_addr *addr, *oldaddr;
                   4257:        struct dhc6_lease *lease, *old;
                   4258:        const char *reason;
                   4259:        TIME dns_update_offset = 1;
                   4260: 
                   4261:        lease = client->active_lease;
                   4262:        if (lease == NULL) {
                   4263:                log_error("Cannot enter bound state unless an active lease "
                   4264:                          "is selected.");
                   4265:                return;
                   4266:        }
                   4267:        lease->released = ISC_FALSE;
                   4268:        old = client->old_lease;
                   4269: 
                   4270:        client->v6_handler = bound_handler;
                   4271: 
                   4272:        switch (client->state) {
                   4273:              case S_SELECTING:
                   4274:              case S_REBOOTING: /* Pretend we got bound. */
                   4275:                reason = "BOUND6";
                   4276:                break;
                   4277: 
                   4278:              case S_RENEWING:
                   4279:                reason = "RENEW6";
                   4280:                break;
                   4281: 
                   4282:              case S_REBINDING:
                   4283:                reason = "REBIND6";
                   4284:                break;
                   4285: 
                   4286:              default:
                   4287:                log_fatal("Impossible condition at %s:%d.", MDL);
                   4288:                /* Silence compiler warnings. */
                   4289:                return;
                   4290:        }
                   4291: 
                   4292:        log_debug("PRC: Bound to lease %s.",
                   4293:                  print_hex_1(client->active_lease->server_id.len,
                   4294:                              client->active_lease->server_id.data, 55));
                   4295:        client->state = S_BOUND;
                   4296: 
                   4297:        write_client6_lease(client, lease, 0, 1);
                   4298: 
                   4299:        oldia = NULL;
                   4300:        for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
                   4301:                if (old != NULL)
                   4302:                        oldia = find_ia(old->bindings,
                   4303:                                        ia->ia_type,
                   4304:                                        (char *)ia->iaid);
                   4305:                else
                   4306:                        oldia = NULL;
                   4307: 
                   4308:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   4309:                        if (oldia != NULL) {
                   4310:                                if (ia->ia_type != D6O_IA_PD)
                   4311:                                        oldaddr = find_addr(oldia->addrs,
                   4312:                                                            &addr->address);
                   4313:                                else
                   4314:                                        oldaddr = find_pref(oldia->addrs,
                   4315:                                                            &addr->address,
                   4316:                                                            addr->plen);
                   4317:                        } else
                   4318:                                oldaddr = NULL;
                   4319: 
                   4320:                        if ((oldaddr == NULL) && (ia->ia_type == D6O_IA_NA))
                   4321:                                dhclient_schedule_updates(client,
                   4322:                                                          &addr->address,
                   4323:                                                          dns_update_offset++);
                   4324: 
                   4325:                        /* Shell out to setup the new binding. */
                   4326:                        script_init(client, reason, NULL);
                   4327: 
                   4328:                        if (old != NULL)
                   4329:                                dhc6_marshall_values("old_", client, old,
                   4330:                                                     oldia, oldaddr);
                   4331:                        dhc6_marshall_values("new_", client, lease, ia, addr);
                   4332: 
                   4333:                        script_go(client);
                   4334:                }
                   4335: 
                   4336:                /* XXX: maybe we should loop on the old values instead? */
                   4337:                if (ia->addrs == NULL) {
                   4338:                        script_init(client, reason, NULL);
                   4339: 
                   4340:                        if (old != NULL)
                   4341:                                dhc6_marshall_values("old_", client, old,
                   4342:                                                     oldia,
                   4343:                                                     oldia != NULL ?
                   4344:                                                         oldia->addrs : NULL);
                   4345: 
                   4346:                        dhc6_marshall_values("new_", client, lease, ia,
                   4347:                                             NULL);
                   4348: 
                   4349:                        script_go(client);
                   4350:                }
                   4351:        }
                   4352: 
                   4353:        /* XXX: maybe we should loop on the old values instead? */
                   4354:        if (lease->bindings == NULL) {
                   4355:                script_init(client, reason, NULL);
                   4356: 
                   4357:                if (old != NULL)
                   4358:                        dhc6_marshall_values("old_", client, old,
                   4359:                                             old->bindings,
                   4360:                                             (old->bindings != NULL) ?
                   4361:                                                old->bindings->addrs : NULL);
                   4362: 
                   4363:                dhc6_marshall_values("new_", client, lease, NULL, NULL);
                   4364: 
                   4365:                script_go(client);
                   4366:        }
                   4367: 
                   4368:        go_daemon();
                   4369: 
                   4370:        if (client->old_lease != NULL) {
                   4371:                dhc6_lease_destroy(&client->old_lease, MDL);
                   4372:                client->old_lease = NULL;
                   4373:        }
                   4374: 
                   4375:        /* Schedule events. */
                   4376:        dhc6_check_times(client);
                   4377: }
                   4378: 
                   4379: /* While bound, ignore packets.  In the future we'll want to answer
                   4380:  * Reconfigure-Request messages and the like.
                   4381:  */
                   4382: void
                   4383: bound_handler(struct packet *packet, struct client_state *client)
                   4384: {
                   4385:        log_debug("RCV: Input packets are ignored once bound.");
                   4386: }
                   4387: 
                   4388: /* start_renew6() gets us all ready to go to start transmitting Renew packets.
                   4389:  * Note that client->next_MRD must be set before entering this function -
                   4390:  * it must be set to the time at which the client should start Rebinding.
                   4391:  */
                   4392: void
                   4393: start_renew6(void *input)
                   4394: {
                   4395:        struct client_state *client;
                   4396: 
                   4397:        client = (struct client_state *)input;
                   4398: 
                   4399:        log_info("PRC: Renewing lease on %s.",
                   4400:                 client->name ? client->name : client->interface->name);
                   4401:        client->state = S_RENEWING;
                   4402: 
                   4403:        client->v6_handler = reply_handler;
                   4404: 
                   4405:        /* Times per RFC3315 section 18.1.3. */
                   4406:        client->IRT = REN_TIMEOUT * 100;
                   4407:        client->MRT = REN_MAX_RT * 100;
                   4408:        client->MRC = 0;
                   4409:        /* MRD is special in renew - we need to set it by checking timer
                   4410:         * state.
                   4411:         */
                   4412:        client->MRD = client->next_MRD - cur_time;
                   4413: 
                   4414:        dhc6_retrans_init(client);
                   4415: 
                   4416:        client->refresh_type = DHCPV6_RENEW;
                   4417:        do_refresh6(client);
                   4418: }
                   4419: 
                   4420: /* do_refresh6() transmits one DHCPv6 packet, be it a Renew or Rebind, and
                   4421:  * gives the retransmission state a bump for the next time.  Note that
                   4422:  * client->refresh_type must be set before entering this function.
                   4423:  */
                   4424: void
                   4425: do_refresh6(void *input)
                   4426: {
                   4427:        struct option_cache *oc;
                   4428:        struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
                   4429:        struct data_string ds;
                   4430:        struct client_state *client;
                   4431:        struct dhc6_lease *lease;
                   4432:        struct timeval elapsed, tv;
                   4433:        int send_ret;
                   4434: 
                   4435:        client = (struct client_state *)input;
                   4436:        memset(&ds, 0, sizeof(ds));
                   4437: 
                   4438:        lease = client->active_lease;
                   4439:        if (lease == NULL) {
                   4440:                log_error("Cannot renew without an active binding.");
                   4441:                return;
                   4442:        }
                   4443: 
                   4444:        /* Ensure we're emitting a valid message type. */
                   4445:        switch (client->refresh_type) {
                   4446:              case DHCPV6_RENEW:
                   4447:              case DHCPV6_REBIND:
                   4448:                break;
                   4449: 
                   4450:              default:
                   4451:                log_fatal("Internal inconsistency (%d) at %s:%d.",
                   4452:                          client->refresh_type, MDL);
                   4453:        }
                   4454: 
                   4455:        /*
                   4456:         * Start_time starts at the first transmission.
                   4457:         */
                   4458:        if (client->txcount == 0) {
                   4459:                client->start_time.tv_sec = cur_tv.tv_sec;
                   4460:                client->start_time.tv_usec = cur_tv.tv_usec;
                   4461:        }
                   4462: 
                   4463:        /* elapsed = cur - start */
                   4464:        elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
                   4465:        elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
                   4466:        if (elapsed.tv_usec < 0) {
                   4467:                elapsed.tv_sec -= 1;
                   4468:                elapsed.tv_usec += 1000000;
                   4469:        }
                   4470:        if (((client->MRC != 0) && (client->txcount > client->MRC)) ||
                   4471:            ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD))) {
                   4472:                /* We're done.  Move on to the next phase, if any. */
                   4473:                dhc6_check_times(client);
                   4474:                return;
                   4475:        }
                   4476: 
                   4477:        /*
                   4478:         * Check whether the server has sent a unicast option; if so, we can
                   4479:         * use the address it specified for RENEWs.
                   4480:         */
                   4481:        oc = lookup_option(&dhcpv6_universe, lease->options, D6O_UNICAST);
                   4482:        if (oc && evaluate_option_cache(&ds, NULL, NULL, NULL,
                   4483:                                        lease->options, NULL, &global_scope,
                   4484:                                        oc, MDL)) {
                   4485:                if (ds.len < 16) {
                   4486:                        log_error("Invalid unicast option length %d.", ds.len);
                   4487:                } else {
                   4488:                        memset(&unicast, 0, sizeof(DHCPv6DestAddr));
                   4489:                        unicast.sin6_family = AF_INET6;
                   4490:                        unicast.sin6_port = remote_port;
                   4491:                        memcpy(&unicast.sin6_addr, ds.data, 16);
                   4492:                        if (client->refresh_type == DHCPV6_RENEW) {
                   4493:                                dest_addr = &unicast;
                   4494:                        }
                   4495:                }
                   4496: 
                   4497:                data_string_forget(&ds, MDL);
                   4498:        }
                   4499: 
                   4500:        /* Commence forming a renew packet. */
                   4501:        memset(&ds, 0, sizeof(ds));
                   4502:        if (!buffer_allocate(&ds.buffer, 4, MDL)) {
                   4503:                log_error("Unable to allocate memory for packet.");
                   4504:                return;
                   4505:        }
                   4506:        ds.data = ds.buffer->data;
                   4507:        ds.len = 4;
                   4508: 
                   4509:        ds.buffer->data[0] = client->refresh_type;
                   4510:        memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
                   4511: 
                   4512:        /* Form an elapsed option. */
                   4513:        /* Maximum value is 65535 1/100s coded as 0xffff. */
                   4514:        if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
                   4515:            ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
                   4516:                client->elapsed = 0xffff;
                   4517:        } else {
                   4518:                client->elapsed = elapsed.tv_sec * 100;
                   4519:                client->elapsed += elapsed.tv_usec / 10000;
                   4520:        }
                   4521: 
                   4522:        if (client->elapsed == 0)
                   4523:                log_debug("XMT: Forming %s, 0 ms elapsed.",
                   4524:                          dhcpv6_type_names[client->refresh_type]);
                   4525:        else
                   4526:                log_debug("XMT: Forming %s, %u0 ms elapsed.",
                   4527:                          dhcpv6_type_names[client->refresh_type],
                   4528:                          (unsigned)client->elapsed);
                   4529: 
                   4530:        client->elapsed = htons(client->elapsed);
                   4531: 
                   4532:        make_client6_options(client, &client->sent_options, lease,
                   4533:                             client->refresh_type);
                   4534: 
                   4535:        /* Put in any options from the sent cache. */
                   4536:        dhcpv6_universe.encapsulate(&ds, NULL, NULL, client, NULL,
                   4537:                                    client->sent_options, &global_scope,
                   4538:                                    &dhcpv6_universe);
                   4539: 
                   4540:        /* Append IA's */
                   4541:        if (wanted_ia_na &&
                   4542:            dhc6_add_ia_na(client, &ds, lease,
                   4543:                           client->refresh_type) != ISC_R_SUCCESS) {
                   4544:                data_string_forget(&ds, MDL);
                   4545:                return;
                   4546:        }
                   4547:        if (wanted_ia_pd &&
                   4548:            dhc6_add_ia_pd(client, &ds, lease,
                   4549:                           client->refresh_type) != ISC_R_SUCCESS) {
                   4550:                data_string_forget(&ds, MDL);
                   4551:                return;
                   4552:        }
                   4553: 
                   4554:        log_info("XMT: %s on %s, interval %ld0ms.",
                   4555:                 dhcpv6_type_names[client->refresh_type],
                   4556:                 client->name ? client->name : client->interface->name,
                   4557:                 (long int)client->RT);
                   4558: 
                   4559:        send_ret = send_packet6(client->interface, ds.data, ds.len, dest_addr);
                   4560: 
                   4561:        if (send_ret != ds.len) {
                   4562:                log_error("dhc6: send_packet6() sent %d of %d bytes",
                   4563:                          send_ret, ds.len);
                   4564:        }
                   4565: 
                   4566:        data_string_forget(&ds, MDL);
                   4567: 
                   4568:        /* Wait RT */
                   4569:        tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
                   4570:        tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
                   4571:        if (tv.tv_usec >= 1000000) {
                   4572:                tv.tv_sec += 1;
                   4573:                tv.tv_usec -= 1000000;
                   4574:        }
                   4575:        add_timeout(&tv, do_refresh6, client, NULL, NULL);
                   4576: 
                   4577:        dhc6_retrans_advance(client);
                   4578: }
                   4579: 
                   4580: /* start_rebind6() gets us all set up to go and rebind a lease.  Note that
                   4581:  * client->next_MRD must be set before entering this function.  In this case,
                   4582:  * MRD must be set to the maximum time any address in the packet will
                   4583:  * expire.
                   4584:  */
                   4585: void
                   4586: start_rebind6(void *input)
                   4587: {
                   4588:        struct client_state *client;
                   4589: 
                   4590:        client = (struct client_state *)input;
                   4591: 
                   4592:        log_info("PRC: Rebinding lease on %s.",
                   4593:                 client->name ? client->name : client->interface->name);
                   4594:        client->state = S_REBINDING;
                   4595: 
                   4596:        client->v6_handler = reply_handler;
                   4597: 
                   4598:        /* Times per RFC3315 section 18.1.4. */
                   4599:        client->IRT = REB_TIMEOUT * 100;
                   4600:        client->MRT = REB_MAX_RT * 100;
                   4601:        client->MRC = 0;
                   4602:        /* MRD is special in rebind - it's determined by the timer
                   4603:         * state.
                   4604:         */
                   4605:        client->MRD = client->next_MRD - cur_time;
                   4606: 
                   4607:        dhc6_retrans_init(client);
                   4608: 
                   4609:        client->refresh_type = DHCPV6_REBIND;
                   4610:        do_refresh6(client);
                   4611: }
                   4612: 
                   4613: /* do_depref() runs through a given lease's addresses, for each that has
                   4614:  * not yet been depreffed, shells out to the dhclient-script to inform it
                   4615:  * of the status change.  The dhclient-script should then do...something...
                   4616:  * to encourage applications to move off the address and onto one of the
                   4617:  * remaining 'preferred' addresses.
                   4618:  */
                   4619: void
                   4620: do_depref(void *input)
                   4621: {
                   4622:        struct client_state *client;
                   4623:        struct dhc6_lease *lease;
                   4624:        struct dhc6_ia *ia;
                   4625:        struct dhc6_addr *addr;
                   4626: 
                   4627:        client = (struct client_state *)input;
                   4628: 
                   4629:        lease = client->active_lease;
                   4630:        if (lease == NULL)
                   4631:                return;
                   4632: 
                   4633:        for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
                   4634:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   4635:                        if (addr->flags & DHC6_ADDR_DEPREFFED)
                   4636:                                continue;
                   4637: 
                   4638:                        if (addr->starts + addr->preferred_life <= cur_time) {
                   4639:                                script_init(client, "DEPREF6", NULL);
                   4640:                                dhc6_marshall_values("cur_", client, lease,
                   4641:                                                     ia, addr);
                   4642:                                script_go(client);
                   4643: 
                   4644:                                addr->flags |= DHC6_ADDR_DEPREFFED;
                   4645: 
                   4646:                                if (ia->ia_type != D6O_IA_PD)
                   4647:                                    log_info("PRC: Address %s depreferred.",
                   4648:                                             piaddr(addr->address));
                   4649:                                else
                   4650:                                    log_info("PRC: Prefix %s/%u depreferred.",
                   4651:                                             piaddr(addr->address),
                   4652:                                             (unsigned) addr->plen);
                   4653: 
                   4654:                                /* Remove DDNS bindings at depref time. */
                   4655:                                if ((ia->ia_type == D6O_IA_NA) &&
                   4656:                                    client->config->do_forward_update)
                   4657:                                        client_dns_update(client, 0, 0,
                   4658:                                                          &addr->address);
                   4659:                        }
                   4660:                }
                   4661:        }
                   4662: 
                   4663:        dhc6_check_times(client);
                   4664: }
                   4665: 
                   4666: /* do_expire() searches through all the addresses on a given lease, and
                   4667:  * expires/removes any addresses that are no longer valid.
                   4668:  */
                   4669: void
                   4670: do_expire(void *input)
                   4671: {
                   4672:        struct client_state *client;
                   4673:        struct dhc6_lease *lease;
                   4674:        struct dhc6_ia *ia;
                   4675:        struct dhc6_addr *addr;
                   4676:        int has_addrs = ISC_FALSE;
                   4677: 
                   4678:        client = (struct client_state *)input;
                   4679: 
                   4680:        lease = client->active_lease;
                   4681:        if (lease == NULL)
                   4682:                return;
                   4683: 
                   4684:        for (ia = lease->bindings ; ia != NULL ; ia = ia->next) {
                   4685:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   4686:                        if (addr->flags & DHC6_ADDR_EXPIRED)
                   4687:                                continue;
                   4688: 
                   4689:                        if (addr->starts + addr->max_life <= cur_time) {
                   4690:                                script_init(client, "EXPIRE6", NULL);
                   4691:                                dhc6_marshall_values("old_", client, lease,
                   4692:                                                     ia, addr);
                   4693:                                script_go(client);
                   4694: 
                   4695:                                addr->flags |= DHC6_ADDR_EXPIRED;
                   4696: 
                   4697:                                if (ia->ia_type != D6O_IA_PD)
                   4698:                                    log_info("PRC: Address %s expired.",
                   4699:                                             piaddr(addr->address));
                   4700:                                else
                   4701:                                    log_info("PRC: Prefix %s/%u expired.",
                   4702:                                             piaddr(addr->address),
                   4703:                                             (unsigned) addr->plen);
                   4704: 
                   4705:                                /* We remove DNS records at depref time, but
                   4706:                                 * it is possible that we might get here
                   4707:                                 * without depreffing.
                   4708:                                 */
                   4709:                                if ((ia->ia_type == D6O_IA_NA) &&
                   4710:                                    client->config->do_forward_update &&
                   4711:                                    !(addr->flags & DHC6_ADDR_DEPREFFED))
                   4712:                                        client_dns_update(client, 0, 0,
                   4713:                                                          &addr->address);
                   4714: 
                   4715:                                continue;
                   4716:                        }
                   4717: 
                   4718:                        has_addrs = ISC_TRUE;
                   4719:                }
                   4720:        }
                   4721: 
                   4722:        /* Clean up empty leases. */
                   4723:        if (has_addrs == ISC_FALSE) {
                   4724:                log_info("PRC: Bound lease is devoid of active addresses."
                   4725:                         "  Re-initializing.");
                   4726: 
                   4727:                dhc6_lease_destroy(&lease, MDL);
                   4728:                client->active_lease = NULL;
                   4729: 
                   4730:                start_init6(client);
                   4731:                return;
                   4732:        }
                   4733: 
                   4734:        /* Schedule the next run through. */
                   4735:        dhc6_check_times(client);
                   4736: }
                   4737: 
                   4738: /*
                   4739:  * Run client script to unconfigure interface.
                   4740:  * Called with reason STOP6 when dhclient -x is run, or with reason
                   4741:  * RELEASE6 when server has replied to a Release message.
                   4742:  * Stateless is a special case.
                   4743:  */
                   4744: void
                   4745: unconfigure6(struct client_state *client, const char *reason)
                   4746: {
                   4747:        struct dhc6_ia *ia;
                   4748:        struct dhc6_addr *addr;
                   4749: 
                   4750:        if (stateless) {
                   4751:                script_init(client, reason, NULL);
                   4752:                if (client->active_lease != NULL)
                   4753:                        script_write_params6(client, "old_",
                   4754:                                             client->active_lease->options);
                   4755:                script_go(client);
                   4756:                return;
                   4757:        }
                   4758: 
                   4759:        if (client->active_lease == NULL)
                   4760:                return;
                   4761: 
                   4762:        for (ia = client->active_lease->bindings ; ia != NULL ; ia = ia->next) {
                   4763:                if (ia->ia_type == D6O_IA_TA)
                   4764:                        continue;
                   4765: 
                   4766:                for (addr = ia->addrs ; addr != NULL ; addr = addr->next) {
                   4767:                        script_init(client, reason, NULL);
                   4768:                        dhc6_marshall_values("old_", client,
                   4769:                                             client->active_lease, ia, addr);
                   4770:                        script_go(client);
                   4771: 
                   4772:                        if ((ia->ia_type == D6O_IA_NA) &&
                   4773:                            client->config->do_forward_update)
                   4774:                                client_dns_update(client, 0, 0, &addr->address);
                   4775:                }
                   4776:        }
                   4777: }
                   4778: 
                   4779: void
                   4780: refresh_info_request6(void *input)
                   4781: {
                   4782:        struct client_state *client;
                   4783: 
                   4784:        client = (struct client_state *)input;
                   4785:        start_info_request6(client);
                   4786: }
                   4787: 
                   4788: /* Timeout for Information-Request (using the IRT option).
                   4789:  */
                   4790: static void
                   4791: dhc6_check_irt(struct client_state *client)
                   4792: {
                   4793:        struct option **req;
                   4794:        struct option_cache *oc;
                   4795:        TIME expire = MAX_TIME;
                   4796:        struct timeval tv;
                   4797:        int i;
                   4798:        isc_boolean_t found = ISC_FALSE;
                   4799: 
                   4800:        cancel_timeout(refresh_info_request6, client);
                   4801: 
                   4802:        req = client->config->requested_options;
                   4803:        for (i = 0; req[i] != NULL; i++) {
                   4804:                if (req[i] == irt_option) {
                   4805:                        found = ISC_TRUE;
                   4806:                        break;
                   4807:                }
                   4808:        }
                   4809:        /* Simply return gives a endless loop waiting for nothing. */
                   4810:        if (!found)
                   4811:                exit(0);
                   4812: 
                   4813:        oc = lookup_option(&dhcpv6_universe, client->active_lease->options,
                   4814:                           D6O_INFORMATION_REFRESH_TIME);
                   4815:        if (oc != NULL) {
                   4816:                struct data_string irt;
                   4817: 
                   4818:                memset(&irt, 0, sizeof(irt));
                   4819:                if (!evaluate_option_cache(&irt, NULL, NULL, client,
                   4820:                                           client->active_lease->options,
                   4821:                                           NULL, &global_scope, oc, MDL) ||
                   4822:                    (irt.len < 4)) {
                   4823:                        log_error("Can't evaluate IRT.");
                   4824:                } else {
                   4825:                        expire = getULong(irt.data);
                   4826:                        if (expire < IRT_MINIMUM)
                   4827:                                expire = IRT_MINIMUM;
                   4828:                        if (expire == 0xffffffff)
                   4829:                                expire = MAX_TIME;
                   4830:                }
                   4831:                data_string_forget(&irt, MDL);
                   4832:        } else
                   4833:                expire = IRT_DEFAULT;
                   4834: 
                   4835:        if (expire != MAX_TIME) {
                   4836:                log_debug("PRC: Refresh event scheduled in %u seconds.",
                   4837:                          (unsigned) expire);
                   4838:                tv.tv_sec = cur_time + expire;
                   4839:                tv.tv_usec = 0;
                   4840:                add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
                   4841:        }
                   4842: }
                   4843: 
                   4844: /* We got a Reply. Give dhclient-script a tickle to inform it about
                   4845:  * the new values, and then lay in wait for the next event.
                   4846:  */
                   4847: static void
                   4848: start_informed(struct client_state *client)
                   4849: {
                   4850:        client->v6_handler = informed_handler;
                   4851: 
                   4852:        log_debug("PRC: Done.");
                   4853: 
                   4854:        client->state = S_BOUND;
                   4855: 
                   4856:        script_init(client, "RENEW6", NULL);
                   4857:        if (client->old_lease != NULL)
                   4858:                script_write_params6(client, "old_",
                   4859:                                     client->old_lease->options);
                   4860:        script_write_params6(client, "new_", client->active_lease->options);
                   4861:        script_go(client);
                   4862: 
                   4863:        go_daemon();
                   4864: 
                   4865:        if (client->old_lease != NULL) {
                   4866:                dhc6_lease_destroy(&client->old_lease, MDL);
                   4867:                client->old_lease = NULL;
                   4868:        }
                   4869: 
                   4870:        /* Schedule events. */
                   4871:        dhc6_check_irt(client);
                   4872: }
                   4873: 
                   4874: /* While informed, ignore packets.
                   4875:  */
                   4876: void
                   4877: informed_handler(struct packet *packet, struct client_state *client)
                   4878: {
                   4879:        log_debug("RCV: Input packets are ignored once bound.");
                   4880: }
                   4881: 
                   4882: /* make_client6_options() fetches option caches relevant to the client's
                   4883:  * scope and places them into the sent_options cache.  This cache is later
                   4884:  * used to populate DHCPv6 output packets with options.
                   4885:  */
                   4886: static void
                   4887: make_client6_options(struct client_state *client, struct option_state **op,
                   4888:                     struct dhc6_lease *lease, u_int8_t message)
                   4889: {
                   4890:        struct option_cache *oc;
                   4891:        struct option **req;
                   4892:        struct buffer *buffer;
                   4893:        int buflen, i, oro_len;
                   4894: 
                   4895:        if ((op == NULL) || (client == NULL))
                   4896:                return;
                   4897: 
                   4898:        if (*op)
                   4899:                option_state_dereference(op, MDL);
                   4900: 
                   4901:        /* Create a cache to carry options to transmission. */
                   4902:        option_state_allocate(op, MDL);
                   4903: 
                   4904:        /* Create and store an 'elapsed time' option in the cache. */
                   4905:        oc = NULL;
                   4906:        if (option_cache_allocate(&oc, MDL)) {
                   4907:                const unsigned char *cdata;
                   4908: 
                   4909:                cdata = (unsigned char *)&client->elapsed;
                   4910: 
                   4911:                if (make_const_data(&oc->expression, cdata, 2, 0, 0, MDL)) {
                   4912:                        option_reference(&oc->option, elapsed_option, MDL);
                   4913:                        save_option(&dhcpv6_universe, *op, oc);
                   4914:                }
                   4915: 
                   4916:                option_cache_dereference(&oc, MDL);
                   4917:        }
                   4918: 
                   4919:        /* Bring in any configured options to send. */
                   4920:        if (client->config->on_transmission)
                   4921:                execute_statements_in_scope(NULL, NULL, NULL, client,
                   4922:                                            lease ? lease->options : NULL,
                   4923:                                            *op, &global_scope,
                   4924:                                            client->config->on_transmission,
                   4925:                                            NULL);
                   4926: 
                   4927:        /* Rapid-commit is only for SOLICITs. */
                   4928:        if (message != DHCPV6_SOLICIT)
                   4929:                delete_option(&dhcpv6_universe, *op, D6O_RAPID_COMMIT);
                   4930: 
                   4931:        /* See if the user configured a DUID in a relevant scope.  If not,
                   4932:         * introduce our default manufactured id.
                   4933:         */
                   4934:        if ((oc = lookup_option(&dhcpv6_universe, *op,
                   4935:                                D6O_CLIENTID)) == NULL) {
                   4936:                if (!option_cache(&oc, &default_duid, NULL, clientid_option,
                   4937:                                  MDL))
                   4938:                        log_fatal("Failure assembling a DUID.");
                   4939: 
                   4940:                save_option(&dhcpv6_universe, *op, oc);
                   4941:                option_cache_dereference(&oc, MDL);
                   4942:        }
                   4943: 
                   4944:        /* In cases where we're responding to a single server, put the
                   4945:         * server's id in the response.
                   4946:         *
                   4947:         * Note that lease is NULL for SOLICIT or INFO request messages,
                   4948:         * and otherwise MUST be present.
                   4949:         */
                   4950:        if (lease == NULL) {
                   4951:                if ((message != DHCPV6_SOLICIT) &&
                   4952:                    (message != DHCPV6_INFORMATION_REQUEST))
                   4953:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   4954:        } else if ((message != DHCPV6_REBIND) &&
                   4955:                   (message != DHCPV6_CONFIRM)) {
                   4956:                oc = lookup_option(&dhcpv6_universe, lease->options,
                   4957:                                   D6O_SERVERID);
                   4958:                if (oc != NULL)
                   4959:                        save_option(&dhcpv6_universe, *op, oc);
                   4960:        }
                   4961: 
                   4962:        /* 'send dhcp6.oro foo;' syntax we used in 4.0.0a1/a2 has been
                   4963:         * deprecated by adjustments to the 'request' syntax also used for
                   4964:         * DHCPv4.
                   4965:         */
                   4966:        if (lookup_option(&dhcpv6_universe, *op, D6O_ORO) != NULL)
                   4967:                log_error("'send dhcp6.oro' syntax is deprecated, please "
                   4968:                          "use the 'request' syntax (\"man dhclient.conf\").");
                   4969: 
                   4970:        /* Construct and store an ORO (Option Request Option).  It is a
                   4971:         * fatal error to fail to send an ORO (of at least zero length).
                   4972:         *
                   4973:         * Discussion:  RFC3315 appears to be inconsistent in its statements
                   4974:         * of whether or not the ORO is mandatory.  In section 18.1.1
                   4975:         * ("Creation and Transmission of Request Messages"):
                   4976:         *
                   4977:         *    The client MUST include an Option Request option (see section
                   4978:         *    22.7) to indicate the options the client is interested in
                   4979:         *    receiving.  The client MAY include options with data values as
                   4980:         *    hints to the server about parameter values the client would like
                   4981:         *    to have returned.
                   4982:         *
                   4983:         * This MUST is missing from the creation/transmission of other
                   4984:         * messages (such as Renew and Rebind), and the section 22.7 ("Option
                   4985:         * Request Option" format and definition):
                   4986:         *
                   4987:         *    A client MAY include an Option Request option in a Solicit,
                   4988:         *    Request, Renew, Rebind, Confirm or Information-request message to
                   4989:         *    inform the server about options the client wants the server to
                   4990:         *    send to the client.  A server MAY include an Option Request
                   4991:         *    option in a Reconfigure option to indicate which options the
                   4992:         *    client should request from the server.
                   4993:         *
                   4994:         * seems to relax the requirement from MUST to MAY (and still other
                   4995:         * language in RFC3315 supports this).
                   4996:         *
                   4997:         * In lieu of a clarification of RFC3315, we will conform with the
                   4998:         * MUST.  Instead of an absent ORO, we will if there are no options
                   4999:         * to request supply an empty ORO.  Theoretically, an absent ORO is
                   5000:         * difficult to interpret (does the client want all options or no
                   5001:         * options?).  A zero-length ORO is intuitively clear: requesting
                   5002:         * nothing.
                   5003:         */
                   5004:        buffer = NULL;
                   5005:        oro_len = 0;
                   5006:        buflen = 32;
                   5007:        if (!buffer_allocate(&buffer, buflen, MDL))
                   5008:                log_fatal("Out of memory constructing DHCPv6 ORO.");
                   5009:        req = client->config->requested_options;
                   5010:        if (req != NULL) {
                   5011:                for (i = 0 ; req[i] != NULL ; i++) {
                   5012:                        if (buflen == oro_len) {
                   5013:                                struct buffer *tmpbuf = NULL;
                   5014: 
                   5015:                                buflen += 32;
                   5016: 
                   5017:                                /* Shell game. */
                   5018:                                buffer_reference(&tmpbuf, buffer, MDL);
                   5019:                                buffer_dereference(&buffer, MDL);
                   5020: 
                   5021:                                if (!buffer_allocate(&buffer, buflen, MDL))
                   5022:                                        log_fatal("Out of memory resizing "
                   5023:                                                  "DHCPv6 ORO buffer.");
                   5024: 
                   5025:                                memcpy(buffer->data, tmpbuf->data, oro_len);
                   5026: 
                   5027:                                buffer_dereference(&tmpbuf, MDL);
                   5028:                        }
                   5029: 
                   5030:                        if (req[i]->universe == &dhcpv6_universe) {
                   5031:                                /* Append the code to the ORO. */
                   5032:                                putUShort(buffer->data + oro_len,
                   5033:                                          req[i]->code);
                   5034:                                oro_len += 2;
                   5035:                        }
                   5036:                }
                   5037:        }
                   5038: 
                   5039:        oc = NULL;
                   5040:        if (make_const_option_cache(&oc, &buffer, NULL, oro_len,
                   5041:                                    oro_option, MDL)) {
                   5042:                save_option(&dhcpv6_universe, *op, oc);
                   5043:        } else {
                   5044:                log_fatal("Unable to create ORO option cache.");
                   5045:        }
                   5046: 
                   5047:        /*
                   5048:         * Note: make_const_option_cache() consumes the buffer, we do not
                   5049:         * need to dereference it (XXX).
                   5050:         */
                   5051:        option_cache_dereference(&oc, MDL);
                   5052: }
                   5053: 
                   5054: /* A clone of the DHCPv4 script_write_params() minus the DHCPv4-specific
                   5055:  * filename, server-name, etc specifics.
                   5056:  *
                   5057:  * Simply, store all values present in all universes of the option state
                   5058:  * (probably derived from a DHCPv6 packet) into environment variables
                   5059:  * named after the option names (and universe names) but with the 'prefix'
                   5060:  * prepended.
                   5061:  *
                   5062:  * Later, dhclient-script may compare for example "new_time_servers" and
                   5063:  * "old_time_servers" for differences, and only upon detecting a change
                   5064:  * bother to rewrite ntp.conf and restart it.  Or something along those
                   5065:  * generic lines.
                   5066:  */
                   5067: static void
                   5068: script_write_params6(struct client_state *client, const char *prefix,
                   5069:                     struct option_state *options)
                   5070: {
                   5071:        struct envadd_state es;
                   5072:        int i;
                   5073: 
                   5074:        if (options == NULL)
                   5075:                return;
                   5076: 
                   5077:        es.client = client;
                   5078:        es.prefix = prefix;
                   5079: 
                   5080:        for (i = 0 ; i < options->universe_count ; i++) {
                   5081:                option_space_foreach(NULL, NULL, client, NULL, options,
                   5082:                                     &global_scope, universes[i], &es,
                   5083:                                     client_option_envadd);
                   5084:        }
                   5085: }
                   5086: 
                   5087: /*
                   5088:  * Check if there is something not fully defined in the active lease.
                   5089:  */
                   5090: static isc_boolean_t
                   5091: active_prefix(struct client_state *client)
                   5092: {
                   5093:        struct dhc6_lease *lease;
                   5094:        struct dhc6_ia *ia;
                   5095:        struct dhc6_addr *pref;
                   5096:        char zeros[16];
                   5097: 
                   5098:        lease = client->active_lease;
                   5099:        if (lease == NULL)
                   5100:                return ISC_FALSE;
                   5101:        memset(zeros, 0, 16);
                   5102:        for (ia = lease->bindings; ia != NULL; ia = ia->next) {
                   5103:                if (ia->ia_type != D6O_IA_PD)
                   5104:                        continue;
                   5105:                for (pref = ia->addrs; pref != NULL; pref = pref->next) {
                   5106:                        if (pref->plen == 0)
                   5107:                                return ISC_FALSE;
                   5108:                        if (pref->address.len != 16)
                   5109:                                return ISC_FALSE;
                   5110:                        if (memcmp(pref->address.iabuf, zeros, 16) == 0)
                   5111:                                return ISC_FALSE;
                   5112:                }
                   5113:        }
                   5114:        return ISC_TRUE;
                   5115: }
                   5116: #endif /* DHCPv6 */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>