Annotation of embedaddon/dhcp/server/dhcpv6.c, revision 1.1.1.1

1.1       misho       1: /*
1.1.1.1 ! misho       2:  * Copyright (C) 2006-2012 by Internet Systems Consortium, Inc. ("ISC")
1.1       misho       3:  *
                      4:  * Permission to use, copy, modify, and distribute this software for any
                      5:  * purpose with or without fee is hereby granted, provided that the above
                      6:  * copyright notice and this permission notice appear in all copies.
                      7:  *
                      8:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
                      9:  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
                     10:  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
                     11:  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
                     12:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
                     13:  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
                     14:  * PERFORMANCE OF THIS SOFTWARE.
                     15:  */
                     16: 
                     17: #include "dhcpd.h"
                     18: 
                     19: #ifdef DHCPv6
                     20: 
                     21: /*
                     22:  * We use print_hex_1() to output DUID values. We could actually output 
                     23:  * the DUID with more information... MAC address if using type 1 or 3, 
                     24:  * and so on. However, RFC 3315 contains Grave Warnings against actually 
                     25:  * attempting to understand a DUID.
                     26:  */
                     27: 
                     28: /* 
                     29:  * TODO: gettext() or other method of localization for the messages
                     30:  *       for status codes (and probably for log formats eventually)
                     31:  * TODO: refactoring (simplify, simplify, simplify)
                     32:  * TODO: support multiple shared_networks on each interface (this 
                     33:  *       will allow the server to issue multiple IPv6 addresses to 
                     34:  *       a single interface)
                     35:  */
                     36: 
                     37: /*
                     38:  * DHCPv6 Reply workflow assist.  A Reply packet is built by various
                     39:  * different functions; this gives us one location where we keep state
                     40:  * regarding a reply.
                     41:  */
                     42: struct reply_state {
                     43:        /* root level persistent state */
                     44:        struct shared_network *shared;
                     45:        struct host_decl *host;
                     46:        struct subnet *subnet; /* Used to match fixed-addrs to subnet scopes. */
                     47:        struct option_state *opt_state;
                     48:        struct packet *packet;
                     49:        struct data_string client_id;
                     50: 
                     51:        /* IA level persistent state */
                     52:        unsigned ia_count;
                     53:        unsigned pd_count;
                     54:        unsigned client_resources;
                     55:        isc_boolean_t resources_included;
                     56:        isc_boolean_t static_lease;
                     57:        unsigned static_prefixes;
                     58:        struct ia_xx *ia;
                     59:        struct ia_xx *old_ia;
                     60:        struct option_state *reply_ia;
                     61:        struct data_string fixed;
                     62: 
                     63:        /* IAADDR/PREFIX level persistent state */
                     64:        struct iasubopt *lease;
                     65: 
                     66:        /*
                     67:         * "t1", "t2", preferred, and valid lifetimes records for calculating
                     68:         * t1 and t2 (min/max).
                     69:         */
                     70:        u_int32_t renew, rebind, prefer, valid;
                     71: 
                     72:        /* Client-requested valid and preferred lifetimes. */
                     73:        u_int32_t client_valid, client_prefer;
                     74: 
                     75:        /* Chosen values to transmit for valid and preferred lifetimes. */
                     76:        u_int32_t send_valid, send_prefer;
                     77: 
                     78:        /* Preferred prefix length (-1 is any). */
                     79:        int preflen;
                     80: 
                     81:        /* Index into the data field that has been consumed. */
                     82:        unsigned cursor;
                     83: 
                     84:        union reply_buffer {
                     85:                unsigned char data[65536];
                     86:                struct dhcpv6_packet reply;
                     87:        } buf;
                     88: };
                     89: 
                     90: /* 
                     91:  * Prototypes local to this file.
                     92:  */
                     93: static int get_encapsulated_IA_state(struct option_state **enc_opt_state,
                     94:                                     struct data_string *enc_opt_data,
                     95:                                     struct packet *packet,
                     96:                                     struct option_cache *oc,
                     97:                                     int offset);
                     98: static void build_dhcpv6_reply(struct data_string *, struct packet *);
                     99: static isc_result_t shared_network_from_packet6(struct shared_network **shared,
                    100:                                                struct packet *packet);
                    101: static void seek_shared_host(struct host_decl **hp,
                    102:                             struct shared_network *shared);
                    103: static isc_boolean_t fixed_matches_shared(struct host_decl *host,
                    104:                                          struct shared_network *shared);
                    105: static isc_result_t reply_process_ia_na(struct reply_state *reply,
                    106:                                        struct option_cache *ia);
                    107: static isc_result_t reply_process_ia_ta(struct reply_state *reply,
                    108:                                        struct option_cache *ia);
                    109: static isc_result_t reply_process_addr(struct reply_state *reply,
                    110:                                       struct option_cache *addr);
                    111: static isc_boolean_t address_is_owned(struct reply_state *reply,
                    112:                                      struct iaddr *addr);
                    113: static isc_boolean_t temporary_is_available(struct reply_state *reply,
                    114:                                            struct iaddr *addr);
                    115: static isc_result_t find_client_temporaries(struct reply_state *reply);
                    116: static isc_result_t reply_process_try_addr(struct reply_state *reply,
                    117:                                           struct iaddr *addr);
                    118: static isc_result_t find_client_address(struct reply_state *reply);
                    119: static isc_result_t reply_process_is_addressed(struct reply_state *reply,
                    120:                                               struct binding_scope **scope,
                    121:                                               struct group *group);
                    122: static isc_result_t reply_process_send_addr(struct reply_state *reply,
                    123:                                            struct iaddr *addr);
                    124: static struct iasubopt *lease_compare(struct iasubopt *alpha,
                    125:                                      struct iasubopt *beta);
                    126: static isc_result_t reply_process_ia_pd(struct reply_state *reply,
                    127:                                        struct option_cache *ia_pd);
                    128: static isc_result_t reply_process_prefix(struct reply_state *reply,
                    129:                                         struct option_cache *pref);
                    130: static isc_boolean_t prefix_is_owned(struct reply_state *reply,
                    131:                                     struct iaddrcidrnet *pref);
                    132: static isc_result_t find_client_prefix(struct reply_state *reply);
                    133: static isc_result_t reply_process_try_prefix(struct reply_state *reply,
                    134:                                             struct iaddrcidrnet *pref);
                    135: static isc_result_t reply_process_is_prefixed(struct reply_state *reply,
                    136:                                              struct binding_scope **scope,
                    137:                                              struct group *group);
                    138: static isc_result_t reply_process_send_prefix(struct reply_state *reply,
                    139:                                              struct iaddrcidrnet *pref);
                    140: static struct iasubopt *prefix_compare(struct reply_state *reply,
                    141:                                       struct iasubopt *alpha,
                    142:                                       struct iasubopt *beta);
                    143: 
                    144: /*
                    145:  * This function returns the time since DUID time start for the
                    146:  * given time_t value.
                    147:  */
                    148: static u_int32_t
                    149: duid_time(time_t when) {
                    150:        /*
                    151:         * This time is modulo 2^32.
                    152:         */
                    153:        while ((when - DUID_TIME_EPOCH) > 4294967295u) {
                    154:                /* use 2^31 to avoid spurious compiler warnings */
                    155:                when -= 2147483648u;
                    156:                when -= 2147483648u;
                    157:        }
                    158: 
                    159:        return when - DUID_TIME_EPOCH;
                    160: }
                    161: 
                    162: 
                    163: /* 
                    164:  * Server DUID.
                    165:  *
                    166:  * This must remain the same for the lifetime of this server, because
                    167:  * clients return the server DUID that we sent them in Request packets.
                    168:  *
                    169:  * We pick the server DUID like this:
                    170:  *
                    171:  * 1. Check dhcpd.conf - any value the administrator has configured 
                    172:  *    overrides any possible values.
                    173:  * 2. Check the leases.txt - we want to use the previous value if 
                    174:  *    possible.
                    175:  * 3. Check if dhcpd.conf specifies a type of server DUID to use,
                    176:  *    and generate that type.
                    177:  * 4. Generate a type 1 (time + hardware address) DUID.
                    178:  */
                    179: static struct data_string server_duid;
                    180: 
                    181: /*
                    182:  * Check if the server_duid has been set.
                    183:  */
                    184: isc_boolean_t
                    185: server_duid_isset(void) {
                    186:        return (server_duid.data != NULL);
                    187: }
                    188: 
                    189: /*
                    190:  * Return the server_duid.
                    191:  */
                    192: void
                    193: copy_server_duid(struct data_string *ds, const char *file, int line) {
                    194:        data_string_copy(ds, &server_duid, file, line);
                    195: }
                    196: 
                    197: /*
                    198:  * Set the server DUID to a specified value. This is used when
                    199:  * the server DUID is stored in persistent memory (basically the
                    200:  * leases.txt file).
                    201:  */
                    202: void
                    203: set_server_duid(struct data_string *new_duid) {
                    204:        /* INSIST(new_duid != NULL); */
                    205:        /* INSIST(new_duid->data != NULL); */
                    206: 
                    207:        if (server_duid_isset()) {
                    208:                data_string_forget(&server_duid, MDL);
                    209:        }
                    210:        data_string_copy(&server_duid, new_duid, MDL);
                    211: }
                    212: 
                    213: 
                    214: /*
                    215:  * Set the server DUID based on the D6O_SERVERID option. This handles
                    216:  * the case where the administrator explicitly put it in the dhcpd.conf 
                    217:  * file.
                    218:  */
                    219: isc_result_t
                    220: set_server_duid_from_option(void) {
                    221:        struct option_state *opt_state;
                    222:        struct option_cache *oc;
                    223:        struct data_string option_duid;
                    224:        isc_result_t ret_val;
                    225: 
                    226:        opt_state = NULL;
                    227:        if (!option_state_allocate(&opt_state, MDL)) {
                    228:                log_fatal("No memory for server DUID.");
                    229:        }
                    230: 
                    231:        execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
                    232:                                    opt_state, &global_scope, root_group, NULL);
                    233: 
                    234:        oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
                    235:        if (oc == NULL) {
                    236:                ret_val = ISC_R_NOTFOUND;
                    237:        } else {
                    238:                memset(&option_duid, 0, sizeof(option_duid));
                    239:                if (!evaluate_option_cache(&option_duid, NULL, NULL, NULL,
                    240:                                           opt_state, NULL, &global_scope,
                    241:                                           oc, MDL)) {
                    242:                        ret_val = ISC_R_UNEXPECTED;
                    243:                } else {
                    244:                        set_server_duid(&option_duid);
                    245:                        data_string_forget(&option_duid, MDL);
                    246:                        ret_val = ISC_R_SUCCESS;
                    247:                }
                    248:        }
                    249: 
                    250:        option_state_dereference(&opt_state, MDL);
                    251: 
                    252:        return ret_val;
                    253: }
                    254: 
                    255: /*
                    256:  * DUID layout, as defined in RFC 3315, section 9.
                    257:  * 
                    258:  * We support type 1 (hardware address plus time) and type 3 (hardware
                    259:  * address).
                    260:  *
                    261:  * We can support type 2 for specific vendors in the future, if they 
                    262:  * publish the specification. And of course there may be additional
                    263:  * types later.
                    264:  */
                    265: static int server_duid_type = DUID_LLT;
                    266: 
                    267: /* 
                    268:  * Set the DUID type.
                    269:  */
                    270: void
                    271: set_server_duid_type(int type) {
                    272:        server_duid_type = type;
                    273: }
                    274: 
                    275: /*
                    276:  * Generate a new server DUID. This is done if there was no DUID in 
                    277:  * the leases.txt or in the dhcpd.conf file.
                    278:  */
                    279: isc_result_t
                    280: generate_new_server_duid(void) {
                    281:        struct interface_info *p;
                    282:        u_int32_t time_val;
                    283:        struct data_string generated_duid;
                    284: 
                    285:        /*
                    286:         * Verify we have a type that we support.
                    287:         */
                    288:        if ((server_duid_type != DUID_LL) && (server_duid_type != DUID_LLT)) {
                    289:                log_error("Invalid DUID type %d specified, "
                    290:                          "only LL and LLT types supported", server_duid_type);
                    291:                return ISC_R_INVALIDARG;
                    292:        }
                    293: 
                    294:        /*
                    295:         * Find an interface with a hardware address.
                    296:         * Any will do. :)
                    297:         */
                    298:        for (p = interfaces; p != NULL; p = p->next) {
                    299:                if (p->hw_address.hlen > 0) {
                    300:                        break;
                    301:                }
                    302:        }
                    303:        if (p == NULL) {
                    304:                return ISC_R_UNEXPECTED;
                    305:        }
                    306: 
                    307:        /*
                    308:         * Build our DUID.
                    309:         */
                    310:        memset(&generated_duid, 0, sizeof(generated_duid));
                    311:        if (server_duid_type == DUID_LLT) {
                    312:                time_val = duid_time(time(NULL));
                    313:                generated_duid.len = 8 + p->hw_address.hlen - 1;
                    314:                if (!buffer_allocate(&generated_duid.buffer,
                    315:                                     generated_duid.len, MDL)) {
                    316:                        log_fatal("No memory for server DUID.");
                    317:                }
                    318:                generated_duid.data = generated_duid.buffer->data;
                    319:                putUShort(generated_duid.buffer->data, DUID_LLT);
                    320:                putUShort(generated_duid.buffer->data + 2,
                    321:                          p->hw_address.hbuf[0]);
                    322:                putULong(generated_duid.buffer->data + 4, time_val);
                    323:                memcpy(generated_duid.buffer->data + 8,
                    324:                       p->hw_address.hbuf+1, p->hw_address.hlen-1);
                    325:        } else if (server_duid_type == DUID_LL) {
                    326:                generated_duid.len = 4 + p->hw_address.hlen - 1;
                    327:                if (!buffer_allocate(&generated_duid.buffer,
                    328:                                     generated_duid.len, MDL)) {
                    329:                        log_fatal("No memory for server DUID.");
                    330:                }
                    331:                generated_duid.data = generated_duid.buffer->data;
                    332:                putUShort(generated_duid.buffer->data, DUID_LL);
                    333:                putUShort(generated_duid.buffer->data + 2,
                    334:                          p->hw_address.hbuf[0]);
                    335:                memcpy(generated_duid.buffer->data + 4,
                    336:                       p->hw_address.hbuf+1, p->hw_address.hlen-1);
                    337:        } else {
                    338:                log_fatal("Unsupported server DUID type %d.", server_duid_type);
                    339:        }
                    340: 
                    341:        set_server_duid(&generated_duid);
                    342:        data_string_forget(&generated_duid, MDL);
                    343: 
                    344:        return ISC_R_SUCCESS;
                    345: }
                    346: 
                    347: /*
                    348:  * Get the client identifier from the packet.
                    349:  */
                    350: isc_result_t
                    351: get_client_id(struct packet *packet, struct data_string *client_id) {
                    352:        struct option_cache *oc;
                    353: 
                    354:        /*
                    355:         * Verify our client_id structure is empty.
                    356:         */
                    357:        if ((client_id->data != NULL) || (client_id->len != 0)) {
                    358:                return ISC_R_INVALIDARG;
                    359:        }
                    360: 
                    361:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_CLIENTID);
                    362:        if (oc == NULL) {
                    363:                return ISC_R_NOTFOUND;
                    364:        }
                    365: 
                    366:        if (!evaluate_option_cache(client_id, packet, NULL, NULL,
                    367:                                   packet->options, NULL,
                    368:                                   &global_scope, oc, MDL)) {
                    369:                return ISC_R_FAILURE;
                    370:        }
                    371: 
                    372:        return ISC_R_SUCCESS;
                    373: }
                    374: 
                    375: /*
                    376:  * Message validation, defined in RFC 3315, sections 15.2, 15.5, 15.7:
                    377:  *
                    378:  *    Servers MUST discard any Solicit messages that do not include a
                    379:  *    Client Identifier option or that do include a Server Identifier
                    380:  *    option.
                    381:  */
                    382: int
                    383: valid_client_msg(struct packet *packet, struct data_string *client_id) {
                    384:        int ret_val;
                    385:        struct option_cache *oc;
                    386:        struct data_string data;
                    387: 
                    388:        ret_val = 0;
                    389:        memset(client_id, 0, sizeof(*client_id));
                    390:        memset(&data, 0, sizeof(data));
                    391: 
                    392:        switch (get_client_id(packet, client_id)) {
                    393:                case ISC_R_SUCCESS:
                    394:                        break;
                    395:                case ISC_R_NOTFOUND:
                    396:                        log_debug("Discarding %s from %s; "
                    397:                                  "client identifier missing",
                    398:                                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                    399:                                  piaddr(packet->client_addr));
                    400:                        goto exit;
                    401:                default:
                    402:                        log_error("Error processing %s from %s; "
                    403:                                  "unable to evaluate Client Identifier",
                    404:                                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                    405:                                  piaddr(packet->client_addr));
                    406:                        goto exit;
                    407:        }
                    408: 
                    409:        /*
                    410:         * Required by RFC 3315, section 15.
                    411:         */
                    412:        if (packet->unicast) {
                    413:                log_debug("Discarding %s from %s; packet sent unicast "
                    414:                          "(CLIENTID %s)",
                    415:                          dhcpv6_type_names[packet->dhcpv6_msg_type],
                    416:                          piaddr(packet->client_addr),
                    417:                          print_hex_1(client_id->len, client_id->data, 60));
                    418:                goto exit;
                    419:        }
                    420: 
                    421: 
                    422:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
                    423:        if (oc != NULL) {
                    424:                if (evaluate_option_cache(&data, packet, NULL, NULL,
                    425:                                          packet->options, NULL,
                    426:                                          &global_scope, oc, MDL)) {
                    427:                        log_debug("Discarding %s from %s; "
                    428:                                  "server identifier found "
                    429:                                  "(CLIENTID %s, SERVERID %s)",
                    430:                                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                    431:                                  piaddr(packet->client_addr),
                    432:                                  print_hex_1(client_id->len,
                    433:                                              client_id->data, 60),
                    434:                                  print_hex_2(data.len,
                    435:                                              data.data, 60));
                    436:                } else {
                    437:                        log_debug("Discarding %s from %s; "
                    438:                                  "server identifier found "
                    439:                                  "(CLIENTID %s)",
                    440:                                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                    441:                                  print_hex_1(client_id->len,
                    442:                                              client_id->data, 60),
                    443:                                  piaddr(packet->client_addr));
                    444:                }
                    445:                goto exit;
                    446:        }
                    447: 
                    448:        /* looks good */
                    449:        ret_val = 1;
                    450: 
                    451: exit:
                    452:        if (data.len > 0) {
                    453:                data_string_forget(&data, MDL);
                    454:        }
                    455:        if (!ret_val) {
                    456:                if (client_id->len > 0) {
                    457:                        data_string_forget(client_id, MDL);
                    458:                }
                    459:        }
                    460:        return ret_val;
                    461: }
                    462: 
                    463: /*
                    464:  * Response validation, defined in RFC 3315, sections 15.4, 15.6, 15.8, 
                    465:  * 15.9 (slightly different wording, but same meaning):
                    466:  *
                    467:  *   Servers MUST discard any received Request message that meet any of
                    468:  *   the following conditions:
                    469:  *
                    470:  *   -  the message does not include a Server Identifier option.
                    471:  *   -  the contents of the Server Identifier option do not match the
                    472:  *      server's DUID.
                    473:  *   -  the message does not include a Client Identifier option.
                    474:  */
                    475: int
                    476: valid_client_resp(struct packet *packet,
                    477:                  struct data_string *client_id,
                    478:                  struct data_string *server_id)
                    479: {
                    480:        int ret_val;
                    481:        struct option_cache *oc;
                    482: 
                    483:        /* INSIST((duid.data != NULL) && (duid.len > 0)); */
                    484: 
                    485:        ret_val = 0;
                    486:        memset(client_id, 0, sizeof(*client_id));
                    487:        memset(server_id, 0, sizeof(*server_id));
                    488: 
                    489:        switch (get_client_id(packet, client_id)) {
                    490:                case ISC_R_SUCCESS:
                    491:                        break;
                    492:                case ISC_R_NOTFOUND:
                    493:                        log_debug("Discarding %s from %s; "
                    494:                                  "client identifier missing",
                    495:                                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                    496:                                  piaddr(packet->client_addr));
                    497:                        goto exit;
                    498:                default:
                    499:                        log_error("Error processing %s from %s; "
                    500:                                  "unable to evaluate Client Identifier",
                    501:                                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                    502:                                  piaddr(packet->client_addr));
                    503:                        goto exit;
                    504:        }
                    505: 
                    506:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
                    507:        if (oc == NULL) {
                    508:                log_debug("Discarding %s from %s: "
                    509:                          "server identifier missing (CLIENTID %s)",
                    510:                          dhcpv6_type_names[packet->dhcpv6_msg_type],
                    511:                          piaddr(packet->client_addr),
                    512:                          print_hex_1(client_id->len, client_id->data, 60));
                    513:                goto exit;
                    514:        }
                    515:        if (!evaluate_option_cache(server_id, packet, NULL, NULL,
                    516:                                   packet->options, NULL,
                    517:                                   &global_scope, oc, MDL)) {
                    518:                log_error("Error processing %s from %s; "
                    519:                          "unable to evaluate Server Identifier (CLIENTID %s)",
                    520:                          dhcpv6_type_names[packet->dhcpv6_msg_type],
                    521:                          piaddr(packet->client_addr),
                    522:                          print_hex_1(client_id->len, client_id->data, 60));
                    523:                goto exit;
                    524:        }
                    525:        if ((server_duid.len != server_id->len) ||
                    526:            (memcmp(server_duid.data, server_id->data, server_duid.len) != 0)) {
                    527:                log_debug("Discarding %s from %s; "
                    528:                          "not our server identifier "
                    529:                          "(CLIENTID %s, SERVERID %s, server DUID %s)",
                    530:                          dhcpv6_type_names[packet->dhcpv6_msg_type],
                    531:                          piaddr(packet->client_addr),
                    532:                          print_hex_1(client_id->len, client_id->data, 60),
                    533:                          print_hex_2(server_id->len, server_id->data, 60),
                    534:                          print_hex_3(server_duid.len, server_duid.data, 60));
                    535:                goto exit;
                    536:        }
                    537: 
                    538:        /* looks good */
                    539:        ret_val = 1;
                    540: 
                    541: exit:
                    542:        if (!ret_val) {
                    543:                if (server_id->len > 0) {
                    544:                        data_string_forget(server_id, MDL);
                    545:                }
                    546:                if (client_id->len > 0) {
                    547:                        data_string_forget(client_id, MDL);
                    548:                }
                    549:        }
                    550:        return ret_val;
                    551: }
                    552: 
                    553: /*
                    554:  * Information request validation, defined in RFC 3315, section 15.12:
                    555:  *
                    556:  *   Servers MUST discard any received Information-request message that
                    557:  *   meets any of the following conditions:
                    558:  *
                    559:  *   -  The message includes a Server Identifier option and the DUID in
                    560:  *      the option does not match the server's DUID.
                    561:  *
                    562:  *   -  The message includes an IA option.
                    563:  */
                    564: int
                    565: valid_client_info_req(struct packet *packet, struct data_string *server_id) {
                    566:        int ret_val;
                    567:        struct option_cache *oc;
                    568:        struct data_string client_id;
                    569:        char client_id_str[80]; /* print_hex_1() uses maximum 60 characters,
                    570:                                   plus a few more for extra information */
                    571: 
                    572:        ret_val = 0;
                    573:        memset(server_id, 0, sizeof(*server_id));
                    574: 
                    575:        /*
                    576:         * Make a string that we can print out to give more 
                    577:         * information about the client if we need to.
                    578:         *
                    579:         * By RFC 3315, Section 18.1.5 clients SHOULD have a 
                    580:         * client-id on an Information-request packet, but it 
                    581:         * is not strictly necessary.
                    582:         */
                    583:        if (get_client_id(packet, &client_id) == ISC_R_SUCCESS) {
                    584:                snprintf(client_id_str, sizeof(client_id_str), " (CLIENTID %s)",
                    585:                         print_hex_1(client_id.len, client_id.data, 60));
                    586:                data_string_forget(&client_id, MDL);
                    587:        } else {
                    588:                client_id_str[0] = '\0';
                    589:        }
                    590: 
                    591:        /*
                    592:         * Required by RFC 3315, section 15.
                    593:         */
                    594:        if (packet->unicast) {
                    595:                log_debug("Discarding %s from %s; packet sent unicast%s",
                    596:                          dhcpv6_type_names[packet->dhcpv6_msg_type],
                    597:                          piaddr(packet->client_addr), client_id_str);
                    598:                goto exit;
                    599:        }
                    600: 
                    601:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
                    602:        if (oc != NULL) {
                    603:                log_debug("Discarding %s from %s; "
                    604:                          "IA_NA option present%s",
                    605:                          dhcpv6_type_names[packet->dhcpv6_msg_type],
                    606:                          piaddr(packet->client_addr), client_id_str);
                    607:                goto exit;
                    608:        }
                    609:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
                    610:        if (oc != NULL) {
                    611:                log_debug("Discarding %s from %s; "
                    612:                          "IA_TA option present%s",
                    613:                          dhcpv6_type_names[packet->dhcpv6_msg_type],
                    614:                          piaddr(packet->client_addr), client_id_str);
                    615:                goto exit;
                    616:        }
                    617:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
                    618:        if (oc != NULL) {
                    619:                log_debug("Discarding %s from %s; "
                    620:                          "IA_PD option present%s",
                    621:                          dhcpv6_type_names[packet->dhcpv6_msg_type],
                    622:                          piaddr(packet->client_addr), client_id_str);
                    623:                goto exit;
                    624:        }
                    625: 
                    626:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_SERVERID);
                    627:        if (oc != NULL) {
                    628:                if (!evaluate_option_cache(server_id, packet, NULL, NULL,
                    629:                                           packet->options, NULL,
                    630:                                           &global_scope, oc, MDL)) {
                    631:                        log_error("Error processing %s from %s; "
                    632:                                  "unable to evaluate Server Identifier%s",
                    633:                                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                    634:                                  piaddr(packet->client_addr), client_id_str);
                    635:                        goto exit;
                    636:                }
                    637:                if ((server_duid.len != server_id->len) ||
                    638:                    (memcmp(server_duid.data, server_id->data,
                    639:                            server_duid.len) != 0)) {
                    640:                        log_debug("Discarding %s from %s; "
                    641:                                  "not our server identifier "
                    642:                                  "(SERVERID %s, server DUID %s)%s",
                    643:                                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                    644:                                  piaddr(packet->client_addr),
                    645:                                  print_hex_1(server_id->len,
                    646:                                              server_id->data, 60),
                    647:                                  print_hex_2(server_duid.len,
                    648:                                              server_duid.data, 60),
                    649:                                  client_id_str);
                    650:                        goto exit;
                    651:                }
                    652:        }
                    653: 
                    654:        /* looks good */
                    655:        ret_val = 1;
                    656: 
                    657: exit:
                    658:        if (!ret_val) {
                    659:                if (server_id->len > 0) {
                    660:                        data_string_forget(server_id, MDL);
                    661:                }
                    662:        }
                    663:        return ret_val;
                    664: }
                    665: 
                    666: /* 
                    667:  * Options that we want to send, in addition to what was requested
                    668:  * via the ORO.
                    669:  */
                    670: static const int required_opts[] = {
                    671:        D6O_CLIENTID,
                    672:        D6O_SERVERID,
                    673:        D6O_STATUS_CODE,
                    674:        D6O_PREFERENCE,
                    675:        0
                    676: };
                    677: static const int required_opts_NAA[] = {
                    678:        D6O_CLIENTID,
                    679:        D6O_SERVERID,
                    680:        D6O_STATUS_CODE,
                    681:        0
                    682: };
                    683: static const int required_opts_solicit[] = {
                    684:        D6O_CLIENTID,
                    685:        D6O_SERVERID,
                    686:        D6O_IA_NA,
                    687:        D6O_IA_TA,
                    688:        D6O_IA_PD,
                    689:        D6O_RAPID_COMMIT,
                    690:        D6O_STATUS_CODE,
                    691:        D6O_RECONF_ACCEPT,
                    692:        D6O_PREFERENCE,
                    693:        0
                    694: };
                    695: static const int required_opts_agent[] = {
                    696:        D6O_INTERFACE_ID,
                    697:        D6O_RELAY_MSG,
                    698:        0
                    699: };
                    700: static const int required_opts_IA[] = {
                    701:        D6O_IAADDR,
                    702:        D6O_STATUS_CODE,
                    703:        0
                    704: };
                    705: static const int required_opts_IA_PD[] = {
                    706:        D6O_IAPREFIX,
                    707:        D6O_STATUS_CODE,
                    708:        0
                    709: };
                    710: static const int required_opts_STATUS_CODE[] = {
                    711:        D6O_STATUS_CODE,
                    712:        0
                    713: };
                    714: 
                    715: /*
                    716:  * Extracts from packet contents an IA_* option, storing the IA structure
                    717:  * in its entirety in enc_opt_data, and storing any decoded DHCPv6 options
                    718:  * in enc_opt_state for later lookup and evaluation.  The 'offset' indicates
                    719:  * where in the IA_* the DHCPv6 options commence.
                    720:  */
                    721: static int
                    722: get_encapsulated_IA_state(struct option_state **enc_opt_state,
                    723:                          struct data_string *enc_opt_data,
                    724:                          struct packet *packet,
                    725:                          struct option_cache *oc,
                    726:                          int offset)
                    727: {
                    728:        /* 
                    729:         * Get the raw data for the encapsulated options.
                    730:         */
                    731:        memset(enc_opt_data, 0, sizeof(*enc_opt_data));
                    732:        if (!evaluate_option_cache(enc_opt_data, packet,
                    733:                                   NULL, NULL, packet->options, NULL,
                    734:                                   &global_scope, oc, MDL)) {
                    735:                log_error("get_encapsulated_IA_state: "
                    736:                          "error evaluating raw option.");
                    737:                return 0;
                    738:        }
                    739:        if (enc_opt_data->len < offset) {
                    740:                log_error("get_encapsulated_IA_state: raw option too small.");
                    741:                data_string_forget(enc_opt_data, MDL);
                    742:                return 0;
                    743:        }
                    744: 
                    745:        /*
                    746:         * Now create the option state structure, and pass it to the 
                    747:         * function that parses options.
                    748:         */
                    749:        *enc_opt_state = NULL;
                    750:        if (!option_state_allocate(enc_opt_state, MDL)) {
                    751:                log_error("get_encapsulated_IA_state: no memory for options.");
                    752:                data_string_forget(enc_opt_data, MDL);
                    753:                return 0;
                    754:        }
                    755:        if (!parse_option_buffer(*enc_opt_state,
                    756:                                 enc_opt_data->data + offset, 
                    757:                                 enc_opt_data->len - offset,
                    758:                                 &dhcpv6_universe)) {
                    759:                log_error("get_encapsulated_IA_state: error parsing options.");
                    760:                option_state_dereference(enc_opt_state, MDL);
                    761:                data_string_forget(enc_opt_data, MDL);
                    762:                return 0;
                    763:        }
                    764: 
                    765:        return 1;
                    766: }
                    767: 
                    768: static int
                    769: set_status_code(u_int16_t status_code, const char *status_message,
                    770:                struct option_state *opt_state)
                    771: {
                    772:        struct data_string d;
                    773:        int ret_val;
                    774: 
                    775:        memset(&d, 0, sizeof(d));
                    776:        d.len = sizeof(status_code) + strlen(status_message);
                    777:        if (!buffer_allocate(&d.buffer, d.len, MDL)) {
                    778:                log_fatal("set_status_code: no memory for status code.");
                    779:        }
                    780:        d.data = d.buffer->data;
                    781:        putUShort(d.buffer->data, status_code);
                    782:        memcpy(d.buffer->data + sizeof(status_code), 
                    783:               status_message, d.len - sizeof(status_code));
                    784:        if (!save_option_buffer(&dhcpv6_universe, opt_state, 
                    785:                                d.buffer, (unsigned char *)d.data, d.len, 
                    786:                                D6O_STATUS_CODE, 0)) {
                    787:                log_error("set_status_code: error saving status code.");
                    788:                ret_val = 0;
                    789:        } else {
                    790:                ret_val = 1;
                    791:        }
                    792:        data_string_forget(&d, MDL);
                    793:        return ret_val;
                    794: }
                    795: 
                    796: /*
                    797:  * We have a set of operations we do to set up the reply packet, which
                    798:  * is the same for many message types.
                    799:  */
                    800: static int
                    801: start_reply(struct packet *packet,
                    802:            const struct data_string *client_id, 
                    803:            const struct data_string *server_id,
                    804:            struct option_state **opt_state,
                    805:            struct dhcpv6_packet *reply)
                    806: {
                    807:        struct option_cache *oc;
                    808:        const unsigned char *server_id_data;
                    809:        int server_id_len;
                    810: 
                    811:        /*
                    812:         * Build our option state for reply.
                    813:         */
                    814:        *opt_state = NULL;
                    815:        if (!option_state_allocate(opt_state, MDL)) {
                    816:                log_error("start_reply: no memory for option_state.");
                    817:                return 0;
                    818:        }
                    819:        execute_statements_in_scope(NULL, packet, NULL, NULL,
                    820:                                    packet->options, *opt_state,
                    821:                                    &global_scope, root_group, NULL);
                    822: 
                    823:        /*
                    824:         * A small bit of special handling for Solicit messages.
                    825:         *
                    826:         * We could move the logic into a flag, but for now just check
                    827:         * explicitly.
                    828:         */
                    829:        if (packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
                    830:                reply->msg_type = DHCPV6_ADVERTISE;
                    831: 
                    832:                /*
                    833:                 * If:
                    834:                 * - this message type supports rapid commit (Solicit), and
                    835:                 * - the server is configured to supply a rapid commit, and
                    836:                 * - the client requests a rapid commit,
                    837:                 * Then we add a rapid commit option, and send Reply (instead
                    838:                 * of an Advertise).
                    839:                 */
                    840:                oc = lookup_option(&dhcpv6_universe,
                    841:                                   *opt_state, D6O_RAPID_COMMIT);
                    842:                if (oc != NULL) {
                    843:                        oc = lookup_option(&dhcpv6_universe,
                    844:                                           packet->options, D6O_RAPID_COMMIT);
                    845:                        if (oc != NULL) {
                    846:                                /* Rapid-commit in action. */
                    847:                                reply->msg_type = DHCPV6_REPLY;
                    848:                        } else {
                    849:                                /* Don't want a rapid-commit in advertise. */
                    850:                                delete_option(&dhcpv6_universe,
                    851:                                              *opt_state, D6O_RAPID_COMMIT);
                    852:                        }
                    853:                }
                    854:        } else {
                    855:                reply->msg_type = DHCPV6_REPLY;
                    856:                /* Delete the rapid-commit from the sent options. */
                    857:                oc = lookup_option(&dhcpv6_universe,
                    858:                                   *opt_state, D6O_RAPID_COMMIT);
                    859:                if (oc != NULL) {
                    860:                        delete_option(&dhcpv6_universe,
                    861:                                      *opt_state, D6O_RAPID_COMMIT);
                    862:                }
                    863:        }
                    864: 
                    865:        /* 
                    866:         * Use the client's transaction identifier for the reply.
                    867:         */
                    868:        memcpy(reply->transaction_id, packet->dhcpv6_transaction_id, 
                    869:               sizeof(reply->transaction_id));
                    870: 
                    871:        /* 
                    872:         * RFC 3315, section 18.2 says we need server identifier and
                    873:         * client identifier.
                    874:         *
                    875:         * If the server ID is defined via the configuration file, then
                    876:         * it will already be present in the option state at this point, 
                    877:         * so we don't need to set it.
                    878:         *
                    879:         * If we have a server ID passed in from the caller, 
                    880:         * use that, otherwise use the global DUID.
                    881:         */
                    882:        oc = lookup_option(&dhcpv6_universe, *opt_state, D6O_SERVERID);
                    883:        if (oc == NULL) {
                    884:                if (server_id == NULL) {
                    885:                        server_id_data = server_duid.data;
                    886:                        server_id_len = server_duid.len;
                    887:                } else {
                    888:                        server_id_data = server_id->data;
                    889:                        server_id_len = server_id->len;
                    890:                }
                    891:                if (!save_option_buffer(&dhcpv6_universe, *opt_state, 
                    892:                                        NULL, (unsigned char *)server_id_data,
                    893:                                        server_id_len, D6O_SERVERID, 0)) {
                    894:                                log_error("start_reply: "
                    895:                                          "error saving server identifier.");
                    896:                                return 0;
                    897:                }
                    898:        }
                    899: 
                    900:        if (client_id->buffer != NULL) {
                    901:                if (!save_option_buffer(&dhcpv6_universe, *opt_state, 
                    902:                                        client_id->buffer, 
                    903:                                        (unsigned char *)client_id->data, 
                    904:                                        client_id->len, 
                    905:                                        D6O_CLIENTID, 0)) {
                    906:                        log_error("start_reply: error saving "
                    907:                                  "client identifier.");
                    908:                        return 0;
                    909:                }
                    910:        }
                    911: 
                    912:        /*
                    913:         * If the client accepts reconfiguration, let it know that we
                    914:         * will send them.
                    915:         *
                    916:         * Note: we don't actually do this yet, but DOCSIS requires we
                    917:         *       claim to.
                    918:         */
                    919:        oc = lookup_option(&dhcpv6_universe, packet->options,
                    920:                           D6O_RECONF_ACCEPT);
                    921:        if (oc != NULL) {
                    922:                if (!save_option_buffer(&dhcpv6_universe, *opt_state,
                    923:                                        NULL, (unsigned char *)"", 0, 
                    924:                                        D6O_RECONF_ACCEPT, 0)) {
                    925:                        log_error("start_reply: "
                    926:                                  "error saving RECONF_ACCEPT option.");
                    927:                        option_state_dereference(opt_state, MDL);
                    928:                        return 0;
                    929:                }
                    930:        }
                    931: 
                    932:        return 1;
                    933: }
                    934: 
                    935: /*
                    936:  * Try to get the IPv6 address the client asked for from the
                    937:  * pool.
                    938:  *
                    939:  * addr is the result (should be a pointer to NULL on entry)
                    940:  * pool is the pool to search in
                    941:  * requested_addr is the address the client wants
                    942:  */
                    943: static isc_result_t
                    944: try_client_v6_address(struct iasubopt **addr,
                    945:                      struct ipv6_pool *pool,
                    946:                      const struct data_string *requested_addr)
                    947: {
                    948:        struct in6_addr tmp_addr;
                    949:        isc_result_t result;
                    950: 
                    951:        if (requested_addr->len < sizeof(tmp_addr)) {
                    952:                return ISC_R_INVALIDARG;
                    953:        }
                    954:        memcpy(&tmp_addr, requested_addr->data, sizeof(tmp_addr));
                    955:        if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
                    956:                return ISC_R_FAILURE;
                    957:        }
                    958: 
                    959:        /*
                    960:         * The address is not covered by this (or possibly any) dynamic
                    961:         * range.
                    962:         */
                    963:        if (!ipv6_in_pool(&tmp_addr, pool)) {
                    964:                return ISC_R_ADDRNOTAVAIL;
                    965:        }
                    966: 
                    967:        if (lease6_exists(pool, &tmp_addr)) {
                    968:                return ISC_R_ADDRINUSE;
                    969:        }
                    970: 
                    971:        result = iasubopt_allocate(addr, MDL);
                    972:        if (result != ISC_R_SUCCESS) {
                    973:                return result;
                    974:        }
                    975:        (*addr)->addr = tmp_addr;
                    976:        (*addr)->plen = 0;
                    977: 
                    978:        /* Default is soft binding for 2 minutes. */
                    979:        result = add_lease6(pool, *addr, cur_time + 120);
                    980:        if (result != ISC_R_SUCCESS) {
                    981:                iasubopt_dereference(addr, MDL);
                    982:        }
                    983:        return result;
                    984: }
                    985: 
                    986: /*
                    987:  * Get an IPv6 address for the client.
                    988:  *
                    989:  * addr is the result (should be a pointer to NULL on entry)
                    990:  * packet is the information about the packet from the client
                    991:  * requested_iaaddr is a hint from the client
                    992:  * client_id is the DUID for the client
                    993:  */
                    994: static isc_result_t 
                    995: pick_v6_address(struct iasubopt **addr, struct shared_network *shared_network,
                    996:                const struct data_string *client_id)
                    997: {
                    998:        struct ipv6_pool *p;
                    999:        int i;
                   1000:        int start_pool;
                   1001:        unsigned int attempts;
                   1002:        char tmp_buf[INET6_ADDRSTRLEN];
                   1003: 
                   1004:        /*
                   1005:         * No address pools, we're done.
                   1006:         */
                   1007:        if (shared_network->ipv6_pools == NULL) {
                   1008:                log_debug("Unable to pick client address: "
                   1009:                          "no IPv6 pools on this shared network");
                   1010:                return ISC_R_NORESOURCES;
                   1011:        }
                   1012:        for (i = 0;; i++) {
                   1013:                p = shared_network->ipv6_pools[i];
                   1014:                if (p == NULL) {
                   1015:                        log_debug("Unable to pick client address: "
                   1016:                                  "no IPv6 address pools "
                   1017:                                  "on this shared network");
                   1018:                        return ISC_R_NORESOURCES;
                   1019:                }
                   1020:                if (p->pool_type == D6O_IA_NA) {
                   1021:                        break;
                   1022:                }
                   1023:        }
                   1024: 
                   1025:        /*
                   1026:         * Otherwise try to get a lease from the first subnet possible.
                   1027:         *
                   1028:         * We start looking at the last pool we allocated from, unless
                   1029:         * it had a collision trying to allocate an address. This will
                   1030:         * tend to move us into less-filled pools.
                   1031:         */
                   1032:        start_pool = shared_network->last_ipv6_pool;
                   1033:        i = start_pool;
                   1034:        do {
                   1035: 
                   1036:                p = shared_network->ipv6_pools[i];
                   1037:                if ((p->pool_type == D6O_IA_NA) &&
                   1038:                    (create_lease6(p, addr, &attempts, client_id,
                   1039:                                   cur_time + 120) == ISC_R_SUCCESS)) {
                   1040:                        /*
                   1041:                         * Record the pool used (or next one if there 
                   1042:                         * was a collision).
                   1043:                         */
                   1044:                        if (attempts > 1) {
                   1045:                                i++;
                   1046:                                if (shared_network->ipv6_pools[i] == NULL) {
                   1047:                                        i = 0;
                   1048:                                }
                   1049:                        }
                   1050:                        shared_network->last_ipv6_pool = i;
                   1051: 
                   1052:                        log_debug("Picking pool address %s",
                   1053:                                  inet_ntop(AF_INET6, &((*addr)->addr),
                   1054:                                            tmp_buf, sizeof(tmp_buf)));
                   1055:                        return ISC_R_SUCCESS;
                   1056:                }
                   1057: 
                   1058:                i++;
                   1059:                if (shared_network->ipv6_pools[i] == NULL) {
                   1060:                        i = 0;
                   1061:                }
                   1062:        } while (i != start_pool);
                   1063: 
                   1064:        /*
                   1065:         * If we failed to pick an IPv6 address from any of the subnets.
                   1066:         * Presumably that means we have no addresses for the client.
                   1067:         */
                   1068:        log_debug("Unable to pick client address: no addresses available");
                   1069:        return ISC_R_NORESOURCES;
                   1070: }
                   1071: 
                   1072: /*
                   1073:  * Try to get the IPv6 prefix the client asked for from the
                   1074:  * prefix pool.
                   1075:  *
                   1076:  * pref is the result (should be a pointer to NULL on entry)
                   1077:  * pool is the prefix pool to search in
                   1078:  * requested_pref is the address the client wants
                   1079:  */
                   1080: static isc_result_t
                   1081: try_client_v6_prefix(struct iasubopt **pref,
                   1082:                     struct ipv6_pool *pool,
                   1083:                     const struct data_string *requested_pref)
                   1084: {
                   1085:        u_int8_t tmp_plen;
                   1086:        struct in6_addr tmp_pref;
                   1087:        struct iaddr ia;
                   1088:        isc_result_t result;
                   1089: 
                   1090:        if (requested_pref->len < sizeof(tmp_plen) + sizeof(tmp_pref)) {
                   1091:                return ISC_R_INVALIDARG;
                   1092:        }
                   1093:        tmp_plen = (int) requested_pref->data[0];
1.1.1.1 ! misho    1094:        if ((tmp_plen < 3) || (tmp_plen > 128) ||
        !          1095:            ((int)tmp_plen != pool->units)) {
1.1       misho    1096:                return ISC_R_FAILURE;
                   1097:        }
                   1098:        memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref));
                   1099:        if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) {
                   1100:                return ISC_R_FAILURE;
                   1101:        }
                   1102:        ia.len = 16;
                   1103:        memcpy(&ia.iabuf, &tmp_pref, 16);
                   1104:        if (!is_cidr_mask_valid(&ia, (int) tmp_plen)) {
                   1105:                return ISC_R_FAILURE;
                   1106:        }
                   1107: 
