Home | History | Annotate | Download | only in server

Lines Matching refs:reply

63  * DHCPv6 Reply workflow assist.  A Reply packet is built by various
65 * regarding a reply.
115 struct dhcpv6_packet reply;
134 static isc_result_t reply_process_ia_na(struct reply_state *reply,
136 static isc_result_t reply_process_ia_ta(struct reply_state *reply,
138 static isc_result_t reply_process_addr(struct reply_state *reply,
140 static isc_boolean_t address_is_owned(struct reply_state *reply,
142 static isc_boolean_t temporary_is_available(struct reply_state *reply,
144 static isc_result_t find_client_temporaries(struct reply_state *reply);
145 static isc_result_t reply_process_try_addr(struct reply_state *reply,
147 static isc_result_t find_client_address(struct reply_state *reply);
148 static isc_result_t reply_process_is_addressed(struct reply_state *reply,
151 static isc_result_t reply_process_send_addr(struct reply_state *reply,
155 static isc_result_t reply_process_ia_pd(struct reply_state *reply,
157 static struct group *find_group_by_prefix(struct reply_state *reply);
158 static isc_result_t reply_process_prefix(struct reply_state *reply,
160 static isc_boolean_t prefix_is_owned(struct reply_state *reply,
162 static isc_result_t find_client_prefix(struct reply_state *reply);
163 static isc_result_t reply_process_try_prefix(struct reply_state *reply,
165 static isc_result_t reply_process_is_prefixed(struct reply_state *reply,
168 static isc_result_t reply_process_send_prefix(struct reply_state *reply,
170 static struct iasubopt *prefix_compare(struct reply_state *reply,
173 static void schedule_lease_timeout_reply(struct reply_state *reply);
176 static isc_result_t pick_v6_prefix_helper(struct reply_state *reply,
191 set_reply_tee_times(struct reply_state* reply, unsigned ia_cursor);
194 static int release_on_roam(struct reply_state *reply);
196 static int reuse_lease6(struct reply_state *reply, struct iasubopt *lease);
197 static void shorten_lifetimes(struct reply_state *reply, struct iasubopt *lease,
199 static void write_to_packet(struct reply_state *reply, unsigned ia_cursor);
203 static void ddns_update_static6(struct reply_state* reply);
312 * Schedule lease timeouts for all of the iasubopts in the reply.
317 schedule_lease_timeout_reply(struct reply_state *reply) {
321 /* sanity check the reply */
322 if ((reply == NULL) || (reply->ia == NULL) || (reply->ia->iasubopt == NULL))
326 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
327 tmp = reply->ia->iasubopt[i];
987 static void check_pool6_threshold(struct reply_state *reply,
1040 if (get_option_int(&poolhigh, &server_universe, reply->packet, NULL,
1041 NULL, reply->packet->options, reply->opt_state,
1042 reply->opt_state, &lease->scope,
1071 if ((get_option_int(&poollow, &server_universe, reply->packet, NULL,
1072 NULL, reply->packet->options, reply->opt_state,
1073 reply->opt_state, &lease->scope,
1091 * We have a set of operations we do to set up the reply packet, which
1099 struct dhcpv6_packet *reply)
1106 * Build our option state for reply.
1124 reply->msg_type = DHCPV6_ADVERTISE;
1131 * Then we add a rapid commit option, and send Reply
1141 reply->msg_type = DHCPV6_REPLY;
1149 reply->msg_type = DHCPV6_REPLY;
1160 * Use the client's transaction identifier for the reply.
1162 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
1163 sizeof(reply->transaction_id));
1288 * \param reply = the state structure for the current work on this request
1289 * if we create a lease we return it using reply->lease
1302 pick_v6_address(struct reply_state *reply)
1310 struct iasubopt **addr = &reply->lease;
1315 char *shared_name = (reply->shared->name ?
1316 reply->shared->name : "(no name)");
1322 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1352 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1356 (permitted(reply->packet, pond->prohibit_list))) ||
1358 (!permitted(reply->packet, pond->permit_list))))
1365 !valid_eui_64_duid(&reply->ia->iaid_duid, IAID_LEN)) {
1379 &reply->ia->iaid_duid,
1387 &reply->ia->iaid_duid,
1541 * \param reply = the state structure for the current work on this request
1542 * if we create a lease we return it using reply->lease
1555 pick_v6_prefix(struct reply_state *reply) {
1565 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1584 if (reply->preflen <= 0) {
1587 result = pick_v6_prefix_helper(reply, PLM_IGNORE);
1593 result = pick_v6_prefix_helper(reply, PLM_EXACT);
1595 result = pick_v6_prefix_helper(reply,
1602 result = pick_v6_prefix_helper(reply, PLM_EXACT);
1609 result = pick_v6_prefix_helper(reply, PLM_EXACT);
1611 result = pick_v6_prefix_helper(reply,
1618 result = pick_v6_prefix_helper(reply, PLM_IGNORE);
1627 inet_ntop(AF_INET6, &(reply->lease->addr),
1629 (unsigned)(reply->lease->plen));
1650 * \param reply = the state structure for the current work on this request
1651 * if we create a lease we return it using reply->lease
1665 pick_v6_prefix_helper(struct reply_state *reply, int prefix_mode) {
1670 struct iasubopt **pref = &reply->lease;
1672 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
1674 (permitted(reply->packet, pond->prohibit_list))) ||
1676 (!permitted(reply->packet, pond->permit_list))))
1681 (eval_prefix_mode(p->units, reply->preflen,
1684 &reply->ia->iaid_duid,
1734 * \brief construct a reply containing information about a client's lease
1737 * reply that contains all that we know about the client's correct lease
1772 static struct reply_state reply;
1780 if (shared_network_from_packet6(&reply.shared,
1785 * Initialize the reply.
1787 packet_reference(&reply.packet, packet, MDL);
1788 data_string_copy(&reply.client_id, client_id, MDL);
1790 if (!start_reply(packet, client_id, server_id, &reply.opt_state,
1791 &reply.buf.reply))
1794 /* Set the write cursor to just past the reply header. */
1795 reply.cursor = REPLY_OPTIONS_INDEX;
1815 if (find_hosts6(&reply.host, packet, client_id, MDL)) {
1817 seek_shared_host(&reply.host, reply.shared);
1820 /* Process the client supplied IA's onto the reply buffer. */
1821 reply.ia_count = 0;
1828 reply.client_resources = 0;
1829 reply.resources_included = ISC_FALSE;
1831 status = reply_process_ia_na(&reply, oc);
1846 reply.client_resources = 0;
1847 reply.resources_included = ISC_FALSE;
1849 status = reply_process_ia_ta(&reply, oc);
1861 reply.pd_count = 0;
1867 reply.client_resources = 0;
1868 reply.resources_included = ISC_FALSE;
1870 status = reply_process_ia_pd(&reply, oc);
1882 * Make no reply if we gave no resources and is not
1885 if ((reply.ia_count == 0) && (reply.pd_count == 0)) {
1886 if (reply.packet->dhcpv6_msg_type !=
1892 * we need to execute statements in any non-IA reply to
1895 execute_statements_in_scope(NULL, reply.packet, NULL, NULL,
1896 reply.packet->options,
1897 reply.opt_state, &global_scope,
1898 reply.shared->group, root_group,
1902 for (i = reply.packet->class_count; i > 0; i--) {
1903 execute_statements_in_scope(NULL, reply.packet,
1905 reply.packet->options,
1906 reply.opt_state,
1908 reply.packet->classes[i - 1]->group,
1909 reply.shared->group, NULL);
1913 if (reply.host != NULL)
1914 execute_statements_in_scope(NULL, reply.packet,
1916 reply.packet->options,
1917 reply.opt_state,
1919 reply.host->group,
1920 reply.shared->group, NULL);
1940 * the Reply message with no addresses in the IA and a Status
1948 * Sends a Renew/Rebind if the IA is not in the Reply message.
1955 reply.cursor += store_options6((char *)reply.buf.data + reply.cursor,
1956 sizeof(reply.buf) - reply.cursor,
1957 reply.opt_state, reply.packet,
1961 /* Return our reply to the caller. */
1962 reply_ret->len = reply.cursor;
1964 if (!buffer_allocate(&reply_ret->buffer, reply.cursor, MDL)) {
1965 log_fatal("No memory to store Reply.");
1967 memcpy(reply_ret->buffer->data, reply.buf.data, reply.cursor);
1975 if (reply.shared != NULL)
1976 shared_network_dereference(&reply.shared, MDL);
1977 if (reply.host != NULL)
1978 host_dereference(&reply.host, MDL);
1979 if (reply.opt_state != NULL)
1980 option_state_dereference(&reply.opt_state, MDL);
1981 if (reply.packet != NULL)
1982 packet_dereference(&reply.packet, MDL);
1983 if (reply.client_id.data != NULL)
1984 data_string_forget(&reply.client_id, MDL);
1987 reply.renew = reply.rebind = reply.min_prefer = reply.min_valid = 0;
1988 reply.cursor = 0;
1992 * the reply packet being built in the reply_state structure.
1995 reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
2008 * Note that find_client_address() may set reply->lease.
2012 if ((reply->cursor + IA_NA_OFFSET + 4) > sizeof(reply->buf)) {
2013 log_error("reply_process_ia_na: Reply too long for IA.");
2019 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
2028 reply->renew = getULong(ia_data.data + 4);
2029 reply->rebind = getULong(ia_data.data + 8);
2032 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
2033 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
2038 reply->ia->ia_type = D6O_IA_NA;
2041 ia_hash_lookup(&reply->old_ia, ia_na_active,
2042 (unsigned char *)reply->ia->iaid_duid.data,
2043 reply->ia->iaid_duid.len, MDL);
2049 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2055 if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
2058 if (!evaluate_option_cache(&reply->fixed, NULL, NULL, NULL,
2060 reply->host->fixed_addr, MDL)) {
2067 if (reply->fixed.len < 16) {
2075 memcpy(tmp_addr.iabuf, reply->fixed.data, 16);
2077 if (find_grouped_subnet(&reply->subnet, reply->shared,
2081 reply->static_lease = ISC_TRUE;
2083 reply->static_lease = ISC_FALSE;
2091 ia_cursor = reply->cursor;
2094 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_NA);
2095 reply->cursor += 2;
2098 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
2099 reply->cursor += 2;
2102 putULong(reply->buf.data + reply->cursor, iaid);
2103 reply->cursor += 4;
2106 putULong(reply->buf.data + reply->cursor, reply->renew);
2107 reply->cursor += 4;
2110 putULong(reply->buf.data + reply->cursor, reply->rebind);
2111 reply->cursor += 4;
2123 reply->min_valid = reply->min_prefer = INFINITE_TIME;
2124 reply->client_valid = reply->client_prefer = 0;
2126 status = reply_process_addr(reply, oc);
2131 * code. So transmit this reply, e.g., move on to the next
2143 reply->ia_count++;
2149 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
2150 status = find_client_address(reply);
2153 switch (reply->packet->dhcpv6_msg_type) {
2166 * server MUST include the IA in the Reply
2171 option_state_dereference(&reply->reply_ia, MDL);
2172 if (!option_state_allocate(&reply->reply_ia,
2185 reply->reply_ia)) {
2213 if (reply->resources_included)
2232 write_to_packet(reply, ia_cursor);
2240 if (reply->static_lease) {
2244 dhcpv6_type_names[reply->buf.reply.msg_type],
2245 inet_ntop(AF_INET6, reply->fixed.data, tmp_addr,
2247 print_hex_1(reply->client_id.len,
2248 reply->client_id.data, 60),
2252 write_to_packet(reply, ia_cursor);
2255 ddns_update_static6(reply);
2257 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
2258 (reply->on_star.on_commit != NULL)) {
2259 execute_statements(NULL, reply->packet, NULL, NULL,
2260 reply->packet->options,
2261 reply->opt_state, NULL,
2262 reply->on_star.on_commit, NULL);
2264 (&reply->on_star.on_commit, MDL);
2272 if (reply->ia->num_iasubopt != 0) {
2277 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2278 tmp = reply->ia->iasubopt[i];
2282 dhcpv6_type_names[reply->buf.reply.msg_type],
2285 print_hex_1(reply->client_id.len,
2286 reply->client_id.data, 60),
2306 if ((reply->ia->num_iasubopt != 0) &&
2307 (reply->buf.reply.msg_type == DHCPV6_REPLY)) {
2313 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2314 tmp = reply->ia->iasubopt[i];
2319 ia_reference(&tmp->ia, reply->ia, MDL);
2323 execute_statements(NULL, reply->packet,
2325 reply->packet->options,
2326 reply->opt_state,
2337 oc = lookup_option(&server_universe, reply->opt_state,
2340 evaluate_boolean_option_cache(NULL, reply->packet,
2342 reply->packet->options,
2343 reply->opt_state,
2346 ddns_updates(reply->packet, NULL, NULL,
2347 tmp, NULL, reply->opt_state);
2350 if (!reuse_lease6(reply, tmp)) {
2357 check_pool6_threshold(reply, tmp);
2362 write_to_packet(reply, ia_cursor);
2365 if (reply->old_ia != NULL) {
2366 if (!release_on_roam(reply)) {
2367 ia_id = &reply->old_ia->iaid_duid;
2373 ia_dereference(&reply->old_ia, MDL);
2377 reply->ia->cltt = cur_time;
2378 ia_id = &reply->ia->iaid_duid;
2380 ia_id->len, reply->ia, MDL);
2385 write_ia(reply->ia);
2389 write_to_packet(reply, ia_cursor);
2390 schedule_lease_timeout_reply(reply);
2396 if (reply->reply_ia != NULL)
2397 option_state_dereference(&reply->reply_ia, MDL);
2402 if (reply->ia != NULL)
2403 ia_dereference(&reply->ia, MDL);
2404 if (reply->old_ia != NULL)
2405 ia_dereference(&reply->old_ia, MDL);
2406 if (reply->lease != NULL)
2407 iasubopt_dereference(&reply->lease, MDL);
2408 if (reply->fixed.data != NULL)
2409 data_string_forget(&reply->fixed, MDL);
2410 if (reply->subnet != NULL)
2411 subnet_dereference(&reply->subnet, MDL);
2412 if (reply->on_star.on_expiry != NULL)
2414 (&reply->on_star.on_expiry, MDL);
2415 if (reply->on_star.on_release != NULL)
2417 (&reply->on_star.on_release, MDL);
2428 * Writes the populated IA_xx in wire format to the reply buffer
2431 write_to_packet(struct reply_state *reply, unsigned ia_cursor) {
2432 reply->cursor += store_options6((char *)reply->buf.data + reply->cursor,
2433 sizeof(reply->buf) - reply->cursor,
2434 reply->reply_ia, reply->packet,
2435 (reply->ia->ia_type != D6O_IA_PD ?
2440 putUShort(reply->buf.data + ia_cursor + 2,
2441 reply->cursor - (ia_cursor + 4));
2443 if (reply->ia->ia_type != D6O_IA_TA) {
2444 /* Calculate T1/T2 and stuff them in the reply */
2445 set_reply_tee_times(reply, ia_cursor);
2450 * Process an IAADDR within a given IA_xA, storing any IAADDR reply contents
2451 * into the reply's current ia-scoped option cache. Returns ISC_R_CANCELED
2456 reply_process_addr(struct reply_state *reply, struct option_cache *addr) {
2472 /* Note that reply->lease may be set by address_is_owned() */
2478 if ((reply->cursor + 28) > sizeof(reply->buf)) {
2484 if (!evaluate_option_cache(&iaaddr, reply->packet, NULL, NULL,
2485 reply->packet->options, NULL, &global_scope,
2497 if ((reply->client_valid == 0) ||
2498 (reply->client_valid > valid_life))
2499 reply->client_valid = valid_life;
2501 if ((reply->client_prefer == 0) ||
2502 (reply->client_prefer > pref_life))
2503 reply->client_prefer = pref_life;
2522 for (subnet = reply->shared->subnets ; subnet != NULL ;
2539 (!valid_for_eui_64_pool(pool, &reply->client_id, 0, addr))) {
2555 if (reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) {
2557 reply->buf.reply.msg_type = DHCPV6_ADVERTISE;
2559 reply->opt_state,
2574 if (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) {
2576 option_state_dereference(&reply->reply_ia, MDL);
2577 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2587 "link.", reply->reply_ia)) {
2607 if ((reply->packet->dhcpv6_msg_type != DHCPV6_RENEW) &&
2608 (reply->packet->dhcpv6_msg_type != DHCPV6_REBIND)) {
2616 reply->send_prefer = reply->send_valid = 0;
2622 if (!address_is_owned(reply, &tmp_addr)) {
2630 if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
2631 (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
2632 (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
2633 status = reply_process_try_addr(reply, &tmp_addr);
2650 if (reply->lease == NULL) {
2651 if (reply->packet->dhcpv6_msg_type ==
2653 reply->send_prefer = 0;
2654 reply->send_valid = 0;
2666 * Code option set to NoBinding in the Reply message.
2671 } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
2673 option_state_dereference(&reply->reply_ia, MDL);
2674 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2684 "interface.", reply->reply_ia)) {
2703 if (reply->static_lease) {
2704 if (reply->host == NULL)
2708 group = reply->subnet->group;
2710 if (reply->lease == NULL)
2713 scope = &reply->lease->scope;
2714 group = reply->lease->ipv6_pool->ipv6_pond->group;
2719 * function has executed configuration state into the reply option
2723 if (reply->client_resources != 0) {
2731 oc = lookup_option(&server_universe, reply->opt_state,
2734 if (!evaluate_option_cache(&data, reply->packet,
2736 reply->packet->options,
2737 reply->opt_state,
2752 * addresses, then omit the address from the reply.
2754 if (reply->client_resources >= limit)
2758 status = reply_process_is_addressed(reply, scope, group);
2763 status = reply_process_send_addr(reply, &tmp_addr);
2770 if (reply->lease != NULL)
2771 iasubopt_dereference(&reply->lease, MDL);
2783 address_is_owned(struct reply_state *reply, struct iaddr *addr) {
2790 if (reply->static_lease) {
2791 if (reply->fixed.data == NULL)
2794 if (memcmp(addr->iabuf, reply->fixed.data, 16) == 0)
2800 if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0))
2803 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
2806 tmp = reply
2815 (permitted(reply->packet, pond->prohibit_list))) ||
2817 (!permitted(reply->packet, pond->permit_list))))
2820 iasubopt_reference(&reply->lease, tmp, MDL);
2830 * the reply packet being built in the reply_state structure.
2833 reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) {
2851 if ((reply->cursor + IA_TA_OFFSET + 4) > sizeof(reply->buf)) {
2852 log_error("reply_process_ia_ta: Reply too long for IA.");
2858 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
2869 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
2870 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
2875 reply->ia->ia_type = D6O_IA_TA;
2878 ia_hash_lookup(&reply->old_ia, ia_ta_active,
2879 (unsigned char *)reply->ia->iaid_duid.data,
2880 reply->ia->iaid_duid.len, MDL);
2886 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2894 reply->static_lease = ISC_FALSE;
2902 ia_cursor = reply->cursor;
2905 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_TA);
2906 reply->cursor += 2;
2909 putUShort(reply->buf.data + reply->cursor, 0x04u);
2910 reply->cursor += 2;
2913 putULong(reply->buf.data + reply->cursor, iaid);
2914 reply->cursor += 4;
2920 reply->min_valid = reply->min_prefer = INFINITE_TIME;
2921 reply->client_valid = reply->client_prefer = 0;
2925 if (!evaluate_option_cache(&iaaddr, reply->packet,
2927 reply->packet->options, NULL,
2939 if ((reply->client_valid == 0) ||
2940 (reply->client_valid > valid_life))
2941 reply->client_valid = valid_life;
2943 if ((reply->client_prefer == 0) ||
2944 (reply->client_prefer > pref_life))
2945 reply->client_prefer = pref_life;
2953 if (!temporary_is_available(reply, &tmp_addr))
2955 status = reply_process_is_addressed(reply,
2956 &reply->lease->scope,
2957 reply->lease->ipv6_pool->ipv6_pond->group);
2960 status = reply_process_send_addr(reply, &tmp_addr);
2963 if (reply->lease != NULL)
2964 iasubopt_dereference(&reply->lease, MDL);
2969 option_state_dereference(&reply->reply_ia, MDL);
2970 if (!option_state_allocate(&reply->reply_ia, MDL)) {
2975 reply->client_resources = 0;
2976 reply->resources_included = ISC_FALSE;
2977 if (reply->lease != NULL)
2978 iasubopt_dereference(&reply->lease, MDL);
2980 reply->ia_count++;
2985 if (reply->client_resources != 0)
2987 status = find_client_temporaries(reply);
2989 switch (reply->packet->dhcpv6_msg_type) {
3002 * server MUST include the IA in the Reply
3007 option_state_dereference(&reply->reply_ia, MDL);
3008 if (!option_state_allocate(&reply->reply_ia, MDL)) {
3018 reply->reply_ia)) {
3034 if (reply->resources_included)
3052 write_to_packet(reply, ia_cursor);
3059 if (reply->ia->num_iasubopt != 0) {
3064 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3065 tmp = reply->ia->iasubopt[i];
3069 dhcpv6_type_names[reply->buf.reply.msg_type],
3072 print_hex_1(reply->client_id.len,
3073 reply->client_id.data, 60),
3087 if ((reply->ia->num_iasubopt != 0) &&
3088 (reply->buf.reply.msg_type == DHCPV6_REPLY)) {
3094 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3095 tmp = reply->ia->iasubopt[i];
3099 ia_reference(&tmp->ia, reply->ia, MDL);
3103 execute_statements(NULL, reply->packet,
3105 reply->packet->options,
3106 reply->opt_state,
3118 oc = lookup_option(&server_universe, reply->opt_state,
3121 evaluate_boolean_option_cache(NULL, reply->packet,
3123 reply->packet->options,
3124 reply->opt_state,
3127 ddns_updates(reply->packet, NULL, NULL,
3128 tmp, NULL, reply->opt_state);
3132 if (!reuse_lease6(reply, tmp)) {
3139 check_pool6_threshold(reply, tmp);
3144 write_to_packet(reply, ia_cursor);
3147 if (reply->old_ia != NULL) {
3148 if (!release_on_roam(reply)) {
3149 ia_id = &reply->old_ia->iaid_duid;
3155 ia_dereference(&reply->old_ia, MDL);
3159 reply->ia->cltt = cur_time;
3160 ia_id = &reply->ia->iaid_duid;
3162 ia_id->len, reply->ia, MDL);
3167 write_ia(reply->ia);
3171 write_to_packet(reply, ia_cursor);
3172 schedule_lease_timeout_reply(reply);
3180 if (reply->reply_ia != NULL)
3181 option_state_dereference(&reply->reply_ia, MDL);
3186 if (reply->ia != NULL)
3187 ia_dereference(&reply->ia, MDL);
3188 if (reply->old_ia != NULL)
3189 ia_dereference(&reply->old_ia, MDL);
3190 if (reply->lease != NULL)
3191 iasubopt_dereference(&reply->lease, MDL);
3214 reuse_lease6(struct reply_state *reply, struct iasubopt *lease) {
3234 oc = lookup_option(&server_universe, reply->opt_state,
3237 evaluate_option_cache(&d1, reply->packet, NULL, NULL,
3238 reply->packet->options, reply->opt_state,
3268 shorten_lifetimes(reply, lease, age, threshold);
3279 * the reply if the lease can be reused. Therefore, when we do reuse a
3283 * Locate the iasubopt by it's address within the reply the reduce both
3289 void shorten_lifetimes(struct reply_state *reply, struct iasubopt *lease,
3298 if (reply->ia->ia_type != D6O_IA_PD) {
3314 oc = lookup_option(&dhcpv6_universe, reply->reply_ia, subopt_type);
3337 if (reply->min_prefer > pref_life) {
3338 reply->min_prefer = pref_life;
3347 if (reply->min_valid > reply->send_valid) {
3348 reply->min_valid = valid_life;
3369 temporary_is_available(struct reply_state *reply, struct iaddr *addr) {
3388 for (subnet = reply->shared->subnets ; subnet != NULL ;
3402 if (address_is_owned(reply, addr))
3408 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3410 (permitted(reply->packet, pond->prohibit_list))) ||
3412 (!permitted(reply->packet, pond->permit_list))))
3431 if (iasubopt_allocate(&reply->lease, MDL) != ISC_R_SUCCESS)
3433 reply->lease->addr = tmp_addr;
3434 reply->lease->plen = 0;
3436 if (add_lease6(pool, reply->lease, cur_time + 120) != ISC_R_SUCCESS)
3446 find_client_temporaries(struct reply_state *reply) {
3458 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3484 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3486 (permitted(reply->packet, pond->prohibit_list))) ||
3488 (!permitted(reply->packet, pond->permit_list))))
3499 status = create_lease6(p, &reply->lease, &attempts,
3500 &reply->client_id,
3508 status = reply_process_is_addressed(reply,
3509 &reply->lease->scope,
3515 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3516 status = reply_process_send_addr(reply, &send_addr);
3521 * reply->lease can't be null as we use it above
3524 iasubopt_dereference(&reply->lease, MDL);
3529 if (reply->lease != NULL) {
3530 iasubopt_dereference(&reply->lease, MDL);
3540 reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) {
3547 if ((reply == NULL) || (reply->shared == NULL) ||
3548 (addr == NULL) || (reply->lease != NULL))
3555 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3589 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
3591 (permitted(reply->packet, pond->prohibit_list))) ||
3593 (!permitted(reply->packet, pond->permit_list))))
3600 status = try_client_v6_address(&reply->lease, pool,
3618 * Finally, actually add that address into the current reply IA.
3621 find_client_address(struct reply_state *reply) {
3629 if (reply->static_lease) {
3630 if (reply->host == NULL)
3634 memcpy(send_addr.iabuf, reply->fixed.data, 16);
3637 group = reply->subnet->group;
3641 if (reply->old_ia != NULL) {
3642 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
3646 lease = reply->old_ia->iasubopt[i];
3655 if ((candidate_shared != reply->shared) ||
3660 (permitted(reply->packet, pond->prohibit_list))) ||
3662 (!permitted(reply->packet, pond->permit_list))))
3673 status = pick_v6_address(reply);
3675 iasubopt_reference(&reply->lease, best_lease, MDL);
3685 print_hex_1(reply->client_id.len,
3686 reply->client_id.data, 60));
3687 /* iasubopt_reference(&reply->lease, best_lease, MDL); */
3694 if (reply->lease == NULL)
3701 scope = &reply->lease->scope;
3702 group = reply->lease->ipv6_pool->ipv6_pond->group;
3705 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3708 status = reply_process_is_addressed(reply, scope, group);
3712 status = reply_process_send_addr(reply, &send_addr);
3721 reply_process_is_addressed(struct reply_state *reply,
3737 * the reply if we don't have a lease because this is
3740 if (reply->lease) {
3741 on_star = &reply->lease->on_star;
3743 on_star = &reply->on_star;
3752 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3753 reply->packet->options, tmp_options,
3765 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3766 reply->packet->options, reply->opt_state,
3770 for (i = reply->packet->class_count; i > 0; i--) {
3771 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3772 reply->packet->options,
3773 reply->opt_state, scope,
3774 reply->packet->classes[i - 1]->group,
3783 if (reply->host != NULL)
3784 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3785 reply->packet->options,
3786 reply->opt_state, scope,
3787 reply->host->group, group,
3791 if (reply->client_valid == 0)
3792 reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
3794 reply->send_valid = reply->client_valid;
3796 oc = lookup_option(&server_universe, reply->opt_state,
3799 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3800 reply->packet->options,
3801 reply->opt_state,
3810 reply->send_valid = getULong(data.data);
3817 * (cur_time + reply->send_valid < cur_time)
3819 if (reply->send_valid != INFINITE_TIME) {
3820 time_t test_time = cur_time + reply->send_valid;
3822 reply->send_valid = INFINITE_TIME;
3825 if (reply->client_prefer == 0)
3826 reply->send_prefer = reply->send_valid;
3828 reply->send_prefer = reply->client_prefer;
3830 if ((reply->send_prefer >= reply->send_valid) &&
3831 (reply->send_valid != INFINITE_TIME))
3832 reply->send_prefer = (reply->send_valid / 2) +
3833 (reply->send_valid / 8);
3835 oc = lookup_option(&server_universe, reply->opt_state,
3838 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
3839 reply->packet->options,
3840 reply->opt_state,
3849 reply->send_prefer = getULong(data.data);
3854 if (reply->min_prefer > reply->send_prefer)
3855 reply->min_prefer = reply->send_prefer;
3857 if (reply->min_valid > reply->send_valid)
3858 reply->min_valid = reply->send_valid;
3870 if (reply->host != NULL)
3871 change_host_uid(host, reply->client_id->data,
3872 reply->client_id->len);
3876 if (reply->lease != NULL) {
3878 reply->lease->prefer = reply->send_prefer;
3879 reply->lease->valid = reply->send_valid;
3885 if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
3886 if (reply->send_valid == INFINITE_TIME) {
3887 reply->lease->soft_lifetime_end_time = MAX_TIME;
3889 reply->lease->soft_lifetime_end_time =
3890 cur_time + reply->send_valid;
3895 status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
3905 if (reply->lease->ia == NULL) {
3906 ia_reference(&reply->lease->ia, reply->ia, MDL);
3911 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3912 reply->packet->options, reply->reply_ia,
3916 for (i = reply->packet->class_count; i > 0; i--) {
3917 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3918 reply->packet->options,
3919 reply->reply_ia, scope,
3920 reply->packet->classes[i - 1]->group,
3928 if (reply->host != NULL)
3929 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
3930 reply->packet->options,
3931 reply->reply_ia, scope,
3932 reply->host->group, group, NULL);
3939 reply->client_resources++;
3946 reply, struct iaddr *addr) {
3963 putULong(data.buffer->data + 16, reply->send_prefer);
3964 putULong(data.buffer->data + 20, reply->send_valid);
3966 if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
3975 reply->resources_included = ISC_TRUE;
4068 * the reply packet being built in the reply_state structure.
4071 reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
4084 * Note that find_client_prefix() may set reply->lease.
4088 if ((reply->cursor + IA_PD_OFFSET + 4) > sizeof(reply->buf)) {
4089 log_error("reply_process_ia_pd: Reply too long for IA.");
4095 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
4104 reply->renew = getULong(ia_data.data + 4);
4105 reply->rebind = getULong(ia_data.data + 8);
4108 if (ia_allocate(&reply->ia, iaid, (char *)reply->client_id.data,
4109 reply->client_id.len, MDL) != ISC_R_SUCCESS) {
4114 reply->ia->ia_type = D6O_IA_PD;
4117 ia_hash_lookup(&reply->old_ia, ia_pd_active,
4118 (unsigned char *)reply->ia->iaid_duid.data,
4119 reply->ia->iaid_duid.len, MDL);
4125 if (!option_state_allocate(&reply->reply_ia, MDL)) {
4131 reply->static_prefixes = 0;
4132 if ((reply->host != NULL) && (reply->host->fixed_prefix != NULL)) {
4135 for (fp = reply->host->fixed_prefix; fp != NULL;
4137 reply->static_prefixes += 1;
4147 ia_cursor = reply->cursor;
4150 putUShort(reply->buf.data + reply->cursor, (unsigned)D6O_IA_PD);
4151 reply->cursor += 2;
4154 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
4155 reply->cursor += 2;
4158 putULong(reply->buf.data + reply->cursor, iaid);
4159 reply->cursor += 4;
4162 putULong(reply->buf.data + reply->cursor, reply->renew);
4163 reply->cursor += 4;
4166 putULong(reply->buf.data + reply->cursor, reply->rebind);
4167 reply->cursor += 4;
4173 reply->min_valid = reply->min_prefer = INFINITE_TIME;
4174 reply->client_valid = reply->client_prefer = 0;
4175 reply->preflen = -1;
4177 status = reply_process_prefix(reply, oc);
4182 * code. So transmit this reply, e.g., move on to the next
4194 reply->pd_count++;
4200 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
4201 status = find_client_prefix(reply);
4204 switch (reply->packet->dhcpv6_msg_type) {
4214 option_state_dereference(&reply->reply_ia, MDL);
4215 if (!option_state_allocate(&reply->reply_ia,
4228 reply->reply_ia)) {
4241 if (reply->resources_included)
4260 write_to_packet(reply, ia_cursor);
4268 if (reply->static_prefixes != 0) {
4272 dhcpv6_type_names[reply->buf.reply.msg_type],
4273 inet_ntop(AF_INET6, reply->fixed_pref.lo_addr.iabuf,
4275 reply->fixed_pref.bits,
4276 print_hex_1(reply->client_id.len,
4277 reply->client_id.data, 60),
4281 write_to_packet(reply, ia_cursor);
4283 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
4284 (reply->on_star.on_commit != NULL)) {
4285 execute_statements(NULL, reply->packet, NULL, NULL,
4286 reply->packet->options,
4287 reply->opt_state,
4288 NULL, reply->on_star.on_commit,
4291 (&reply->on_star.on_commit, MDL);
4299 if (reply->ia->num_iasubopt != 0) {
4304 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
4305 tmp = reply->ia->iasubopt[i];
4309 dhcpv6_type_names[reply->buf.reply.msg_type],
4313 print_hex_1(reply->client_id.len,
4314 reply->client_id.data, 60),
4331 if ((reply->buf.reply.msg_type == DHCPV6_REPLY) &&
4332 (reply->ia->num_iasubopt != 0)) {
4338 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
4339 tmp = reply->ia->iasubopt[i];
4343 ia_reference(&tmp->ia, reply->ia, MDL);
4347 execute_statements(NULL, reply->packet,
4349 reply->packet->options,
4350 reply->opt_state,
4358 if (!reuse_lease6(reply, tmp)) {
4365 check_pool6_threshold(reply, tmp);
4370 write_to_packet(reply, ia_cursor);
4373 if (reply->old_ia != NULL) {
4374 if (!release_on_roam(reply)) {
4375 ia_id = &reply->old_ia->iaid_duid;
4381 ia_dereference(&reply->old_ia, MDL);
4385 reply->ia->cltt = cur_time;
4386 ia_id = &reply->ia->iaid_duid;
4388 ia_id->len, reply->ia, MDL);
4393 write_ia(reply->ia);
4397 write_to_packet(reply, ia_cursor);
4398 schedule_lease_timeout_reply(reply);
4404 if (reply->reply_ia != NULL)
4405 option_state_dereference(&reply->reply_ia, MDL);
4410 if (reply->ia != NULL)
4411 ia_dereference(&reply->ia, MDL);
4412 if (reply->old_ia != NULL)
4413 ia_dereference(&reply->old_ia, MDL);
4414 if (reply->lease != NULL)
4415 iasubopt_dereference(&reply->lease, MDL);
4416 if (reply->on_star.on_expiry != NULL)
4418 (&reply->on_star.on_expiry, MDL);
4419 if (reply->on_star.on_release != NULL)
4421 (&reply->on_star.on_release, MDL);
4443 * \param reply - the reply structure we use to collect information
4451 find_group_by_prefix(struct reply_state *reply) {
4453 struct group *group = reply->shared->group;
4459 if (find_grouped_subnet(&subnet, reply->shared,
4460 reply->fixed_pref.lo_addr, MDL) != 0) {
4467 /* The caller has already tested reply->host != NULL */
4471 if ((reply->host->fixed_addr != NULL) &&
4474 reply->host->fixed_addr, MDL))) {
4478 if (find_grouped_subnet(&subnet, reply->shared,
4492 * Process an IAPREFIX within a given IA_PD, storing any IAPREFIX reply
4493 * contents into the reply's current ia_pd-scoped option cache. Returns
4498 reply_process_prefix(struct reply_state *reply, struct option_cache *pref) {
4510 /* Note that reply->lease may be set by prefix_is_owned() */
4516 if ((reply->cursor + 29) > sizeof(reply->buf)) {
4522 if (!evaluate_option_cache(&iapref, reply->packet, NULL, NULL,
4523 reply->packet->options, NULL, &global_scope,
4538 if ((reply->client_valid == 0) ||
4539 (reply->client_valid > valid_life))
4540 reply->client_valid = valid_life;
4542 if ((reply->client_prefer == 0) ||
4543 (reply->client_prefer > pref_life))
4544 reply->client_prefer = pref_life;
4563 if (reply->preflen < 0) {
4565 reply->preflen = tmp_pref.bits;
4574 if (!prefix_is_owned(reply, &tmp_pref)) {
4576 if ((reply->packet->dhcpv6_msg_type == DHCPV6_SOLICIT) ||
4577 (reply->packet->dhcpv6_msg_type == DHCPV6_REQUEST) ||
4578 (reply->packet->dhcpv6_msg_type == DHCPV6_REBIND)) {
4579 status = reply_process_try_prefix(reply, &tmp_pref);
4587 if (reply->lease == NULL) {
4588 if (reply->packet->dhcpv6_msg_type ==
4590 reply->send_prefer = 0;
4591 reply->send_valid = 0;
4605 * Reply message.
4610 } else if (reply->packet->dhcpv6_msg_type == DHCPV6_RENEW) {
4612 option_state_dereference(&reply->reply_ia, MDL);
4613 if (!option_state_allocate(&reply->reply_ia, MDL)) {
4623 "interface.", reply->reply_ia)) {
4642 if (reply->static_prefixes > 0) {
4643 if (reply->host == NULL)
4649 memcpy(&reply->fixed_pref, &tmp_pref, sizeof(tmp_pref));
4652 group = find_group_by_prefix(reply);
4654 if (reply->lease == NULL)
4657 scope = &reply->lease->scope;
4658 group = reply->lease->ipv6_pool->ipv6_pond->group;
4663 * function has executed configuration state into the reply option
4667 if (reply->client_resources != 0) {
4675 oc = lookup_option(&server_universe, reply->opt_state,
4678 if (!evaluate_option_cache(&data, reply->packet,
4680 reply->packet->options,
4681 reply->opt_state,
4696 * prefixes, then omit the prefix from the reply.
4698 if (reply->client_resources >= limit)
4702 status = reply_process_is_prefixed(reply, scope, group);
4707 status = reply_process_send_prefix(reply, &tmp_pref);
4714 if (reply->lease != NULL)
4715 iasubopt_dereference(&reply->lease, MDL);
4727 prefix_is_owned(struct reply_state *reply, struct iaddrcidrnet *pref) {
4735 if (reply->static_prefixes > 0) {
4736 for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
4745 if ((reply->old_ia == NULL) ||
4746 (reply->old_ia->num_iasubopt == 0))
4749 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4752 tmp = reply->old_ia->iasubopt[i];
4762 (permitted(reply->packet, pond->prohibit_list))) ||
4764 (!permitted(reply->packet, pond->permit_list))))
4767 iasubopt_reference(&reply->lease, tmp, MDL);
4780 reply_process_try_prefix(struct reply_state *reply,
4788 if ((reply == NULL) || (reply->shared == NULL) ||
4789 (pref == NULL) || (reply->lease != NULL))
4796 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
4831 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->next) {
4833 (permitted(reply->packet, pond->prohibit_list))) ||
4835 (!permitted(reply->packet, pond->permit_list))))
4843 status = try_client_v6_prefix(&reply->lease, pool,
4861 * Finally, actually add that prefix into the current reply IA_PD.
4864 find_client_prefix(struct reply_state *reply) {
4872 if (reply->static_prefixes > 0) {
4875 if (reply->host == NULL)
4878 for (l = reply->host->fixed_prefix; l != NULL; l = l->next) {
4879 if (l->cidrnet.bits == reply->preflen)
4887 l = reply->host->fixed_prefix;
4894 memcpy(&reply->fixed_pref, &l->cidrnet, sizeof(send_pref));
4897 group = find_group_by_prefix(reply);
4902 if (reply->old_ia != NULL) {
4903 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4907 prefix = reply->old_ia->iasubopt[i];
4917 (candidate_shared != reply->shared)) ||
4926 (permitted(reply->packet, pond->prohibit_list))) ||
4928 (!permitted(reply->packet, pond->permit_list))))
4931 best_prefix = prefix_compare(reply, prefix,
4941 if (best_prefix && (reply->preflen > 0)
4943 && (reply->preflen != best_prefix->plen)
4944 && (reply->packet->dhcpv6_msg_type != DHCPV6_REBIND)) {
4953 status = pick_v6_prefix(reply);
4955 iasubopt_reference(&reply->lease, best_prefix, MDL);
4965 /* iasubopt_reference(&reply->lease, best_prefix, MDL); */
4972 if (reply->lease == NULL)
4975 scope = &reply->lease->scope;
4976 group = reply->lease->ipv6_pool->ipv6_pond->group;
4979 memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
4980 send_pref.bits = (int) reply->lease->plen;
4983 status = reply_process_is_prefixed(reply, scope, group);
4987 status = reply_process_send_prefix(reply, &send_pref);
4996 reply_process_is_prefixed(struct reply_state *reply,
5012 * the reply if we don't have a lease because this is
5015 if (reply->lease) {
5016 on_star = &reply->lease->on_star;
5018 on_star = &reply->on_star;
5027 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
5028 reply->packet->options, tmp_options,
5040 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
5041 reply->packet->options, reply->opt_state,
5045 for (i = reply->packet->class_count; i > 0; i--) {
5046 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
5047 reply->packet->options,
5048 reply->opt_state, scope,
5049 reply->packet->classes[i - 1]->group,
5058 if (reply->host != NULL)
5059 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
5060 reply->packet->options,
5061 reply->opt_state, scope,
5062 reply->host->group, group,
5066 if (reply->client_valid == 0)
5067 reply->send_valid = DEFAULT_DEFAULT_LEASE_TIME;
5069 reply->send_valid = reply->client_valid;
5071 oc = lookup_option(&server_universe, reply->opt_state,
5074 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
5075 reply->packet->options,
5076 reply->opt_state,
5085 reply->send_valid = getULong(data.data);
5092 * (cur_time + reply->send_valid < cur_time)
5094 if (reply->send_valid != INFINITE_TIME) {
5095 time_t test_time = cur_time + reply->send_valid;
5097 reply->send_valid = INFINITE_TIME;
5100 if (reply->client_prefer == 0)
5101 reply->send_prefer = reply->send_valid;
5103 reply->send_prefer = reply->client_prefer;
5105 if ((reply->send_prefer >= reply->send_valid) &&
5106 (reply->send_valid != INFINITE_TIME))
5107 reply->send_prefer = (reply->send_valid / 2) +
5108 (reply->send_valid / 8);
5110 oc = lookup_option(&server_universe, reply->opt_state,
5113 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
5114 reply->packet->options,
5115 reply->opt_state,
5124 reply->send_prefer = getULong(data.data);
5129 if (reply->min_prefer > reply->send_prefer)
5130 reply->min_prefer = reply->send_prefer;
5132 if (reply->min_valid > reply->send_valid)
5133 reply->min_valid = reply->send_valid;
5136 if (reply->lease != NULL) {
5138 reply->lease->prefer = reply->send_prefer;
5139 reply->lease->valid = reply->send_valid;
5145 if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
5146 if (reply->send_valid == INFINITE_TIME) {
5147 reply->lease->soft_lifetime_end_time = MAX_TIME;
5149 reply->lease->soft_lifetime_end_time =
5150 cur_time + reply->send_valid;
5155 status = ia_add_iasubopt(reply->ia, reply->lease, MDL);
5165 if (reply->lease->ia == NULL) {
5166 ia_reference(&reply->lease->ia, reply->ia, MDL);
5171 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
5172 reply->packet->options, reply->reply_ia,
5176 for (i = reply->packet->class_count; i > 0; i--) {
5177 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
5178 reply->packet->options,
5179 reply->reply_ia, scope,
5180 reply->packet->classes[i - 1]->group,
5188 if (reply->host != NULL)
5189 execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
5190 reply->packet->options,
5191 reply->reply_ia, scope,
5192 reply->host->group, group, NULL);
5199 reply->client_resources++;
5206 reply_process_send_prefix(struct reply_state *reply,
5223 putULong(data.buffer->data, reply->send_prefer);
5224 putULong(data.buffer->data + 4, reply->send_valid);
5228 if (!append_option_buffer(&dhcpv6_universe, reply->reply_ia,
5237 reply->resources_included = ISC_TRUE;
5248 prefix_compare(struct reply_state *reply,
5255 if (reply->preflen >= 0) {
5256 if ((alpha->plen == reply->preflen) &&
5257 (beta->plen != reply->preflen))
5259 if ((beta->plen == reply->preflen) &&
5260 (alpha->plen != reply->preflen))
5343 * allocate the addresses and reply.
5497 * NOT send a reply to the client.
5511 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
5637 /* If the client supplied no addresses, do not reply. */
5642 * Set up reply.
5644 if (!start_reply(packet, &client_id, NULL, &opt_state, reply)) {
5674 * Return our reply to the caller.
5679 log_fatal("No memory to store reply.");
5682 memcpy(reply_ret->buffer->data, reply, reply_ofs);
5710 dhcpv6_renew(struct data_string *reply, struct packet *packet) {
5725 unicast_reject(reply, packet, &client_id, &server_id);
5730 lease_to_client(reply, packet, &client_id, &server_id);
5748 dhcpv6_rebind(struct data_string *reply, struct packet *packet) {
5755 lease_to_client(reply, packet, &client_id, NULL);
5816 "out of space for reply packet.");
5821 * Put our status code into the reply packet.
5830 * IA_NA into our reply packet. Defined in RFC 3315,
5877 struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data;
5903 * Set our reply information.
5905 reply->msg_type = DHCPV6_REPLY;
5906 memcpy(reply->transaction_id, packet->dhcpv6_transaction_id,
5907 sizeof(reply->transaction_id));
5910 * Build our option state for reply.
6092 * Return our reply to the caller.
6097 log_fatal("No memory to store reply.");
6100 memcpy(reply_ret->buffer->data, reply, reply_ofs);
6138 dhcpv6_decline(struct data_string *reply, struct packet *packet) {
6153 unicast_reject(reply, packet, &client_id, &server_id);
6163 iterate_over_ia_na(reply, packet, &client_id, &server_id,
6228 "out of space for reply packet.");
6233 * Put our status code into the reply packet.
6242 * IA_NA into our reply packet. Defined in RFC 3315,
6323 "out of space for reply packet.");
6328 * Put our status code into the reply packet.
6337 * IA_PD into our reply packet. Defined in RFC 3315,
6403 * Compute the available length for the reply.
6415 * Build our option state for reply.
6559 * Return our reply to the caller.
6564 log_fatal("No memory to store reply.");
6598 dhcpv6_release(struct data_string *reply, struct packet *packet) {
6613 unicast_reject(reply, packet, &client_id, &server_id);
6618 iterate_over_ia_na(reply, packet, &client_id, &server_id,
6625 iterate_over_ia_pd(reply, packet, &client_id, &server_id,
6640 dhcpv6_information_request(struct data_string *reply, struct packet *packet) {
6665 lease_to_client(reply, packet, &client_id,
6681 * We need to build an encapsulated reply.
6701 struct dhcpv6_relay_packet *reply;
6833 * our reply-forw is also discarded.
6843 reply = (struct dhcpv6_relay_packet *)reply_data;
6844 reply->msg_type = DHCPV6_RELAY_REPL;
6845 reply->hop_count = packet->dhcpv6_hop_count;
6846 memcpy(reply->link_address, &packet->dhcpv6_link_address,
6847 sizeof(reply->link_address));
6848 memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
6849 sizeof(reply->peer_address));
6853 * Get the reply option state.
6946 /* Already in the reply? */
6985 * Return our reply to the caller.
6990 log_fatal("No memory to store reply.");
7039 struct dhcpv6_relay_packet *reply;
7156 * our reply-forw is also discarded.
7166 reply = (struct dhcpv6_relay_packet *)reply_data;
7167 reply->msg_type = DHCPV6_RELAY_REPL;
7168 reply->hop_count = packet->dhcpv6_hop_count;
7169 memcpy(reply->link_address, &packet->dhcpv6_link_address,
7170 sizeof(reply->link_address));
7171 memcpy(reply->peer_address, &packet->dhcpv6_peer_address,
7172 sizeof(reply->peer_address));
7176 * Get the reply option state.
7268 /* Already in the reply? */
7307 * Return our reply to the caller.
7312 log_fatal("No memory to store reply.");
7503 log_fatal("dhcp4o6_dhcpv4_query: no memory to store reply.");
7589 build_dhcpv6_reply(struct data_string *reply, struct packet *packet) {
7590 memset(reply, 0, sizeof(*reply));
7603 dhcpv6_solicit(reply, packet);
7610 dhcpv6_request(reply, packet);
7614 dhcpv6_confirm(reply, packet);
7618 dhcpv6_renew(reply, packet);
7622 dhcpv6_rebind(reply, packet);
7629 dhcpv6_release(reply, packet);
7633 dhcpv6_decline(reply, packet);
7640 dhcpv6_information_request(reply, packet);
7645 dhcp4o6_relay_forw(reply, packet);
7648 dhcpv6_relay_forw(reply, packet);
7655 dhcpv6_leasequery(reply, packet);
7666 dhcp4o6_dhcpv4_query(reply, packet);
7746 struct data_string reply;
7756 * Build our reply packet.
7758 build_dhcpv6_reply(&reply, packet);
7760 if (reply.data != NULL) {
7762 * Send our reply, if we have one.
7797 dhcpv6_type_names[reply.data[0]],
7802 reply.data, reply.len, &to_addr);
7803 if (send_ret != reply.len) {
7805 send_ret, reply.len);
7807 data_string_forget(&reply, MDL);
7831 struct data_string reply;
7981 * Build our reply packet.
7983 build_dhcpv6_reply(&reply, packet);
7985 if (reply.data == NULL) {
7993 len = reply.len + 36;
8007 memcpy(ds.buffer->data + 36, reply.data, reply.len);
8089 * \brief Constructs a REPLY with status of UseMulticast to a given packet
8097 * reply
8109 struct reply_state reply;
8110 memset(&reply, 0x0, sizeof(struct reply_state));
8113 if (shared_network_from_packet6(&reply.shared, packet)
8119 /* Initialize the reply. */
8120 packet_reference(&reply.packet, packet, MDL);
8121 data_string_copy(&reply.client_id, client_id, MDL);
8123 if (start_reply(packet, client_id, server_id, &reply.opt_state,
8124 &reply.buf.reply)) {
8128 reply.opt_state)) {
8131 /* Set write cursor to just past the reply header. */
8132 reply.cursor = REPLY_OPTIONS_INDEX;
8133 reply.cursor += store_options6(((char *)reply.buf.data
8134 + reply.cursor),
8135 (sizeof(reply.buf)
8136 - reply.cursor),
8137 reply.opt_state,
8138 reply.packet,
8142 /* Return our reply to the caller. */
8143 reply_ret->len = reply.cursor;
8146 reply.cursor, MDL)) {
8148 "No memory to store Reply.");
8151 memcpy(reply_ret->buffer->data, reply.buf.data,
8152 reply.cursor);
8159 if (reply.shared != NULL)
8160 shared_network_dereference(&reply.shared, MDL);
8161 if (reply.opt_state != NULL)
8162 option_state_dereference(&reply.opt_state, MDL);
8163 if (reply.packet != NULL)
8164 packet_dereference(&reply.packet, MDL);
8165 if (reply.client_id.data != NULL)
8166 data_string_forget(&reply.client_id, MDL);
8397 * \brief Calculates the reply T1/T2 times and stuffs them in outbound buffer
8421 * \param reply - pointer to the reply_state structure
8423 * reply's outbound data buffer
8426 set_reply_tee_times(struct reply_state* reply, unsigned ia_cursor)
8432 oc = lookup_option(&server_universe, reply->opt_state,
8435 evaluate_boolean_option_cache(NULL, reply->packet,
8437 reply->packet->options,
8438 reply->opt_state,
8441 oc = lookup_option(&dhcp_universe, reply->opt_state,
8448 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
8449 reply->packet->options,
8450 reply->opt_state, &global_scope,
8454 reply->renew = 0;
8456 reply->renew = getULong(data.data);
8464 if (reply->min_prefer == INFINITE_TIME)
8465 reply->renew = INFINITE_TIME;
8467 reply->renew = reply->min_prefer / 2;
8470 reply->renew = 0;
8473 putULong(reply->buf.data + ia_cursor + 8, reply->renew);
8476 oc = lookup_option(&dhcp_universe, reply->opt_state,
8483 if (!evaluate_option_cache(&data, reply->packet, NULL, NULL,
8484 reply->packet->options,
8485 reply->opt_state, &global_scope,
8489 reply->rebind = 0;
8491 reply->rebind = getULong(data.data);
8498 * 0.8 * the shortest preferred lifetime in the reply */
8499 if (reply->min_prefer == INFINITE_TIME)
8500 reply->rebind = INFINITE_TIME;
8502 reply->rebind = (reply->min_prefer / 5) * 4;
8505 reply->rebind = 0;
8508 putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
8518 release_on_roam(struct reply_state* reply) {
8519 struct ia_xx* old_ia = reply->old_ia;
8533 if (lease->ipv6_pool->shared_network == reply->shared) {
8544 print_hex_1(reply->client_id.len,
8545 reply->client_id.data, 60),
8582 void ddns_update_static6(struct reply_state* reply) {
8587 oc = lookup_option(&server_universe, reply->opt_state, SV_DDNS_UPDATES);
8589 (evaluate_boolean_option_cache(NULL, reply->packet, NULL, NULL,
8590 reply->packet->options,
8591 reply->opt_state, NULL,
8596 oc = lookup_option(&server_universe, reply->opt_state,
8599 (evaluate_boolean_option_cache(NULL, reply->packet,
8601 reply->packet->options,
8602 reply->opt_state, NULL,
8611 if (ia_add_iasubopt(reply->ia, iasub, MDL) != ISC_R_SUCCESS) {
8615 ia_reference(&iasub->ia, reply->ia, MDL);
8617 memcpy(iasub->addr.s6_addr, reply->fixed.data, 16);
8629 ddns_updates(reply->packet, NULL, NULL, iasub, NULL, reply->opt_state);