File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / server / dhcpv6.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:06:55 2012 UTC (11 years, 8 months ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, v4_1_R4, HEAD
dhcp 4.1 r7

    1: /*
    2:  * Copyright (C) 2006-2012 by Internet Systems Consortium, Inc. ("ISC")
    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];
 1094: 	if ((tmp_plen < 3) || (tmp_plen > 128) ||
 1095: 	    ((int)tmp_plen != pool->units)) {
 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: 
 1108: 	if (!ipv6_in_pool(&tmp_pref, pool)) {
 1109: 		return ISC_R_ADDRNOTAVAIL;
 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: /*
 1209:  *! \file server/dhcpv6.c
 1210:  *
 1211:  * \brief construct a reply containing information about a client's lease
 1212:  *
 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.
 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.
 1240:  */
 1241: /* TODO: look at client hints for lease times */
 1242: 
 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;
 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));
 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);
 1307: 
 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: 
 1325: #if defined (RFC3315_PRE_ERRATA_2010_08)
 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;
 1332: #endif
 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: 
 1352: #if defined (RFC3315_PRE_ERRATA_2010_08)
 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;
 1359: #endif
 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: 	 */
 1436: #if defined (RFC3315_PRE_ERRATA_2010_08)
 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: 	}
 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) */
 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: 
 1501: 	/* If appropriate commit and rotate the lease file */
 1502: 	(void) commit_leases_timed();
 1503: 
 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);
 1516: 	if (packet_oro.buffer != NULL)
 1517: 		data_string_forget(&packet_oro, MDL);
 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)
 2217: 			return (ISC_TRUE);
 2218: 
 2219: 		return (ISC_FALSE);
 2220: 	}
 2221: 
 2222: 	if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0))
 2223: 		return (ISC_FALSE);
 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) {
 2231: 			if (lease6_usable(tmp) == ISC_FALSE) {
 2232: 				return (ISC_FALSE);
 2233: 			}
 2234: 			iasubopt_reference(&reply->lease, tmp, MDL);
 2235: 			return (ISC_TRUE);
 2236: 		}
 2237: 	}
 2238: 
 2239: 	return (ISC_FALSE);
 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) {
 2690: 	isc_result_t status = ISC_R_ADDRNOTAVAIL;
 2691: 	struct ipv6_pool *pool;
 2692: 	int i;
 2693: 	struct data_string data_addr;
 2694: 
 2695: 	if ((reply == NULL) || (reply->shared == NULL) ||
 2696: 	    (addr == NULL) || (reply->lease != NULL))
 2697: 		return ISC_R_INVALIDARG;
 2698: 
 2699: 	if (reply->shared->ipv6_pools == NULL)
 2700: 		return (ISC_R_ADDRNOTAVAIL);
 2701: 
 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... */
 2718: 	return (status);
 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: 			 */
 2758: 			if ((candidate_shared == reply->shared) && 
 2759: 			    (lease6_usable(lease) == ISC_TRUE)) {
 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,
 2770: 					 &reply->ia->iaid_duid);
 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: 
 3214: 		if ((status != ISC_R_SUCCESS) &&
 3215: 		    (status != ISC_R_ADDRINUSE) &&
 3216: 		    (status != ISC_R_ADDRNOTAVAIL))
 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. */
 3492: 			if ((status != ISC_R_SUCCESS) &&
 3493: 			    (status != ISC_R_ADDRINUSE) &&
 3494: 			    (status != ISC_R_ADDRNOTAVAIL))
 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))
 3642: 				return (ISC_TRUE);
 3643: 		}
 3644: 		return (ISC_FALSE);
 3645: 	}
 3646: 
 3647: 	if ((reply->old_ia == NULL) ||
 3648: 	    (reply->old_ia->num_iasubopt == 0))
 3649: 		return (ISC_FALSE);
 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) &&
 3657: 		    (memcmp(pref->lo_addr.iabuf, &tmp->addr, 16) == 0)) {
 3658: 			if (lease6_usable(tmp) == ISC_FALSE) {
 3659: 				return (ISC_FALSE);
 3660: 			}
 3661: 			iasubopt_reference(&reply->lease, tmp, MDL);
 3662: 			return (ISC_TRUE);
 3663: 		}
 3664: 	}
 3665: 
 3666: 	return (ISC_FALSE);
 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) {
 3676: 	isc_result_t status = ISC_R_ADDRNOTAVAIL;
 3677: 	struct ipv6_pool *pool;
 3678: 	int i;
 3679: 	struct data_string data_pref;
 3680: 
 3681: 	if ((reply == NULL) || (reply->shared == NULL) ||
 3682: 	    (pref == NULL) || (reply->lease != NULL))
 3683: 		return ISC_R_INVALIDARG;
 3684: 
 3685: 	if (reply->shared->ipv6_pools == NULL)
 3686: 		return (ISC_R_ADDRNOTAVAIL);
 3687: 
 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.");
 3692: 		return (ISC_R_NOMEMORY);
 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... */
 3711: 	return (status);
 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: 			 */
 3762: 			if (((candidate_shared == NULL) ||
 3763: 			     (candidate_shared == reply->shared)) &&
 3764: 			    (lease6_usable(prefix) == ISC_TRUE)) {
 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)) {
 5513: 		int relaylen = (int)(offsetof(struct dhcpv6_relay_packet, options));
 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, 
 5526: 					 enc_opt_data.len - relaylen,
 5527: 					 &dhcpv6_universe)) {
 5528: 			/* no logging here, as parse_option_buffer() logs all
 5529: 			   cases where it fails */
 5530: 			goto exit;
 5531: 		}
 5532: 	} else {
 5533: 		int msglen = (int)(offsetof(struct dhcpv6_packet, options));
 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, 
 5544: 					 enc_opt_data.len - msglen,
 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>