1.1.1.1 ! misho    1108:        if (!ipv6_in_pool(&tmp_pref, pool)) {
        !          1109:                return ISC_R_ADDRNOTAVAIL;
1.1       misho    1110:        }
                   1111: 
                   1112:        if (prefix6_exists(pool, &tmp_pref, tmp_plen)) {
                   1113:                return ISC_R_ADDRINUSE;
                   1114:        }
                   1115: 
                   1116:        result = iasubopt_allocate(pref, MDL);
                   1117:        if (result != ISC_R_SUCCESS) {
                   1118:                return result;
                   1119:        }
                   1120:        (*pref)->addr = tmp_pref;
                   1121:        (*pref)->plen = tmp_plen;
                   1122: 
                   1123:        /* Default is soft binding for 2 minutes. */
                   1124:        result = add_lease6(pool, *pref, cur_time + 120);
                   1125:        if (result != ISC_R_SUCCESS) {
                   1126:                iasubopt_dereference(pref, MDL);
                   1127:        }
                   1128:        return result;
                   1129: }
                   1130: 
                   1131: /*
                   1132:  * Get an IPv6 prefix for the client.
                   1133:  *
                   1134:  * pref is the result (should be a pointer to NULL on entry)
                   1135:  * packet is the information about the packet from the client
                   1136:  * requested_iaprefix is a hint from the client
                   1137:  * plen is -1 or the requested prefix length
                   1138:  * client_id is the DUID for the client
                   1139:  */
                   1140: static isc_result_t 
                   1141: pick_v6_prefix(struct iasubopt **pref, int plen,
                   1142:               struct shared_network *shared_network,
                   1143:               const struct data_string *client_id)
                   1144: {
                   1145:        struct ipv6_pool *p;
                   1146:        int i;
                   1147:        unsigned int attempts;
                   1148:        char tmp_buf[INET6_ADDRSTRLEN];
                   1149: 
                   1150:        /*
                   1151:         * No prefix pools, we're done.
                   1152:         */
                   1153:        if (shared_network->ipv6_pools == NULL) {
                   1154:                log_debug("Unable to pick client prefix: "
                   1155:                          "no IPv6 pools on this shared network");
                   1156:                return ISC_R_NORESOURCES;
                   1157:        }
                   1158:        for (i = 0;; i++) {
                   1159:                p = shared_network->ipv6_pools[i];
                   1160:                if (p == NULL) {
                   1161:                        log_debug("Unable to pick client prefix: "
                   1162:                                  "no IPv6 prefix pools "
                   1163:                                  "on this shared network");
                   1164:                        return ISC_R_NORESOURCES;
                   1165:                }
                   1166:                if (p->pool_type == D6O_IA_PD) {
                   1167:                        break;
                   1168:                }
                   1169:        }
                   1170: 
                   1171:        /*
                   1172:         * Otherwise try to get a prefix.
                   1173:         */
                   1174:        for (i = 0;; i++) {
                   1175:                p = shared_network->ipv6_pools[i];
                   1176:                if (p == NULL) {
                   1177:                        break;
                   1178:                }
                   1179:                if (p->pool_type != D6O_IA_PD) {
                   1180:                        continue;
                   1181:                }
                   1182: 
                   1183:                /*
                   1184:                 * Try only pools with the requested prefix length if any.
                   1185:                 */
                   1186:                if ((plen >= 0) && (p->units != plen)) {
                   1187:                        continue;
                   1188:                }
                   1189: 
                   1190:                if (create_prefix6(p, pref, &attempts, client_id,
                   1191:                                   cur_time + 120) == ISC_R_SUCCESS) {
                   1192:                        log_debug("Picking pool prefix %s/%u",
                   1193:                                  inet_ntop(AF_INET6, &((*pref)->addr),
                   1194:                                            tmp_buf, sizeof(tmp_buf)),
                   1195:                                  (unsigned) (*pref)->plen);
                   1196:                        return ISC_R_SUCCESS;
                   1197:                }
                   1198:        }
                   1199: 
                   1200:        /*
                   1201:         * If we failed to pick an IPv6 prefix
                   1202:         * Presumably that means we have no prefixes for the client.
                   1203:         */
                   1204:        log_debug("Unable to pick client prefix: no prefixes available");
                   1205:        return ISC_R_NORESOURCES;
                   1206: }
                   1207: 
                   1208: /*
1.1.1.1 ! misho    1209:  *! \file server/dhcpv6.c
        !          1210:  *
        !          1211:  * \brief construct a reply containing information about a client's lease
        !          1212:  *
1.1       misho    1213:  * lease_to_client() is called from several messages to construct a
                   1214:  * reply that contains all that we know about the client's correct lease
                   1215:  * (or projected lease).
                   1216:  *
                   1217:  * Solicit - "Soft" binding, ignore unknown addresses or bindings, just
                   1218:  *          send what we "may" give them on a request.
                   1219:  *
                   1220:  * Request - "Hard" binding, but ignore supplied addresses (just provide what
                   1221:  *          the client should really use).
                   1222:  *
                   1223:  * Renew   - "Hard" binding, but client-supplied addresses are 'real'.  Error
                   1224:  * Rebind    out any "wrong" addresses the client sends.  This means we send
                   1225:  *          an empty IA_NA with a status code of NoBinding or NotOnLink or
                   1226:  *          possibly send the address with zeroed lifetimes.
                   1227:  *
                   1228:  * Information-Request - No binding.
                   1229:  *
                   1230:  * The basic structure is to traverse the client-supplied data first, and
                   1231:  * validate and echo back any contents that can be.  If the client-supplied
                   1232:  * data does not error out (on renew/rebind as above), but we did not send
                   1233:  * any addresses, attempt to allocate one.
1.1.1.1 ! misho    1234:  *
        !          1235:  * At the end of the this function we call commit_leases_timed() to
        !          1236:  * fsync and rotate the file as necessary.  commit_leases_timed() will
        !          1237:  * check that we have written at least one lease to the file and that
        !          1238:  * some time has passed before doing any fsync or file rewrite so we
        !          1239:  * don't bother tracking if we did a write_ia during this function.
1.1       misho    1240:  */
                   1241: /* TODO: look at client hints for lease times */
1.1.1.1 ! misho    1242: 
1.1       misho    1243: static void
                   1244: lease_to_client(struct data_string *reply_ret,
                   1245:                struct packet *packet, 
                   1246:                const struct data_string *client_id,
                   1247:                const struct data_string *server_id)
                   1248: {
                   1249:        static struct reply_state reply;
                   1250:        struct option_cache *oc;
                   1251:        struct data_string packet_oro;
1.1.1.1 ! misho    1252: #if defined (RFC3315_PRE_ERRATA_2010_08)
        !          1253:        isc_boolean_t no_resources_avail = ISC_FALSE;
        !          1254: #endif
        !          1255: 
        !          1256:        memset(&packet_oro, 0, sizeof(packet_oro));
1.1       misho    1257: 
                   1258:        /* Locate the client.  */
                   1259:        if (shared_network_from_packet6(&reply.shared,
                   1260:                                        packet) != ISC_R_SUCCESS)
                   1261:                goto exit;
                   1262: 
                   1263:        /* 
                   1264:         * Initialize the reply.
                   1265:         */
                   1266:        packet_reference(&reply.packet, packet, MDL);
                   1267:        data_string_copy(&reply.client_id, client_id, MDL);
                   1268: 
                   1269:        if (!start_reply(packet, client_id, server_id, &reply.opt_state,
                   1270:                         &reply.buf.reply))
                   1271:                goto exit;
                   1272: 
                   1273:        /* Set the write cursor to just past the reply header. */
                   1274:        reply.cursor = REPLY_OPTIONS_INDEX;
                   1275: 
                   1276:        /*
                   1277:         * Get the ORO from the packet, if any.
                   1278:         */
                   1279:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ORO);
                   1280:        if (oc != NULL) {
                   1281:                if (!evaluate_option_cache(&packet_oro, packet, 
                   1282:                                           NULL, NULL, 
                   1283:                                           packet->options, NULL,
                   1284:                                           &global_scope, oc, MDL)) {
                   1285:                        log_error("lease_to_client: error evaluating ORO.");
                   1286:                        goto exit;
                   1287:                }
                   1288:        }
                   1289: 
                   1290:        /* 
                   1291:         * Find a host record that matches from the packet, if any, and is
                   1292:         * valid for the shared network the client is on.
                   1293:         */
                   1294:        if (find_hosts_by_option(&reply.host, packet, packet->options, MDL)) {
                   1295:                seek_shared_host(&reply.host, reply.shared);
                   1296:        }
                   1297: 
                   1298:        if ((reply.host == NULL) &&
                   1299:            find_hosts_by_uid(&reply.host, client_id->data, client_id->len,
                   1300:                              MDL)) {
                   1301:                seek_shared_host(&reply.host, reply.shared);
                   1302:        }
                   1303: 
                   1304:        /* Process the client supplied IA's onto the reply buffer. */
                   1305:        reply.ia_count = 0;
                   1306:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
1.1.1.1 ! misho    1307: 
1.1       misho    1308:        for (; oc != NULL ; oc = oc->next) {
                   1309:                isc_result_t status;
                   1310: 
                   1311:                /* Start counting resources (addresses) offered. */
                   1312:                reply.client_resources = 0;
                   1313:                reply.resources_included = ISC_FALSE;
                   1314: 
                   1315:                status = reply_process_ia_na(&reply, oc);
                   1316: 
                   1317:                /*
                   1318:                 * We continue to try other IA's whether we can address
                   1319:                 * this one or not.  Any other result is an immediate fail.
                   1320:                 */
                   1321:                if ((status != ISC_R_SUCCESS) &&
                   1322:                    (status != ISC_R_NORESOURCES))
                   1323:                        goto exit;
                   1324: 
1.1.1.1 ! misho    1325: #if defined (RFC3315_PRE_ERRATA_2010_08)
1.1       misho    1326:                /*
                   1327:                 * If any address cannot be given to any IA, then set the
                   1328:                 * NoAddrsAvail status code.
                   1329:                 */
                   1330:                if (reply.client_resources == 0)
                   1331:                        no_resources_avail = ISC_TRUE;
1.1.1.1 ! misho    1332: #endif
1.1       misho    1333:        }
                   1334:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
                   1335:        for (; oc != NULL ; oc = oc->next) {
                   1336:                isc_result_t status;
                   1337: 
                   1338:                /* Start counting resources (addresses) offered. */
                   1339:                reply.client_resources = 0;
                   1340:                reply.resources_included = ISC_FALSE;
                   1341: 
                   1342:                status = reply_process_ia_ta(&reply, oc);
                   1343: 
                   1344:                /*
                   1345:                 * We continue to try other IA's whether we can address
                   1346:                 * this one or not.  Any other result is an immediate fail.
                   1347:                 */
                   1348:                if ((status != ISC_R_SUCCESS) &&
                   1349:                    (status != ISC_R_NORESOURCES))
                   1350:                        goto exit;
                   1351: 
1.1.1.1 ! misho    1352: #if defined (RFC3315_PRE_ERRATA_2010_08)
1.1       misho    1353:                /*
                   1354:                 * If any address cannot be given to any IA, then set the
                   1355:                 * NoAddrsAvail status code.
                   1356:                 */
                   1357:                if (reply.client_resources == 0)
                   1358:                        no_resources_avail = ISC_TRUE;
1.1.1.1 ! misho    1359: #endif
1.1       misho    1360:        }
                   1361: 
                   1362:        /* Same for IA_PD's. */
                   1363:        reply.pd_count = 0;
                   1364:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
                   1365:        for (; oc != NULL ; oc = oc->next) {
                   1366:                isc_result_t status;
                   1367: 
                   1368:                /* Start counting resources (prefixes) offered. */
                   1369:                reply.client_resources = 0;
                   1370:                reply.resources_included = ISC_FALSE;
                   1371: 
                   1372:                status = reply_process_ia_pd(&reply, oc);
                   1373: 
                   1374:                /*
                   1375:                 * We continue to try other IA_PD's whether we can address
                   1376:                 * this one or not.  Any other result is an immediate fail.
                   1377:                 */
                   1378:                if ((status != ISC_R_SUCCESS) &&
                   1379:                    (status != ISC_R_NORESOURCES))
                   1380:                        goto exit;
                   1381:        }
                   1382: 
                   1383:        /*
                   1384:         * Make no reply if we gave no resources and is not
                   1385:         * for Information-Request.
                   1386:         */
                   1387:        if ((reply.ia_count == 0) && (reply.pd_count == 0)) {
                   1388:                if (reply.packet->dhcpv6_msg_type !=
                   1389:                                            DHCPV6_INFORMATION_REQUEST)
                   1390:                        goto exit;
                   1391: 
                   1392:                /*
                   1393:                 * Because we only execute statements on a per-IA basis,
                   1394:                 * we need to execute statements in any non-IA reply to
                   1395:                 * source configuration.
                   1396:                 */
                   1397:                execute_statements_in_scope(NULL, reply.packet, NULL, NULL,
                   1398:                                            reply.packet->options,
                   1399:                                            reply.opt_state, &global_scope,
                   1400:                                            reply.shared->group, root_group);
                   1401: 
                   1402:                /* Bring in any configuration from a host record. */
                   1403:                if (reply.host != NULL)
                   1404:                        execute_statements_in_scope(NULL, reply.packet, NULL,
                   1405:                                                    NULL, reply.packet->options,
                   1406:                                                    reply.opt_state,
                   1407:                                                    &global_scope,
                   1408:                                                    reply.host->group,
                   1409:                                                    reply.shared->group);
                   1410:        }
                   1411: 
                   1412:        /*
                   1413:         * RFC3315 section 17.2.2 (Solicit):
                   1414:         *
                   1415:         * If the server will not assign any addresses to any IAs in a
                   1416:         * subsequent Request from the client, the server MUST send an
                   1417:         * Advertise message to the client that includes only a Status
                   1418:         * Code option with code NoAddrsAvail and a status message for
                   1419:         * the user, a Server Identifier option with the server's DUID,
                   1420:         * and a Client Identifier option with the client's DUID.
                   1421:         *
                   1422:         * Section 18.2.1 (Request):
                   1423:         *
                   1424:         * If the server cannot assign any addresses to an IA in the
                   1425:         * message from the client, the server MUST include the IA in
                   1426:         * the Reply message with no addresses in the IA and a Status
                   1427:         * Code option in the IA containing status code NoAddrsAvail.
                   1428:         *
                   1429:         * Section 18.1.8 (Client Behavior):
                   1430:         *
                   1431:         * Leave unchanged any information about addresses the client has
                   1432:         * recorded in the IA but that were not included in the IA from
                   1433:         * the server.
                   1434:         * Sends a Renew/Rebind if the IA is not in the Reply message.
                   1435:         */
1.1.1.1 ! misho    1436: #if defined (RFC3315_PRE_ERRATA_2010_08)
1.1       misho    1437:        if (no_resources_avail && (reply.ia_count != 0) &&
                   1438:            (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT))
                   1439:        {
                   1440:                /* Set the NoAddrsAvail status code. */
                   1441:                if (!set_status_code(STATUS_NoAddrsAvail,
                   1442:                                     "No addresses available for this "
                   1443:                                     "interface.", reply.opt_state)) {
                   1444:                        log_error("lease_to_client: Unable to set "
                   1445:                                  "NoAddrsAvail status code.");
                   1446:                        goto exit;
                   1447:                }
                   1448: 
                   1449:                /* Rewind the cursor to the start. */
                   1450:                reply.cursor = REPLY_OPTIONS_INDEX;
                   1451: 
                   1452:                /*
                   1453:                 * Produce an advertise that includes only:
                   1454:                 *
                   1455:                 * Status code.
                   1456:                 * Server DUID.
                   1457:                 * Client DUID.
                   1458:                 */
                   1459:                reply.buf.reply.msg_type = DHCPV6_ADVERTISE;
                   1460:                reply.cursor += store_options6((char *)reply.buf.data +
                   1461:                                                        reply.cursor,
                   1462:                                               sizeof(reply.buf) -
                   1463:                                                        reply.cursor,
                   1464:                                               reply.opt_state, reply.packet,
                   1465:                                               required_opts_NAA,
                   1466:                                               NULL);
                   1467:        } else {
                   1468:                /*
                   1469:                 * Having stored the client's IA's, store any options that
                   1470:                 * will fit in the remaining space.
                   1471:                 */
                   1472:                reply.cursor += store_options6((char *)reply.buf.data +
                   1473:                                                        reply.cursor,
                   1474:                                               sizeof(reply.buf) -
                   1475:                                                        reply.cursor,
                   1476:                                               reply.opt_state, reply.packet,
                   1477:                                               required_opts_solicit,
                   1478:                                               &packet_oro);
                   1479:        }
1.1.1.1 ! misho    1480: #else /* defined (RFC3315_PRE_ERRATA_2010_08) */
        !          1481:        /*
        !          1482:         * Having stored the client's IA's, store any options that
        !          1483:         * will fit in the remaining space.
        !          1484:         */
        !          1485:        reply.cursor += store_options6((char *)reply.buf.data + reply.cursor,
        !          1486:                                       sizeof(reply.buf) - reply.cursor,
        !          1487:                                       reply.opt_state, reply.packet,
        !          1488:                                       required_opts_solicit,
        !          1489:                                       &packet_oro);
        !          1490: #endif /* defined (RFC3315_PRE_ERRATA_2010_08) */
1.1       misho    1491: 
                   1492:        /* Return our reply to the caller. */
                   1493:        reply_ret->len = reply.cursor;
                   1494:        reply_ret->buffer = NULL;
                   1495:        if (!buffer_allocate(&reply_ret->buffer, reply.cursor, MDL)) {
                   1496:                log_fatal("No memory to store Reply.");
                   1497:        }
                   1498:        memcpy(reply_ret->buffer->data, reply.buf.data, reply.cursor);
                   1499:        reply_ret->data = reply_ret->buffer->data;
                   1500: 
1.1.1.1 ! misho    1501:        /* If appropriate commit and rotate the lease file */
        !          1502:        (void) commit_leases_timed();
        !          1503: 
1.1       misho    1504:       exit:
                   1505:        /* Cleanup. */
                   1506:        if (reply.shared != NULL)
                   1507:                shared_network_dereference(&reply.shared, MDL);
                   1508:        if (reply.host != NULL)
                   1509:                host_dereference(&reply.host, MDL);
                   1510:        if (reply.opt_state != NULL)
                   1511:                option_state_dereference(&reply.opt_state, MDL);
                   1512:        if (reply.packet != NULL)
                   1513:                packet_dereference(&reply.packet, MDL);
                   1514:        if (reply.client_id.data != NULL)
                   1515:                data_string_forget(&reply.client_id, MDL);
1.1.1.1 ! misho    1516:        if (packet_oro.buffer != NULL)
        !          1517:                data_string_forget(&packet_oro, MDL);
1.1       misho    1518:        reply.renew = reply.rebind = reply.prefer = reply.valid = 0;
                   1519:        reply.cursor = 0;
                   1520: }
                   1521: 
                   1522: /* Process a client-supplied IA_NA.  This may append options to the tail of
                   1523:  * the reply packet being built in the reply_state structure.
                   1524:  */
                   1525: static isc_result_t
                   1526: reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
                   1527:        isc_result_t status = ISC_R_SUCCESS;
                   1528:        u_int32_t iaid;
                   1529:        unsigned ia_cursor;
                   1530:        struct option_state *packet_ia;
                   1531:        struct option_cache *oc;
                   1532:        struct data_string ia_data, data;
                   1533: 
                   1534:        /* Initialize values that will get cleaned up on return. */
                   1535:        packet_ia = NULL;
                   1536:        memset(&ia_data, 0, sizeof(ia_data));
                   1537:        memset(&data, 0, sizeof(data));
                   1538:        /* 
                   1539:         * Note that find_client_address() may set reply->lease. 
                   1540:         */
                   1541: 
                   1542:        /* Make sure there is at least room for the header. */
                   1543:        if ((reply->cursor + IA_NA_OFFSET + 4) > sizeof(reply->buf)) {
                   1544:                log_error("reply_process_ia_na: Reply too long for IA.");
                   1545:                return ISC_R_NOSPACE;
                   1546:        }
                   1547: 
                   1548: 
                   1549:        /* Fetch the IA_NA contents. */
                   1550:        if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
                   1551:                                       ia, IA_NA_OFFSET)) {
                   1552:                log_error("reply_process_ia_na: error evaluating ia");
                   1553:                status = ISC_R_FAILURE;
                   1554:                goto cleanup;
                   1555:        }
                   1556: 
                   1557:        /* Extract IA_NA header contents. */
                   1558:        iaid = getULong(ia_data.data);
                   1559:        reply->renew = getULong(ia_data.data + 4);
                   1560:        reply->rebind = getULong(ia_data.data + 8);
                   1561: 
                   1562:        /* Create an IA_NA structure. */
                   1563:        if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data, 
                   1564:                        reply->client_id.len, MDL) != ISC_R_SUCCESS) {
                   1565:                log_error("reply_process_ia_na: no memory for ia.");
                   1566:                status = ISC_R_NOMEMORY;
                   1567:                goto cleanup;
                   1568:        }
                   1569:        reply->ia->ia_type = D6O_IA_NA;
                   1570: 
                   1571:        /* Cache pre-existing IA, if any. */
                   1572:        ia_hash_lookup(&reply->old_ia, ia_na_active,
                   1573:                       (unsigned char *)reply->ia->iaid_duid.data,
                   1574:                       reply->ia->iaid_duid.len, MDL);
                   1575: 
                   1576:        /*
                   1577:         * Create an option cache to carry the IA_NA option contents, and
                   1578:         * execute any user-supplied values into it.
                   1579:         */
                   1580:        if (!option_state_allocate(&reply->reply_ia, MDL)) {
                   1581:                status = ISC_R_NOMEMORY;
                   1582:                goto cleanup;
                   1583:        }
                   1584: 
                   1585:        /* Check & cache the fixed host record. */
                   1586:        if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
                   1587:                struct iaddr tmp_addr;
                   1588: 
                   1589:                if (!evaluate_option_cache(&reply->fixed, NULL, NULL, NULL,
                   1590:                                           NULL, NULL, &global_scope,
                   1591:                                           reply->host->fixed_addr, MDL)) {
                   1592:                        log_error("reply_process_ia_na: unable to evaluate "
                   1593:                                  "fixed address.");
                   1594:                        status = ISC_R_FAILURE;
                   1595:                        goto cleanup;
                   1596:                }
                   1597: 
                   1598:                if (reply->fixed.len < 16) {
                   1599:                        log_error("reply_process_ia_na: invalid fixed address.");
                   1600:                        status = ISC_R_INVALIDARG;
                   1601:                        goto cleanup;
                   1602:                }
                   1603: 
                   1604:                /* Find the static lease's subnet. */
                   1605:                tmp_addr.len = 16;
                   1606:                memcpy(tmp_addr.iabuf, reply->fixed.data, 16);
                   1607: 
                   1608:                if (find_grouped_subnet(&reply->subnet, reply->shared,
                   1609:                                        tmp_addr, MDL) == 0)
                   1610:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   1611: 
                   1612:                reply->static_lease = ISC_TRUE;
                   1613:        } else
                   1614:                reply->static_lease = ISC_FALSE;
                   1615: 
                   1616:        /*
                   1617:         * Save the cursor position at the start of the IA, so we can
                   1618:         * set length and adjust t1/t2 values later.  We write a temporary
                   1619:         * header out now just in case we decide to adjust the packet
                   1620:         * within sub-process functions.
                   1621:         */
                   1622:        ia_cursor = reply->cursor;
                   1623: 
                   1624:        /* Initialize the IA_NA header.  First the code. */
                   1625:        putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_NA);
                   1626:        reply->cursor += 2;
                   1627: 
                   1628:        /* Then option length. */
                   1629:        putUShort(reply->buf.data + reply->cursor, 0x0Cu);
                   1630:        reply->cursor += 2;
                   1631: 
                   1632:        /* Then IA_NA header contents; IAID. */
                   1633:        putULong(reply->buf.data + reply->cursor, iaid);
                   1634:        reply->cursor += 4;
                   1635: 
                   1636:        /* We store the client's t1 for now, and may over-ride it later. */
                   1637:        putULong(reply->buf.data + reply->cursor, reply->renew);
                   1638:        reply->cursor += 4;
                   1639: 
                   1640:        /* We store the client's t2 for now, and may over-ride it later. */
                   1641:        putULong(reply->buf.data + reply->cursor, reply->rebind);
                   1642:        reply->cursor += 4;
                   1643: 
                   1644:        /* 
                   1645:         * For each address in this IA_NA, decide what to do about it.
                   1646:         *
                   1647:         * Guidelines:
                   1648:         *
                   1649:         * The client leaves unchanged any infomation about addresses
                   1650:         * it has recorded but are not included ("cancel/break" below).
                   1651:         * A not included IA ("cleanup" below) could give a Renew/Rebind.
                   1652:         */
                   1653:        oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
                   1654:        reply->valid = reply->prefer = 0xffffffff;
                   1655:        reply->client_valid = reply->client_prefer = 0;
                   1656:        for (; oc != NULL ; oc = oc->next) {
                   1657:                status = reply_process_addr(reply, oc);
                   1658: 
                   1659:                /*
                   1660:                 * Canceled means we did not allocate addresses to the
                   1661:                 * client, but we're "done" with this IA - we set a status
                   1662:                 * code.  So transmit this reply, e.g., move on to the next
                   1663:                 * IA.
                   1664:                 */
                   1665:                if (status == ISC_R_CANCELED)
                   1666:                        break;
                   1667: 
                   1668:                if ((status != ISC_R_SUCCESS) &&
                   1669:                    (status != ISC_R_ADDRINUSE) &&
                   1670:                    (status != ISC_R_ADDRNOTAVAIL))
                   1671:                        goto cleanup;
                   1672:        }
                   1673: 
                   1674:        reply->ia_count++;
                   1675: 
                   1676:        /*
                   1677:         * If we fell through the above and never gave the client
                   1678:         * an address, give it one now.
                   1679:         */
                   1680:        if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
                   1681:                status = find_client_address(reply);
                   1682: 
                   1683:                if (status == ISC_R_NORESOURCES) {
                   1684:                        switch (reply->packet->dhcpv6_msg_type) {
                   1685:                              case DHCPV6_SOLICIT:
                   1686:                                /*
                   1687:                                 * No address for any IA is handled
                   1688:                                 * by the caller.
                   1689:                                 */
                   1690:                                /* FALL THROUGH */
                   1691: 
                   1692:                              case DHCPV6_REQUEST:
                   1693:                                /* Section 18.2.1 (Request):
                   1694:                                 *
                   1695:                                 * If the server cannot assign any addresses to
                   1696:                                 * an IA in the message from the client, the
                   1697:                                 * server MUST include the IA in the Reply
                   1698:                                 * message with no addresses in the IA and a
                   1699:                                 * Status Code option in the IA containing
                   1700:                                 * status code NoAddrsAvail.
                   1701:                                 */
                   1702:                                option_state_dereference(&reply->reply_ia, MDL);
                   1703:                                if (!option_state_allocate(&reply->reply_ia,
                   1704:                                                           MDL))
                   1705:                                {
                   1706:                                        log_error("reply_process_ia_na: No "
                   1707:                                                  "memory for option state "
                   1708:                                                  "wipe.");
                   1709:                                        status = ISC_R_NOMEMORY;
                   1710:                                        goto cleanup;
                   1711:                                }
                   1712: 
                   1713:                                if (!set_status_code(STATUS_NoAddrsAvail,
                   1714:                                                     "No addresses available "
                   1715:                                                     "for this interface.",
                   1716:                                                      reply->reply_ia)) {
                   1717:                                        log_error("reply_process_ia_na: Unable "
                   1718:                                                  "to set NoAddrsAvail status "
                   1719:                                                  "code.");
                   1720:                                        status = ISC_R_FAILURE;
                   1721:                                        goto cleanup;
                   1722:                                }
                   1723: 
                   1724:                                status = ISC_R_SUCCESS;
                   1725:                                break;
                   1726: 
                   1727:                              default:
                   1728:                                /*
                   1729:                                 * RFC 3315 does not tell us to emit a status
                   1730:                                 * code in this condition, or anything else.
                   1731:                                 *
                   1732:                                 * If we included non-allocated addresses
                   1733:                                 * (zeroed lifetimes) in an IA, then the client
                   1734:                                 * will deconfigure them.
                   1735:                                 *
                   1736:                                 * So we want to include the IA even if we
                   1737:                                 * can't give it a new address if it includes
                   1738:                                 * zeroed lifetime addresses.
                   1739:                                 *
                   1740:                                 * We don't want to include the IA if we
                   1741:                                 * provide zero addresses including zeroed
                   1742:                                 * lifetimes.
                   1743:                                 */
                   1744:                                if (reply->resources_included)
                   1745:                                        status = ISC_R_SUCCESS;
                   1746:                                else
                   1747:                                        goto cleanup;
                   1748:                                break;
                   1749:                        }
                   1750:                }
                   1751: 
                   1752:                if (status != ISC_R_SUCCESS)
                   1753:                        goto cleanup;
                   1754:        }
                   1755: 
                   1756:        reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
                   1757:                                        sizeof(reply->buf) - reply->cursor,
                   1758:                                        reply->reply_ia, reply->packet,
                   1759:                                        required_opts_IA, NULL);
                   1760: 
                   1761:        /* Reset the length of this IA to match what was just written. */
                   1762:        putUShort(reply->buf.data + ia_cursor + 2,
                   1763:                  reply->cursor - (ia_cursor + 4));
                   1764: 
                   1765:        /*
                   1766:         * T1/T2 time selection is kind of weird.  We actually use DHCP
                   1767:         * (v4) scoped options as handy existing places where these might
                   1768:         * be configured by an administrator.  A value of zero tells the
                   1769:         * client it may choose its own renewal time.
                   1770:         */
                   1771:        reply->renew = 0;
                   1772:        oc = lookup_option(&dhcp_universe, reply->opt_state,
                   1773:                           DHO_DHCP_RENEWAL_TIME);
                   1774:        if (oc != NULL) {
                   1775:                if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
                   1776:                                           reply->packet->options,
                   1777:                                           reply->opt_state, &global_scope,
                   1778:                                           oc, MDL) ||
                   1779:                    (data.len != 4)) {
                   1780:                        log_error("Invalid renewal time.");
                   1781:                } else {
                   1782:                        reply->renew = getULong(data.data);
                   1783:                }
                   1784: 
                   1785:                if (data.data != NULL)
                   1786:                        data_string_forget(&data, MDL);
                   1787:        }
                   1788:        putULong(reply->buf.data + ia_cursor + 8, reply->renew);
                   1789: 
                   1790:        /* Now T2. */
                   1791:        reply->rebind = 0;
                   1792:        oc = lookup_option(&dhcp_universe, reply->opt_state,
                   1793:                           DHO_DHCP_REBINDING_TIME);
                   1794:        if (oc != NULL) {
                   1795:                if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
                   1796:                                           reply->packet->options,
                   1797:                                           reply->opt_state, &global_scope,
                   1798:                                           oc, MDL) ||
                   1799:                    (data.len != 4)) {
                   1800:                        log_error("Invalid rebinding time.");
                   1801:                } else {
                   1802:                        reply->rebind = getULong(data.data);
                   1803:                }
                   1804: 
                   1805:                if (data.data != NULL)
                   1806:                        data_string_forget(&data, MDL);
                   1807:        }
                   1808:        putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
                   1809: 
                   1810:        /*
                   1811:         * If this is not a 'soft' binding, consume the new changes into
                   1812:         * the database (if any have been attached to the ia_na).
                   1813:         *
                   1814:         * Loop through the assigned dynamic addresses, referencing the
                   1815:         * leases onto this IA_NA rather than any old ones, and updating
                   1816:         * pool timers for each (if any).
                   1817:         */
                   1818:        if ((status != ISC_R_CANCELED) && !reply->static_lease &&
                   1819:            (reply->buf.reply.msg_type == DHCPV6_REPLY) &&
                   1820:            (reply->ia->num_iasubopt != 0)) {
                   1821:                struct iasubopt *tmp;
                   1822:                struct data_string *ia_id;
                   1823:                int i;
                   1824: 
                   1825:                for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
                   1826:                        tmp = reply->ia->iasubopt[i];
                   1827: 
                   1828:                        if (tmp->ia != NULL)
                   1829:                                ia_dereference(&tmp->ia, MDL);
                   1830:                        ia_reference(&tmp->ia, reply->ia, MDL);
                   1831: 
                   1832:                        /* Commit 'hard' bindings. */
                   1833:                        renew_lease6(tmp->ipv6_pool, tmp);
                   1834:                        schedule_lease_timeout(tmp->ipv6_pool);
                   1835: 
                   1836:                        /*
                   1837:                         * Perform ddns updates.
                   1838:                         */
                   1839:                        oc = lookup_option(&server_universe, reply->opt_state,
                   1840:                                           SV_DDNS_UPDATES);
                   1841:                        if ((oc == NULL) ||
                   1842:                            evaluate_boolean_option_cache(NULL, reply->packet,
                   1843:                                                          NULL, NULL,
                   1844:                                                        reply->packet->options,
                   1845:                                                          reply->opt_state,
                   1846:                                                          &tmp->scope,
                   1847:                                                          oc, MDL)) {
                   1848:                                ddns_updates(reply->packet, NULL, NULL,
                   1849:                                             tmp, NULL, reply->opt_state);
                   1850:                        }
                   1851:                }
                   1852: 
                   1853:                /* Remove any old ia from the hash. */
                   1854:                if (reply->old_ia != NULL) {
                   1855:                        ia_id = &reply->old_ia->iaid_duid;
                   1856:                        ia_hash_delete(ia_na_active,
                   1857:                                       (unsigned char *)ia_id->data,
                   1858:                                       ia_id->len, MDL);
                   1859:                        ia_dereference(&reply->old_ia, MDL);
                   1860:                }
                   1861: 
                   1862:                /* Put new ia into the hash. */
                   1863:                reply->ia->cltt = cur_time;
                   1864:                ia_id = &reply->ia->iaid_duid;
                   1865:                ia_hash_add(ia_na_active, (unsigned char *)ia_id->data,
                   1866:                            ia_id->len, reply->ia, MDL);
                   1867: 
                   1868:                write_ia(reply->ia);
                   1869:        }
                   1870: 
                   1871:       cleanup:
                   1872:        if (packet_ia != NULL)
                   1873:                option_state_dereference(&packet_ia, MDL);
                   1874:        if (reply->reply_ia != NULL)
                   1875:                option_state_dereference(&reply->reply_ia, MDL);
                   1876:        if (ia_data.data != NULL)
                   1877:                data_string_forget(&ia_data, MDL);
                   1878:        if (data.data != NULL)
                   1879:                data_string_forget(&data, MDL);
                   1880:        if (reply->ia != NULL)
                   1881:                ia_dereference(&reply->ia, MDL);
                   1882:        if (reply->old_ia != NULL)
                   1883:                ia_dereference(&reply->old_ia, MDL);
                   1884:        if (reply->lease != NULL)
                   1885:                iasubopt_dereference(&reply->lease, MDL);
                   1886:        if (reply->fixed.data != NULL)
                   1887:                data_string_forget(&reply->fixed, MDL);
                   1888:        if (reply->subnet != NULL)
                   1889:                subnet_dereference(&reply->subnet, MDL);
                   1890: 
                   1891:        /*
                   1892:         * ISC_R_CANCELED is a status code used by the addr processing to
                   1893:         * indicate we're replying with a status code.  This is still a
                   1894:         * success at higher layers.
                   1895:         */
                   1896:        return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
                   1897: }
                   1898: 
                   1899: /*
                   1900:  * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
                   1901:  * into the reply's current ia-scoped option cache.  Returns ISC_R_CANCELED
                   1902:  * in the event we are replying with a status code and do not wish to process
                   1903:  * more IAADDRs within this IA.
                   1904:  */
                   1905: static isc_result_t
                   1906: reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
                   1907:        u_int32_t pref_life, valid_life;
                   1908:        struct binding_scope **scope;
                   1909:        struct group *group;
                   1910:        struct subnet *subnet;
                   1911:        struct iaddr tmp_addr;
                   1912:        struct option_cache *oc;
                   1913:        struct data_string iaaddr, data;
                   1914:        isc_result_t status = ISC_R_SUCCESS;
                   1915: 
                   1916:        /* Initializes values that will be cleaned up. */
                   1917:        memset(&iaaddr, 0, sizeof(iaaddr));
                   1918:        memset(&data, 0, sizeof(data));
                   1919:        /* Note that reply->lease may be set by address_is_owned() */
                   1920: 
                   1921:        /*
                   1922:         * There is no point trying to process an incoming address if there
                   1923:         * is no room for an outgoing address.
                   1924:         */
                   1925:        if ((reply->cursor + 28) > sizeof(reply->buf)) {
                   1926:                log_error("reply_process_addr: Out of room for address.");
                   1927:                return ISC_R_NOSPACE;
                   1928:        }
                   1929: 
                   1930:        /* Extract this IAADDR option. */
                   1931:        if (!evaluate_option_cache(&iaaddr, reply->packet, NULL, NULL, 
                   1932:                                   reply->packet->options, NULL, &global_scope,
                   1933:                                   addr, MDL) ||
                   1934:            (iaaddr.len < IAADDR_OFFSET)) {
                   1935:                log_error("reply_process_addr: error evaluating IAADDR.");
                   1936:                status = ISC_R_FAILURE;
                   1937:                goto cleanup;
                   1938:        }
                   1939: 
                   1940:        /* The first 16 bytes are the IPv6 address. */
                   1941:        pref_life = getULong(iaaddr.data + 16);
                   1942:        valid_life = getULong(iaaddr.data + 20);
                   1943: 
                   1944:        if ((reply->client_valid == 0) ||
                   1945:            (reply->client_valid > valid_life))
                   1946:                reply->client_valid = valid_life;
                   1947: 
                   1948:        if ((reply->client_prefer == 0) ||
                   1949:            (reply->client_prefer > pref_life))
                   1950:                reply->client_prefer = pref_life;
                   1951: 
                   1952:        /* 
                   1953:         * Clients may choose to send :: as an address, with the idea to give
                   1954:         * hints about preferred-lifetime or valid-lifetime.
                   1955:         */
                   1956:        tmp_addr.len = 16;
                   1957:        memset(tmp_addr.iabuf, 0, 16);
                   1958:        if (!memcmp(iaaddr.data, tmp_addr.iabuf, 16)) {
                   1959:                /* Status remains success; we just ignore this one. */
                   1960:                goto cleanup;
                   1961:        }
                   1962: 
                   1963:        /* tmp_addr len remains 16 */
                   1964:        memcpy(tmp_addr.iabuf, iaaddr.data, 16);
                   1965: 
                   1966:        /*
                   1967:         * Verify that this address is on the client's network.
                   1968:         */
                   1969:        for (subnet = reply->shared->subnets ; subnet != NULL ;
                   1970:             subnet = subnet->next_sibling) {
                   1971:                if (addr_eq(subnet_number(tmp_addr, subnet->netmask),
                   1972:                            subnet->net))
                   1973:                        break;
                   1974:        }
                   1975: 
                   1976:        /* Address not found on shared network. */
                   1977:        if (subnet == NULL) {
                   1978:                /* Ignore this address on 'soft' bindings. */
                   1979:                if (reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
                   1980:                        /* disable rapid commit */
                   1981:                        reply->buf.reply.msg_type = DHCPV6_ADVERTISE;
                   1982:                        delete_option(&dhcpv6_universe,
                   1983:                                      reply->opt_state,
                   1984:                                      D6O_RAPID_COMMIT);
                   1985:                        /* status remains success */
                   1986:                        goto cleanup;
                   1987:                }
                   1988: 
                   1989:                /*
                   1990:                 * RFC3315 section 18.2.1:
                   1991:                 *
                   1992:                 * If the server finds that the prefix on one or more IP
                   1993:                 * addresses in any IA in the message from the client is not
                   1994:                 * appropriate for the link to which the client is connected,
                   1995:                 * the server MUST return the IA to the client with a Status
                   1996:                 * Code option with the value NotOnLink.
                   1997:                 */
                   1998:                if (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) {
                   1999:                        /* Rewind the IA_NA to empty. */
                   2000:                        option_state_dereference(&reply->reply_ia, MDL);
                   2001:                        if (!option_state_allocate(&reply->reply_ia, MDL)) {
                   2002:                                log_error("reply_process_addr: No memory for "
                   2003:                                          "option state wipe.");
                   2004:                                status = ISC_R_NOMEMORY;
                   2005:                                goto cleanup;
                   2006:                        }
                   2007: 
                   2008:                        /* Append a NotOnLink status code. */
                   2009:                        if (!set_status_code(STATUS_NotOnLink,
                   2010:                                             "Address not for use on this "
                   2011:                                             "link.", reply->reply_ia)) {
                   2012:                                log_error("reply_process_addr: Failure "
                   2013:                                          "setting status code.");
                   2014:                                status = ISC_R_FAILURE;
                   2015:                                goto cleanup;
                   2016:                        }
                   2017: 
                   2018:                        /* Fin (no more IAADDRs). */
                   2019:                        status = ISC_R_CANCELED;
                   2020:                        goto cleanup;
                   2021:                }
                   2022: 
                   2023:                /*
                   2024:                 * RFC3315 sections 18.2.3 and 18.2.4 have identical language:
                   2025:                 *
                   2026:                 * If the server finds that any of the addresses are not
                   2027:                 * appropriate for the link to which the client is attached,
                   2028:                 * the server returns the address to the client with lifetimes
                   2029:                 * of 0.
                   2030:                 */
                   2031:                if ((reply->packet->dhcpv6_msg_type != DHCPV6_RENEW) &&
                   2032:                    (reply->packet->dhcpv6_msg_type != DHCPV6_REBIND)) {
                   2033:                        log_error("It is impossible to lease a client that is "
                   2034:                                  "not sending a solicit, request, renew, or "
                   2035:                                  "rebind.");
                   2036:                        status = ISC_R_FAILURE;
                   2037:                        goto cleanup;
                   2038:                }
                   2039: 
                   2040:                reply->send_prefer = reply->send_valid = 0;
                   2041:                goto send_addr;
                   2042:        }
                   2043: 
                   2044:        /* Verify the address belongs to the client. */
                   2045:        if (!address_is_owned(reply, &tmp_addr)) {
                   2046:                /*
                   2047:                 * For solicit and request, any addresses included are
                   2048:                 * 'requested' addresses.  For rebind, we actually have
                   2049:                 * no direction on what to do from 3315 section 18.2.4!
                   2050:                 * So I think the best bet is to try and give it out, and if
                   2051:                 * we can't, zero lifetimes.
                   2052:                 */
                   2053:                if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
                   2054:                    (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
                   2055:                    (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
                   2056:                        status = reply_process_try_addr(reply, &tmp_addr);
                   2057: 
                   2058:                        /*
                   2059:                         * If the address is in use, or isn't in any dynamic
                   2060:                         * range, continue as normal.  If any other error was
                   2061:                         * found, error out.
                   2062:                         */
                   2063:                        if ((status != ISC_R_SUCCESS) && 
                   2064:                            (status != ISC_R_ADDRINUSE) &&
                   2065:                            (status != ISC_R_ADDRNOTAVAIL))
                   2066:                                goto cleanup;
                   2067: 
                   2068:                        /*
                   2069:                         * If we didn't honor this lease, for solicit and
                   2070:                         * request we simply omit it from our answer.  For
                   2071:                         * rebind, we send it with zeroed lifetimes.
                   2072:                         */
                   2073:                        if (reply->lease == NULL) {
                   2074:                                if (reply->packet->dhcpv6_msg_type ==
                   2075:                                                        DHCPV6_REBIND) {
                   2076:                                        reply->send_prefer = 0;
                   2077:                                        reply->send_valid = 0;
                   2078:                                        goto send_addr;
                   2079:                                }
                   2080: 
                   2081:                                /* status remains success - ignore */
                   2082:                                goto cleanup;
                   2083:                        }
                   2084:                /*
                   2085:                 * RFC3315 section 18.2.3:
                   2086:                 *
                   2087:                 * If the server cannot find a client entry for the IA the
                   2088:                 * server returns the IA containing no addresses with a Status
                   2089:                 * Code option set to NoBinding in the Reply message.
                   2090:                 *
                   2091:                 * On mismatch we (ab)use this pretending we have not the IA
                   2092:                 * as soon as we have not an address.
                   2093:                 */
                   2094:                } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
                   2095:                        /* Rewind the IA_NA to empty. */
                   2096:                        option_state_dereference(&reply->reply_ia, MDL);
                   2097:                        if (!option_state_allocate(&reply->reply_ia, MDL)) {
                   2098:                                log_error("reply_process_addr: No memory for "
                   2099:                                          "option state wipe.");
                   2100:                                status = ISC_R_NOMEMORY;
                   2101:                                goto cleanup;
                   2102:                        }
                   2103: 
                   2104:                        /* Append a NoBinding status code.  */
                   2105:                        if (!set_status_code(STATUS_NoBinding,
                   2106:                                             "Address not bound to this "
                   2107:                                             "interface.", reply->reply_ia)) {
                   2108:                                log_error("reply_process_addr: Unable to "
                   2109:                                          "attach status code.");
                   2110:                                status = ISC_R_FAILURE;
                   2111:                                goto cleanup;
                   2112:                        }
                   2113: 
                   2114:                        /* Fin (no more IAADDRs). */
                   2115:                        status = ISC_R_CANCELED;
                   2116:                        goto cleanup;
                   2117:                } else {
                   2118:                        log_error("It is impossible to lease a client that is "
                   2119:                                  "not sending a solicit, request, renew, or "
                   2120:                                  "rebind message.");
                   2121:                        status = ISC_R_FAILURE;
                   2122:                        goto cleanup;
                   2123:                }
                   2124:        }
                   2125: 
                   2126:        if (reply->static_lease) {
                   2127:                if (reply->host == NULL)
                   2128:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   2129: 
                   2130:                scope = &global_scope;
                   2131:                group = reply->subnet->group;
                   2132:        } else {
                   2133:                if (reply->lease == NULL)
                   2134:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   2135: 
                   2136:                scope = &reply->lease->scope;
                   2137:                group = reply->lease->ipv6_pool->subnet->group;
                   2138:        }
                   2139: 
                   2140:        /*
                   2141:         * If client_resources is nonzero, then the reply_process_is_addressed
                   2142:         * function has executed configuration state into the reply option
                   2143:         * cache.  We will use that valid cache to derive configuration for
                   2144:         * whether or not to engage in additional addresses, and similar.
                   2145:         */
                   2146:        if (reply->client_resources != 0) {
                   2147:                unsigned limit = 1;
                   2148: 
                   2149:                /*
                   2150:                 * Does this client have "enough" addresses already?  Default
                   2151:                 * to one.  Everybody gets one, and one should be enough for
                   2152:                 * anybody.
                   2153:                 */
                   2154:                oc = lookup_option(&server_universe, reply->opt_state,
                   2155:                                   SV_LIMIT_ADDRS_PER_IA);
                   2156:                if (oc != NULL) {
                   2157:                        if (!evaluate_option_cache(&data, reply->packet,
                   2158:                                                   NULL, NULL,
                   2159:                                                   reply->packet->options,
                   2160:                                                   reply->opt_state,
                   2161:                                                   scope, oc, MDL) ||
                   2162:                            (data.len != 4)) {
                   2163:                                log_error("reply_process_addr: unable to "
                   2164:                                          "evaluate addrs-per-ia value.");
                   2165:                                status = ISC_R_FAILURE;
                   2166:                                goto cleanup;
                   2167:                        }
                   2168: 
                   2169:                        limit = getULong(data.data);
                   2170:                        data_string_forget(&data, MDL);
                   2171:                }
                   2172: 
                   2173:                /*
                   2174:                 * If we wish to limit the client to a certain number of
                   2175:                 * addresses, then omit the address from the reply.
                   2176:                 */
                   2177:                if (reply->client_resources >= limit)
                   2178:                        goto cleanup;
                   2179:        }
                   2180: 
                   2181:        status = reply_process_is_addressed(reply, scope, group);
                   2182:        if (status != ISC_R_SUCCESS)
                   2183:                goto cleanup;
                   2184: 
                   2185:       send_addr:
                   2186:        status = reply_process_send_addr(reply, &tmp_addr);
                   2187: 
                   2188:       cleanup:
                   2189:        if (iaaddr.data != NULL)
                   2190:                data_string_forget(&iaaddr, MDL);
                   2191:        if (data.data != NULL)
                   2192:                data_string_forget(&data, MDL);
                   2193:        if (reply->lease != NULL)
                   2194:                iasubopt_dereference(&reply->lease, MDL);
                   2195: 
                   2196:        return status;
                   2197: }
                   2198: 
                   2199: /*
                   2200:  * Verify the address belongs to the client.  If we've got a host
                   2201:  * record with a fixed address, it has to be the assigned address
                   2202:  * (fault out all else).  Otherwise it's a dynamic address, so lookup
                   2203:  * that address and make sure it belongs to this DUID:IAID pair.
                   2204:  */
                   2205: static isc_boolean_t
                   2206: address_is_owned(struct reply_state *reply, struct iaddr *addr) {
                   2207:        int i;
                   2208: 
                   2209:        /*
                   2210:         * This faults out addresses that don't match fixed addresses.
                   2211:         */
                   2212:        if (reply->static_lease) {
                   2213:                if (reply->fixed.data == NULL)
                   2214:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   2215: 
                   2216:                if (memcmp(addr->iabuf, reply->fixed.data, 16) == 0)
1.1.1.1 ! misho    2217:                        return (ISC_TRUE);
1.1       misho    2218: 
1.1.1.1 ! misho    2219:                return (ISC_FALSE);
1.1       misho    2220:        }
                   2221: 
                   2222:        if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0))
1.1.1.1 ! misho    2223:                return (ISC_FALSE);
1.1       misho    2224: 
                   2225:        for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
                   2226:                struct iasubopt *tmp;
                   2227: 
                   2228:                tmp = reply->old_ia->iasubopt[i];
                   2229: 
                   2230:                if (memcmp(addr->iabuf, &tmp->addr, 16) == 0) {
1.1.1.1 ! misho    2231:                        if (lease6_usable(tmp) == ISC_FALSE) {
        !          2232:                                return (ISC_FALSE);
        !          2233:                        }
1.1       misho    2234:                        iasubopt_reference(&reply->lease, tmp, MDL);
1.1.1.1 ! misho    2235:                        return (ISC_TRUE);
1.1       misho    2236:                }
                   2237:        }
                   2238: 
1.1.1.1 ! misho    2239:        return (ISC_FALSE);
1.1       misho    2240: }
                   2241: 
                   2242: /* Process a client-supplied IA_TA.  This may append options to the tail of
                   2243:  * the reply packet being built in the reply_state structure.
                   2244:  */
                   2245: static isc_result_t
                   2246: reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) {
                   2247:        isc_result_t status = ISC_R_SUCCESS;
                   2248:        u_int32_t iaid;
                   2249:        unsigned ia_cursor;
                   2250:        struct option_state *packet_ia;
                   2251:        struct option_cache *oc;
                   2252:        struct data_string ia_data, data;
                   2253:        struct data_string iaaddr;
                   2254:        u_int32_t pref_life, valid_life;
                   2255:        struct iaddr tmp_addr;
                   2256: 
                   2257:        /* Initialize values that will get cleaned up on return. */
                   2258:        packet_ia = NULL;
                   2259:        memset(&ia_data, 0, sizeof(ia_data));
                   2260:        memset(&data, 0, sizeof(data));
                   2261:        memset(&iaaddr, 0, sizeof(iaaddr));
                   2262: 
                   2263:        /* Make sure there is at least room for the header. */
                   2264:        if ((reply->cursor + IA_TA_OFFSET + 4) > sizeof(reply->buf)) {
                   2265:                log_error("reply_process_ia_ta: Reply too long for IA.");
                   2266:                return ISC_R_NOSPACE;
                   2267:        }
                   2268: 
                   2269: 
                   2270:        /* Fetch the IA_TA contents. */
                   2271:        if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
                   2272:                                       ia, IA_TA_OFFSET)) {
                   2273:                log_error("reply_process_ia_ta: error evaluating ia");
                   2274:                status = ISC_R_FAILURE;
                   2275:                goto cleanup;
                   2276:        }
                   2277: 
                   2278:        /* Extract IA_TA header contents. */
                   2279:        iaid = getULong(ia_data.data);
                   2280: 
                   2281:        /* Create an IA_TA structure. */
                   2282:        if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
                   2283:                        reply->client_id.len, MDL) != ISC_R_SUCCESS) {
                   2284:                log_error("reply_process_ia_ta: no memory for ia.");
                   2285:                status = ISC_R_NOMEMORY;
                   2286:                goto cleanup;
                   2287:        }
                   2288:        reply->ia->ia_type = D6O_IA_TA;
                   2289: 
                   2290:        /* Cache pre-existing IA, if any. */
                   2291:        ia_hash_lookup(&reply->old_ia, ia_ta_active,
                   2292:                       (unsigned char *)reply->ia->iaid_duid.data,
                   2293:                       reply->ia->iaid_duid.len, MDL);
                   2294: 
                   2295:        /*
                   2296:         * Create an option cache to carry the IA_TA option contents, and
                   2297:         * execute any user-supplied values into it.
                   2298:         */
                   2299:        if (!option_state_allocate(&reply->reply_ia, MDL)) {
                   2300:                status = ISC_R_NOMEMORY;
                   2301:                goto cleanup;
                   2302:        }
                   2303: 
                   2304:        /*
                   2305:         * Temporary leases are dynamic by definition.
                   2306:         */
                   2307:        reply->static_lease = ISC_FALSE;
                   2308: 
                   2309:        /*
                   2310:         * Save the cursor position at the start of the IA, so we can
                   2311:         * set length later.  We write a temporary
                   2312:         * header out now just in case we decide to adjust the packet
                   2313:         * within sub-process functions.
                   2314:         */
                   2315:        ia_cursor = reply->cursor;
                   2316: 
                   2317:        /* Initialize the IA_TA header.  First the code. */
                   2318:        putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_TA);
                   2319:        reply->cursor += 2;
                   2320: 
                   2321:        /* Then option length. */
                   2322:        putUShort(reply->buf.data + reply->cursor, 0x04u);
                   2323:        reply->cursor += 2;
                   2324: 
                   2325:        /* Then IA_TA header contents; IAID. */
                   2326:        putULong(reply->buf.data + reply->cursor, iaid);
                   2327:        reply->cursor += 4;
                   2328: 
                   2329:        /* 
                   2330:         * Deal with an IAADDR for lifetimes.
                   2331:         * For all or none, process IAADDRs as hints.
                   2332:         */
                   2333:        reply->valid = reply->prefer = 0xffffffff;
                   2334:        reply->client_valid = reply->client_prefer = 0;
                   2335:        oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAADDR);
                   2336:        for (; oc != NULL; oc = oc->next) {
                   2337:                memset(&iaaddr, 0, sizeof(iaaddr));
                   2338:                if (!evaluate_option_cache(&iaaddr, reply->packet,
                   2339:                                           NULL, NULL,
                   2340:                                           reply->packet->options, NULL,
                   2341:                                           &global_scope, oc, MDL) ||
                   2342:                    (iaaddr.len < IAADDR_OFFSET)) {
                   2343:                        log_error("reply_process_ia_ta: error "
                   2344:                                  "evaluating IAADDR.");
                   2345:                        status = ISC_R_FAILURE;
                   2346:                        goto cleanup;
                   2347:                }
                   2348:                /* The first 16 bytes are the IPv6 address. */
                   2349:                pref_life = getULong(iaaddr.data + 16);
                   2350:                valid_life = getULong(iaaddr.data + 20);
                   2351: 
                   2352:                if ((reply->client_valid == 0) ||
                   2353:                    (reply->client_valid > valid_life))
                   2354:                        reply->client_valid = valid_life;
                   2355: 
                   2356:                if ((reply->client_prefer == 0) ||
                   2357:                    (reply->client_prefer > pref_life))
                   2358:                        reply->client_prefer = pref_life;
                   2359: 
                   2360:                /* Nothing more if something has failed. */
                   2361:                if (status == ISC_R_CANCELED)
                   2362:                        continue;
                   2363: 
                   2364:                tmp_addr.len = 16;
                   2365:                memcpy(tmp_addr.iabuf, iaaddr.data, 16);
                   2366:                if (!temporary_is_available(reply, &tmp_addr))
                   2367:                        goto bad_temp;
                   2368:                status = reply_process_is_addressed(reply,
                   2369:                                                    &reply->lease->scope,
                   2370:                                                    reply->shared->group);
                   2371:                if (status != ISC_R_SUCCESS)
                   2372:                        goto bad_temp;
                   2373:                status = reply_process_send_addr(reply, &tmp_addr);
                   2374:                if (status != ISC_R_SUCCESS)
                   2375:                        goto bad_temp;
                   2376:                if (reply->lease != NULL)
                   2377:                        iasubopt_dereference(&reply->lease, MDL);
                   2378:                continue;
                   2379: 
                   2380:        bad_temp:
                   2381:                /* Rewind the IA_TA to empty. */
                   2382:                option_state_dereference(&reply->reply_ia, MDL);
                   2383:                if (!option_state_allocate(&reply->reply_ia, MDL)) {
                   2384:                        status = ISC_R_NOMEMORY;
                   2385:                        goto cleanup;
                   2386:                }
                   2387:                status = ISC_R_CANCELED;
                   2388:                reply->client_resources = 0;
                   2389:                reply->resources_included = ISC_FALSE;
                   2390:                if (reply->lease != NULL)
                   2391:                        iasubopt_dereference(&reply->lease, MDL);
                   2392:        }
                   2393:        reply->ia_count++;
                   2394: 
                   2395:        /*
                   2396:         * Give the client temporary addresses.
                   2397:         */
                   2398:        if (reply->client_resources != 0)
                   2399:                goto store;
                   2400:        status = find_client_temporaries(reply);
                   2401:        if (status == ISC_R_NORESOURCES) {
                   2402:                switch (reply->packet->dhcpv6_msg_type) {
                   2403:                      case DHCPV6_SOLICIT:
                   2404:                        /*
                   2405:                         * No address for any IA is handled
                   2406:                         * by the caller.
                   2407:                         */
                   2408:                        /* FALL THROUGH */
                   2409: 
                   2410:                      case DHCPV6_REQUEST:
                   2411:                        /* Section 18.2.1 (Request):
                   2412:                         *
                   2413:                         * If the server cannot assign any addresses to
                   2414:                         * an IA in the message from the client, the
                   2415:                         * server MUST include the IA in the Reply
                   2416:                         * message with no addresses in the IA and a
                   2417:                         * Status Code option in the IA containing
                   2418:                         * status code NoAddrsAvail.
                   2419:                         */
                   2420:                        option_state_dereference(&reply->reply_ia, MDL);
                   2421:                        if (!option_state_allocate(&reply->reply_ia,  MDL)) {
                   2422:                                log_error("reply_process_ia_ta: No "
                   2423:                                          "memory for option state wipe.");
                   2424:                                status = ISC_R_NOMEMORY;
                   2425:                                goto cleanup;
                   2426:                        }
                   2427: 
                   2428:                        if (!set_status_code(STATUS_NoAddrsAvail,
                   2429:                                             "No addresses available "
                   2430:                                             "for this interface.",
                   2431:                                              reply->reply_ia)) {
                   2432:                                log_error("reply_process_ia_ta: Unable "
                   2433:                                          "to set NoAddrsAvail status code.");
                   2434:                                status = ISC_R_FAILURE;
                   2435:                                goto cleanup;
                   2436:                        }
                   2437: 
                   2438:                        status = ISC_R_SUCCESS;
                   2439:                        break;
                   2440: 
                   2441:                      default:
                   2442:                        /*
                   2443:                         * We don't want to include the IA if we
                   2444:                         * provide zero addresses including zeroed
                   2445:                         * lifetimes.
                   2446:                         */
                   2447:                        if (reply->resources_included)
                   2448:                                status = ISC_R_SUCCESS;
                   2449:                        else
                   2450:                                goto cleanup;
                   2451:                        break;
                   2452:                }
                   2453:        } else if (status != ISC_R_SUCCESS)
                   2454:                goto cleanup;
                   2455: 
                   2456:       store:
                   2457:        reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
                   2458:                                        sizeof(reply->buf) - reply->cursor,
                   2459:                                        reply->reply_ia, reply->packet,
                   2460:                                        required_opts_IA, NULL);
                   2461: 
                   2462:        /* Reset the length of this IA to match what was just written. */
                   2463:        putUShort(reply->buf.data + ia_cursor + 2,
                   2464:                  reply->cursor - (ia_cursor + 4));
                   2465: 
                   2466:        /*
                   2467:         * Consume the new changes into the database (if any have been
                   2468:         * attached to the ia_ta).
                   2469:         *
                   2470:         * Loop through the assigned dynamic addresses, referencing the
                   2471:         * leases onto this IA_TA rather than any old ones, and updating
                   2472:         * pool timers for each (if any).
                   2473:         */
                   2474:        if ((status != ISC_R_CANCELED) &&
                   2475:            (reply->buf.reply.msg_type == DHCPV6_REPLY) &&
                   2476:            (reply->ia->num_iasubopt != 0)) {
                   2477:                struct iasubopt *tmp;
                   2478:                struct data_string *ia_id;
                   2479:                int i;
                   2480: 
                   2481:                for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
                   2482:                        tmp = reply->ia->iasubopt[i];
                   2483: 
                   2484:                        if (tmp->ia != NULL)
                   2485:                                ia_dereference(&tmp->ia, MDL);
                   2486:                        ia_reference(&tmp->ia, reply->ia, MDL);
                   2487: 
                   2488:                        /* Commit 'hard' bindings. */
                   2489:                        renew_lease6(tmp->ipv6_pool, tmp);
                   2490:                        schedule_lease_timeout(tmp->ipv6_pool);
                   2491: 
                   2492:                        /*
                   2493:                         * Perform ddns updates.
                   2494:                         */
                   2495:                        oc = lookup_option(&server_universe, reply->opt_state,
                   2496:                                           SV_DDNS_UPDATES);
                   2497:                        if ((oc == NULL) ||
                   2498:                            evaluate_boolean_option_cache(NULL, reply->packet,
                   2499:                                                          NULL, NULL,
                   2500:                                                        reply->packet->options,
                   2501:                                                          reply->opt_state,
                   2502:                                                          &tmp->scope,
                   2503:                                                          oc, MDL)) {
                   2504:                                ddns_updates(reply->packet, NULL, NULL,
                   2505:                                             tmp, NULL, reply->opt_state);
                   2506:                        }
                   2507:                }
                   2508: 
                   2509:                /* Remove any old ia from the hash. */
                   2510:                if (reply->old_ia != NULL) {
                   2511:                        ia_id = &reply->old_ia->iaid_duid;
                   2512:                        ia_hash_delete(ia_ta_active,
                   2513:                                       (unsigned char *)ia_id->data,
                   2514:                                       ia_id->len, MDL);
                   2515:                        ia_dereference(&reply->old_ia, MDL);
                   2516:                }
                   2517: 
                   2518:                /* Put new ia into the hash. */
                   2519:                reply->ia->cltt = cur_time;
                   2520:                ia_id = &reply->ia->iaid_duid;
                   2521:                ia_hash_add(ia_ta_active, (unsigned char *)ia_id->data,
                   2522:                            ia_id->len, reply->ia, MDL);
                   2523: 
                   2524:                write_ia(reply->ia);
                   2525:        }
                   2526: 
                   2527:       cleanup:
                   2528:        if (packet_ia != NULL)
                   2529:                option_state_dereference(&packet_ia, MDL);
                   2530:        if (iaaddr.data != NULL)
                   2531:                data_string_forget(&iaaddr, MDL);
                   2532:        if (reply->reply_ia != NULL)
                   2533:                option_state_dereference(&reply->reply_ia, MDL);
                   2534:        if (ia_data.data != NULL)
                   2535:                data_string_forget(&ia_data, MDL);
                   2536:        if (data.data != NULL)
                   2537:                data_string_forget(&data, MDL);
                   2538:        if (reply->ia != NULL)
                   2539:                ia_dereference(&reply->ia, MDL);
                   2540:        if (reply->old_ia != NULL)
                   2541:                ia_dereference(&reply->old_ia, MDL);
                   2542:        if (reply->lease != NULL)
                   2543:                iasubopt_dereference(&reply->lease, MDL);
                   2544: 
                   2545:        /*
                   2546:         * ISC_R_CANCELED is a status code used by the addr processing to
                   2547:         * indicate we're replying with other addresses.  This is still a
                   2548:         * success at higher layers.
                   2549:         */
                   2550:        return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
                   2551: }
                   2552: 
                   2553: /*
                   2554:  * Verify the temporary address is available.
                   2555:  */
                   2556: static isc_boolean_t
                   2557: temporary_is_available(struct reply_state *reply, struct iaddr *addr) {
                   2558:        struct in6_addr tmp_addr;
                   2559:        struct subnet *subnet;
                   2560:        struct ipv6_pool *pool;
                   2561:        int i;
                   2562: 
                   2563:        memcpy(&tmp_addr, addr->iabuf, sizeof(tmp_addr));
                   2564:        /*
                   2565:         * Clients may choose to send :: as an address, with the idea to give
                   2566:         * hints about preferred-lifetime or valid-lifetime.
                   2567:         * So this is not a request for this address.
                   2568:         */
                   2569:        if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr))
                   2570:                return ISC_FALSE;
                   2571: 
                   2572:        /*
                   2573:         * Verify that this address is on the client's network.
                   2574:         */
                   2575:        for (subnet = reply->shared->subnets ; subnet != NULL ;
                   2576:             subnet = subnet->next_sibling) {
                   2577:                if (addr_eq(subnet_number(*addr, subnet->netmask),
                   2578:                            subnet->net))
                   2579:                        break;
                   2580:        }
                   2581: 
                   2582:        /* Address not found on shared network. */
                   2583:        if (subnet == NULL)
                   2584:                return ISC_FALSE;
                   2585: 
                   2586:        /*
                   2587:         * Check if this address is owned (must be before next step).
                   2588:         */
                   2589:        if (address_is_owned(reply, addr))
                   2590:                return ISC_TRUE;
                   2591: 
                   2592:        /*
                   2593:         * Verify that this address is in a temporary pool and try to get it.
                   2594:         */
                   2595:        if (reply->shared->ipv6_pools == NULL)
                   2596:                return ISC_FALSE;
                   2597:        for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) {
                   2598:                if (pool->pool_type != D6O_IA_TA)
                   2599:                        continue;
                   2600:                if (ipv6_in_pool(&tmp_addr, pool))
                   2601:                        break;
                   2602:        }
                   2603:        if (pool == NULL)
                   2604:                return ISC_FALSE;
                   2605:        if (lease6_exists(pool, &tmp_addr))
                   2606:                return ISC_FALSE;
                   2607:        if (iasubopt_allocate(&reply->lease, MDL) != ISC_R_SUCCESS)
                   2608:                return ISC_FALSE;
                   2609:        reply->lease->addr = tmp_addr;
                   2610:        reply->lease->plen = 0;
                   2611:        /* Default is soft binding for 2 minutes. */
                   2612:        if (add_lease6(pool, reply->lease, cur_time + 120) != ISC_R_SUCCESS)
                   2613:                return ISC_FALSE;
                   2614: 
                   2615:        return ISC_TRUE;
                   2616: }
                   2617: 
                   2618: /*
                   2619:  * Get a temporary address per prefix.
                   2620:  */
                   2621: static isc_result_t
                   2622: find_client_temporaries(struct reply_state *reply) {
                   2623:        struct shared_network *shared;
                   2624:        int i;
                   2625:        struct ipv6_pool *p;
                   2626:        isc_result_t status;
                   2627:        unsigned int attempts;
                   2628:        struct iaddr send_addr;
                   2629: 
                   2630:        /*
                   2631:         * No pools, we're done.
                   2632:         */
                   2633:        shared = reply->shared;
                   2634:        if (shared->ipv6_pools == NULL) {
                   2635:                log_debug("Unable to get client addresses: "
                   2636:                          "no IPv6 pools on this shared network");
                   2637:                return ISC_R_NORESOURCES;
                   2638:        }
                   2639: 
                   2640:        status = ISC_R_NORESOURCES;
                   2641:        for (i = 0;; i++) {
                   2642:                p = shared->ipv6_pools[i];
                   2643:                if (p == NULL) {
                   2644:                        break;
                   2645:                }
                   2646:                if (p->pool_type != D6O_IA_TA) {
                   2647:                        continue;
                   2648:                }
                   2649: 
                   2650:                /*
                   2651:                 * Get an address in this temporary pool.
                   2652:                 */
                   2653:                status = create_lease6(p, &reply->lease, &attempts,
                   2654:                                       &reply->client_id, cur_time + 120);
                   2655:                if (status != ISC_R_SUCCESS) {
                   2656:                        log_debug("Unable to get a temporary address.");
                   2657:                        goto cleanup;
                   2658:                }
                   2659: 
                   2660:                status = reply_process_is_addressed(reply,
                   2661:                                                    &reply->lease->scope,
                   2662:                                      reply->lease->ipv6_pool->subnet->group);
                   2663:                if (status != ISC_R_SUCCESS) {
                   2664:                        goto cleanup;
                   2665:                }
                   2666:                send_addr.len = 16;
                   2667:                memcpy(send_addr.iabuf, &reply->lease->addr, 16);
                   2668:                status = reply_process_send_addr(reply, &send_addr);
                   2669:                if (status != ISC_R_SUCCESS) {
                   2670:                        goto cleanup;
                   2671:                }
                   2672:                if (reply->lease != NULL) {
                   2673:                        iasubopt_dereference(&reply->lease, MDL);
                   2674:                }
                   2675:        }
                   2676: 
                   2677:       cleanup:
                   2678:        if (reply->lease != NULL) {
                   2679:                iasubopt_dereference(&reply->lease, MDL);
                   2680:        }
                   2681:        return status;
                   2682: }
                   2683: 
                   2684: /*
                   2685:  * This function only returns failure on 'hard' failures.  If it succeeds,
                   2686:  * it will leave a lease structure behind.
                   2687:  */
                   2688: static isc_result_t
                   2689: reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) {
1.1.1.1 ! misho    2690:        isc_result_t status = ISC_R_ADDRNOTAVAIL;
1.1       misho    2691:        struct ipv6_pool *pool;
                   2692:        int i;
                   2693:        struct data_string data_addr;
                   2694: 
                   2695:        if ((reply == NULL) || (reply->shared == NULL) ||
1.1.1.1 ! misho    2696:            (addr == NULL) || (reply->lease != NULL))
1.1       misho    2697:                return ISC_R_INVALIDARG;
                   2698: 
1.1.1.1 ! misho    2699:        if (reply->shared->ipv6_pools == NULL)
        !          2700:                return (ISC_R_ADDRNOTAVAIL);
        !          2701: 
1.1       misho    2702:        memset(&data_addr, 0, sizeof(data_addr));
                   2703:        data_addr.len = addr->len;
                   2704:        data_addr.data = addr->iabuf;
                   2705: 
                   2706:        for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) {
                   2707:                if (pool->pool_type != D6O_IA_NA)
                   2708:                        continue;
                   2709:                status = try_client_v6_address(&reply->lease, pool,
                   2710:                                               &data_addr);
                   2711:                if (status == ISC_R_SUCCESS)
                   2712:                        break;
                   2713:        }
                   2714: 
                   2715:        /* Note that this is just pedantry.  There is no allocation to free. */
                   2716:        data_string_forget(&data_addr, MDL);
                   2717:        /* Return just the most recent status... */
1.1.1.1 ! misho    2718:        return (status);
1.1       misho    2719: }
                   2720: 
                   2721: /* Look around for an address to give the client.  First, look through the
                   2722:  * old IA for addresses we can extend.  Second, try to allocate a new address.
                   2723:  * Finally, actually add that address into the current reply IA.
                   2724:  */
                   2725: static isc_result_t
                   2726: find_client_address(struct reply_state *reply) {
                   2727:        struct iaddr send_addr;
                   2728:        isc_result_t status = ISC_R_NORESOURCES;
                   2729:        struct iasubopt *lease, *best_lease = NULL;
                   2730:        struct binding_scope **scope;
                   2731:        struct group *group;
                   2732:        int i;
                   2733: 
                   2734:        if (reply->static_lease) {
                   2735:                if (reply->host == NULL)
                   2736:                        return ISC_R_INVALIDARG;
                   2737: 
                   2738:                send_addr.len = 16;
                   2739:                memcpy(send_addr.iabuf, reply->fixed.data, 16);
                   2740: 
                   2741:                status = ISC_R_SUCCESS;
                   2742:                scope = &global_scope;
                   2743:                group = reply->subnet->group;
                   2744:                goto send_addr;
                   2745:        }
                   2746: 
                   2747:        if (reply->old_ia != NULL)  {
                   2748:                for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
                   2749:                        struct shared_network *candidate_shared;
                   2750: 
                   2751:                        lease = reply->old_ia->iasubopt[i];
                   2752:                        candidate_shared = lease->ipv6_pool->shared_network;
                   2753: 
                   2754:                        /*
                   2755:                         * Look for the best lease on the client's shared
                   2756:                         * network.
                   2757:                         */
1.1.1.1 ! misho    2758:                        if ((candidate_shared == reply->shared) && 
        !          2759:                            (lease6_usable(lease) == ISC_TRUE)) {
1.1       misho    2760:                                best_lease = lease_compare(lease, best_lease);
                   2761:                        }
                   2762:                }
                   2763:        }
                   2764: 
                   2765:        /* Try to pick a new address if we didn't find one, or if we found an
                   2766:         * abandoned lease.
                   2767:         */
                   2768:        if ((best_lease == NULL) || (best_lease->state == FTS_ABANDONED)) {
                   2769:                status = pick_v6_address(&reply->lease, reply->shared,
1.1.1.1 ! misho    2770:                                         &reply->ia->iaid_duid);
1.1       misho    2771:        } else if (best_lease != NULL) {
                   2772:                iasubopt_reference(&reply->lease, best_lease, MDL);
                   2773:                status = ISC_R_SUCCESS;
                   2774:        }
                   2775: 
                   2776:        /* Pick the abandoned lease as a last resort. */
                   2777:        if ((status == ISC_R_NORESOURCES) && (best_lease != NULL)) {
                   2778:                /* I don't see how this is supposed to be done right now. */
                   2779:                log_error("Reclaiming abandoned addresses is not yet "
                   2780:                          "supported.  Treating this as an out of space "
                   2781:                          "condition.");
                   2782:                /* iasubopt_reference(&reply->lease, best_lease, MDL); */
                   2783:        }
                   2784: 
                   2785:        /* Give up now if we didn't find a lease. */
                   2786:        if (status != ISC_R_SUCCESS)
                   2787:                return status;
                   2788: 
                   2789:        if (reply->lease == NULL)
                   2790:                log_fatal("Impossible condition at %s:%d.", MDL);
                   2791: 
                   2792:        /* Draw binding scopes from the lease's binding scope, and config
                   2793:         * from the lease's containing subnet and higher.  Note that it may
                   2794:         * be desirable to place the group attachment directly in the pool.
                   2795:         */
                   2796:        scope = &reply->lease->scope;
                   2797:        group = reply->lease->ipv6_pool->subnet->group;
                   2798: 
                   2799:        send_addr.len = 16;
                   2800:        memcpy(send_addr.iabuf, &reply->lease->addr, 16);
                   2801: 
                   2802:       send_addr:
                   2803:        status = reply_process_is_addressed(reply, scope, group);
                   2804:        if (status != ISC_R_SUCCESS)
                   2805:                return status;
                   2806: 
                   2807:        status = reply_process_send_addr(reply, &send_addr);
                   2808:        return status;
                   2809: }
                   2810: 
                   2811: /* Once an address is found for a client, perform several common functions;
                   2812:  * Calculate and store valid and preferred lease times, draw client options
                   2813:  * into the option state.
                   2814:  */
                   2815: static isc_result_t
                   2816: reply_process_is_addressed(struct reply_state *reply,
                   2817:                           struct binding_scope **scope, struct group *group)
                   2818: {
                   2819:        isc_result_t status = ISC_R_SUCCESS;
                   2820:        struct data_string data;
                   2821:        struct option_cache *oc;
                   2822: 
                   2823:        /* Initialize values we will cleanup. */
                   2824:        memset(&data, 0, sizeof(data));
                   2825: 
                   2826:        /*
                   2827:         * Bring configured options into the root packet level cache - start
                   2828:         * with the lease's closest enclosing group (passed in by the caller
                   2829:         * as 'group').
                   2830:         */
                   2831:        execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                   2832:                                    reply->packet->options, reply->opt_state,
                   2833:                                    scope, group, root_group);
                   2834: 
                   2835:        /*
                   2836:         * If there is a host record, over-ride with values configured there,
                   2837:         * without re-evaluating configuration from the previously executed
                   2838:         * group or its common enclosers.
                   2839:         */
                   2840:        if (reply->host != NULL)
                   2841:                execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                   2842:                                            reply->packet->options,
                   2843:                                            reply->opt_state, scope,
                   2844:                                            reply->host->group, group);
                   2845: 
                   2846:        /* Determine valid lifetime. */
                   2847:        if (reply->client_valid == 0)
                   2848:                reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
                   2849:        else
                   2850:                reply->send_valid = reply->client_valid;
                   2851: 
                   2852:        oc = lookup_option(&server_universe, reply->opt_state,
                   2853:                           SV_DEFAULT_LEASE_TIME);
                   2854:        if (oc != NULL) {
                   2855:                if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
                   2856:                                           reply->packet->options,
                   2857:                                           reply->opt_state,
                   2858:                                           scope, oc, MDL) ||
                   2859:                    (data.len != 4)) {
                   2860:                        log_error("reply_process_is_addressed: unable to "
                   2861:                                  "evaluate default lease time");
                   2862:                        status = ISC_R_FAILURE;
                   2863:                        goto cleanup;
                   2864:                }
                   2865: 
                   2866:                reply->send_valid = getULong(data.data);
                   2867:                data_string_forget(&data, MDL);
                   2868:        }
                   2869: 
                   2870:        if (reply->client_prefer == 0)
                   2871:                reply->send_prefer = reply->send_valid;
                   2872:        else
                   2873:                reply->send_prefer = reply->client_prefer;
                   2874: 
                   2875:        if (reply->send_prefer >= reply->send_valid)
                   2876:                reply->send_prefer = (reply->send_valid / 2) +
                   2877:                                     (reply->send_valid / 8);
                   2878: 
                   2879:        oc = lookup_option(&server_universe, reply->opt_state,
                   2880:                           SV_PREFER_LIFETIME);
                   2881:        if (oc != NULL) {
                   2882:                if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
                   2883:                                           reply->packet->options,
                   2884:                                           reply->opt_state,
                   2885:                                           scope, oc, MDL) ||
                   2886:                    (data.len != 4)) {
                   2887:                        log_error("reply_process_is_addressed: unable to "
                   2888:                                  "evaluate preferred lease time");
                   2889:                        status = ISC_R_FAILURE;
                   2890:                        goto cleanup;
                   2891:                }
                   2892: 
                   2893:                reply->send_prefer = getULong(data.data);
                   2894:                data_string_forget(&data, MDL);
                   2895:        }
                   2896: 
                   2897:        /* Note lowest values for later calculation of renew/rebind times. */
                   2898:        if (reply->prefer > reply->send_prefer)
                   2899:                reply->prefer = reply->send_prefer;
                   2900: 
                   2901:        if (reply->valid > reply->send_valid)
                   2902:                reply->valid = reply->send_valid;
                   2903: 
                   2904: #if 0
                   2905:        /*
                   2906:         * XXX: Old 4.0.0 alpha code would change the host {} record
                   2907:         * XXX: uid upon lease assignment.  This was intended to cover the
                   2908:         * XXX: case where a client first identifies itself using vendor
                   2909:         * XXX: options in a solicit, or request, but later neglects to include
                   2910:         * XXX: these options in a Renew or Rebind.  It is not clear that this
                   2911:         * XXX: is required, and has some startling ramifications (such as
                   2912:         * XXX: how to recover this dynamic host {} state across restarts).
                   2913:         */
                   2914:        if (reply->host != NULL)
                   2915:                change_host_uid(host, reply->client_id->data,
                   2916:                                reply->client_id->len);
                   2917: #endif /* 0 */
                   2918: 
                   2919:        /* Perform dynamic lease related update work. */
                   2920:        if (reply->lease != NULL) {
                   2921:                /* Cached lifetimes */
                   2922:                reply->lease->prefer = reply->send_prefer;
                   2923:                reply->lease->valid = reply->send_valid;
                   2924: 
                   2925:                /* Advance (or rewind) the valid lifetime. */
                   2926:                if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
                   2927:                        reply->lease->soft_lifetime_end_time =
                   2928:                                cur_time + reply->send_valid;
                   2929:                        /* Wait before renew! */
                   2930:                }
                   2931: 
                   2932:                status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
                   2933:                if (status != ISC_R_SUCCESS) {
                   2934:                        log_fatal("reply_process_is_addressed: Unable to "
                   2935:                                  "attach lease to new IA: %s",
                   2936:                                  isc_result_totext(status));
                   2937:                }
                   2938: 
                   2939:                /*
                   2940:                 * If this is a new lease, make sure it is attached somewhere.
                   2941:                 */
                   2942:                if (reply->lease->ia == NULL) {
                   2943:                        ia_reference(&reply->lease->ia, reply->ia, MDL);
                   2944:                }
                   2945:        }
                   2946: 
                   2947:        /* Bring a copy of the relevant options into the IA scope. */
                   2948:        execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                   2949:                                    reply->packet->options, reply->reply_ia,
                   2950:                                    scope, group, root_group);
                   2951: 
                   2952:        /*
                   2953:         * And bring in host record configuration, if any, but not to overlap
                   2954:         * the previous group or its common enclosers.
                   2955:         */
                   2956:        if (reply->host != NULL)
                   2957:                execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                   2958:                                            reply->packet->options,
                   2959:                                            reply->reply_ia, scope,
                   2960:                                            reply->host->group, group);
                   2961: 
                   2962:       cleanup:
                   2963:        if (data.data != NULL)
                   2964:                data_string_forget(&data, MDL);
                   2965: 
                   2966:        if (status == ISC_R_SUCCESS)
                   2967:                reply->client_resources++;
                   2968: 
                   2969:        return status;
                   2970: }
                   2971: 
                   2972: /* Simply send an IAADDR within the IA scope as described. */
                   2973: static isc_result_t
                   2974: reply_process_send_addr(struct reply_state *reply, struct iaddr *addr) {
                   2975:        isc_result_t status = ISC_R_SUCCESS;
                   2976:        struct data_string data;
                   2977: 
                   2978:        memset(&data, 0, sizeof(data));
                   2979: 
                   2980:        /* Now append the lease. */
                   2981:        data.len = IAADDR_OFFSET;
                   2982:        if (!buffer_allocate(&data.buffer, data.len, MDL)) {
                   2983:                log_error("reply_process_send_addr: out of memory"
                   2984:                          "allocating new IAADDR buffer.");
                   2985:                status = ISC_R_NOMEMORY;
                   2986:                goto cleanup;
                   2987:        }
                   2988:        data.data = data.buffer->data;
                   2989: 
                   2990:        memcpy(data.buffer->data, addr->iabuf, 16);
                   2991:        putULong(data.buffer->data + 16, reply->send_prefer);
                   2992:        putULong(data.buffer->data + 20, reply->send_valid);
                   2993: 
                   2994:        if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
                   2995:                                  data.buffer, data.buffer->data,
                   2996:                                  data.len, D6O_IAADDR, 0)) {
                   2997:                log_error("reply_process_send_addr: unable "
                   2998:                          "to save IAADDR option");
                   2999:                status = ISC_R_FAILURE;
                   3000:                goto cleanup;
                   3001:        }
                   3002: 
                   3003:        reply->resources_included = ISC_TRUE;
                   3004: 
                   3005:       cleanup:
                   3006:        if (data.data != NULL)
                   3007:                data_string_forget(&data, MDL);
                   3008: 
                   3009:        return status;
                   3010: }
                   3011: 
                   3012: /* Choose the better of two leases. */
                   3013: static struct iasubopt *
                   3014: lease_compare(struct iasubopt *alpha, struct iasubopt *beta) {
                   3015:        if (alpha == NULL)
                   3016:                return beta;
                   3017:        if (beta == NULL)
                   3018:                return alpha;
                   3019: 
                   3020:        switch(alpha->state) {
                   3021:              case FTS_ACTIVE:
                   3022:                switch(beta->state) {
                   3023:                      case FTS_ACTIVE:
                   3024:                        /* Choose the lease with the longest lifetime (most
                   3025:                         * likely the most recently allocated).
                   3026:                         */
                   3027:                        if (alpha->hard_lifetime_end_time < 
                   3028:                            beta->hard_lifetime_end_time)
                   3029:                                return beta;
                   3030:                        else
                   3031:                                return alpha;
                   3032: 
                   3033:                      case FTS_EXPIRED:
                   3034:                      case FTS_ABANDONED:
                   3035:                        return alpha;
                   3036: 
                   3037:                      default:
                   3038:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   3039:                }
                   3040:                break;
                   3041: 
                   3042:              case FTS_EXPIRED:
                   3043:                switch (beta->state) {
                   3044:                      case FTS_ACTIVE:
                   3045:                        return beta;
                   3046: 
                   3047:                      case FTS_EXPIRED:
                   3048:                        /* Choose the most recently expired lease. */
                   3049:                        if (alpha->hard_lifetime_end_time <
                   3050:                            beta->hard_lifetime_end_time)
                   3051:                                return beta;
                   3052:                        else if ((alpha->hard_lifetime_end_time ==
                   3053:                                  beta->hard_lifetime_end_time) &&
                   3054:                                 (alpha->soft_lifetime_end_time <
                   3055:                                  beta->soft_lifetime_end_time))
                   3056:                                return beta;
                   3057:                        else
                   3058:                                return alpha;
                   3059: 
                   3060:                      case FTS_ABANDONED:
                   3061:                        return alpha;
                   3062: 
                   3063:                      default:
                   3064:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   3065:                }
                   3066:                break;
                   3067: 
                   3068:              case FTS_ABANDONED:
                   3069:                switch (beta->state) {
                   3070:                      case FTS_ACTIVE:
                   3071:                      case FTS_EXPIRED:
                   3072:                        return alpha;
                   3073: 
                   3074:                      case FTS_ABANDONED:
                   3075:                        /* Choose the lease that was abandoned longest ago. */
                   3076:                        if (alpha->hard_lifetime_end_time <
                   3077:                            beta->hard_lifetime_end_time)
                   3078:                                return alpha;
                   3079: 
                   3080:                      default:
                   3081:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   3082:                }
                   3083:                break;
                   3084: 
                   3085:              default:
                   3086:                log_fatal("Impossible condition at %s:%d.", MDL);
                   3087:        }
                   3088: 
                   3089:        log_fatal("Triple impossible condition at %s:%d.", MDL);
                   3090:        return NULL;
                   3091: }
                   3092: 
                   3093: /* Process a client-supplied IA_PD.  This may append options to the tail of
                   3094:  * the reply packet being built in the reply_state structure.
                   3095:  */
                   3096: static isc_result_t
                   3097: reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
                   3098:        isc_result_t status = ISC_R_SUCCESS;
                   3099:        u_int32_t iaid;
                   3100:        unsigned ia_cursor;
                   3101:        struct option_state *packet_ia;
                   3102:        struct option_cache *oc;
                   3103:        struct data_string ia_data, data;
                   3104: 
                   3105:        /* Initialize values that will get cleaned up on return. */
                   3106:        packet_ia = NULL;
                   3107:        memset(&ia_data, 0, sizeof(ia_data));
                   3108:        memset(&data, 0, sizeof(data));
                   3109:        /* 
                   3110:         * Note that find_client_prefix() may set reply->lease.
                   3111:         */
                   3112: 
                   3113:        /* Make sure there is at least room for the header. */
                   3114:        if ((reply->cursor + IA_PD_OFFSET + 4) > sizeof(reply->buf)) {
                   3115:                log_error("reply_process_ia_pd: Reply too long for IA.");
                   3116:                return ISC_R_NOSPACE;
                   3117:        }
                   3118: 
                   3119: 
                   3120:        /* Fetch the IA_PD contents. */
                   3121:        if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
                   3122:                                       ia, IA_PD_OFFSET)) {
                   3123:                log_error("reply_process_ia_pd: error evaluating ia");
                   3124:                status = ISC_R_FAILURE;
                   3125:                goto cleanup;
                   3126:        }
                   3127: 
                   3128:        /* Extract IA_PD header contents. */
                   3129:        iaid = getULong(ia_data.data);
                   3130:        reply->renew = getULong(ia_data.data + 4);
                   3131:        reply->rebind = getULong(ia_data.data + 8);
                   3132: 
                   3133:        /* Create an IA_PD structure. */
                   3134:        if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data, 
                   3135:                        reply->client_id.len, MDL) != ISC_R_SUCCESS) {
                   3136:                log_error("reply_process_ia_pd: no memory for ia.");
                   3137:                status = ISC_R_NOMEMORY;
                   3138:                goto cleanup;
                   3139:        }
                   3140:        reply->ia->ia_type = D6O_IA_PD;
                   3141: 
                   3142:        /* Cache pre-existing IA_PD, if any. */
                   3143:        ia_hash_lookup(&reply->old_ia, ia_pd_active,
                   3144:                       (unsigned char *)reply->ia->iaid_duid.data,
                   3145:                       reply->ia->iaid_duid.len, MDL);
                   3146: 
                   3147:        /*
                   3148:         * Create an option cache to carry the IA_PD option contents, and
                   3149:         * execute any user-supplied values into it.
                   3150:         */
                   3151:        if (!option_state_allocate(&reply->reply_ia, MDL)) {
                   3152:                status = ISC_R_NOMEMORY;
                   3153:                goto cleanup;
                   3154:        }
                   3155: 
                   3156:        /* Check & count the fixed prefix host records. */
                   3157:        reply->static_prefixes = 0;
                   3158:        if ((reply->host != NULL) && (reply->host->fixed_prefix != NULL)) {
                   3159:                struct iaddrcidrnetlist *fp;
                   3160: 
                   3161:                for (fp = reply->host->fixed_prefix; fp != NULL;
                   3162:                     fp = fp->next) {
                   3163:                        reply->static_prefixes += 1;
                   3164:                }
                   3165:        }
                   3166: 
                   3167:        /*
                   3168:         * Save the cursor position at the start of the IA_PD, so we can
                   3169:         * set length and adjust t1/t2 values later.  We write a temporary
                   3170:         * header out now just in case we decide to adjust the packet
                   3171:         * within sub-process functions.
                   3172:         */
                   3173:        ia_cursor = reply->cursor;
                   3174: 
                   3175:        /* Initialize the IA_PD header.  First the code. */
                   3176:        putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_PD);
                   3177:        reply->cursor += 2;
                   3178: 
                   3179:        /* Then option length. */
                   3180:        putUShort(reply->buf.data + reply->cursor, 0x0Cu);
                   3181:        reply->cursor += 2;
                   3182: 
                   3183:        /* Then IA_PD header contents; IAID. */
                   3184:        putULong(reply->buf.data + reply->cursor, iaid);
                   3185:        reply->cursor += 4;
                   3186: 
                   3187:        /* We store the client's t1 for now, and may over-ride it later. */
                   3188:        putULong(reply->buf.data + reply->cursor, reply->renew);
                   3189:        reply->cursor += 4;
                   3190: 
                   3191:        /* We store the client's t2 for now, and may over-ride it later. */
                   3192:        putULong(reply->buf.data + reply->cursor, reply->rebind);
                   3193:        reply->cursor += 4;
                   3194: 
                   3195:        /* 
                   3196:         * For each prefix in this IA_PD, decide what to do about it.
                   3197:         */
                   3198:        oc = lookup_option(&dhcpv6_universe, packet_ia, D6O_IAPREFIX);
                   3199:        reply->valid = reply->prefer = 0xffffffff;
                   3200:        reply->client_valid = reply->client_prefer = 0;
                   3201:        reply->preflen = -1;
                   3202:        for (; oc != NULL ; oc = oc->next) {
                   3203:                status = reply_process_prefix(reply, oc);
                   3204: 
                   3205:                /*
                   3206:                 * Canceled means we did not allocate prefixes to the
                   3207:                 * client, but we're "done" with this IA - we set a status
                   3208:                 * code.  So transmit this reply, e.g., move on to the next
                   3209:                 * IA.
                   3210:                 */
                   3211:                if (status == ISC_R_CANCELED)
                   3212:                        break;
                   3213: 
1.1.1.1 ! misho    3214:                if ((status != ISC_R_SUCCESS) &&
        !          3215:                    (status != ISC_R_ADDRINUSE) &&
        !          3216:                    (status != ISC_R_ADDRNOTAVAIL))
1.1       misho    3217:                        goto cleanup;
                   3218:        }
                   3219: 
                   3220:        reply->pd_count++;
                   3221: 
                   3222:        /*
                   3223:         * If we fell through the above and never gave the client
                   3224:         * a prefix, give it one now.
                   3225:         */
                   3226:        if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
                   3227:                status = find_client_prefix(reply);
                   3228: 
                   3229:                if (status == ISC_R_NORESOURCES) {
                   3230:                        switch (reply->packet->dhcpv6_msg_type) {
                   3231:                              case DHCPV6_SOLICIT:
                   3232:                                /*
                   3233:                                 * No prefix for any IA is handled
                   3234:                                 * by the caller.
                   3235:                                 */
                   3236:                                /* FALL THROUGH */
                   3237: 
                   3238:                              case DHCPV6_REQUEST:
                   3239:                                /* Same than for addresses. */
                   3240:                                option_state_dereference(&reply->reply_ia, MDL);
                   3241:                                if (!option_state_allocate(&reply->reply_ia,
                   3242:                                                           MDL))
                   3243:                                {
                   3244:                                        log_error("reply_process_ia_pd: No "
                   3245:                                                  "memory for option state "
                   3246:                                                  "wipe.");
                   3247:                                        status = ISC_R_NOMEMORY;
                   3248:                                        goto cleanup;
                   3249:                                }
                   3250: 
                   3251:                                if (!set_status_code(STATUS_NoPrefixAvail,
                   3252:                                                     "No prefixes available "
                   3253:                                                     "for this interface.",
                   3254:                                                      reply->reply_ia)) {
                   3255:                                        log_error("reply_process_ia_pd: "
                   3256:                                                  "Unable to set "
                   3257:                                                  "NoPrefixAvail status "
                   3258:                                                  "code.");
                   3259:                                        status = ISC_R_FAILURE;
                   3260:                                        goto cleanup;
                   3261:                                }
                   3262: 
                   3263:                                status = ISC_R_SUCCESS;
                   3264:                                break;
                   3265: 
                   3266:                              default:
                   3267:                                if (reply->resources_included)
                   3268:                                        status = ISC_R_SUCCESS;
                   3269:                                else
                   3270:                                        goto cleanup;
                   3271:                                break;
                   3272:                        }
                   3273:                }
                   3274: 
                   3275:                if (status != ISC_R_SUCCESS)
                   3276:                        goto cleanup;
                   3277:        }
                   3278: 
                   3279:        reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
                   3280:                                        sizeof(reply->buf) - reply->cursor,
                   3281:                                        reply->reply_ia, reply->packet,
                   3282:                                        required_opts_IA_PD, NULL);
                   3283: 
                   3284:        /* Reset the length of this IA_PD to match what was just written. */
                   3285:        putUShort(reply->buf.data + ia_cursor + 2,
                   3286:                  reply->cursor - (ia_cursor + 4));
                   3287: 
                   3288:        /*
                   3289:         * T1/T2 time selection is kind of weird.  We actually use DHCP
                   3290:         * (v4) scoped options as handy existing places where these might
                   3291:         * be configured by an administrator.  A value of zero tells the
                   3292:         * client it may choose its own renewal time.
                   3293:         */
                   3294:        reply->renew = 0;
                   3295:        oc = lookup_option(&dhcp_universe, reply->opt_state,
                   3296:                           DHO_DHCP_RENEWAL_TIME);
                   3297:        if (oc != NULL) {
                   3298:                if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
                   3299:                                           reply->packet->options,
                   3300:                                           reply->opt_state, &global_scope,
                   3301:                                           oc, MDL) ||
                   3302:                    (data.len != 4)) {
                   3303:                        log_error("Invalid renewal time.");
                   3304:                } else {
                   3305:                        reply->renew = getULong(data.data);
                   3306:                }
                   3307: 
                   3308:                if (data.data != NULL)
                   3309:                        data_string_forget(&data, MDL);
                   3310:        }
                   3311:        putULong(reply->buf.data + ia_cursor + 8, reply->renew);
                   3312: 
                   3313:        /* Now T2. */
                   3314:        reply->rebind = 0;
                   3315:        oc = lookup_option(&dhcp_universe, reply->opt_state,
                   3316:                           DHO_DHCP_REBINDING_TIME);
                   3317:        if (oc != NULL) {
                   3318:                if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
                   3319:                                           reply->packet->options,
                   3320:                                           reply->opt_state, &global_scope,
                   3321:                                           oc, MDL) ||
                   3322:                    (data.len != 4)) {
                   3323:                        log_error("Invalid rebinding time.");
                   3324:                } else {
                   3325:                        reply->rebind = getULong(data.data);
                   3326:                }
                   3327: 
                   3328:                if (data.data != NULL)
                   3329:                        data_string_forget(&data, MDL);
                   3330:        }
                   3331:        putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
                   3332: 
                   3333:        /*
                   3334:         * If this is not a 'soft' binding, consume the new changes into
                   3335:         * the database (if any have been attached to the ia_pd).
                   3336:         *
                   3337:         * Loop through the assigned dynamic prefixes, referencing the
                   3338:         * prefixes onto this IA_PD rather than any old ones, and updating
                   3339:         * prefix pool timers for each (if any).
                   3340:         */
                   3341:        if ((status != ISC_R_CANCELED) && (reply->static_prefixes == 0) &&
                   3342:            (reply->buf.reply.msg_type == DHCPV6_REPLY) &&
                   3343:            (reply->ia->num_iasubopt != 0)) {
                   3344:                struct iasubopt *tmp;
                   3345:                struct data_string *ia_id;
                   3346:                int i;
                   3347: 
                   3348:                for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
                   3349:                        tmp = reply->ia->iasubopt[i];
                   3350: 
                   3351:                        if (tmp->ia != NULL)
                   3352:                                ia_dereference(&tmp->ia, MDL);
                   3353:                        ia_reference(&tmp->ia, reply->ia, MDL);
                   3354: 
                   3355:                        /* Commit 'hard' bindings. */
                   3356:                        renew_lease6(tmp->ipv6_pool, tmp);
                   3357:                        schedule_lease_timeout(tmp->ipv6_pool);
                   3358:                }
                   3359: 
                   3360:                /* Remove any old ia from the hash. */
                   3361:                if (reply->old_ia != NULL) {
                   3362:                        ia_id = &reply->old_ia->iaid_duid;
                   3363:                        ia_hash_delete(ia_pd_active,
                   3364:                                       (unsigned char *)ia_id->data,
                   3365:                                       ia_id->len, MDL);
                   3366:                        ia_dereference(&reply->old_ia, MDL);
                   3367:                }
                   3368: 
                   3369:                /* Put new ia into the hash. */
                   3370:                reply->ia->cltt = cur_time;
                   3371:                ia_id = &reply->ia->iaid_duid;
                   3372:                ia_hash_add(ia_pd_active, (unsigned char *)ia_id->data,
                   3373:                            ia_id->len, reply->ia, MDL);
                   3374: 
                   3375:                write_ia(reply->ia);
                   3376:        }
                   3377: 
                   3378:       cleanup:
                   3379:        if (packet_ia != NULL)
                   3380:                option_state_dereference(&packet_ia, MDL);
                   3381:        if (reply->reply_ia != NULL)
                   3382:                option_state_dereference(&reply->reply_ia, MDL);
                   3383:        if (ia_data.data != NULL)
                   3384:                data_string_forget(&ia_data, MDL);
                   3385:        if (data.data != NULL)
                   3386:                data_string_forget(&data, MDL);
                   3387:        if (reply->ia != NULL)
                   3388:                ia_dereference(&reply->ia, MDL);
                   3389:        if (reply->old_ia != NULL)
                   3390:                ia_dereference(&reply->old_ia, MDL);
                   3391:        if (reply->lease != NULL)
                   3392:                iasubopt_dereference(&reply->lease, MDL);
                   3393: 
                   3394:        /*
                   3395:         * ISC_R_CANCELED is a status code used by the prefix processing to
                   3396:         * indicate we're replying with a status code.  This is still a
                   3397:         * success at higher layers.
                   3398:         */
                   3399:        return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
                   3400: }
                   3401: 
                   3402: /*
                   3403:  * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
                   3404:  * contents into the reply's current ia_pd-scoped option cache.  Returns
                   3405:  * ISC_R_CANCELED in the event we are replying with a status code and do
                   3406:  * not wish to process more IAPREFIXes within this IA_PD.
                   3407:  */
                   3408: static isc_result_t
                   3409: reply_process_prefix(struct reply_state *reply, struct option_cache *pref) {
                   3410:        u_int32_t pref_life, valid_life;
                   3411:        struct binding_scope **scope;
                   3412:        struct iaddrcidrnet tmp_pref;
                   3413:        struct option_cache *oc;
                   3414:        struct data_string iapref, data;
                   3415:        isc_result_t status = ISC_R_SUCCESS;
                   3416: 
                   3417:        /* Initializes values that will be cleaned up. */
                   3418:        memset(&iapref, 0, sizeof(iapref));
                   3419:        memset(&data, 0, sizeof(data));
                   3420:        /* Note that reply->lease may be set by prefix_is_owned() */
                   3421: 
                   3422:        /*
                   3423:         * There is no point trying to process an incoming prefix if there
                   3424:         * is no room for an outgoing prefix.
                   3425:         */
                   3426:        if ((reply->cursor + 29) > sizeof(reply->buf)) {
                   3427:                log_error("reply_process_prefix: Out of room for prefix.");
                   3428:                return ISC_R_NOSPACE;
                   3429:        }
                   3430: 
                   3431:        /* Extract this IAPREFIX option. */
                   3432:        if (!evaluate_option_cache(&iapref, reply->packet, NULL, NULL, 
                   3433:                                   reply->packet->options, NULL, &global_scope,
                   3434:                                   pref, MDL) ||
                   3435:            (iapref.len < IAPREFIX_OFFSET)) {
                   3436:                log_error("reply_process_prefix: error evaluating IAPREFIX.");
                   3437:                status = ISC_R_FAILURE;
                   3438:                goto cleanup;
                   3439:        }
                   3440: 
                   3441:        /*
                   3442:         * Layout: preferred and valid lifetimes followed by the prefix
                   3443:         * length and the IPv6 address.
                   3444:         */
                   3445:        pref_life = getULong(iapref.data);
                   3446:        valid_life = getULong(iapref.data + 4);
                   3447: 
                   3448:        if ((reply->client_valid == 0) ||
                   3449:            (reply->client_valid > valid_life))
                   3450:                reply->client_valid = valid_life;
                   3451: 
                   3452:        if ((reply->client_prefer == 0) ||
                   3453:            (reply->client_prefer > pref_life))
                   3454:                reply->client_prefer = pref_life;
                   3455: 
                   3456:        /* 
                   3457:         * Clients may choose to send ::/0 as a prefix, with the idea to give
                   3458:         * hints about preferred-lifetime or valid-lifetime.
                   3459:         */
                   3460:        tmp_pref.lo_addr.len = 16;
                   3461:        memset(tmp_pref.lo_addr.iabuf, 0, 16);
                   3462:        if ((iapref.data[8] == 0) &&
                   3463:            (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0)) {
                   3464:                /* Status remains success; we just ignore this one. */
                   3465:                goto cleanup;
                   3466:        }
                   3467: 
                   3468:        /*
                   3469:         * Clients may choose to send ::/X as a prefix to specify a
                   3470:         * preferred/requested prefix length. Note X is never zero here.
                   3471:         */
                   3472:        tmp_pref.bits = (int) iapref.data[8];
                   3473:        if (reply->preflen < 0) {
                   3474:                /* Cache the first preferred prefix length. */
                   3475:                reply->preflen = tmp_pref.bits;
                   3476:        }
                   3477:        if (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0) {
                   3478:                goto cleanup;
                   3479:        }
                   3480: 
                   3481:        memcpy(tmp_pref.lo_addr.iabuf, iapref.data + 9, 16);
                   3482: 
                   3483:        /* Verify the prefix belongs to the client. */
                   3484:        if (!prefix_is_owned(reply, &tmp_pref)) {
                   3485:                /* Same than for addresses. */
                   3486:                if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
                   3487:                    (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
                   3488:                    (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
                   3489:                        status = reply_process_try_prefix(reply, &tmp_pref);
                   3490: 
                   3491:                        /* Either error out or skip this prefix. */
1.1.1.1 ! misho    3492:                        if ((status != ISC_R_SUCCESS) &&
        !          3493:                            (status != ISC_R_ADDRINUSE) &&
        !          3494:                            (status != ISC_R_ADDRNOTAVAIL))
1.1       misho    3495:                                goto cleanup;
                   3496: 
                   3497:                        if (reply->lease == NULL) {
                   3498:                                if (reply->packet->dhcpv6_msg_type ==
                   3499:                                                        DHCPV6_REBIND) {
                   3500:                                        reply->send_prefer = 0;
                   3501:                                        reply->send_valid = 0;
                   3502:                                        goto send_pref;
                   3503:                                }
                   3504: 
                   3505:                                /* status remains success - ignore */
                   3506:                                goto cleanup;
                   3507:                        }
                   3508:                /*
                   3509:                 * RFC3633 section 18.2.3:
                   3510:                 *
                   3511:                 * If the delegating router cannot find a binding
                   3512:                 * for the requesting router's IA_PD the delegating
                   3513:                 * router returns the IA_PD containing no prefixes
                   3514:                 * with a Status Code option set to NoBinding in the
                   3515:                 * Reply message.
                   3516:                 *
                   3517:                 * On mismatch we (ab)use this pretending we have not the IA
                   3518:                 * as soon as we have not a prefix.
                   3519:                 */
                   3520:                } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
                   3521:                        /* Rewind the IA_PD to empty. */
                   3522:                        option_state_dereference(&reply->reply_ia, MDL);
                   3523:                        if (!option_state_allocate(&reply->reply_ia, MDL)) {
                   3524:                                log_error("reply_process_prefix: No memory "
                   3525:                                          "for option state wipe.");
                   3526:                                status = ISC_R_NOMEMORY;
                   3527:                                goto cleanup;
                   3528:                        }
                   3529: 
                   3530:                        /* Append a NoBinding status code.  */
                   3531:                        if (!set_status_code(STATUS_NoBinding,
                   3532:                                             "Prefix not bound to this "
                   3533:                                             "interface.", reply->reply_ia)) {
                   3534:                                log_error("reply_process_prefix: Unable to "
                   3535:                                          "attach status code.");
                   3536:                                status = ISC_R_FAILURE;
                   3537:                                goto cleanup;
                   3538:                        }
                   3539: 
                   3540:                        /* Fin (no more IAPREFIXes). */
                   3541:                        status = ISC_R_CANCELED;
                   3542:                        goto cleanup;
                   3543:                } else {
                   3544:                        log_error("It is impossible to lease a client that is "
                   3545:                                  "not sending a solicit, request, renew, or "
                   3546:                                  "rebind message.");
                   3547:                        status = ISC_R_FAILURE;
                   3548:                        goto cleanup;
                   3549:                }
                   3550:        }
                   3551: 
                   3552:        if (reply->static_prefixes > 0) {
                   3553:                if (reply->host == NULL)
                   3554:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   3555: 
                   3556:                scope = &global_scope;
                   3557:        } else {
                   3558:                if (reply->lease == NULL)
                   3559:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   3560: 
                   3561:                scope = &reply->lease->scope;
                   3562:        }
                   3563: 
                   3564:        /*
                   3565:         * If client_resources is nonzero, then the reply_process_is_prefixed
                   3566:         * function has executed configuration state into the reply option
                   3567:         * cache.  We will use that valid cache to derive configuration for
                   3568:         * whether or not to engage in additional prefixes, and similar.
                   3569:         */
                   3570:        if (reply->client_resources != 0) {
                   3571:                unsigned limit = 1;
                   3572: 
                   3573:                /*
                   3574:                 * Does this client have "enough" prefixes already?  Default
                   3575:                 * to one.  Everybody gets one, and one should be enough for
                   3576:                 * anybody.
                   3577:                 */
                   3578:                oc = lookup_option(&server_universe, reply->opt_state,
                   3579:                                   SV_LIMIT_PREFS_PER_IA);
                   3580:                if (oc != NULL) {
                   3581:                        if (!evaluate_option_cache(&data, reply->packet,
                   3582:                                                   NULL, NULL,
                   3583:                                                   reply->packet->options,
                   3584:                                                   reply->opt_state,
                   3585:                                                   scope, oc, MDL) ||
                   3586:                            (data.len != 4)) {
                   3587:                                log_error("reply_process_prefix: unable to "
                   3588:                                          "evaluate prefs-per-ia value.");
                   3589:                                status = ISC_R_FAILURE;
                   3590:                                goto cleanup;
                   3591:                        }
                   3592: 
                   3593:                        limit = getULong(data.data);
                   3594:                        data_string_forget(&data, MDL);
                   3595:                }
                   3596: 
                   3597:                /*
                   3598:                 * If we wish to limit the client to a certain number of
                   3599:                 * prefixes, then omit the prefix from the reply.
                   3600:                 */
                   3601:                if (reply->client_resources >= limit)
                   3602:                        goto cleanup;
                   3603:        }
                   3604: 
                   3605:        status = reply_process_is_prefixed(reply, scope, reply->shared->group);
                   3606:        if (status != ISC_R_SUCCESS)
                   3607:                goto cleanup;
                   3608: 
                   3609:       send_pref:
                   3610:        status = reply_process_send_prefix(reply, &tmp_pref);
                   3611: 
                   3612:       cleanup:
                   3613:        if (iapref.data != NULL)
                   3614:                data_string_forget(&iapref, MDL);
                   3615:        if (data.data != NULL)
                   3616:                data_string_forget(&data, MDL);
                   3617:        if (reply->lease != NULL)
                   3618:                iasubopt_dereference(&reply->lease, MDL);
                   3619: 
                   3620:        return status;
                   3621: }
                   3622: 
                   3623: /*
                   3624:  * Verify the prefix belongs to the client.  If we've got a host
                   3625:  * record with fixed prefixes, it has to be an assigned prefix
                   3626:  * (fault out all else).  Otherwise it's a dynamic prefix, so lookup
                   3627:  * that prefix and make sure it belongs to this DUID:IAID pair.
                   3628:  */
                   3629: static isc_boolean_t
                   3630: prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) {
                   3631:        struct iaddrcidrnetlist *l;
                   3632:        int i;
                   3633: 
                   3634:        /*
                   3635:         * This faults out prefixes that don't match fixed prefixes.
                   3636:         */
                   3637:        if (reply->static_prefixes > 0) {
                   3638:                for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
                   3639:                        if ((pref->bits == l->cidrnet.bits) &&
                   3640:                            (memcmp(pref->lo_addr.iabuf,
                   3641:                                    l->cidrnet.lo_addr.iabuf, 16) == 0))
1.1.1.1 ! misho    3642:                                return (ISC_TRUE);
1.1       misho    3643:                }
1.1.1.1 ! misho    3644:                return (ISC_FALSE);
1.1       misho    3645:        }
                   3646: 
                   3647:        if ((reply->old_ia == NULL) ||
                   3648:            (reply->old_ia->num_iasubopt == 0))
1.1.1.1 ! misho    3649:                return (ISC_FALSE);
1.1       misho    3650: 
                   3651:        for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
                   3652:                struct iasubopt *tmp;
                   3653: 
                   3654:                tmp = reply->old_ia->iasubopt[i];
                   3655: 
                   3656:                if ((pref->bits == (int) tmp->plen) &&
1.1.1.1 ! misho    3657:                    (memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0)) {
        !          3658:                        if (lease6_usable(tmp) == ISC_FALSE) {
        !          3659:                                return (ISC_FALSE);
        !          3660:                        }
1.1       misho    3661:                        iasubopt_reference(&reply->lease, tmp, MDL);
1.1.1.1 ! misho    3662:                        return (ISC_TRUE);
1.1       misho    3663:                }
                   3664:        }
                   3665: 
1.1.1.1 ! misho    3666:        return (ISC_FALSE);
1.1       misho    3667: }
                   3668: 
                   3669: /*
                   3670:  * This function only returns failure on 'hard' failures.  If it succeeds,
                   3671:  * it will leave a prefix structure behind.
                   3672:  */
                   3673: static isc_result_t
                   3674: reply_process_try_prefix(struct reply_state *reply,
                   3675:                         struct iaddrcidrnet *pref) {
1.1.1.1 ! misho    3676:        isc_result_t status = ISC_R_ADDRNOTAVAIL;
1.1       misho    3677:        struct ipv6_pool *pool;
                   3678:        int i;
                   3679:        struct data_string data_pref;
                   3680: 
                   3681:        if ((reply == NULL) || (reply->shared == NULL) ||
1.1.1.1 ! misho    3682:            (pref == NULL) || (reply->lease != NULL))
1.1       misho    3683:                return ISC_R_INVALIDARG;
                   3684: 
1.1.1.1 ! misho    3685:        if (reply->shared->ipv6_pools == NULL)
        !          3686:                return (ISC_R_ADDRNOTAVAIL);
        !          3687: 
1.1       misho    3688:        memset(&data_pref, 0, sizeof(data_pref));
                   3689:        data_pref.len = 17;
                   3690:        if (!buffer_allocate(&data_pref.buffer, data_pref.len, MDL)) {
                   3691:                log_error("reply_process_try_prefix: out of memory.");
1.1.1.1 ! misho    3692:                return (ISC_R_NOMEMORY);
1.1       misho    3693:        }
                   3694:        data_pref.data = data_pref.buffer->data;
                   3695:        data_pref.buffer->data[0] = (u_int8_t) pref->bits;
                   3696:        memcpy(data_pref.buffer->data + 1, pref->lo_addr.iabuf, 16);
                   3697: 
                   3698:        for (i = 0 ; (pool = reply->shared->ipv6_pools[i]) != NULL ; i++) {
                   3699:                if (pool->pool_type != D6O_IA_PD)
                   3700:                        continue;
                   3701:                status = try_client_v6_prefix(&reply->lease, pool,
                   3702:                                              &data_pref);
                   3703:                 /* If we found it in this pool (either in use or available), 
                   3704:                    there is no need to look further. */
                   3705:                if ( (status == ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
                   3706:                        break;
                   3707:        }
                   3708: 
                   3709:        data_string_forget(&data_pref, MDL);
                   3710:        /* Return just the most recent status... */
1.1.1.1 ! misho    3711:        return (status);
1.1       misho    3712: }
                   3713: 
                   3714: /* Look around for a prefix to give the client.  First, look through the old
                   3715:  * IA_PD for prefixes we can extend.  Second, try to allocate a new prefix.
                   3716:  * Finally, actually add that prefix into the current reply IA_PD.
                   3717:  */
                   3718: static isc_result_t
                   3719: find_client_prefix(struct reply_state *reply) {
                   3720:        struct iaddrcidrnet send_pref;
                   3721:        isc_result_t status = ISC_R_NORESOURCES;
                   3722:        struct iasubopt *prefix, *best_prefix = NULL;
                   3723:        struct binding_scope **scope;
                   3724:        int i;
                   3725: 
                   3726:        if (reply->static_prefixes > 0) {
                   3727:                struct iaddrcidrnetlist *l;
                   3728: 
                   3729:                if (reply->host == NULL)
                   3730:                        return ISC_R_INVALIDARG;
                   3731: 
                   3732:                for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
                   3733:                        if (l->cidrnet.bits == reply->preflen)
                   3734:                                break;
                   3735:                }
                   3736:                if (l == NULL) {
                   3737:                        /*
                   3738:                         * If no fixed prefix has the preferred length,
                   3739:                         * get the first one.
                   3740:                         */
                   3741:                        l = reply->host->fixed_prefix;
                   3742:                }
                   3743:                memcpy(&send_pref, &l->cidrnet, sizeof(send_pref));
                   3744: 
                   3745:                status = ISC_R_SUCCESS;
                   3746:                scope = &global_scope;
                   3747:                goto send_pref;
                   3748:        }
                   3749: 
                   3750:        if (reply->old_ia != NULL)  {
                   3751:                for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
                   3752:                        struct shared_network *candidate_shared;
                   3753: 
                   3754:                        prefix = reply->old_ia->iasubopt[i];
                   3755:                        candidate_shared = prefix->ipv6_pool->shared_network;
                   3756: 
                   3757:                        /*
                   3758:                         * Consider this prefix if it is in a global pool or
                   3759:                         * if it is scoped in a pool under the client's shared
                   3760:                         * network.
                   3761:                         */
1.1.1.1 ! misho    3762:                        if (((candidate_shared == NULL) ||
        !          3763:                             (candidate_shared == reply->shared)) &&
        !          3764:                            (lease6_usable(prefix) == ISC_TRUE)) {
1.1       misho    3765:                                best_prefix = prefix_compare(reply, prefix,
                   3766:                                                             best_prefix);
                   3767:                        }
                   3768:                }
                   3769:        }
                   3770: 
                   3771:        /* Try to pick a new prefix if we didn't find one, or if we found an
                   3772:         * abandoned prefix.
                   3773:         */
                   3774:        if ((best_prefix == NULL) || (best_prefix->state == FTS_ABANDONED)) {
                   3775:                status = pick_v6_prefix(&reply->lease, reply->preflen,
                   3776:                                        reply->shared, &reply->client_id);
                   3777:        } else if (best_prefix != NULL) {
                   3778:                iasubopt_reference(&reply->lease, best_prefix, MDL);
                   3779:                status = ISC_R_SUCCESS;
                   3780:        }
                   3781: 
                   3782:        /* Pick the abandoned prefix as a last resort. */
                   3783:        if ((status == ISC_R_NORESOURCES) && (best_prefix != NULL)) {
                   3784:                /* I don't see how this is supposed to be done right now. */
                   3785:                log_error("Reclaiming abandoned prefixes is not yet "
                   3786:                          "supported.  Treating this as an out of space "
                   3787:                          "condition.");
                   3788:                /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
                   3789:        }
                   3790: 
                   3791:        /* Give up now if we didn't find a prefix. */
                   3792:        if (status != ISC_R_SUCCESS)
                   3793:                return status;
                   3794: 
                   3795:        if (reply->lease == NULL)
                   3796:                log_fatal("Impossible condition at %s:%d.", MDL);
                   3797: 
                   3798:        scope = &reply->lease->scope;
                   3799: 
                   3800:        send_pref.lo_addr.len = 16;
                   3801:        memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
                   3802:        send_pref.bits = (int) reply->lease->plen;
                   3803: 
                   3804:       send_pref:
                   3805:        status = reply_process_is_prefixed(reply, scope, reply->shared->group);
                   3806:        if (status != ISC_R_SUCCESS)
                   3807:                return status;
                   3808: 
                   3809:        status = reply_process_send_prefix(reply, &send_pref);
                   3810:        return status;
                   3811: }
                   3812: 
                   3813: /* Once a prefix is found for a client, perform several common functions;
                   3814:  * Calculate and store valid and preferred prefix times, draw client options
                   3815:  * into the option state.
                   3816:  */
                   3817: static isc_result_t
                   3818: reply_process_is_prefixed(struct reply_state *reply,
                   3819:                          struct binding_scope **scope, struct group *group)
                   3820: {
                   3821:        isc_result_t status = ISC_R_SUCCESS;
                   3822:        struct data_string data;
                   3823:        struct option_cache *oc;
                   3824: 
                   3825:        /* Initialize values we will cleanup. */
                   3826:        memset(&data, 0, sizeof(data));
                   3827: 
                   3828:        /*
                   3829:         * Bring configured options into the root packet level cache - start
                   3830:         * with the lease's closest enclosing group (passed in by the caller
                   3831:         * as 'group').
                   3832:         */
                   3833:        execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                   3834:                                    reply->packet->options, reply->opt_state,
                   3835:                                    scope, group, root_group);
                   3836: 
                   3837:        /*
                   3838:         * If there is a host record, over-ride with values configured there,
                   3839:         * without re-evaluating configuration from the previously executed
                   3840:         * group or its common enclosers.
                   3841:         */
                   3842:        if (reply->host != NULL)
                   3843:                execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                   3844:                                            reply->packet->options,
                   3845:                                            reply->opt_state, scope,
                   3846:                                            reply->host->group, group);
                   3847: 
                   3848:        /* Determine valid lifetime. */
                   3849:        if (reply->client_valid == 0)
                   3850:                reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
                   3851:        else
                   3852:                reply->send_valid = reply->client_valid;
                   3853: 
                   3854:        oc = lookup_option(&server_universe, reply->opt_state,
                   3855:                           SV_DEFAULT_LEASE_TIME);
                   3856:        if (oc != NULL) {
                   3857:                if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
                   3858:                                           reply->packet->options,
                   3859:                                           reply->opt_state,
                   3860:                                           scope, oc, MDL) ||
                   3861:                    (data.len != 4)) {
                   3862:                        log_error("reply_process_is_prefixed: unable to "
                   3863:                                  "evaluate default prefix time");
                   3864:                        status = ISC_R_FAILURE;
                   3865:                        goto cleanup;
                   3866:                }
                   3867: 
                   3868:                reply->send_valid = getULong(data.data);
                   3869:                data_string_forget(&data, MDL);
                   3870:        }
                   3871: 
                   3872:        if (reply->client_prefer == 0)
                   3873:                reply->send_prefer = reply->send_valid;
                   3874:        else
                   3875:                reply->send_prefer = reply->client_prefer;
                   3876: 
                   3877:        if (reply->send_prefer >= reply->send_valid)
                   3878:                reply->send_prefer = (reply->send_valid / 2) +
                   3879:                                     (reply->send_valid / 8);
                   3880: 
                   3881:        oc = lookup_option(&server_universe, reply->opt_state,
                   3882:                           SV_PREFER_LIFETIME);
                   3883:        if (oc != NULL) {
                   3884:                if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
                   3885:                                           reply->packet->options,
                   3886:                                           reply->opt_state,
                   3887:                                           scope, oc, MDL) ||
                   3888:                    (data.len != 4)) {
                   3889:                        log_error("reply_process_is_prefixed: unable to "
                   3890:                                  "evaluate preferred prefix time");
                   3891:                        status = ISC_R_FAILURE;
                   3892:                        goto cleanup;
                   3893:                }
                   3894: 
                   3895:                reply->send_prefer = getULong(data.data);
                   3896:                data_string_forget(&data, MDL);
                   3897:        }
                   3898: 
                   3899:        /* Note lowest values for later calculation of renew/rebind times. */
                   3900:        if (reply->prefer > reply->send_prefer)
                   3901:                reply->prefer = reply->send_prefer;
                   3902: 
                   3903:        if (reply->valid > reply->send_valid)
                   3904:                reply->valid = reply->send_valid;
                   3905: 
                   3906:        /* Perform dynamic prefix related update work. */
                   3907:        if (reply->lease != NULL) {
                   3908:                /* Cached lifetimes */
                   3909:                reply->lease->prefer = reply->send_prefer;
                   3910:                reply->lease->valid = reply->send_valid;
                   3911: 
                   3912:                /* Advance (or rewind) the valid lifetime. */
                   3913:                if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
                   3914:                        reply->lease->soft_lifetime_end_time =
                   3915:                                cur_time + reply->send_valid;
                   3916:                        /* Wait before renew! */
                   3917:                }
                   3918: 
                   3919:                status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
                   3920:                if (status != ISC_R_SUCCESS) {
                   3921:                        log_fatal("reply_process_is_prefixed: Unable to "
                   3922:                                  "attach prefix to new IA_PD: %s",
                   3923:                                  isc_result_totext(status));
                   3924:                }
                   3925: 
                   3926:                /*
                   3927:                 * If this is a new prefix, make sure it is attached somewhere.
                   3928:                 */
                   3929:                if (reply->lease->ia == NULL) {
                   3930:                        ia_reference(&reply->lease->ia, reply->ia, MDL);
                   3931:                }
                   3932:        }
                   3933: 
                   3934:        /* Bring a copy of the relevant options into the IA_PD scope. */
                   3935:        execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                   3936:                                    reply->packet->options, reply->reply_ia,
                   3937:                                    scope, group, root_group);
                   3938: 
                   3939:        /*
                   3940:         * And bring in host record configuration, if any, but not to overlap
                   3941:         * the previous group or its common enclosers.
                   3942:         */
                   3943:        if (reply->host != NULL)
                   3944:                execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                   3945:                                            reply->packet->options,
                   3946:                                            reply->reply_ia, scope,
                   3947:                                            reply->host->group, group);
                   3948: 
                   3949:       cleanup:
                   3950:        if (data.data != NULL)
                   3951:                data_string_forget(&data, MDL);
                   3952: 
                   3953:        if (status == ISC_R_SUCCESS)
                   3954:                reply->client_resources++;
                   3955: 
                   3956:        return status;
                   3957: }
                   3958: 
                   3959: /* Simply send an IAPREFIX within the IA_PD scope as described. */
                   3960: static isc_result_t
                   3961: reply_process_send_prefix(struct reply_state *reply,
                   3962:                          struct iaddrcidrnet *pref) {
                   3963:        isc_result_t status = ISC_R_SUCCESS;
                   3964:        struct data_string data;
                   3965: 
                   3966:        memset(&data, 0, sizeof(data));
                   3967: 
                   3968:        /* Now append the prefix. */
                   3969:        data.len = IAPREFIX_OFFSET;
                   3970:        if (!buffer_allocate(&data.buffer, data.len, MDL)) {
                   3971:                log_error("reply_process_send_prefix: out of memory"
                   3972:                          "allocating new IAPREFIX buffer.");
                   3973:                status = ISC_R_NOMEMORY;
                   3974:                goto cleanup;
                   3975:        }
                   3976:        data.data = data.buffer->data;
                   3977: 
                   3978:        putULong(data.buffer->data, reply->send_prefer);
                   3979:        putULong(data.buffer->data + 4, reply->send_valid);
                   3980:        data.buffer->data[8] = pref->bits;
                   3981:        memcpy(data.buffer->data + 9, pref->lo_addr.iabuf, 16);
                   3982: 
                   3983:        if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
                   3984:                                  data.buffer, data.buffer->data,
                   3985:                                  data.len, D6O_IAPREFIX, 0)) {
                   3986:                log_error("reply_process_send_prefix: unable "
                   3987:                          "to save IAPREFIX option");
                   3988:                status = ISC_R_FAILURE;
                   3989:                goto cleanup;
                   3990:        }
                   3991: 
                   3992:        reply->resources_included = ISC_TRUE;
                   3993: 
                   3994:       cleanup:
                   3995:        if (data.data != NULL)
                   3996:                data_string_forget(&data, MDL);
                   3997: 
                   3998:        return status;
                   3999: }
                   4000: 
                   4001: /* Choose the better of two prefixes. */
                   4002: static struct iasubopt *
                   4003: prefix_compare(struct reply_state *reply,
                   4004:               struct iasubopt *alpha, struct iasubopt *beta) {
                   4005:        if (alpha == NULL)
                   4006:                return beta;
                   4007:        if (beta == NULL)
                   4008:                return alpha;
                   4009: 
                   4010:        if (reply->preflen >= 0) {
                   4011:                if ((alpha->plen == reply->preflen) &&
                   4012:                    (beta->plen != reply->preflen))
                   4013:                        return alpha;
                   4014:                if ((beta->plen == reply->preflen) &&
                   4015:                    (alpha->plen != reply->preflen))
                   4016:                        return beta;
                   4017:        }
                   4018: 
                   4019:        switch(alpha->state) {
                   4020:              case FTS_ACTIVE:
                   4021:                switch(beta->state) {
                   4022:                      case FTS_ACTIVE:
                   4023:                        /* Choose the prefix with the longest lifetime (most
                   4024:                         * likely the most recently allocated).
                   4025:                         */
                   4026:                        if (alpha->hard_lifetime_end_time < 
                   4027:                            beta->hard_lifetime_end_time)
                   4028:                                return beta;
                   4029:                        else
                   4030:                                return alpha;
                   4031: 
                   4032:                      case FTS_EXPIRED:
                   4033:                      case FTS_ABANDONED:
                   4034:                        return alpha;
                   4035: 
                   4036:                      default:
                   4037:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   4038:                }
                   4039:                break;
                   4040: 
                   4041:              case FTS_EXPIRED:
                   4042:                switch (beta->state) {
                   4043:                      case FTS_ACTIVE:
                   4044:                        return beta;
                   4045: 
                   4046:                      case FTS_EXPIRED:
                   4047:                        /* Choose the most recently expired prefix. */
                   4048:                        if (alpha->hard_lifetime_end_time <
                   4049:                            beta->hard_lifetime_end_time)
                   4050:                                return beta;
                   4051:                        else if ((alpha->hard_lifetime_end_time ==
                   4052:                                  beta->hard_lifetime_end_time) &&
                   4053:                                 (alpha->soft_lifetime_end_time <
                   4054:                                  beta->soft_lifetime_end_time))
                   4055:                                return beta;
                   4056:                        else
                   4057:                                return alpha;
                   4058: 
                   4059:                      case FTS_ABANDONED:
                   4060:                        return alpha;
                   4061: 
                   4062:                      default:
                   4063:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   4064:                }
                   4065:                break;
                   4066: 
                   4067:              case FTS_ABANDONED:
                   4068:                switch (beta->state) {
                   4069:                      case FTS_ACTIVE:
                   4070:                      case FTS_EXPIRED:
                   4071:                        return alpha;
                   4072: 
                   4073:                      case FTS_ABANDONED:
                   4074:                        /* Choose the prefix that was abandoned longest ago. */
                   4075:                        if (alpha->hard_lifetime_end_time <
                   4076:                            beta->hard_lifetime_end_time)
                   4077:                                return alpha;
                   4078: 
                   4079:                      default:
                   4080:                        log_fatal("Impossible condition at %s:%d.", MDL);
                   4081:                }
                   4082:                break;
                   4083: 
                   4084:              default:
                   4085:                log_fatal("Impossible condition at %s:%d.", MDL);
                   4086:        }
                   4087: 
                   4088:        log_fatal("Triple impossible condition at %s:%d.", MDL);
                   4089:        return NULL;
                   4090: }
                   4091: 
                   4092: /*
                   4093:  * Solicit is how a client starts requesting addresses.
                   4094:  *
                   4095:  * If the client asks for rapid commit, and we support it, we will 
                   4096:  * allocate the addresses and reply.
                   4097:  *
                   4098:  * Otherwise we will send an advertise message.
                   4099:  */
                   4100: 
                   4101: static void
                   4102: dhcpv6_solicit(struct data_string *reply_ret, struct packet *packet) {
                   4103:        struct data_string client_id;
                   4104: 
                   4105:        /* 
                   4106:         * Validate our input.
                   4107:         */
                   4108:        if (!valid_client_msg(packet, &client_id)) {
                   4109:                return;
                   4110:        }
                   4111: 
                   4112:        lease_to_client(reply_ret, packet, &client_id, NULL);
                   4113: 
                   4114:        /*
                   4115:         * Clean up.
                   4116:         */
                   4117:        data_string_forget(&client_id, MDL);
                   4118: }
                   4119: 
                   4120: /*
                   4121:  * Request is how a client actually requests addresses.
                   4122:  *
                   4123:  * Very similar to Solicit handling, except the server DUID is required.
                   4124:  */
                   4125: 
                   4126: /* TODO: reject unicast messages, unless we set unicast option */
                   4127: static void
                   4128: dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
                   4129:        struct data_string client_id;
                   4130:        struct data_string server_id;
                   4131: 
                   4132:        /*
                   4133:         * Validate our input.
                   4134:         */
                   4135:        if (!valid_client_resp(packet, &client_id, &server_id)) {
                   4136:                return;
                   4137:        }
                   4138: 
                   4139:        /*
                   4140:         * Issue our lease.
                   4141:         */
                   4142:        lease_to_client(reply_ret, packet, &client_id, &server_id);
                   4143: 
                   4144:        /*
                   4145:         * Cleanup.
                   4146:         */
                   4147:        data_string_forget(&client_id, MDL);
                   4148:        data_string_forget(&server_id, MDL);
                   4149: }
                   4150: 
                   4151: /* Find a DHCPv6 packet's shared network from hints in the packet.
                   4152:  */
                   4153: static isc_result_t
                   4154: shared_network_from_packet6(struct shared_network **shared,
                   4155:                            struct packet *packet)
                   4156: {
                   4157:        const struct packet *chk_packet;
                   4158:        const struct in6_addr *link_addr, *first_link_addr;
                   4159:        struct iaddr tmp_addr;
                   4160:        struct subnet *subnet;
                   4161:        isc_result_t status;
                   4162: 
                   4163:        if ((shared == NULL) || (*shared != NULL) || (packet == NULL))
                   4164:                return ISC_R_INVALIDARG;
                   4165: 
                   4166:        /*
                   4167:         * First, find the link address where the packet from the client
                   4168:         * first appeared (if this packet was relayed).
                   4169:         */
                   4170:        first_link_addr = NULL;
                   4171:        chk_packet = packet->dhcpv6_container_packet;
                   4172:        while (chk_packet != NULL) {
                   4173:                link_addr = &chk_packet->dhcpv6_link_address;
                   4174:                if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
                   4175:                    !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
                   4176:                        first_link_addr = link_addr;
                   4177:                        break;
                   4178:                }
                   4179:                chk_packet = chk_packet->dhcpv6_container_packet;
                   4180:        }
                   4181: 
                   4182:        /*
                   4183:         * If there is a relayed link address, find the subnet associated
                   4184:         * with that, and use that to get the appropriate
                   4185:         * shared_network.
                   4186:         */
                   4187:        if (first_link_addr != NULL) {
                   4188:                tmp_addr.len = sizeof(*first_link_addr);
                   4189:                memcpy(tmp_addr.iabuf,
                   4190:                       first_link_addr, sizeof(*first_link_addr));
                   4191:                subnet = NULL;
                   4192:                if (!find_subnet(&subnet, tmp_addr, MDL)) {
                   4193:                        log_debug("No subnet found for link-address %s.",
                   4194:                                  piaddr(tmp_addr));
                   4195:                        return ISC_R_NOTFOUND;
                   4196:                }
                   4197:                status = shared_network_reference(shared,
                   4198:                                                  subnet->shared_network, MDL);
                   4199:                subnet_dereference(&subnet, MDL);
                   4200: 
                   4201:        /*
                   4202:         * If there is no link address, we will use the interface
                   4203:         * that this packet came in on to pick the shared_network.
                   4204:         */
                   4205:        } else if (packet->interface != NULL) {
                   4206:                status = shared_network_reference(shared,
                   4207:                                         packet->interface->shared_network,
                   4208:                                         MDL);
                   4209:                 if (packet->dhcpv6_container_packet != NULL) {
                   4210:                        log_info("[L2 Relay] No link address in relay packet "
                   4211:                                 "assuming L2 relay and using receiving "
                   4212:                                 "interface");
                   4213:                 }
                   4214: 
                   4215:        } else {
                   4216:                /*
                   4217:                 * We shouldn't be able to get here but if there is no link
                   4218:                 * address and no interface we don't know where to get the
                   4219:                 * pool from log an error and return an error.
                   4220:                 */
                   4221:                log_error("No interface and no link address " 
                   4222:                          "can't determine pool");
                   4223:                status = ISC_R_INVALIDARG;
                   4224:        }
                   4225: 
                   4226:        return status;
                   4227: }
                   4228: 
                   4229: /*
                   4230:  * When a client thinks it might be on a new link, it sends a 
                   4231:  * Confirm message.
                   4232:  *
                   4233:  * From RFC3315 section 18.2.2:
                   4234:  *
                   4235:  *   When the server receives a Confirm message, the server determines
                   4236:  *   whether the addresses in the Confirm message are appropriate for the
                   4237:  *   link to which the client is attached.  If all of the addresses in the
                   4238:  *   Confirm message pass this test, the server returns a status of
                   4239:  *   Success.  If any of the addresses do not pass this test, the server
                   4240:  *   returns a status of NotOnLink.  If the server is unable to perform
                   4241:  *   this test (for example, the server does not have information about
                   4242:  *   prefixes on the link to which the client is connected), or there were
                   4243:  *   no addresses in any of the IAs sent by the client, the server MUST
                   4244:  *   NOT send a reply to the client.
                   4245:  */
                   4246: 
                   4247: static void
                   4248: dhcpv6_confirm(struct data_string *reply_ret, struct packet *packet) {
                   4249:        struct shared_network *shared;
                   4250:        struct subnet *subnet;
                   4251:        struct option_cache *ia, *ta, *oc;
                   4252:        struct data_string cli_enc_opt_data, iaaddr, client_id, packet_oro;
                   4253:        struct option_state *cli_enc_opt_state, *opt_state;
                   4254:        struct iaddr cli_addr;
                   4255:        int pass;
                   4256:        isc_boolean_t inappropriate, has_addrs;
                   4257:        char reply_data[65536];
                   4258:        struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
                   4259:        int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options));
                   4260: 
                   4261:        /* 
                   4262:         * Basic client message validation.
                   4263:         */
                   4264:        memset(&client_id, 0, sizeof(client_id));
                   4265:        if (!valid_client_msg(packet, &client_id)) {
                   4266:                return;
                   4267:        }
                   4268: 
                   4269:        /*
                   4270:         * Do not process Confirms that do not have IA's we do not recognize.
                   4271:         */
                   4272:        ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
                   4273:        ta = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_TA);
                   4274:        if ((ia == NULL) && (ta == NULL))
                   4275:                return;
                   4276: 
                   4277:        /*
                   4278:         * IA_PD's are simply ignored.
                   4279:         */
                   4280:        delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
                   4281: 
                   4282:        /* 
                   4283:         * Bit of variable initialization.
                   4284:         */
                   4285:        opt_state = cli_enc_opt_state = NULL;
                   4286:        memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
                   4287:        memset(&iaaddr, 0, sizeof(iaaddr));
                   4288:        memset(&packet_oro, 0, sizeof(packet_oro));
                   4289: 
                   4290:        /* Determine what shared network the client is connected to.  We
                   4291:         * must not respond if we don't have any information about the
                   4292:         * network the client is on.
                   4293:         */
                   4294:        shared = NULL;
                   4295:        if ((shared_network_from_packet6(&shared, packet) != ISC_R_SUCCESS) ||
                   4296:            (shared == NULL))
                   4297:                goto exit;
                   4298: 
                   4299:        /* If there are no recorded subnets, then we have no
                   4300:         * information about this subnet - ignore Confirms.
                   4301:         */
                   4302:        subnet = shared->subnets;
                   4303:        if (subnet == NULL)
                   4304:                goto exit;
                   4305: 
                   4306:        /* Are the addresses in all the IA's appropriate for that link? */
                   4307:        has_addrs = inappropriate = ISC_FALSE;
                   4308:        pass = D6O_IA_NA;
                   4309:        while(!inappropriate) {
                   4310:                /* If we've reached the end of the IA_NA pass, move to the
                   4311:                 * IA_TA pass.
                   4312:                 */
                   4313:                if ((pass == D6O_IA_NA) && (ia == NULL)) {
                   4314:                        pass = D6O_IA_TA;
                   4315:                        ia = ta;
                   4316:                }
                   4317: 
                   4318:                /* If we've reached the end of all passes, we're done. */
                   4319:                if (ia == NULL)
                   4320:                        break;
                   4321: 
                   4322:                if (((pass == D6O_IA_NA) &&
                   4323:                     !get_encapsulated_IA_state(&cli_enc_opt_state,
                   4324:                                                &cli_enc_opt_data,
                   4325:                                                packet, ia, IA_NA_OFFSET)) ||
                   4326:                    ((pass == D6O_IA_TA) &&
                   4327:                     !get_encapsulated_IA_state(&cli_enc_opt_state,
                   4328:                                                &cli_enc_opt_data,
                   4329:                                                packet, ia, IA_TA_OFFSET))) {
                   4330:                        goto exit;
                   4331:                }
                   4332: 
                   4333:                oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state,
                   4334:                                   D6O_IAADDR);
                   4335: 
                   4336:                for ( ; oc != NULL ; oc = oc->next) {
                   4337:                        if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL,
                   4338:                                                   packet->options, NULL,
                   4339:                                                   &global_scope, oc, MDL) ||
                   4340:                            (iaaddr.len < IAADDR_OFFSET)) {
                   4341:                                log_error("dhcpv6_confirm: "
                   4342:                                          "error evaluating IAADDR.");
                   4343:                                goto exit;
                   4344:                        }
                   4345: 
                   4346:                        /* Copy out the IPv6 address for processing. */
                   4347:                        cli_addr.len = 16;
                   4348:                        memcpy(cli_addr.iabuf, iaaddr.data, 16);
                   4349: 
                   4350:                        data_string_forget(&iaaddr, MDL);
                   4351: 
                   4352:                        /* Record that we've processed at least one address. */
                   4353:                        has_addrs = ISC_TRUE;
                   4354: 
                   4355:                        /* Find out if any subnets cover this address. */
                   4356:                        for (subnet = shared->subnets ; subnet != NULL ;
                   4357:                             subnet = subnet->next_sibling) {
                   4358:                                if (addr_eq(subnet_number(cli_addr,
                   4359:                                                          subnet->netmask),
                   4360:                                            subnet->net))
                   4361:                                        break;
                   4362:                        }
                   4363: 
                   4364:                        /* If we reach the end of the subnet list, and no
                   4365:                         * subnet matches the client address, then it must
                   4366:                         * be inappropriate to the link (so far as our
                   4367:                         * configuration says).  Once we've found one
                   4368:                         * inappropriate address, there is no reason to
                   4369:                         * continue searching.
                   4370:                         */
                   4371:                        if (subnet == NULL) {
                   4372:                                inappropriate = ISC_TRUE;
                   4373:                                break;
                   4374:                        }
                   4375:                }
                   4376: 
                   4377:                option_state_dereference(&cli_enc_opt_state, MDL);
                   4378:                data_string_forget(&cli_enc_opt_data, MDL);
                   4379: 
                   4380:                /* Advance to the next IA_*. */
                   4381:                ia = ia->next;
                   4382:        }
                   4383: 
                   4384:        /* If the client supplied no addresses, do not reply. */
                   4385:        if (!has_addrs)
                   4386:                goto exit;
                   4387: 
                   4388:        /* 
                   4389:         * Set up reply.
                   4390:         */
                   4391:        if (!start_reply(packet, &client_id, NULL, &opt_state, reply)) {
                   4392:                goto exit;
                   4393:        }
                   4394: 
                   4395:        /* 
                   4396:         * Set our status.
                   4397:         */
                   4398:        if (inappropriate) {
                   4399:                if (!set_status_code(STATUS_NotOnLink, 
                   4400:                                     "Some of the addresses are not on link.",
                   4401:                                     opt_state)) {
                   4402:                        goto exit;
                   4403:                }
                   4404:        } else {
                   4405:                if (!set_status_code(STATUS_Success, 
                   4406:                                     "All addresses still on link.",
                   4407:                                     opt_state)) {
                   4408:                        goto exit;
                   4409:                }
                   4410:        }
                   4411: 
                   4412:        /* 
                   4413:         * Only one option: add it.
                   4414:         */
                   4415:        reply_ofs += store_options6(reply_data+reply_ofs,
                   4416:                                    sizeof(reply_data)-reply_ofs, 
                   4417:                                    opt_state, packet,
                   4418:                                    required_opts, &packet_oro);
                   4419: 
                   4420:        /* 
                   4421:         * Return our reply to the caller.
                   4422:         */
                   4423:        reply_ret->len = reply_ofs;
                   4424:        reply_ret->buffer = NULL;
                   4425:        if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
                   4426:                log_fatal("No memory to store reply.");
                   4427:        }
                   4428:        reply_ret->data = reply_ret->buffer->data;
                   4429:        memcpy(reply_ret->buffer->data, reply, reply_ofs);
                   4430: 
                   4431: exit:
                   4432:        /* Cleanup any stale data strings. */
                   4433:        if (cli_enc_opt_data.buffer != NULL)
                   4434:                data_string_forget(&cli_enc_opt_data, MDL);
                   4435:        if (iaaddr.buffer != NULL)
                   4436:                data_string_forget(&iaaddr, MDL);
                   4437:        if (client_id.buffer != NULL)
                   4438:                data_string_forget(&client_id, MDL);
                   4439:        if (packet_oro.buffer != NULL)
                   4440:                data_string_forget(&packet_oro, MDL);
                   4441: 
                   4442:        /* Release any stale option states. */
                   4443:        if (cli_enc_opt_state != NULL)
                   4444:                option_state_dereference(&cli_enc_opt_state, MDL);
                   4445:        if (opt_state != NULL)
                   4446:                option_state_dereference(&opt_state, MDL);
                   4447: }
                   4448: 
                   4449: /*
                   4450:  * Renew is when a client wants to extend its lease/prefix, at time T1.
                   4451:  *
                   4452:  * We handle this the same as if the client wants a new lease/prefix,
                   4453:  * except for the error code of when addresses don't match.
                   4454:  */
                   4455: 
                   4456: /* TODO: reject unicast messages, unless we set unicast option */
                   4457: static void
                   4458: dhcpv6_renew(struct data_string *reply, struct packet *packet) {
                   4459:        struct data_string client_id;
                   4460:        struct data_string server_id;
                   4461: 
                   4462:        /* 
                   4463:         * Validate the request.
                   4464:         */
                   4465:        if (!valid_client_resp(packet, &client_id, &server_id)) {
                   4466:                return;
                   4467:        }
                   4468: 
                   4469:        /*
                   4470:         * Renew our lease.
                   4471:         */
                   4472:        lease_to_client(reply, packet, &client_id, &server_id);
                   4473: 
                   4474:        /*
                   4475:         * Cleanup.
                   4476:         */
                   4477:        data_string_forget(&server_id, MDL);
                   4478:        data_string_forget(&client_id, MDL);
                   4479: }
                   4480: 
                   4481: /*
                   4482:  * Rebind is when a client wants to extend its lease, at time T2.
                   4483:  *
                   4484:  * We handle this the same as if the client wants a new lease, except
                   4485:  * for the error code of when addresses don't match.
                   4486:  */
                   4487: 
                   4488: static void
                   4489: dhcpv6_rebind(struct data_string *reply, struct packet *packet) {
                   4490:        struct data_string client_id;
                   4491: 
                   4492:        if (!valid_client_msg(packet, &client_id)) {
                   4493:                return;
                   4494:        }
                   4495: 
                   4496:        lease_to_client(reply, packet, &client_id, NULL);
                   4497: 
                   4498:        data_string_forget(&client_id, MDL);
                   4499: }
                   4500: 
                   4501: static void
                   4502: ia_na_match_decline(const struct data_string *client_id,
                   4503:                    const struct data_string *iaaddr,
                   4504:                    struct iasubopt *lease)
                   4505: {
                   4506:        char tmp_addr[INET6_ADDRSTRLEN];
                   4507: 
                   4508:        log_error("Client %s reports address %s is "
                   4509:                  "already in use by another host!",
                   4510:                  print_hex_1(client_id->len, client_id->data, 60),
                   4511:                  inet_ntop(AF_INET6, iaaddr->data, 
                   4512:                            tmp_addr, sizeof(tmp_addr)));
                   4513:        if (lease != NULL) {
                   4514:                decline_lease6(lease->ipv6_pool, lease);
                   4515:                lease->ia->cltt = cur_time;
                   4516:                write_ia(lease->ia);
                   4517:        }
                   4518: }
                   4519: 
                   4520: static void
                   4521: ia_na_nomatch_decline(const struct data_string *client_id,
                   4522:                      const struct data_string *iaaddr,
                   4523:                      u_int32_t *ia_na_id,
                   4524:                      struct packet *packet,
                   4525:                      char *reply_data,
                   4526:                      int *reply_ofs,
                   4527:                      int reply_len)
                   4528: {
                   4529:        char tmp_addr[INET6_ADDRSTRLEN];
                   4530:        struct option_state *host_opt_state;
                   4531:        int len;
                   4532: 
                   4533:        log_info("Client %s declines address %s, which is not offered to it.",
                   4534:                 print_hex_1(client_id->len, client_id->data, 60),
                   4535:                 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
                   4536: 
                   4537:        /*
                   4538:         * Create state for this IA_NA.
                   4539:         */
                   4540:        host_opt_state = NULL;
                   4541:        if (!option_state_allocate(&host_opt_state, MDL)) {
                   4542:                log_error("ia_na_nomatch_decline: out of memory "
                   4543:                          "allocating option_state.");
                   4544:                goto exit;
                   4545:        }
                   4546: 
                   4547:        if (!set_status_code(STATUS_NoBinding, "Decline for unknown address.",
                   4548:                             host_opt_state)) {
                   4549:                goto exit;
                   4550:        }
                   4551: 
                   4552:        /*
                   4553:         * Insure we have enough space
                   4554:         */
                   4555:        if (reply_len < (*reply_ofs + 16)) {
                   4556:                log_error("ia_na_nomatch_decline: "
                   4557:                          "out of space for reply packet.");
                   4558:                goto exit;
                   4559:        }
                   4560: 
                   4561:        /*
                   4562:         * Put our status code into the reply packet.
                   4563:         */
                   4564:        len = store_options6(reply_data+(*reply_ofs)+16,
                   4565:                             reply_len-(*reply_ofs)-16,
                   4566:                             host_opt_state, packet,
                   4567:                             required_opts_STATUS_CODE, NULL);
                   4568: 
                   4569:        /*
                   4570:         * Store the non-encapsulated option data for this 
                   4571:         * IA_NA into our reply packet. Defined in RFC 3315, 
                   4572:         * section 22.4.  
                   4573:         */
                   4574:        /* option number */
                   4575:        putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
                   4576:        /* option length */
                   4577:        putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
                   4578:        /* IA_NA, copied from the client */
                   4579:        memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
                   4580:        /* t1 and t2, odd that we need them, but here it is */
                   4581:        putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
                   4582:        putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
                   4583: 
                   4584:        /*
                   4585:         * Get ready for next IA_NA.
                   4586:         */
                   4587:        *reply_ofs += (len + 16);
                   4588: 
                   4589: exit:
                   4590:        option_state_dereference(&host_opt_state, MDL);
                   4591: }
                   4592: 
                   4593: static void
                   4594: iterate_over_ia_na(struct data_string *reply_ret, 
                   4595:                   struct packet *packet,
                   4596:                   const struct data_string *client_id,
                   4597:                   const struct data_string *server_id,
                   4598:                   const char *packet_type,
                   4599:                   void (*ia_na_match)(),
                   4600:                   void (*ia_na_nomatch)())
                   4601: {
                   4602:        struct option_state *opt_state;
                   4603:        struct host_decl *packet_host;
                   4604:        struct option_cache *ia;
                   4605:        struct option_cache *oc;
                   4606:        /* cli_enc_... variables come from the IA_NA/IA_TA options */
                   4607:        struct data_string cli_enc_opt_data;
                   4608:        struct option_state *cli_enc_opt_state;
                   4609:        struct host_decl *host;
                   4610:        struct option_state *host_opt_state;
                   4611:        struct data_string iaaddr;
                   4612:        struct data_string fixed_addr;
                   4613:        char reply_data[65536];
                   4614:        struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
                   4615:        int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options));
                   4616:        char status_msg[32];
                   4617:        struct iasubopt *lease;
                   4618:        struct ia_xx *existing_ia_na;
                   4619:        int i;
                   4620:        struct data_string key;
                   4621:        u_int32_t iaid;
                   4622: 
                   4623:        /*
                   4624:         * Initialize to empty values, in case we have to exit early.
                   4625:         */
                   4626:        opt_state = NULL;
                   4627:        memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
                   4628:        cli_enc_opt_state = NULL;
                   4629:        memset(&iaaddr, 0, sizeof(iaaddr));
                   4630:        memset(&fixed_addr, 0, sizeof(fixed_addr));
                   4631:        host_opt_state = NULL;
                   4632:        lease = NULL;
                   4633: 
                   4634:        /* 
                   4635:         * Find the host record that matches from the packet, if any.
                   4636:         */
                   4637:        packet_host = NULL;
                   4638:        if (!find_hosts_by_uid(&packet_host, 
                   4639:                               client_id->data, client_id->len, MDL)) {
                   4640:                packet_host = NULL;
                   4641:                /* 
                   4642:                 * Note: In general, we don't expect a client to provide
                   4643:                 *       enough information to match by option for these
                   4644:                 *       types of messages, but if we don't have a UID
                   4645:                 *       match we can check anyway.
                   4646:                 */
                   4647:                if (!find_hosts_by_option(&packet_host, 
                   4648:                                          packet, packet->options, MDL)) {
                   4649:                        packet_host = NULL;
                   4650:                }
                   4651:        }
                   4652: 
                   4653:        /* 
                   4654:         * Set our reply information.
                   4655:         */
                   4656:        reply->msg_type = DHCPV6_REPLY;
                   4657:        memcpy(reply->transaction_id, packet->dhcpv6_transaction_id, 
                   4658:               sizeof(reply->transaction_id));
                   4659: 
                   4660:        /*
                   4661:         * Build our option state for reply.
                   4662:         */
                   4663:        opt_state = NULL;
                   4664:        if (!option_state_allocate(&opt_state, MDL)) {
                   4665:                log_error("iterate_over_ia_na: no memory for option_state.");
                   4666:                goto exit;
                   4667:        }
                   4668:        execute_statements_in_scope(NULL, packet, NULL, NULL, 
                   4669:                                    packet->options, opt_state, 
                   4670:                                    &global_scope, root_group, NULL);
                   4671: 
                   4672:        /* 
                   4673:         * RFC 3315, section 18.2.7 tells us which options to include.
                   4674:         */
                   4675:        oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
                   4676:        if (oc == NULL) {
                   4677:                if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL, 
                   4678:                                        (unsigned char *)server_duid.data, 
                   4679:                                        server_duid.len, D6O_SERVERID, 0)) {
                   4680:                        log_error("iterate_over_ia_na: "
                   4681:                                  "error saving server identifier.");
                   4682:                        goto exit;
                   4683:                }
                   4684:        }
                   4685: 
                   4686:        if (!save_option_buffer(&dhcpv6_universe, opt_state, 
                   4687:                                client_id->buffer, 
                   4688:                                (unsigned char *)client_id->data,
                   4689:                                client_id->len, 
                   4690:                                D6O_CLIENTID, 0)) {
                   4691:                log_error("iterate_over_ia_na: "
                   4692:                          "error saving client identifier.");
                   4693:                goto exit;
                   4694:        }
                   4695: 
                   4696:        snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
                   4697:        if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
                   4698:                goto exit;
                   4699:        }
                   4700: 
                   4701:        /* 
                   4702:         * Add our options that are not associated with any IA_NA or IA_TA. 
                   4703:         */
                   4704:        reply_ofs += store_options6(reply_data+reply_ofs,
                   4705:                                    sizeof(reply_data)-reply_ofs, 
                   4706:                                    opt_state, packet,
                   4707:                                    required_opts, NULL);
                   4708: 
                   4709:        /*
                   4710:         * Loop through the IA_NA reported by the client, and deal with
                   4711:         * addresses reported as already in use.
                   4712:         */
                   4713:        for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_NA);
                   4714:             ia != NULL; ia = ia->next) {
                   4715: 
                   4716:                if (!get_encapsulated_IA_state(&cli_enc_opt_state,
                   4717:                                               &cli_enc_opt_data,
                   4718:                                               packet, ia, IA_NA_OFFSET)) {
                   4719:                        goto exit;
                   4720:                }
                   4721: 
                   4722:                iaid = getULong(cli_enc_opt_data.data);
                   4723: 
                   4724:                /* 
                   4725:                 * XXX: It is possible that we can get multiple addresses
                   4726:                 *      sent by the client. We don't send multiple 
                   4727:                 *      addresses, so this indicates a client error. 
                   4728:                 *      We should check for multiple IAADDR options, log
                   4729:                 *      if found, and set as an error.
                   4730:                 */
                   4731:                oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state, 
                   4732:                                   D6O_IAADDR);
                   4733:                if (oc == NULL) {
                   4734:                        /* no address given for this IA, ignore */
                   4735:                        option_state_dereference(&cli_enc_opt_state, MDL);
                   4736:                        data_string_forget(&cli_enc_opt_data, MDL);
                   4737:                        continue;
                   4738:                }
                   4739: 
                   4740:                memset(&iaaddr, 0, sizeof(iaaddr));
                   4741:                if (!evaluate_option_cache(&iaaddr, packet, NULL, NULL, 
                   4742:                                           packet->options, NULL,
                   4743:                                           &global_scope, oc, MDL)) {
                   4744:                        log_error("iterate_over_ia_na: "
                   4745:                                  "error evaluating IAADDR.");
                   4746:                        goto exit;
                   4747:                }
                   4748: 
                   4749:                /* 
                   4750:                 * Now we need to figure out which host record matches
                   4751:                 * this IA_NA and IAADDR.
                   4752:                 *
                   4753:                 * XXX: We don't currently track IA_NA separately, but
                   4754:                 *      we will need to do this!
                   4755:                 */
                   4756:                host = NULL;
                   4757:                if (!find_hosts_by_option(&host, packet, 
                   4758:                                          cli_enc_opt_state, MDL)) { 
                   4759:                        if (packet_host != NULL) {
                   4760:                                host = packet_host;
                   4761:                        } else {
                   4762:                                host = NULL;
                   4763:                        }
                   4764:                }
                   4765:                while (host != NULL) {
                   4766:                        if (host->fixed_addr != NULL) {
                   4767:                                if (!evaluate_option_cache(&fixed_addr, NULL, 
                   4768:                                                           NULL, NULL, NULL, 
                   4769:                                                           NULL, &global_scope,
                   4770:                                                           host->fixed_addr, 
                   4771:                                                           MDL)) {
                   4772:                                        log_error("iterate_over_ia_na: error "
                   4773:                                                  "evaluating host address.");
                   4774:                                        goto exit;
                   4775:                                }
                   4776:                                if ((iaaddr.len >= 16) &&
                   4777:                                    !memcmp(fixed_addr.data, iaaddr.data, 16)) {
                   4778:                                        data_string_forget(&fixed_addr, MDL);
                   4779:                                        break;
                   4780:                                }
                   4781:                                data_string_forget(&fixed_addr, MDL);
                   4782:                        }
                   4783:                        host = host->n_ipaddr;
                   4784:                }
                   4785: 
                   4786:                if ((host == NULL) && (iaaddr.len >= IAADDR_OFFSET)) {
                   4787:                        /*
                   4788:                         * Find existing IA_NA.
                   4789:                         */
                   4790:                        if (ia_make_key(&key, iaid, 
                   4791:                                        (char *)client_id->data,
                   4792:                                        client_id->len, 
                   4793:                                        MDL) != ISC_R_SUCCESS) {
                   4794:                                log_fatal("iterate_over_ia_na: no memory for "
                   4795:                                          "key.");
                   4796:                        }
                   4797: 
                   4798:                        existing_ia_na = NULL;
                   4799:                        if (ia_hash_lookup(&existing_ia_na, ia_na_active, 
                   4800:                                           (unsigned char *)key.data, 
                   4801:                                           key.len, MDL)) {
                   4802:                                /* 
                   4803:                                 * Make sure this address is in the IA_NA.
                   4804:                                 */
                   4805:                                for (i=0; i<existing_ia_na->num_iasubopt; i++) {
                   4806:                                        struct iasubopt *tmp;
                   4807:                                        struct in6_addr *in6_addr;
                   4808: 
                   4809:                                        tmp = existing_ia_na->iasubopt[i];
                   4810:                                        in6_addr = &tmp->addr;
                   4811:                                        if (memcmp(in6_addr, 
                   4812:                                                   iaaddr.data, 16) == 0) {
                   4813:                                                iasubopt_reference(&lease,
                   4814:                                                                   tmp, MDL);
                   4815:                                                break;
                   4816:                                        }
                   4817:                                }
                   4818:                        }
                   4819: 
                   4820:                        data_string_forget(&key, MDL);
                   4821:                }
                   4822: 
                   4823:                if ((host != NULL) || (lease != NULL)) {
                   4824:                        ia_na_match(client_id, &iaaddr, lease);
                   4825:                } else {
                   4826:                        ia_na_nomatch(client_id, &iaaddr, 
                   4827:                                      (u_int32_t *)cli_enc_opt_data.data, 
                   4828:                                      packet, reply_data, &reply_ofs, 
                   4829:                                      sizeof(reply_data));
                   4830:                }
                   4831: 
                   4832:                if (lease != NULL) {
                   4833:                        iasubopt_dereference(&lease, MDL);
                   4834:                }
                   4835: 
                   4836:                data_string_forget(&iaaddr, MDL);
                   4837:                option_state_dereference(&cli_enc_opt_state, MDL);
                   4838:                data_string_forget(&cli_enc_opt_data, MDL);
                   4839:        }
                   4840: 
                   4841:        /* 
                   4842:         * Return our reply to the caller.
                   4843:         */
                   4844:        reply_ret->len = reply_ofs;
                   4845:        reply_ret->buffer = NULL;
                   4846:        if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
                   4847:                log_fatal("No memory to store reply.");
                   4848:        }
                   4849:        reply_ret->data = reply_ret->buffer->data;
                   4850:        memcpy(reply_ret->buffer->data, reply, reply_ofs);
                   4851: 
                   4852: exit:
                   4853:        if (lease != NULL) {
                   4854:                iasubopt_dereference(&lease, MDL);
                   4855:        }
                   4856:        if (host_opt_state != NULL) {
                   4857:                option_state_dereference(&host_opt_state, MDL);
                   4858:        }
                   4859:        if (fixed_addr.buffer != NULL) {
                   4860:                data_string_forget(&fixed_addr, MDL);
                   4861:        }
                   4862:        if (iaaddr.buffer != NULL) {
                   4863:                data_string_forget(&iaaddr, MDL);
                   4864:        }
                   4865:        if (cli_enc_opt_state != NULL) {
                   4866:                option_state_dereference(&cli_enc_opt_state, MDL);
                   4867:        }
                   4868:        if (cli_enc_opt_data.buffer != NULL) {
                   4869:                data_string_forget(&cli_enc_opt_data, MDL);
                   4870:        }
                   4871:        if (opt_state != NULL) {
                   4872:                option_state_dereference(&opt_state, MDL);
                   4873:        }
                   4874: }
                   4875: 
                   4876: /*
                   4877:  * Decline means a client has detected that something else is using an
                   4878:  * address we gave it.
                   4879:  *
                   4880:  * Since we're only dealing with fixed leases for now, there's not
                   4881:  * much we can do, other that log the occurrence.
                   4882:  * 
                   4883:  * When we start issuing addresses from pools, then we will have to
                   4884:  * record our declined addresses and issue another. In general with
                   4885:  * IPv6 there is no worry about DoS by clients exhausting space, but
                   4886:  * we still need to be aware of this possibility.
                   4887:  */
                   4888: 
                   4889: /* TODO: reject unicast messages, unless we set unicast option */
                   4890: /* TODO: IA_TA */
                   4891: static void
                   4892: dhcpv6_decline(struct data_string *reply, struct packet *packet) {
                   4893:        struct data_string client_id;
                   4894:        struct data_string server_id;
                   4895: 
                   4896:        /* 
                   4897:         * Validate our input.
                   4898:         */
                   4899:        if (!valid_client_resp(packet, &client_id, &server_id)) {
                   4900:                return;
                   4901:        }
                   4902: 
                   4903:        /*
                   4904:         * Undefined for IA_PD.
                   4905:         */
                   4906:        delete_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
                   4907: 
                   4908:        /*
                   4909:         * And operate on each IA_NA in this packet.
                   4910:         */
                   4911:        iterate_over_ia_na(reply, packet, &client_id, &server_id, "Decline", 
                   4912:                           ia_na_match_decline, ia_na_nomatch_decline);
                   4913: 
                   4914:        data_string_forget(&server_id, MDL);
                   4915:        data_string_forget(&client_id, MDL);
                   4916: }
                   4917: 
                   4918: static void
                   4919: ia_na_match_release(const struct data_string *client_id,
                   4920:                    const struct data_string *iaaddr,
                   4921:                    struct iasubopt *lease)
                   4922: {
                   4923:        char tmp_addr[INET6_ADDRSTRLEN];
                   4924: 
                   4925:        log_info("Client %s releases address %s",
                   4926:                 print_hex_1(client_id->len, client_id->data, 60),
                   4927:                 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
                   4928:        if (lease != NULL) {
                   4929:                release_lease6(lease->ipv6_pool, lease);
                   4930:                lease->ia->cltt = cur_time;
                   4931:                write_ia(lease->ia);
                   4932:        }
                   4933: }
                   4934: 
                   4935: static void
                   4936: ia_na_nomatch_release(const struct data_string *client_id,
                   4937:                      const struct data_string *iaaddr,
                   4938:                      u_int32_t *ia_na_id,
                   4939:                      struct packet *packet,
                   4940:                      char *reply_data,
                   4941:                      int *reply_ofs,
                   4942:                      int reply_len)
                   4943: {
                   4944:        char tmp_addr[INET6_ADDRSTRLEN];
                   4945:        struct option_state *host_opt_state;
                   4946:        int len;
                   4947: 
                   4948:        log_info("Client %s releases address %s, which is not leased to it.",
                   4949:                 print_hex_1(client_id->len, client_id->data, 60),
                   4950:                 inet_ntop(AF_INET6, iaaddr->data, tmp_addr, sizeof(tmp_addr)));
                   4951: 
                   4952:        /*
                   4953:         * Create state for this IA_NA.
                   4954:         */
                   4955:        host_opt_state = NULL;
                   4956:        if (!option_state_allocate(&host_opt_state, MDL)) {
                   4957:                log_error("ia_na_nomatch_release: out of memory "
                   4958:                          "allocating option_state.");
                   4959:                goto exit;
                   4960:        }
                   4961: 
                   4962:        if (!set_status_code(STATUS_NoBinding, 
                   4963:                             "Release for non-leased address.",
                   4964:                             host_opt_state)) {
                   4965:                goto exit;
                   4966:        }
                   4967: 
                   4968:        /*
                   4969:         * Insure we have enough space
                   4970:         */
                   4971:        if (reply_len < (*reply_ofs + 16)) {
                   4972:                log_error("ia_na_nomatch_release: "
                   4973:                          "out of space for reply packet.");
                   4974:                goto exit;
                   4975:        }
                   4976: 
                   4977:        /*
                   4978:         * Put our status code into the reply packet.
                   4979:         */
                   4980:        len = store_options6(reply_data+(*reply_ofs)+16,
                   4981:                             reply_len-(*reply_ofs)-16,
                   4982:                             host_opt_state, packet,
                   4983:                             required_opts_STATUS_CODE, NULL);
                   4984: 
                   4985:        /*
                   4986:         * Store the non-encapsulated option data for this 
                   4987:         * IA_NA into our reply packet. Defined in RFC 3315, 
                   4988:         * section 22.4.  
                   4989:         */
                   4990:        /* option number */
                   4991:        putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_NA);
                   4992:        /* option length */
                   4993:        putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
                   4994:        /* IA_NA, copied from the client */
                   4995:        memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
                   4996:        /* t1 and t2, odd that we need them, but here it is */
                   4997:        putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
                   4998:        putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
                   4999: 
                   5000:        /*
                   5001:         * Get ready for next IA_NA.
                   5002:         */
                   5003:        *reply_ofs += (len + 16);
                   5004: 
                   5005: exit:
                   5006:        option_state_dereference(&host_opt_state, MDL);
                   5007: }
                   5008: 
                   5009: static void
                   5010: ia_pd_match_release(const struct data_string *client_id,
                   5011:                    const struct data_string *iapref,
                   5012:                    struct iasubopt *prefix)
                   5013: {
                   5014:        char tmp_addr[INET6_ADDRSTRLEN];
                   5015: 
                   5016:        log_info("Client %s releases prefix %s/%u",
                   5017:                 print_hex_1(client_id->len, client_id->data, 60),
                   5018:                 inet_ntop(AF_INET6, iapref->data + 9,
                   5019:                           tmp_addr, sizeof(tmp_addr)),
                   5020:                 (unsigned) getUChar(iapref->data + 8));
                   5021:        if (prefix != NULL) {
                   5022:                release_lease6(prefix->ipv6_pool, prefix);
                   5023:                prefix->ia->cltt = cur_time;
                   5024:                write_ia(prefix->ia);
                   5025:        }
                   5026: }
                   5027: 
                   5028: static void
                   5029: ia_pd_nomatch_release(const struct data_string *client_id,
                   5030:                      const struct data_string *iapref,
                   5031:                      u_int32_t *ia_pd_id,
                   5032:                      struct packet *packet,
                   5033:                      char *reply_data,
                   5034:                      int *reply_ofs,
                   5035:                      int reply_len)
                   5036: {
                   5037:        char tmp_addr[INET6_ADDRSTRLEN];
                   5038:        struct option_state *host_opt_state;
                   5039:        int len;
                   5040: 
                   5041:        log_info("Client %s releases prefix %s/%u, which is not leased to it.",
                   5042:                 print_hex_1(client_id->len, client_id->data, 60),
                   5043:                 inet_ntop(AF_INET6, iapref->data + 9,
                   5044:                           tmp_addr, sizeof(tmp_addr)),
                   5045:                 (unsigned) getUChar(iapref->data + 8));
                   5046: 
                   5047:        /*
                   5048:         * Create state for this IA_PD.
                   5049:         */
                   5050:        host_opt_state = NULL;
                   5051:        if (!option_state_allocate(&host_opt_state, MDL)) {
                   5052:                log_error("ia_pd_nomatch_release: out of memory "
                   5053:                          "allocating option_state.");
                   5054:                goto exit;
                   5055:        }
                   5056: 
                   5057:        if (!set_status_code(STATUS_NoBinding, 
                   5058:                             "Release for non-leased prefix.",
                   5059:                             host_opt_state)) {
                   5060:                goto exit;
                   5061:        }
                   5062: 
                   5063:        /*
                   5064:         * Insure we have enough space
                   5065:         */
                   5066:        if (reply_len < (*reply_ofs + 16)) {
                   5067:                log_error("ia_pd_nomatch_release: "
                   5068:                          "out of space for reply packet.");
                   5069:                goto exit;
                   5070:        }
                   5071: 
                   5072:        /*
                   5073:         * Put our status code into the reply packet.
                   5074:         */
                   5075:        len = store_options6(reply_data+(*reply_ofs)+16,
                   5076:                             reply_len-(*reply_ofs)-16,
                   5077:                             host_opt_state, packet,
                   5078:                             required_opts_STATUS_CODE, NULL);
                   5079: 
                   5080:        /*
                   5081:         * Store the non-encapsulated option data for this 
                   5082:         * IA_PD into our reply packet. Defined in RFC 3315, 
                   5083:         * section 22.4.  
                   5084:         */
                   5085:        /* option number */
                   5086:        putUShort((unsigned char *)reply_data+(*reply_ofs), D6O_IA_PD);
                   5087:        /* option length */
                   5088:        putUShort((unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
                   5089:        /* IA_PD, copied from the client */
                   5090:        memcpy(reply_data+(*reply_ofs)+4, ia_pd_id, 4);
                   5091:        /* t1 and t2, odd that we need them, but here it is */
                   5092:        putULong((unsigned char *)reply_data+(*reply_ofs)+8, 0);
                   5093:        putULong((unsigned char *)reply_data+(*reply_ofs)+12, 0);
                   5094: 
                   5095:        /*
                   5096:         * Get ready for next IA_PD.
                   5097:         */
                   5098:        *reply_ofs += (len + 16);
                   5099: 
                   5100: exit:
                   5101:        option_state_dereference(&host_opt_state, MDL);
                   5102: }
                   5103: 
                   5104: static void
                   5105: iterate_over_ia_pd(struct data_string *reply_ret, 
                   5106:                   struct packet *packet,
                   5107:                   const struct data_string *client_id,
                   5108:                   const struct data_string *server_id,
                   5109:                   const char *packet_type,
                   5110:                   void (*ia_pd_match)(),
                   5111:                   void (*ia_pd_nomatch)())
                   5112: {
                   5113:        struct data_string reply_new;
                   5114:        int reply_len;
                   5115:        struct option_state *opt_state;
                   5116:        struct host_decl *packet_host;
                   5117:        struct option_cache *ia;
                   5118:        struct option_cache *oc;
                   5119:        /* cli_enc_... variables come from the IA_PD options */
                   5120:        struct data_string cli_enc_opt_data;
                   5121:        struct option_state *cli_enc_opt_state;
                   5122:        struct host_decl *host;
                   5123:        struct option_state *host_opt_state;
                   5124:        struct data_string iaprefix;
                   5125:        char reply_data[65536];
                   5126:        int reply_ofs;
                   5127:        struct iasubopt *prefix;
                   5128:        struct ia_xx *existing_ia_pd;
                   5129:        int i;
                   5130:        struct data_string key;
                   5131:        u_int32_t iaid;
                   5132: 
                   5133:        /*
                   5134:         * Initialize to empty values, in case we have to exit early.
                   5135:         */
                   5136:        memset(&reply_new, 0, sizeof(reply_new));
                   5137:        opt_state = NULL;
                   5138:        memset(&cli_enc_opt_data, 0, sizeof(cli_enc_opt_data));
                   5139:        cli_enc_opt_state = NULL;
                   5140:        memset(&iaprefix, 0, sizeof(iaprefix));
                   5141:        host_opt_state = NULL;
                   5142:        prefix = NULL;
                   5143: 
                   5144:        /*
                   5145:         * Compute the available length for the reply.
                   5146:         */
                   5147:        reply_len = sizeof(reply_data) - reply_ret->len;
                   5148:        reply_ofs = 0;
                   5149: 
                   5150:        /* 
                   5151:         * Find the host record that matches from the packet, if any.
                   5152:         */
                   5153:        packet_host = NULL;
                   5154:        if (!find_hosts_by_uid(&packet_host, 
                   5155:                               client_id->data, client_id->len, MDL)) {
                   5156:                packet_host = NULL;
                   5157:                /* 
                   5158:                 * Note: In general, we don't expect a client to provide
                   5159:                 *       enough information to match by option for these
                   5160:                 *       types of messages, but if we don't have a UID
                   5161:                 *       match we can check anyway.
                   5162:                 */
                   5163:                if (!find_hosts_by_option(&packet_host, 
                   5164:                                          packet, packet->options, MDL)) {
                   5165:                        packet_host = NULL;
                   5166:                }
                   5167:        }
                   5168: 
                   5169:        /*
                   5170:         * Build our option state for reply.
                   5171:         */
                   5172:        opt_state = NULL;
                   5173:        if (!option_state_allocate(&opt_state, MDL)) {
                   5174:                log_error("iterate_over_ia_pd: no memory for option_state.");
                   5175:                goto exit;
                   5176:        }
                   5177:        execute_statements_in_scope(NULL, packet, NULL, NULL, 
                   5178:                                    packet->options, opt_state, 
                   5179:                                    &global_scope, root_group, NULL);
                   5180: 
                   5181:        /*
                   5182:         * Loop through the IA_PD reported by the client, and deal with
                   5183:         * prefixes reported as already in use.
                   5184:         */
                   5185:        for (ia = lookup_option(&dhcpv6_universe, packet->options, D6O_IA_PD);
                   5186:             ia != NULL; ia = ia->next) {
                   5187: 
                   5188:            if (!get_encapsulated_IA_state(&cli_enc_opt_state,
                   5189:                                           &cli_enc_opt_data,
                   5190:                                           packet, ia, IA_PD_OFFSET)) {
                   5191:                goto exit;
                   5192:            }
                   5193: 
                   5194:            iaid = getULong(cli_enc_opt_data.data);
                   5195: 
                   5196:            oc = lookup_option(&dhcpv6_universe, cli_enc_opt_state, 
                   5197:                               D6O_IAPREFIX);
                   5198:            if (oc == NULL) {
                   5199:                /* no prefix given for this IA_PD, ignore */
                   5200:                option_state_dereference(&cli_enc_opt_state, MDL);
                   5201:                data_string_forget(&cli_enc_opt_data, MDL);
                   5202:                continue;
                   5203:            }
                   5204: 
                   5205:            for (; oc != NULL; oc = oc->next) {
                   5206:                memset(&iaprefix, 0, sizeof(iaprefix));
                   5207:                if (!evaluate_option_cache(&iaprefix, packet, NULL, NULL, 
                   5208:                                           packet->options, NULL,
                   5209:                                           &global_scope, oc, MDL)) {
                   5210:                        log_error("iterate_over_ia_pd: "
                   5211:                                  "error evaluating IAPREFIX.");
                   5212:                        goto exit;
                   5213:                }
                   5214: 
                   5215:                /* 
                   5216:                 * Now we need to figure out which host record matches
                   5217:                 * this IA_PD and IAPREFIX.
                   5218:                 *
                   5219:                 * XXX: We don't currently track IA_PD separately, but
                   5220:                 *      we will need to do this!
                   5221:                 */
                   5222:                host = NULL;
                   5223:                if (!find_hosts_by_option(&host, packet, 
                   5224:                                          cli_enc_opt_state, MDL)) { 
                   5225:                        if (packet_host != NULL) {
                   5226:                                host = packet_host;
                   5227:                        } else {
                   5228:                                host = NULL;
                   5229:                        }
                   5230:                }
                   5231:                while (host != NULL) {
                   5232:                        if (host->fixed_prefix != NULL) {
                   5233:                                struct iaddrcidrnetlist *l;
                   5234:                                int plen = (int) getUChar(iaprefix.data + 8);
                   5235: 
                   5236:                                for (l = host->fixed_prefix; l != NULL;
                   5237:                                     l = l->next) {
                   5238:                                        if (plen != l->cidrnet.bits)
                   5239:                                                continue;
                   5240:                                        if (memcmp(iaprefix.data + 9,
                   5241:                                                   l->cidrnet.lo_addr.iabuf,
                   5242:                                                   16) == 0)
                   5243:                                                break;
                   5244:                                }
                   5245:                                if ((l != NULL) && (iaprefix.len >= 17))
                   5246:                                        break;
                   5247:                        }
                   5248:                        host = host->n_ipaddr;
                   5249:                }
                   5250: 
                   5251:                if ((host == NULL) && (iaprefix.len >= IAPREFIX_OFFSET)) {
                   5252:                        /*
                   5253:                         * Find existing IA_PD.
                   5254:                         */
                   5255:                        if (ia_make_key(&key, iaid, 
                   5256:                                        (char *)client_id->data,
                   5257:                                        client_id->len, 
                   5258:                                        MDL) != ISC_R_SUCCESS) {
                   5259:                                log_fatal("iterate_over_ia_pd: no memory for "
                   5260:                                          "key.");
                   5261:                        }
                   5262: 
                   5263:                        existing_ia_pd = NULL;
                   5264:                        if (ia_hash_lookup(&existing_ia_pd, ia_pd_active, 
                   5265:                                           (unsigned char *)key.data, 
                   5266:                                           key.len, MDL)) {
                   5267:                                /* 
                   5268:                                 * Make sure this prefix is in the IA_PD.
                   5269:                                 */
                   5270:                                for (i = 0;
                   5271:                                     i < existing_ia_pd->num_iasubopt;
                   5272:                                     i++) {
                   5273:                                        struct iasubopt *tmp;
                   5274:                                        u_int8_t plen;
                   5275: 
                   5276:                                        plen = getUChar(iaprefix.data + 8);
                   5277:                                        tmp = existing_ia_pd->iasubopt[i];
                   5278:                                        if ((tmp->plen == plen) &&
                   5279:                                            (memcmp(&tmp->addr,
                   5280:                                                    iaprefix.data + 9,
                   5281:                                                    16) == 0)) {
                   5282:                                                iasubopt_reference(&prefix,
                   5283:                                                                   tmp, MDL);
                   5284:                                                break;
                   5285:                                        }
                   5286:                                }
                   5287:                        }
                   5288: 
                   5289:                        data_string_forget(&key, MDL);
                   5290:                }
                   5291: 
                   5292:                if ((host != NULL) || (prefix != NULL)) {
                   5293:                        ia_pd_match(client_id, &iaprefix, prefix);
                   5294:                } else {
                   5295:                        ia_pd_nomatch(client_id, &iaprefix, 
                   5296:                                      (u_int32_t *)cli_enc_opt_data.data, 
                   5297:                                      packet, reply_data, &reply_ofs, 
                   5298:                                      reply_len - reply_ofs);
                   5299:                }
                   5300: 
                   5301:                if (prefix != NULL) {
                   5302:                        iasubopt_dereference(&prefix, MDL);
                   5303:                }
                   5304: 
                   5305:                data_string_forget(&iaprefix, MDL);
                   5306:            }
                   5307: 
                   5308:            option_state_dereference(&cli_enc_opt_state, MDL);
                   5309:            data_string_forget(&cli_enc_opt_data, MDL);
                   5310:        }
                   5311: 
                   5312:        /* 
                   5313:         * Return our reply to the caller.
                   5314:         * The IA_NA routine has already filled at least the header.
                   5315:         */
                   5316:        reply_new.len = reply_ret->len + reply_ofs;
                   5317:        if (!buffer_allocate(&reply_new.buffer, reply_new.len, MDL)) {
                   5318:                log_fatal("No memory to store reply.");
                   5319:        }
                   5320:        reply_new.data = reply_new.buffer->data;
                   5321:        memcpy(reply_new.buffer->data,
                   5322:               reply_ret->buffer->data, reply_ret->len);
                   5323:        memcpy(reply_new.buffer->data + reply_ret->len,
                   5324:               reply_data, reply_ofs);
                   5325:        data_string_forget(reply_ret, MDL);
                   5326:        data_string_copy(reply_ret, &reply_new, MDL);
                   5327:        data_string_forget(&reply_new, MDL);
                   5328: 
                   5329: exit:
                   5330:        if (prefix != NULL) {
                   5331:                iasubopt_dereference(&prefix, MDL);
                   5332:        }
                   5333:        if (host_opt_state != NULL) {
                   5334:                option_state_dereference(&host_opt_state, MDL);
                   5335:        }
                   5336:        if (iaprefix.buffer != NULL) {
                   5337:                data_string_forget(&iaprefix, MDL);
                   5338:        }
                   5339:        if (cli_enc_opt_state != NULL) {
                   5340:                option_state_dereference(&cli_enc_opt_state, MDL);
                   5341:        }
                   5342:        if (cli_enc_opt_data.buffer != NULL) {
                   5343:                data_string_forget(&cli_enc_opt_data, MDL);
                   5344:        }
                   5345:        if (opt_state != NULL) {
                   5346:                option_state_dereference(&opt_state, MDL);
                   5347:        }
                   5348: }
                   5349: 
                   5350: /*
                   5351:  * Release means a client is done with the leases.
                   5352:  */
                   5353: 
                   5354: /* TODO: reject unicast messages, unless we set unicast option */
                   5355: static void
                   5356: dhcpv6_release(struct data_string *reply, struct packet *packet) {
                   5357:        struct data_string client_id;
                   5358:        struct data_string server_id;
                   5359: 
                   5360:        /* 
                   5361:         * Validate our input.
                   5362:         */
                   5363:        if (!valid_client_resp(packet, &client_id, &server_id)) {
                   5364:                return;
                   5365:        }
                   5366: 
                   5367:        /*
                   5368:         * And operate on each IA_NA in this packet.
                   5369:         */
                   5370:        iterate_over_ia_na(reply, packet, &client_id, &server_id, "Release", 
                   5371:                           ia_na_match_release, ia_na_nomatch_release);
                   5372: 
                   5373:        /*
                   5374:         * And operate on each IA_PD in this packet.
                   5375:         */
                   5376:        iterate_over_ia_pd(reply, packet, &client_id, &server_id, "Release",
                   5377:                           ia_pd_match_release, ia_pd_nomatch_release);
                   5378: 
                   5379:        data_string_forget(&server_id, MDL);
                   5380:        data_string_forget(&client_id, MDL);
                   5381: }
                   5382: 
                   5383: /*
                   5384:  * Information-Request is used by clients who have obtained an address
                   5385:  * from other means, but want configuration information from the server.
                   5386:  */
                   5387: 
                   5388: static void
                   5389: dhcpv6_information_request(struct data_string *reply, struct packet *packet) {
                   5390:        struct data_string client_id;
                   5391:        struct data_string server_id;
                   5392: 
                   5393:        /*
                   5394:         * Validate our input.
                   5395:         */
                   5396:        if (!valid_client_info_req(packet, &server_id)) {
                   5397:                return;
                   5398:        }
                   5399: 
                   5400:        /*
                   5401:         * Get our client ID, if there is one.
                   5402:         */
                   5403:        memset(&client_id, 0, sizeof(client_id));
                   5404:        if (get_client_id(packet, &client_id) != ISC_R_SUCCESS) {
                   5405:                data_string_forget(&client_id, MDL);
                   5406:        }
                   5407: 
                   5408:        /*
                   5409:         * Use the lease_to_client() function. This will work fine, 
                   5410:         * because the valid_client_info_req() insures that we 
                   5411:         * don't have any IA that would cause us to allocate
                   5412:         * resources to the client.
                   5413:         */
                   5414:        lease_to_client(reply, packet, &client_id,
                   5415:                        server_id.data != NULL ? &server_id : NULL);
                   5416: 
                   5417:        /*
                   5418:         * Cleanup.
                   5419:         */
                   5420:        if (client_id.data != NULL) {
                   5421:                data_string_forget(&client_id, MDL);
                   5422:        }
                   5423:        data_string_forget(&server_id, MDL);
                   5424: }
                   5425: 
                   5426: /* 
                   5427:  * The Relay-forw message is sent by relays. It typically contains a
                   5428:  * single option, which encapsulates an entire packet.
                   5429:  *
                   5430:  * We need to build an encapsulated reply.
                   5431:  */
                   5432: 
                   5433: /* XXX: this is very, very similar to do_packet6(), and should probably
                   5434:        be combined in a clever way */
                   5435: static void
                   5436: dhcpv6_relay_forw(struct data_string *reply_ret, struct packet *packet) {
                   5437:        struct option_cache *oc;
                   5438:        struct data_string enc_opt_data;
                   5439:        struct packet *enc_packet;
                   5440:        unsigned char msg_type;
                   5441:        const struct dhcpv6_packet *msg;
                   5442:        const struct dhcpv6_relay_packet *relay;
                   5443:        struct data_string enc_reply;
                   5444:        char link_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
                   5445:        char peer_addr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
                   5446:        struct data_string a_opt, packet_ero;
                   5447:        struct option_state *opt_state;
                   5448:        static char reply_data[65536];
                   5449:        struct dhcpv6_relay_packet *reply;
                   5450:        int reply_ofs;
                   5451: 
                   5452:        /* 
                   5453:         * Initialize variables for early exit.
                   5454:         */
                   5455:        opt_state = NULL;
                   5456:        memset(&a_opt, 0, sizeof(a_opt));
                   5457:        memset(&packet_ero, 0, sizeof(packet_ero));
                   5458:        memset(&enc_reply, 0, sizeof(enc_reply));
                   5459:        memset(&enc_opt_data, 0, sizeof(enc_opt_data));
                   5460:        enc_packet = NULL;
                   5461: 
                   5462:        /*
                   5463:         * Get our encapsulated relay message.
                   5464:         */
                   5465:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_RELAY_MSG);
                   5466:        if (oc == NULL) {
                   5467:                inet_ntop(AF_INET6, &packet->dhcpv6_link_address,
                   5468:                          link_addr, sizeof(link_addr));
                   5469:                inet_ntop(AF_INET6, &packet->dhcpv6_peer_address,
                   5470:                          peer_addr, sizeof(peer_addr));
                   5471:                log_info("Relay-forward from %s with link address=%s and "
                   5472:                         "peer address=%s missing Relay Message option.",
                   5473:                          piaddr(packet->client_addr), link_addr, peer_addr);
                   5474:                goto exit;
                   5475:        }
                   5476: 
                   5477:        if (!evaluate_option_cache(&enc_opt_data, NULL, NULL, NULL, 
                   5478:                                   NULL, NULL, &global_scope, oc, MDL)) {
                   5479:                log_error("dhcpv6_forw_relay: error evaluating "
                   5480:                          "relayed message.");
                   5481:                goto exit;
                   5482:        }
                   5483: 
                   5484:        if (!packet6_len_okay((char *)enc_opt_data.data, enc_opt_data.len)) {
                   5485:                log_error("dhcpv6_forw_relay: encapsulated packet too short.");
                   5486:                goto exit;
                   5487:        }
                   5488: 
                   5489:        /*
                   5490:         * Build a packet structure from this encapsulated packet.
                   5491:         */
                   5492:        enc_packet = NULL;
                   5493:        if (!packet_allocate(&enc_packet, MDL)) {
                   5494:                log_error("dhcpv6_forw_relay: "
                   5495:                          "no memory for encapsulated packet.");
                   5496:                goto exit;
                   5497:        }
                   5498: 
                   5499:        if (!option_state_allocate(&enc_packet->options, MDL)) {
                   5500:                log_error("dhcpv6_forw_relay: "
                   5501:                          "no memory for encapsulated packet's options.");
                   5502:                goto exit;
                   5503:        }
                   5504: 
                   5505:        enc_packet->client_port = packet->client_port;
                   5506:        enc_packet->client_addr = packet->client_addr;
                   5507:        interface_reference(&enc_packet->interface, packet->interface, MDL);
                   5508:        enc_packet->dhcpv6_container_packet = packet;
                   5509: 
                   5510:        msg_type = enc_opt_data.data[0];
                   5511:        if ((msg_type == DHCPV6_RELAY_FORW) ||
                   5512:            (msg_type == DHCPV6_RELAY_REPL)) {
1.1.1.1 ! misho    5513:                int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options));
1.1       misho    5514:                relay = (struct dhcpv6_relay_packet *)enc_opt_data.data;
                   5515:                enc_packet->dhcpv6_msg_type = relay->msg_type;
                   5516: 
                   5517:                /* relay-specific data */
                   5518:                enc_packet->dhcpv6_hop_count = relay->hop_count;
                   5519:                memcpy(&enc_packet->dhcpv6_link_address,
                   5520:                       relay->link_address, sizeof(relay->link_address));
                   5521:                memcpy(&enc_packet->dhcpv6_peer_address,
                   5522:                       relay->peer_address, sizeof(relay->peer_address));
                   5523: 
                   5524:                if (!parse_option_buffer(enc_packet->options,
                   5525:                                         relay->options, 
1.1.1.1 ! misho    5526:                                         enc_opt_data.len - relaylen,
1.1       misho    5527:                                         &dhcpv6_universe)) {
                   5528:                        /* no logging here, as parse_option_buffer() logs all
                   5529:                           cases where it fails */
                   5530:                        goto exit;
                   5531:                }
                   5532:        } else {
1.1.1.1 ! misho    5533:                int msglen = (int)(offsetof(struct dhcpv6_packet, options));
1.1       misho    5534:                msg = (struct dhcpv6_packet *)enc_opt_data.data;
                   5535:                enc_packet->dhcpv6_msg_type = msg->msg_type;
                   5536: 
                   5537:                /* message-specific data */
                   5538:                memcpy(enc_packet->dhcpv6_transaction_id,
                   5539:                       msg->transaction_id,
                   5540:                       sizeof(enc_packet->dhcpv6_transaction_id));
                   5541: 
                   5542:                if (!parse_option_buffer(enc_packet->options,
                   5543:                                         msg->options, 
1.1.1.1 ! misho    5544:                                         enc_opt_data.len - msglen,
1.1       misho    5545:                                         &dhcpv6_universe)) {
                   5546:                        /* no logging here, as parse_option_buffer() logs all
                   5547:                           cases where it fails */
                   5548:                        goto exit;
                   5549:                }
                   5550:        }
                   5551: 
                   5552:        /*
                   5553:         * This is recursive. It is possible to exceed maximum packet size.
                   5554:         * XXX: This will cause the packet send to fail.
                   5555:         */
                   5556:        build_dhcpv6_reply(&enc_reply, enc_packet);
                   5557: 
                   5558:        /*
                   5559:         * If we got no encapsulated data, then it is discarded, and
                   5560:         * our reply-forw is also discarded.
                   5561:         */
                   5562:        if (enc_reply.data == NULL) {
                   5563:                goto exit;
                   5564:        }
                   5565: 
                   5566:        /*
                   5567:         * Now we can use the reply_data buffer.
                   5568:         * Packet header stuff all comes from the forward message.
                   5569:         */
                   5570:        reply = (struct dhcpv6_relay_packet *)reply_data;
                   5571:        reply->msg_type = DHCPV6_RELAY_REPL;
                   5572:        reply->hop_count = packet->dhcpv6_hop_count;
                   5573:        memcpy(reply->link_address, &packet->dhcpv6_link_address,
                   5574:               sizeof(reply->link_address));
                   5575:        memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
                   5576:               sizeof(reply->peer_address));
                   5577:        reply_ofs = (int)(offsetof(struct dhcpv6_relay_packet, options));
                   5578: 
                   5579:        /*
                   5580:         * Get the reply option state.
                   5581:         */
                   5582:        opt_state = NULL;
                   5583:        if (!option_state_allocate(&opt_state, MDL)) {
                   5584:                log_error("dhcpv6_relay_forw: no memory for option state.");
                   5585:                goto exit;
                   5586:        }
                   5587: 
                   5588:        /*
                   5589:         * Append the interface-id if present.
                   5590:         */
                   5591:        oc = lookup_option(&dhcpv6_universe, packet->options,
                   5592:                           D6O_INTERFACE_ID);
                   5593:        if (oc != NULL) {
                   5594:                if (!evaluate_option_cache(&a_opt, packet,
                   5595:                                           NULL, NULL, 
                   5596:                                           packet->options, NULL,
                   5597:                                           &global_scope, oc, MDL)) {
                   5598:                        log_error("dhcpv6_relay_forw: error evaluating "
                   5599:                                  "Interface ID.");
                   5600:                        goto exit;
                   5601:                }
                   5602:                if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
                   5603:                                        (unsigned char *)a_opt.data,
                   5604:                                        a_opt.len,
                   5605:                                        D6O_INTERFACE_ID, 0)) {
                   5606:                        log_error("dhcpv6_relay_forw: error saving "
                   5607:                                  "Interface ID.");
                   5608:                        goto exit;
                   5609:                }
                   5610:                data_string_forget(&a_opt, MDL);
                   5611:        }
                   5612: 
                   5613:        /* 
                   5614:         * Append our encapsulated stuff for caller.
                   5615:         */
                   5616:        if (!save_option_buffer(&dhcpv6_universe, opt_state, NULL,
                   5617:                                (unsigned char *)enc_reply.data,
                   5618:                                enc_reply.len,
                   5619:                                D6O_RELAY_MSG, 0)) {
                   5620:                log_error("dhcpv6_relay_forw: error saving Relay MSG.");
                   5621:                goto exit;
                   5622:        }
                   5623: 
                   5624:        /*
                   5625:         * Get the ERO if any.
                   5626:         */
                   5627:        oc = lookup_option(&dhcpv6_universe, packet->options, D6O_ERO);
                   5628:        if (oc != NULL) {
                   5629:                unsigned req;
                   5630:                int i;
                   5631: 
                   5632:                if (!evaluate_option_cache(&packet_ero, packet,
                   5633:                                           NULL, NULL,
                   5634:                                           packet->options, NULL,
                   5635:                                           &global_scope, oc, MDL) ||
                   5636:                        (packet_ero.len & 1)) {
                   5637:                        log_error("dhcpv6_relay_forw: error evaluating ERO.");
                   5638:                        goto exit;
                   5639:                }
                   5640: 
                   5641:                /* Decode and apply the ERO. */
                   5642:                for (i = 0; i < packet_ero.len; i += 2) {
                   5643:                        req = getUShort(packet_ero.data + i);
                   5644:                        /* Already in the reply? */
                   5645:                        oc = lookup_option(&dhcpv6_universe, opt_state, req);
                   5646:                        if (oc != NULL)
                   5647:                                continue;
                   5648:                        /* Get it from the packet if present. */
                   5649:                        oc = lookup_option(&dhcpv6_universe,
                   5650:                                           packet->options,
                   5651:                                           req);
                   5652:                        if (oc == NULL)
                   5653:                                continue;
                   5654:                        if (!evaluate_option_cache(&a_opt, packet,
                   5655:                                                   NULL, NULL,
                   5656:                                                   packet->options, NULL,
                   5657:                                                   &global_scope, oc, MDL)) {
                   5658:                                log_error("dhcpv6_relay_forw: error "
                   5659:                                          "evaluating option %u.", req);
                   5660:                                goto exit;
                   5661:                        }
                   5662:                        if (!save_option_buffer(&dhcpv6_universe,
                   5663:                                                opt_state,
                   5664:                                                NULL,
                   5665:                                                (unsigned char *)a_opt.data,
                   5666:                                                a_opt.len,
                   5667:                                                req,
                   5668:                                                0)) {
                   5669:                                log_error("dhcpv6_relay_forw: error saving "
                   5670:                                          "option %u.", req);
                   5671:                                goto exit;
                   5672:                        }
                   5673:                        data_string_forget(&a_opt, MDL);
                   5674:                }
                   5675:        }
                   5676: 
                   5677:        reply_ofs += store_options6(reply_data + reply_ofs,
                   5678:                                    sizeof(reply_data) - reply_ofs,
                   5679:                                    opt_state, packet,
                   5680:                                    required_opts_agent, &packet_ero);
                   5681: 
                   5682:        /*
                   5683:         * Return our reply to the caller.
                   5684:         */
                   5685:        reply_ret->len = reply_ofs;
                   5686:        reply_ret->buffer = NULL;
                   5687:        if (!buffer_allocate(&reply_ret->buffer, reply_ret->len, MDL)) {
                   5688:                log_fatal("No memory to store reply.");
                   5689:        }
                   5690:        reply_ret->data = reply_ret->buffer->data;
                   5691:        memcpy(reply_ret->buffer->data, reply_data, reply_ofs);
                   5692: 
                   5693: exit:
                   5694:        if (opt_state != NULL)
                   5695:                option_state_dereference(&opt_state, MDL);
                   5696:        if (a_opt.data != NULL) {
                   5697:                data_string_forget(&a_opt, MDL);
                   5698:        }
                   5699:        if (packet_ero.data != NULL) {
                   5700:                data_string_forget(&packet_ero, MDL);
                   5701:        }
                   5702:        if (enc_reply.data != NULL) {
                   5703:                data_string_forget(&enc_reply, MDL);
                   5704:        }
                   5705:        if (enc_opt_data.data != NULL) {
                   5706:                data_string_forget(&enc_opt_data, MDL);
                   5707:        }
                   5708:        if (enc_packet != NULL) {
                   5709:                packet_dereference(&enc_packet, MDL);
                   5710:        }
                   5711: }
                   5712: 
                   5713: static void
                   5714: dhcpv6_discard(struct packet *packet) {
                   5715:        /* INSIST(packet->msg_type > 0); */
                   5716:        /* INSIST(packet->msg_type < dhcpv6_type_name_max); */
                   5717: 
                   5718:        log_debug("Discarding %s from %s; message type not handled by server", 
                   5719:                  dhcpv6_type_names[packet->dhcpv6_msg_type],
                   5720:                  piaddr(packet->client_addr));
                   5721: }
                   5722: 
                   5723: static void 
                   5724: build_dhcpv6_reply(struct data_string *reply, struct packet *packet) {
                   5725:        memset(reply, 0, sizeof(*reply));
                   5726:        switch (packet->dhcpv6_msg_type) {
                   5727:                case DHCPV6_SOLICIT:
                   5728:                        dhcpv6_solicit(reply, packet);
                   5729:                        break;
                   5730:                case DHCPV6_ADVERTISE:
                   5731:                        dhcpv6_discard(packet);
                   5732:                        break;
                   5733:                case DHCPV6_REQUEST:
                   5734:                        dhcpv6_request(reply, packet);
                   5735:                        break;
                   5736:                case DHCPV6_CONFIRM:
                   5737:                        dhcpv6_confirm(reply, packet);
                   5738:                        break;
                   5739:                case DHCPV6_RENEW:
                   5740:                        dhcpv6_renew(reply, packet);
                   5741:                        break;
                   5742:                case DHCPV6_REBIND:
                   5743:                        dhcpv6_rebind(reply, packet);
                   5744:                        break;
                   5745:                case DHCPV6_REPLY:
                   5746:                        dhcpv6_discard(packet);
                   5747:                        break;
                   5748:                case DHCPV6_RELEASE:
                   5749:                        dhcpv6_release(reply, packet);
                   5750:                        break;
                   5751:                case DHCPV6_DECLINE:
                   5752:                        dhcpv6_decline(reply, packet);
                   5753:                        break;
                   5754:                case DHCPV6_RECONFIGURE:
                   5755:                        dhcpv6_discard(packet);
                   5756:                        break;
                   5757:                case DHCPV6_INFORMATION_REQUEST:
                   5758:                        dhcpv6_information_request(reply, packet);
                   5759:                        break;
                   5760:                case DHCPV6_RELAY_FORW:
                   5761:                        dhcpv6_relay_forw(reply, packet);
                   5762:                        break;
                   5763:                case DHCPV6_RELAY_REPL:
                   5764:                        dhcpv6_discard(packet);
                   5765:                        break;
                   5766:                case DHCPV6_LEASEQUERY:
                   5767:                        dhcpv6_leasequery(reply, packet);
                   5768:                        break;
                   5769:                case DHCPV6_LEASEQUERY_REPLY:
                   5770:                        dhcpv6_discard(packet);
                   5771:                        break;
                   5772:                default:
                   5773:                        /* XXX: would be nice if we had "notice" level, 
                   5774:                                as syslog, for this */
                   5775:                        log_info("Discarding unknown DHCPv6 message type %d "
                   5776:                                 "from %s", packet->dhcpv6_msg_type, 
                   5777:                                 piaddr(packet->client_addr));
                   5778:        }
                   5779: }
                   5780: 
                   5781: static void
                   5782: log_packet_in(const struct packet *packet) {
                   5783:        struct data_string s;
                   5784:        u_int32_t tid;
                   5785:        char tmp_addr[INET6_ADDRSTRLEN];
                   5786:        const void *addr;
                   5787: 
                   5788:        memset(&s, 0, sizeof(s));
                   5789: 
                   5790:        if (packet->dhcpv6_msg_type < dhcpv6_type_name_max) {
                   5791:                data_string_sprintfa(&s, "%s message from %s port %d",
                   5792:                                     dhcpv6_type_names[packet->dhcpv6_msg_type],
                   5793:                                     piaddr(packet->client_addr),
                   5794:                                     ntohs(packet->client_port));
                   5795:        } else {
                   5796:                data_string_sprintfa(&s, 
                   5797:                                     "Unknown message type %d from %s port %d",
                   5798:                                     packet->dhcpv6_msg_type,
                   5799:                                     piaddr(packet->client_addr),
                   5800:                                     ntohs(packet->client_port));
                   5801:        }
                   5802:        if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) || 
                   5803:            (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
                   5804:                addr = &packet->dhcpv6_link_address;
                   5805:                data_string_sprintfa(&s, ", link address %s", 
                   5806:                                     inet_ntop(AF_INET6, addr, 
                   5807:                                               tmp_addr, sizeof(tmp_addr)));
                   5808:                addr = &packet->dhcpv6_peer_address;
                   5809:                data_string_sprintfa(&s, ", peer address %s", 
                   5810:                                     inet_ntop(AF_INET6, addr, 
                   5811:                                               tmp_addr, sizeof(tmp_addr)));
                   5812:        } else {
                   5813:                tid = 0;
                   5814:                memcpy(((char *)&tid)+1, packet->dhcpv6_transaction_id, 3);
                   5815:                data_string_sprintfa(&s, ", transaction ID 0x%06X", tid);
                   5816: 
                   5817: /*
                   5818:                oc = lookup_option(&dhcpv6_universe, packet->options, 
                   5819:                                   D6O_CLIENTID);
                   5820:                if (oc != NULL) {
                   5821:                        memset(&tmp_ds, 0, sizeof(tmp_ds_));
                   5822:                        if (!evaluate_option_cache(&tmp_ds, packet, NULL, NULL, 
                   5823:                                                   packet->options, NULL,
                   5824:                                                   &global_scope, oc, MDL)) {
                   5825:                                log_error("Error evaluating Client Identifier");
                   5826:                        } else {
                   5827:                                data_strint_sprintf(&s, ", client ID %s",
                   5828: 
                   5829:                                data_string_forget(&tmp_ds, MDL);
                   5830:                        }
                   5831:                }
                   5832: */
                   5833: 
                   5834:        }
                   5835:        log_info("%s", s.data);
                   5836: 
                   5837:        data_string_forget(&s, MDL);
                   5838: }
                   5839: 
                   5840: void 
                   5841: dhcpv6(struct packet *packet) {
                   5842:        struct data_string reply;
                   5843:        struct sockaddr_in6 to_addr;
                   5844:        int send_ret;
                   5845: 
                   5846:        /* 
                   5847:         * Log a message that we received this packet.
                   5848:         */
                   5849:        log_packet_in(packet); 
                   5850: 
                   5851:        /*
                   5852:         * Build our reply packet.
                   5853:         */
                   5854:        build_dhcpv6_reply(&reply, packet);
                   5855: 
                   5856:        if (reply.data != NULL) {
                   5857:                /* 
                   5858:                 * Send our reply, if we have one.
                   5859:                 */
                   5860:                memset(&to_addr, 0, sizeof(to_addr));
                   5861:                to_addr.sin6_family = AF_INET6;
                   5862:                if ((packet->dhcpv6_msg_type == DHCPV6_RELAY_FORW) || 
                   5863:                    (packet->dhcpv6_msg_type == DHCPV6_RELAY_REPL)) {
                   5864:                        to_addr.sin6_port = local_port;
                   5865:                } else {
                   5866:                        to_addr.sin6_port = remote_port;
                   5867:                }
                   5868: 
                   5869: #if defined (REPLY_TO_SOURCE_PORT)
                   5870:                /*
                   5871:                 * This appears to have been included for testing so we would
                   5872:                 * not need a root client, but was accidently left in the
                   5873:                 * final code.  We continue to include it in case
                   5874:                 * some users have come to rely upon it, but leave
                   5875:                 * it off by default as it's a bad idea.
                   5876:                 */
                   5877:                to_addr.sin6_port = packet->client_port;
                   5878: #endif
                   5879: 
                   5880:                memcpy(&to_addr.sin6_addr, packet->client_addr.iabuf, 
                   5881:                       sizeof(to_addr.sin6_addr));
                   5882: 
                   5883:                log_info("Sending %s to %s port %d", 
                   5884:                         dhcpv6_type_names[reply.data[0]],
                   5885:                         piaddr(packet->client_addr),
                   5886:                         ntohs(to_addr.sin6_port));
                   5887: 
                   5888:                send_ret = send_packet6(packet->interface, 
                   5889:                                        reply.data, reply.len, &to_addr);
                   5890:                if (send_ret != reply.len) {
                   5891:                        log_error("dhcpv6: send_packet6() sent %d of %d bytes",
                   5892:                                  send_ret, reply.len);
                   5893:                }
                   5894:                data_string_forget(&reply, MDL);
                   5895:        }
                   5896: }
                   5897: 
                   5898: static void
                   5899: seek_shared_host(struct host_decl **hp, struct shared_network *shared) {
                   5900:        struct host_decl *nofixed = NULL;
                   5901:        struct host_decl *seek, *hold = NULL;
                   5902: 
                   5903:        /*
                   5904:         * Seek forward through fixed addresses for the right link.
                   5905:         *
                   5906:         * Note: how to do this for fixed prefixes???
                   5907:         */
                   5908:        host_reference(&hold, *hp, MDL);
                   5909:        host_dereference(hp, MDL);
                   5910:        seek = hold;
                   5911:        while (seek != NULL) {
                   5912:                if (seek->fixed_addr == NULL)
                   5913:                        nofixed = seek;
                   5914:                else if (fixed_matches_shared(seek, shared))
                   5915:                        break;
                   5916: 
                   5917:                seek = seek->n_ipaddr;
                   5918:        }
                   5919: 
                   5920:        if ((seek == NULL) && (nofixed != NULL))
                   5921:                seek = nofixed;
                   5922: 
                   5923:        if (seek != NULL)
                   5924:                host_reference(hp, seek, MDL);
                   5925: }
                   5926: 
                   5927: static isc_boolean_t
                   5928: fixed_matches_shared(struct host_decl *host, struct shared_network *shared) {
                   5929:        struct subnet *subnet;
                   5930:        struct data_string addr;
                   5931:        isc_boolean_t matched;
                   5932:        struct iaddr fixed;
                   5933: 
                   5934:        if (host->fixed_addr == NULL)
                   5935:                return ISC_FALSE;
                   5936: 
                   5937:        memset(&addr, 0, sizeof(addr));
                   5938:        if (!evaluate_option_cache(&addr, NULL, NULL, NULL, NULL, NULL,
                   5939:                                   &global_scope, host->fixed_addr, MDL))
                   5940:                return ISC_FALSE;
                   5941: 
                   5942:        if (addr.len < 16) {
                   5943:                data_string_forget(&addr, MDL);
                   5944:                return ISC_FALSE;
                   5945:        }
                   5946: 
                   5947:        fixed.len = 16;
                   5948:        memcpy(fixed.iabuf, addr.data, 16);
                   5949: 
                   5950:        matched = ISC_FALSE;
                   5951:        for (subnet = shared->subnets ; subnet != NULL ;
                   5952:             subnet = subnet->next_sibling) {
                   5953:                if (addr_eq(subnet_number(fixed, subnet->netmask),
                   5954:                            subnet->net)) {
                   5955:                        matched = ISC_TRUE;
                   5956:                        break;
                   5957:                }
                   5958:        }
                   5959: 
                   5960:        data_string_forget(&addr, MDL);
                   5961:        return matched;
                   5962: }
                   5963: 
                   5964: #endif /* DHCPv6 */
                   5965: 

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