25static void send_dhcpv4_response(
struct data_string *raw);
27static void recv_dhcpv4_query(
struct data_string *raw);
28static void dhcp4o6_dhcpv4_query(
struct data_string *reply_ret,
33 u_int8_t rsp_opt_exist;
37static int offset_data4o6 = 36;
63 struct shared_network *shared;
64 struct host_decl *host;
65 struct subnet *subnet;
66 struct option_state *opt_state;
67 struct packet *packet;
68 struct data_string client_id;
73 unsigned client_resources;
76 unsigned static_prefixes;
79 struct option_state *reply_ia;
80 struct data_string fixed;
81 struct iaddrcidrnet fixed_pref;
84 struct iasubopt *lease;
90 u_int32_t renew, rebind, min_prefer, min_valid;
93 u_int32_t client_valid, client_prefer;
96 u_int32_t send_valid, send_prefer;
105 struct on_star on_star;
108 unsigned char data[65536];
109 struct dhcpv6_packet reply;
116static int get_encapsulated_IA_state(
struct option_state **enc_opt_state,
122static isc_result_t shared_network_from_packet6(
struct shared_network **shared,
124static void seek_shared_host(
struct host_decl **hp,
128static isc_result_t reply_process_ia_na(
struct reply_state *reply,
130static isc_result_t reply_process_ia_ta(
struct reply_state *reply,
132static isc_result_t reply_process_addr(
struct reply_state *reply,
134static isc_boolean_t address_is_owned(
struct reply_state *reply,
136static isc_boolean_t temporary_is_available(
struct reply_state *reply,
138static isc_result_t find_client_temporaries(
struct reply_state *reply);
139static isc_result_t reply_process_try_addr(
struct reply_state *reply,
141static isc_result_t find_client_address(
struct reply_state *reply);
142static isc_result_t reply_process_is_addressed(
struct reply_state *reply,
145static isc_result_t reply_process_send_addr(
struct reply_state *reply,
149static isc_result_t reply_process_ia_pd(
struct reply_state *reply,
151static struct group *find_group_by_prefix(
struct reply_state *reply);
152static isc_result_t reply_process_prefix(
struct reply_state *reply,
154static isc_boolean_t prefix_is_owned(
struct reply_state *reply,
156static isc_result_t find_client_prefix(
struct reply_state *reply);
157static isc_result_t reply_process_try_prefix(
struct reply_state *reply,
159static isc_result_t reply_process_is_prefixed(
struct reply_state *reply,
162static isc_result_t reply_process_send_prefix(
struct reply_state *reply,
164static struct iasubopt *prefix_compare(
struct reply_state *reply,
167static void schedule_lease_timeout_reply(
struct reply_state *reply);
169static int eval_prefix_mode(
int thislen,
int preflen,
int prefix_mode);
170static isc_result_t pick_v6_prefix_helper(
struct reply_state *reply,
178static isc_result_t shared_network_from_requested_addr (
struct shared_network
181static isc_result_t get_first_ia_addr_val (
struct packet*
packet,
int addr_type,
185set_reply_tee_times(
struct reply_state* reply,
unsigned ia_cursor);
188static int release_on_roam(
struct reply_state *reply);
190static int reuse_lease6(
struct reply_state *reply,
struct iasubopt *
lease);
191static void shorten_lifetimes(
struct reply_state *reply,
struct iasubopt *
lease,
192 time_t age,
int threshold);
193static void write_to_packet(
struct reply_state *reply,
unsigned ia_cursor);
197static void ddns_update_static6(
struct reply_state* reply);
217 if (h->type != dhcp4o6_type)
220 cc = recv(dhcp4o6_fd, buf,
sizeof(buf), 0);
223 return ISC_R_UNEXPECTED;
224 memset(&raw, 0,
sizeof(raw));
226 log_error(
"dhcpv4o6_handler: no memory buffer.");
227 return ISC_R_NOMEMORY;
229 raw.data = raw.buffer->data;
231 memcpy(raw.buffer->data, buf, cc);
234 send_dhcpv4_response(&raw);
236 recv_dhcpv4_query(&raw);
252static void send_dhcpv4_response(
struct data_string *raw) {
255 struct sockaddr_in6 to_addr;
256 char pbuf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
257 struct udp_data4o6 udp_data;
260 memset(name, 0,
sizeof(name));
261 memcpy(name, raw->
data, 16);
263 if (!strcmp(name,
ip->name))
267 log_error(
"send_dhcpv4_response: can't find interface %s.",
272 memset(&to_addr, 0,
sizeof(to_addr));
273 to_addr.sin6_family = AF_INET6;
274 memcpy(&to_addr.sin6_addr, raw->
data + 16, 16);
275 memset(&udp_data, 0,
sizeof(udp_data));
276 memcpy(&udp_data, raw->
data + 32, 4);
279 if (udp_data.rsp_opt_exist) {
280 to_addr.sin6_port = udp_data.src_port;
288 log_info(
"send_dhcpv4_response(): sending %s on %s to %s port %d",
291 inet_ntop(AF_INET6, raw->
data + 16, pbuf,
sizeof(pbuf)),
292 ntohs(to_addr.sin6_port));
296 log_error(
"send_dhcpv4_response: send_packet6(): %m");
297 }
else if (send_ret != raw->
len - 36) {
298 log_error(
"send_dhcpv4_response: send_packet6() "
299 "sent %d of %d bytes",
300 send_ret, raw->
len - 36);
311schedule_lease_timeout_reply(
struct reply_state *reply) {
316 if ((reply == NULL) || (reply->ia == NULL) || (reply->ia->iasubopt == NULL))
320 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
321 tmp = reply->ia->iasubopt[i];
331duid_time(time_t when) {
368 return (server_duid.data != NULL);
406 isc_result_t ret_val;
419 ret_val = ISC_R_NOTFOUND;
421 memset(&option_duid, 0,
sizeof(option_duid));
425 ret_val = ISC_R_UNEXPECTED;
448static int server_duid_type =
DUID_LLT;
455 server_duid_type = type;
472 log_error(
"Invalid DUID type %d specified, "
473 "only LL and LLT types supported", server_duid_type);
486 log_error(
"Can not generate DUID from interfaces which do not have hardware addresses, please configure server-duid!");
490 return ISC_R_UNEXPECTED;
496 memset(&generated_duid, 0,
sizeof(generated_duid));
498 time_val = duid_time(time(NULL));
501 generated_duid.len,
MDL)) {
504 generated_duid.data = generated_duid.buffer->data;
506 putUShort(generated_duid.buffer->data + 2,
508 putULong(generated_duid.buffer->data + 4, time_val);
509 memcpy(generated_duid.buffer->data + 8,
511 }
else if (server_duid_type ==
DUID_LL) {
514 generated_duid.len,
MDL)) {
517 generated_duid.data = generated_duid.buffer->data;
519 putUShort(generated_duid.buffer->data + 2,
521 memcpy(generated_duid.buffer->data + 4,
524 log_fatal(
"Unsupported server DUID type %d.", server_duid_type);
543 if ((client_id->
data != NULL) || (client_id->
len != 0)) {
549 return ISC_R_NOTFOUND;
555 return ISC_R_FAILURE;
575 memset(client_id, 0,
sizeof(*client_id));
583 "client identifier missing",
588 log_error(
"Error processing %s from %s; "
589 "unable to evaluate Client Identifier",
599 log_debug(
"Discarding %s from %s; packet sent unicast "
614 "server identifier found "
615 "(CLIENTID %s, SERVERID %s)",
619 client_id->
data, 60),
624 "server identifier found "
628 client_id->
data, 60),
668 memset(client_id, 0,
sizeof(*client_id));
669 memset(server_id, 0,
sizeof(*server_id));
676 "client identifier missing",
681 log_error(
"Error processing %s from %s; "
682 "unable to evaluate Client Identifier",
691 "server identifier missing (CLIENTID %s)",
700 log_error(
"Error processing %s from %s; "
701 "unable to evaluate Server Identifier (CLIENTID %s)",
707 if ((server_duid.len != server_id->
len) ||
708 (memcmp(server_duid.data, server_id->
data, server_duid.len) != 0)) {
710 "not our server identifier "
711 "(CLIENTID %s, SERVERID %s, server DUID %s)",
716 print_hex_3(server_duid.len, server_duid.data, 60));
747 char client_id_str[80];
751 memset(server_id, 0,
sizeof(*server_id));
752 memset(&client_id, 0,
sizeof(client_id));
763 snprintf(client_id_str,
sizeof(client_id_str),
" (CLIENTID %s)",
767 client_id_str[0] =
'\0';
774 log_debug(
"Discarding %s from %s; packet sent unicast%s",
783 "IA_NA option present%s",
791 "IA_TA option present%s",
799 "IA_PD option present%s",
810 log_error(
"Error processing %s from %s; "
811 "unable to evaluate Server Identifier%s",
816 if ((server_duid.len != server_id->
len) ||
817 (memcmp(server_duid.data, server_id->
data,
818 server_duid.len) != 0)) {
820 "not our server identifier "
821 "(SERVERID %s, server DUID %s)%s",
825 server_id->
data, 60),
827 server_duid.data, 60),
847static const int required_opts[] = {
854static const int required_opts_solicit[] = {
866static const int required_opts_agent[] = {
868#if defined(RELAY_PORT)
874static const int required_opts_IA[] = {
879static const int required_opts_IA_PD[] = {
884static const int required_opts_STATUS_CODE[] = {
889static const int required_opts_4o6[] = {
895static const int unicast_reject_opts[] = {
910get_encapsulated_IA_state(
struct option_state **enc_opt_state,
919 memset(enc_opt_data, 0,
sizeof(*enc_opt_data));
924 "error evaluating raw option.");
927 if (enc_opt_data->
len < offset) {
928 log_error(
"get_encapsulated_IA_state: raw option too small.");
937 *enc_opt_state = NULL;
939 log_error(
"get_encapsulated_IA_state: no memory for options.");
944 enc_opt_data->
data + offset,
945 enc_opt_data->
len - offset,
947 log_error(
"get_encapsulated_IA_state: error parsing options.");
957set_status_code(u_int16_t status_code,
const char *status_message,
963 memset(&d, 0,
sizeof(d));
964 d.len =
sizeof(status_code) + strlen(status_message);
966 log_fatal(
"set_status_code: no memory for status code.");
968 d.data = d.buffer->data;
970 memcpy(d.buffer->data +
sizeof(status_code),
971 status_message, d.len -
sizeof(status_code));
973 d.buffer, (
unsigned char *)d.data, d.len,
975 log_error(
"set_status_code: error saving status code.");
984void check_pool6_threshold(
struct reply_state *reply,
988 isc_uint64_t used, count, high_threshold;
989 int poolhigh = 0, poollow = 0;
990 char *shared_name =
"no name";
991 char tmp_addr[INET6_ADDRSTRLEN];
993 if ((
lease->ipv6_pool == NULL) || (
lease->ipv6_pool->ipv6_pond == NULL))
995 pond =
lease->ipv6_pool->ipv6_pond;
1025 log_error(
"Pool threshold reset - shared subnet: %s; "
1026 "address: %s; low threshold %llu/%llu.",
1028 inet_ntop(AF_INET6, &
lease->addr,
1029 tmp_addr,
sizeof(tmp_addr)),
1030 (
long long unsigned)(used),
1031 (
long long unsigned)(count));
1038 NULL, reply->packet->options, reply->opt_state,
1046 if ((poolhigh <= 0) || (poolhigh > 100)) {
1053 if (used < high_threshold) {
1059 log_error(
"Pool threshold exceeded - shared subnet: %s; "
1060 "address: %s; high threshold %d%% %llu/%llu.",
1062 inet_ntop(AF_INET6, &
lease->addr, tmp_addr,
sizeof(tmp_addr)),
1063 poolhigh, (
long long unsigned)(used),
1064 (
long long unsigned)(count));
1069 NULL, reply->packet->options, reply->opt_state,
1081 if (poollow < poolhigh) {
1099 const unsigned char *server_id_data;
1107 log_error(
"start_reply: no memory for option_state.");
1175 if (server_id == NULL) {
1176 server_id_data = server_duid.data;
1177 server_id_len = server_duid.len;
1179 server_id_data = server_id->
data;
1180 server_id_len = server_id->
len;
1183 NULL, (
unsigned char *)server_id_data,
1186 "error saving server identifier.");
1191 if (client_id->
buffer != NULL) {
1194 (
unsigned char *)client_id->
data,
1198 "client identifier.");
1214 NULL, (
unsigned char *)
"", 0,
1217 "error saving RECONF_ACCEPT option.");
1235try_client_v6_address(
struct iasubopt **addr,
1239 struct in6_addr tmp_addr;
1240 isc_result_t result;
1242 if (requested_addr->
len <
sizeof(tmp_addr)) {
1245 memcpy(&tmp_addr, requested_addr->
data,
sizeof(tmp_addr));
1246 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
1247 return ISC_R_FAILURE;
1255 return ISC_R_ADDRNOTAVAIL;
1259 return ISC_R_ADDRINUSE;
1262 result = iasubopt_allocate(addr,
MDL);
1266 (*addr)->addr = tmp_addr;
1299pick_v6_address(
struct reply_state *reply)
1305 unsigned int attempts;
1306 char tmp_buf[INET6_ADDRSTRLEN];
1308 isc_uint64_t total = 0;
1309 isc_uint64_t active = 0;
1310 isc_uint64_t abandoned = 0;
1311 int jumbo_range = 0;
1312 char *shared_name = (reply->shared->name ?
1313 reply->shared->name :
"(no name)");
1319 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
1323 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
1333 log_debug(
"Unable to pick client address: "
1334 "no IPv6 pools on this shared network");
1335 return ISC_R_NORESOURCES;
1349 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
1350 isc_result_t result = ISC_R_FAILURE;
1361 if (pond->use_eui_64 &&
1362 !valid_eui_64_duid(&reply->ia->iaid_duid,
IAID_LEN)) {
1373 if (pond->use_eui_64) {
1375 create_lease6_eui_64(p,
addr,
1376 &reply->ia->iaid_duid,
1384 &reply->ia->iaid_duid,
1407 tmp_buf,
sizeof(tmp_buf)));
1416 }
while (i != start_pool);
1418 if (result == ISC_R_NORESOURCES) {
1430 if (jumbo_range != 0) {
1431 log_debug(
"Unable to pick client address: "
1432 "no addresses available - shared network %s: "
1433 " 2^64-1 < total, %llu active, %llu abandoned",
1434 shared_name, (
long long unsigned)(active - abandoned),
1435 (
long long unsigned)(abandoned));
1437 log_debug(
"Unable to pick client address: "
1438 "no addresses available - shared network %s: "
1439 "%llu total, %llu active, %llu abandoned",
1440 shared_name, (
long long unsigned)(total),
1441 (
long long unsigned)(active - abandoned),
1442 (
long long unsigned)(abandoned));
1445 return ISC_R_NORESOURCES;
1457try_client_v6_prefix(
struct iasubopt **pref,
1462 struct in6_addr tmp_pref;
1464 isc_result_t result;
1466 if (requested_pref->
len <
sizeof(tmp_plen) +
sizeof(tmp_pref)) {
1470 tmp_plen = (
int) requested_pref->
data[0];
1471 if ((tmp_plen < 3) || (tmp_plen > 128)) {
1472 return ISC_R_FAILURE;
1475 memcpy(&tmp_pref, requested_pref->
data + 1,
sizeof(tmp_pref));
1476 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) {
1477 return ISC_R_FAILURE;
1481 memcpy(&ia.iabuf, &tmp_pref, 16);
1483 return ISC_R_FAILURE;
1487 ((
int)tmp_plen !=
pool->units)) {
1488 return ISC_R_ADDRNOTAVAIL;
1492 return ISC_R_ADDRINUSE;
1495 result = iasubopt_allocate(pref,
MDL);
1500 (*pref)->addr = tmp_pref;
1501 (*pref)->plen = tmp_plen;
1552pick_v6_prefix(
struct reply_state *reply) {
1556 isc_result_t result;
1562 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
1566 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
1576 log_debug(
"Unable to pick client prefix: "
1577 "no IPv6 pools on this shared network");
1578 return ISC_R_NORESOURCES;
1581 if (reply->preflen <= 0) {
1584 result = pick_v6_prefix_helper(reply,
PLM_IGNORE);
1590 result = pick_v6_prefix_helper(reply,
PLM_EXACT);
1592 result = pick_v6_prefix_helper(reply,
1599 result = pick_v6_prefix_helper(reply,
PLM_EXACT);
1606 result = pick_v6_prefix_helper(reply,
PLM_EXACT);
1608 result = pick_v6_prefix_helper(reply,
1615 result = pick_v6_prefix_helper(reply,
PLM_IGNORE);
1621 char tmp_buf[INET6_ADDRSTRLEN];
1624 inet_ntop(AF_INET6, &(reply->lease->addr),
1625 tmp_buf,
sizeof(tmp_buf)),
1626 (
unsigned)(reply->lease->plen));
1634 log_debug(
"Unable to pick client prefix: no prefixes available");
1635 return ISC_R_NORESOURCES;
1662pick_v6_prefix_helper(
struct reply_state *reply,
int prefix_mode) {
1666 unsigned int attempts;
1667 struct iasubopt **pref = &reply->lease;
1669 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
1676 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
1678 (eval_prefix_mode(p->
units, reply->preflen,
1679 prefix_mode) == 1) &&
1681 &reply->ia->iaid_duid,
1688 return ISC_R_NORESOURCES;
1706eval_prefix_mode(
int len,
int preflen,
int prefix_mode) {
1708 switch (prefix_mode) {
1710 use_it = (len == preflen);
1714 use_it = (len >= preflen);
1718 use_it = (len <= preflen);
1769 static struct reply_state reply;
1774 memset(&packet_oro, 0,
sizeof(packet_oro));
1777 if (shared_network_from_packet6(&reply.shared,
1787 if (!start_reply(
packet, client_id, server_id, &reply.opt_state,
1803 log_error(
"lease_to_client: error evaluating ORO.");
1814 seek_shared_host(&reply.host, reply.shared);
1821 for (; oc != NULL ; oc = oc->
next) {
1822 isc_result_t status;
1825 reply.client_resources = 0;
1828 status = reply_process_ia_na(&reply, oc);
1835 (status != ISC_R_NORESOURCES))
1839 for (; oc != NULL ; oc = oc->
next) {
1840 isc_result_t status;
1843 reply.client_resources = 0;
1846 status = reply_process_ia_ta(&reply, oc);
1853 (status != ISC_R_NORESOURCES))
1860 for (; oc != NULL ; oc = oc->
next) {
1861 isc_result_t status;
1864 reply.client_resources = 0;
1867 status = reply_process_ia_pd(&reply, oc);
1874 (status != ISC_R_NORESOURCES))
1882 if ((reply.ia_count == 0) && (reply.pd_count == 0)) {
1883 if (reply.packet->dhcpv6_msg_type !=
1893 reply.packet->options,
1899 for (i = reply.packet->class_count; i > 0; i--) {
1902 reply.packet->options,
1905 reply.packet->classes[i - 1]->group,
1906 reply.shared->group, NULL);
1910 if (reply.host != NULL)
1913 reply.packet->options,
1917 reply.shared->group, NULL);
1952 reply.cursor +=
store_options6((
char *)reply.buf.data + reply.cursor,
1953 sizeof(reply.buf) - reply.cursor,
1954 reply.opt_state, reply.packet,
1955 required_opts_solicit,
1959 reply_ret->
len = reply.cursor;
1960 reply_ret->
buffer = NULL;
1964 memcpy(reply_ret->
buffer->
data, reply.buf.data, reply.cursor);
1972 if (reply.shared != NULL)
1973 shared_network_dereference(&reply.shared,
MDL);
1974 if (reply.host != NULL)
1975 host_dereference(&reply.host,
MDL);
1976 if (reply.opt_state != NULL)
1978 if (reply.packet != NULL)
1980 if (reply.client_id.data != NULL)
1982 if (packet_oro.buffer != NULL)
1984 reply.renew = reply.rebind = reply.min_prefer = reply.min_valid = 0;
1992reply_process_ia_na(
struct reply_state *reply,
struct option_cache *ia) {
2002 memset(&ia_data, 0,
sizeof(ia_data));
2009 if ((reply->cursor +
IA_NA_OFFSET + 4) >
sizeof(reply->buf)) {
2010 log_error(
"reply_process_ia_na: Reply too long for IA.");
2011 return ISC_R_NOSPACE;
2016 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
2018 log_error(
"reply_process_ia_na: error evaluating ia");
2019 status = ISC_R_FAILURE;
2025 reply->renew =
getULong(ia_data.data + 4);
2026 reply->rebind =
getULong(ia_data.data + 8);
2029 if (
ia_allocate(&reply->ia, iaid, (
char *)reply->client_id.data,
2031 log_error(
"reply_process_ia_na: no memory for ia.");
2032 status = ISC_R_NOMEMORY;
2039 (
unsigned char *)reply->ia->iaid_duid.data,
2040 reply->ia->iaid_duid.len,
MDL);
2047 status = ISC_R_NOMEMORY;
2052 if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
2053 struct iaddr tmp_addr;
2057 reply->host->fixed_addr,
MDL)) {
2058 log_error(
"reply_process_ia_na: unable to evaluate "
2060 status = ISC_R_FAILURE;
2064 if (reply->fixed.len < 16) {
2065 log_error(
"reply_process_ia_na: invalid fixed address.");
2072 memcpy(tmp_addr.iabuf, reply->fixed.data, 16);
2075 tmp_addr,
MDL) == 0)
2088 ia_cursor = reply->cursor;
2095 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
2099 putULong(reply->buf.data + reply->cursor, iaid);
2103 putULong(reply->buf.data + reply->cursor, reply->renew);
2107 putULong(reply->buf.data + reply->cursor, reply->rebind);
2121 reply->client_valid = reply->client_prefer = 0;
2122 for (; oc != NULL ; oc = oc->
next) {
2123 status = reply_process_addr(reply, oc);
2131 if (status == ISC_R_CANCELED)
2135 (status != ISC_R_ADDRINUSE) &&
2136 (status != ISC_R_ADDRNOTAVAIL))
2146 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
2147 status = find_client_address(reply);
2149 if (status == ISC_R_NORESOURCES) {
2150 switch (reply->packet->dhcpv6_msg_type) {
2173 "memory for option state "
2175 status = ISC_R_NOMEMORY;
2180 "No addresses available "
2181 "for this interface.",
2183 log_error(
"reply_process_ia_na: Unable "
2184 "to set NoAddrsAvail status "
2186 status = ISC_R_FAILURE;
2210 if (reply->resources_included)
2226 if (status == ISC_R_CANCELED) {
2229 write_to_packet(reply, ia_cursor);
2237 if (reply->static_lease) {
2238 char tmp_addr[INET6_ADDRSTRLEN];
2239 log_info(
"%s NA: address %s to client with duid %s iaid = %d "
2242 inet_ntop(AF_INET6, reply->fixed.data, tmp_addr,
2245 reply->client_id.data, 60),
2249 write_to_packet(reply, ia_cursor);
2252 ddns_update_static6(reply);
2255 (reply->on_star.on_commit != NULL)) {
2257 reply->packet->options,
2258 reply->opt_state, NULL,
2259 reply->on_star.on_commit, NULL);
2261 (&reply->on_star.on_commit,
MDL);
2269 if (reply->ia->num_iasubopt != 0) {
2272 char tmp_addr[INET6_ADDRSTRLEN];
2274 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2275 tmp = reply->ia->iasubopt[i];
2277 log_info(
"%s NA: address %s to client with duid %s "
2278 "iaid = %d valid for %u seconds",
2280 inet_ntop(AF_INET6, &tmp->
addr,
2281 tmp_addr,
sizeof(tmp_addr)),
2283 reply->client_id.data, 60),
2303 if ((reply->ia->num_iasubopt != 0) &&
2305 int must_commit = 0;
2310 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2311 tmp = reply->ia->iasubopt[i];
2312 if (tmp->
ia != NULL) {
2322 reply->packet->options,
2331#if defined (NSUPDATE)
2339 reply->packet->options,
2344 tmp, NULL, reply->opt_state);
2347 if (!reuse_lease6(reply, tmp)) {
2354 check_pool6_threshold(reply, tmp);
2359 write_to_packet(reply, ia_cursor);
2362 if (reply->old_ia != NULL) {
2363 if (!release_on_roam(reply)) {
2364 ia_id = &reply->old_ia->iaid_duid;
2366 (
unsigned char *)ia_id->
data,
2375 ia_id = &reply->ia->iaid_duid;
2377 ia_id->
len, reply->ia,
MDL);
2386 write_to_packet(reply, ia_cursor);
2387 schedule_lease_timeout_reply(reply);
2391 if (packet_ia != NULL)
2393 if (reply->reply_ia != NULL)
2395 if (ia_data.data != NULL)
2397 if (
data.data != NULL)
2399 if (reply->ia != NULL)
2401 if (reply->old_ia != NULL)
2403 if (reply->lease != NULL)
2405 if (reply->fixed.data != NULL)
2407 if (reply->subnet != NULL)
2408 subnet_dereference(&reply->subnet,
MDL);
2409 if (reply->on_star.on_expiry != NULL)
2411 (&reply->on_star.on_expiry,
MDL);
2412 if (reply->on_star.on_release != NULL)
2414 (&reply->on_star.on_release,
MDL);
2421 return((status == ISC_R_CANCELED) ?
ISC_R_SUCCESS : status);
2428write_to_packet(
struct reply_state *reply,
unsigned ia_cursor) {
2429 reply->cursor +=
store_options6((
char *)reply->buf.data + reply->cursor,
2430 sizeof(reply->buf) - reply->cursor,
2431 reply->reply_ia, reply->packet,
2433 required_opts_IA : required_opts_IA_PD),
2437 putUShort(reply->buf.data + ia_cursor + 2,
2438 reply->cursor - (ia_cursor + 4));
2442 set_reply_tee_times(reply, ia_cursor);
2453reply_process_addr(
struct reply_state *reply,
struct option_cache *addr) {
2454 u_int32_t pref_life, valid_life;
2458 struct iaddr tmp_addr;
2463 int invalid_for_eui_64 = 0;
2467 memset(&iaaddr, 0,
sizeof(iaaddr));
2475 if ((reply->cursor + 28) >
sizeof(reply->buf)) {
2476 log_error(
"reply_process_addr: Out of room for address.");
2477 return ISC_R_NOSPACE;
2485 log_error(
"reply_process_addr: error evaluating IAADDR.");
2486 status = ISC_R_FAILURE;
2491 pref_life =
getULong(iaaddr.data + 16);
2492 valid_life =
getULong(iaaddr.data + 20);
2494 if ((reply->client_valid == 0) ||
2495 (reply->client_valid > valid_life))
2496 reply->client_valid = valid_life;
2498 if ((reply->client_prefer == 0) ||
2499 (reply->client_prefer > pref_life))
2500 reply->client_prefer = pref_life;
2507 memset(tmp_addr.iabuf, 0, 16);
2508 if (!memcmp(iaaddr.data, tmp_addr.iabuf, 16)) {
2514 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2519 for (
subnet = reply->shared->subnets ;
subnet != NULL ;
2533 struct in6_addr* addr = (
struct in6_addr*)(iaaddr.data);
2535 && (
pool->ipv6_pond->use_eui_64) &&
2536 (!valid_for_eui_64_pool(
pool, &reply->client_id, 0, addr))) {
2538 " not valid for EUI-64 pool",
2540 invalid_for_eui_64 = 1;
2547 if ((
subnet == NULL) || invalid_for_eui_64) {
2575 log_error(
"reply_process_addr: No memory for "
2576 "option state wipe.");
2577 status = ISC_R_NOMEMORY;
2583 "Address not for use on this "
2584 "link.", reply->reply_ia)) {
2585 log_error(
"reply_process_addr: Failure "
2586 "setting status code.");
2587 status = ISC_R_FAILURE;
2592 status = ISC_R_CANCELED;
2604 if ((reply->packet->dhcpv6_msg_type !=
DHCPV6_RENEW) &&
2606 log_error(
"It is impossible to lease a client that is "
2607 "not sending a solicit, request, renew, or "
2609 status = ISC_R_FAILURE;
2613 reply->send_prefer = reply->send_valid = 0;
2619 if (!address_is_owned(reply, &tmp_addr)) {
2630 status = reply_process_try_addr(reply, &tmp_addr);
2638 (status != ISC_R_ADDRINUSE) &&
2639 (status != ISC_R_ADDRNOTAVAIL))
2647 if (reply->lease == NULL) {
2648 if (reply->packet->dhcpv6_msg_type ==
2650 reply->send_prefer = 0;
2651 reply->send_valid = 0;
2668 }
else if (reply->packet->dhcpv6_msg_type ==
DHCPV6_RENEW) {
2672 log_error(
"reply_process_addr: No memory for "
2673 "option state wipe.");
2674 status = ISC_R_NOMEMORY;
2680 "Address not bound to this "
2681 "interface.", reply->reply_ia)) {
2682 log_error(
"reply_process_addr: Unable to "
2683 "attach status code.");
2684 status = ISC_R_FAILURE;
2689 status = ISC_R_CANCELED;
2692 log_error(
"It is impossible to lease a client that is "
2693 "not sending a solicit, request, renew, or "
2695 status = ISC_R_FAILURE;
2700 if (reply->static_lease) {
2701 if (reply->host == NULL)
2705 group = reply->subnet->group;
2707 if (reply->lease == NULL)
2710 scope = &reply->lease->scope;
2711 group = reply->lease->ipv6_pool->ipv6_pond->group;
2720 if (reply->client_resources != 0) {
2733 reply->packet->options,
2737 log_error(
"reply_process_addr: unable to "
2738 "evaluate addrs-per-ia value.");
2739 status = ISC_R_FAILURE;
2751 if (reply->client_resources >= limit)
2755 status = reply_process_is_addressed(reply, scope,
group);
2760 status = reply_process_send_addr(reply, &tmp_addr);
2763 if (iaaddr.data != NULL)
2765 if (data.data != NULL)
2767 if (reply->lease != NULL)
2780address_is_owned(
struct reply_state *reply,
struct iaddr *addr) {
2787 if (reply->static_lease) {
2788 if (reply->fixed.data == NULL)
2791 if (memcmp(addr->
iabuf, reply->fixed.data, 16) == 0)
2797 if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0))
2800 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
2803 tmp = reply->old_ia->iasubopt[i];
2805 if (memcmp(
addr->iabuf, &tmp->
addr, 16) == 0) {
2830reply_process_ia_ta(
struct reply_state *reply,
struct option_cache *
ia) {
2838 u_int32_t pref_life, valid_life;
2839 struct iaddr tmp_addr;
2843 memset(&ia_data, 0,
sizeof(ia_data));
2844 memset(&data, 0,
sizeof(data));
2845 memset(&iaaddr, 0,
sizeof(iaaddr));
2848 if ((reply->cursor +
IA_TA_OFFSET + 4) >
sizeof(reply->buf)) {
2849 log_error(
"reply_process_ia_ta: Reply too long for IA.");
2850 return ISC_R_NOSPACE;
2855 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
2857 log_error(
"reply_process_ia_ta: error evaluating ia");
2858 status = ISC_R_FAILURE;
2866 if (
ia_allocate(&reply->ia, iaid, (
char *)reply->client_id.data,
2868 log_error(
"reply_process_ia_ta: no memory for ia.");
2869 status = ISC_R_NOMEMORY;
2876 (
unsigned char *)reply->ia->iaid_duid.data,
2877 reply->ia->iaid_duid.len,
MDL);
2884 status = ISC_R_NOMEMORY;
2899 ia_cursor = reply->cursor;
2906 putUShort(reply->buf.data + reply->cursor, 0x04u);
2910 putULong(reply->buf.data + reply->cursor, iaid);
2918 reply->client_valid = reply->client_prefer = 0;
2920 for (; oc != NULL; oc = oc->
next) {
2921 memset(&iaaddr, 0,
sizeof(iaaddr));
2924 reply->packet->options, NULL,
2928 "evaluating IAADDR.");
2929 status = ISC_R_FAILURE;
2933 pref_life =
getULong(iaaddr.data + 16);
2934 valid_life =
getULong(iaaddr.data + 20);
2936 if ((reply->client_valid == 0) ||
2937 (reply->client_valid > valid_life))
2938 reply->client_valid = valid_life;
2940 if ((reply->client_prefer == 0) ||
2941 (reply->client_prefer > pref_life))
2942 reply->client_prefer = pref_life;
2945 if (status == ISC_R_CANCELED)
2949 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2950 if (!temporary_is_available(reply, &tmp_addr))
2952 status = reply_process_is_addressed(reply,
2953 &reply->lease->scope,
2954 reply->lease->ipv6_pool->ipv6_pond->group);
2957 status = reply_process_send_addr(reply, &tmp_addr);
2960 if (reply->lease != NULL)
2968 status = ISC_R_NOMEMORY;
2971 status = ISC_R_CANCELED;
2972 reply->client_resources = 0;
2974 if (reply->lease != NULL)
2982 if (reply->client_resources != 0)
2984 status = find_client_temporaries(reply);
2985 if (status == ISC_R_NORESOURCES) {
2986 switch (reply->packet->dhcpv6_msg_type) {
3007 "memory for option state wipe.");
3008 status = ISC_R_NOMEMORY;
3013 "No addresses available "
3014 "for this interface.",
3016 log_error(
"reply_process_ia_ta: Unable "
3017 "to set NoAddrsAvail status code.");
3018 status = ISC_R_FAILURE;
3031 if (reply->resources_included)
3046 if (status == ISC_R_CANCELED) {
3049 write_to_packet(reply, ia_cursor);
3056 if (reply->ia->num_iasubopt != 0) {
3059 char tmp_addr[INET6_ADDRSTRLEN];
3061 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3062 tmp = reply->ia->iasubopt[i];
3064 log_info(
"%s TA: address %s to client with duid %s "
3065 "iaid = %d valid for %u seconds",
3067 inet_ntop(AF_INET6, &tmp->
addr,
3068 tmp_addr,
sizeof(tmp_addr)),
3070 reply->client_id.data, 60),
3084 if ((reply->ia->num_iasubopt != 0) &&
3086 int must_commit = 0;
3091 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
3092 tmp = reply->ia->iasubopt[i];
3094 if (tmp->
ia != NULL)
3102 reply->packet->options,
3111#if defined (NSUPDATE)
3120 reply->packet->options,
3125 tmp, NULL, reply->opt_state);
3129 if (!reuse_lease6(reply, tmp)) {
3136 check_pool6_threshold(reply, tmp);
3141 write_to_packet(reply, ia_cursor);
3144 if (reply->old_ia != NULL) {
3145 if (!release_on_roam(reply)) {
3146 ia_id = &reply->old_ia->iaid_duid;
3148 (
unsigned char *)ia_id->
data,
3157 ia_id = &reply->ia->iaid_duid;
3159 ia_id->
len, reply->ia,
MDL);
3168 write_to_packet(reply, ia_cursor);
3169 schedule_lease_timeout_reply(reply);
3173 if (packet_ia != NULL)
3175 if (iaaddr.data != NULL)
3177 if (reply->reply_ia != NULL)
3179 if (ia_data.data != NULL)
3181 if (
data.data != NULL)
3183 if (reply->ia != NULL)
3185 if (reply->old_ia != NULL)
3187 if (reply->lease != NULL)
3195 return((status == ISC_R_CANCELED) ?
ISC_R_SUCCESS : status);
3211reuse_lease6(
struct reply_state *reply,
struct iasubopt *
lease) {
3224 (
lease->hard_lifetime_end_time == 0) ||
3235 reply->packet->options, reply->opt_state,
3237 if (d1.len == 1 && (d1.data[0] < 100)) {
3238 threshold = d1.data[0];
3244 if (threshold <= 0) {
3252 log_debug (
"reusing infinite lease for: %s%s",
3258 if (
lease->valid <= (INT_MAX / threshold))
3259 limit =
lease->valid * threshold / 100;
3261 limit =
lease->valid / 100 * threshold;
3265 shorten_lifetimes(reply,
lease, age, threshold);
3286void shorten_lifetimes(
struct reply_state *reply,
struct iasubopt *
lease,
3287 time_t age,
int threshold) {
3312 for (; oc != NULL ; oc = oc->
next) {
3320 if (!memcmp(oc->
data.
data + addr_offset, &
lease->addr, 16) &&
3329 if (pref_life < MAX_TIME && pref_life > age) {
3332 pref_offset, pref_life);
3334 if (reply->min_prefer > pref_life) {
3335 reply->min_prefer = pref_life;
3339 if (valid_life < MAX_TIME && valid_life > age) {
3342 val_offset, valid_life);
3344 if (reply->min_valid > reply->send_valid) {
3345 reply->min_valid = valid_life;
3350 "age %ld secs < %d%%,"
3351 " sending shortened lifetimes -"
3352 " preferred: %u, valid %u",
3354 iasubopt_plen_str(
lease),
3355 (
long)age, threshold,
3356 pref_life, valid_life);
3366temporary_is_available(
struct reply_state *reply,
struct iaddr *addr) {
3367 struct in6_addr tmp_addr;
3373 memcpy(&tmp_addr, addr->
iabuf,
sizeof(tmp_addr));
3379 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr))
3385 for (
subnet = reply->shared->subnets ;
subnet != NULL ;
3399 if (address_is_owned(reply, addr))
3405 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3430 reply->lease->addr = tmp_addr;
3431 reply->lease->plen = 0;
3443find_client_temporaries(
struct reply_state *reply) {
3447 isc_result_t status = ISC_R_NORESOURCES;;
3448 unsigned int attempts;
3449 struct iaddr send_addr;
3455 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3459 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
3469 log_debug(
"Unable to get client addresses: "
3470 "no IPv6 pools on this shared network");
3471 return ISC_R_NORESOURCES;
3481 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3488 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
3501 log_debug(
"Unable to get a temporary address.");
3505 status = reply_process_is_addressed(reply,
3506 &reply->lease->scope,
3512 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3513 status = reply_process_send_addr(reply, &send_addr);
3526 if (reply->lease != NULL) {
3537reply_process_try_addr(
struct reply_state *reply,
struct iaddr *addr) {
3538 isc_result_t status = ISC_R_ADDRNOTAVAIL;
3544 if ((reply == NULL) || (reply->shared == NULL) ||
3545 (addr == NULL) || (reply->lease != NULL))
3552 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3556 for (i = 0; ; i++) {
3558 if ((
pool == NULL) ||
3568 return (ISC_R_ADDRNOTAVAIL);
3571 memset(&data_addr, 0,
sizeof(data_addr));
3572 data_addr.len = addr->
len;
3573 data_addr.data = addr->
iabuf;
3586 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3597 status = try_client_v6_address(&reply->lease,
pool,
3618find_client_address(
struct reply_state *reply) {
3619 struct iaddr send_addr;
3620 isc_result_t status = ISC_R_NORESOURCES;
3626 if (reply->static_lease) {
3627 if (reply->host == NULL)
3631 memcpy(send_addr.iabuf, reply->fixed.data, 16);
3634 group = reply->subnet->group;
3638 if (reply->old_ia != NULL) {
3639 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
3643 lease = reply->old_ia->iasubopt[i];
3644 candidate_shared =
lease->ipv6_pool->shared_network;
3645 pond =
lease->ipv6_pool->ipv6_pond;
3652 if ((candidate_shared != reply->shared) ||
3662 best_lease = lease_compare(
lease, best_lease);
3670 status = pick_v6_address(reply);
3671 }
else if (best_lease != NULL) {
3677 if ((status == ISC_R_NORESOURCES) && (best_lease != NULL)) {
3679 log_error(
"Best match for DUID %s is an abandoned address,"
3680 " This may be a result of multiple clients attempting"
3681 " to use this DUID",
3683 reply->client_id.data, 60));
3691 if (reply->lease == NULL)
3698 scope = &reply->lease->scope;
3699 group = reply->lease->ipv6_pool->ipv6_pond->group;
3702 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3705 status = reply_process_is_addressed(reply, scope,
group);
3709 status = reply_process_send_addr(reply, &send_addr);
3718reply_process_is_addressed(
struct reply_state *reply,
3729 memset(&data, 0,
sizeof(data));
3738 on_star = &reply->lease->on_star;
3750 reply->packet->options, tmp_options,
3753 if (tmp_options != NULL) {
3763 reply->packet->options, reply->opt_state,
3767 for (i = reply->packet->class_count; i > 0; i--) {
3769 reply->packet->options,
3770 reply->opt_state, scope,
3771 reply->packet->classes[i - 1]->group,
3780 if (reply->host != NULL)
3782 reply->packet->options,
3783 reply->opt_state, scope,
3784 reply->host->group,
group,
3788 if (reply->client_valid == 0)
3791 reply->send_valid = reply->client_valid;
3797 reply->packet->options,
3801 log_error(
"reply_process_is_addressed: unable to "
3802 "evaluate default lease time");
3803 status = ISC_R_FAILURE;
3807 reply->send_valid =
getULong(data.data);
3817 time_t test_time =
cur_time + reply->send_valid;
3822 if (reply->client_prefer == 0)
3823 reply->send_prefer = reply->send_valid;
3825 reply->send_prefer = reply->client_prefer;
3827 if ((reply->send_prefer >= reply->send_valid) &&
3829 reply->send_prefer = (reply->send_valid / 2) +
3830 (reply->send_valid / 8);
3836 reply->packet->options,
3840 log_error(
"reply_process_is_addressed: unable to "
3841 "evaluate preferred lease time");
3842 status = ISC_R_FAILURE;
3846 reply->send_prefer =
getULong(data.data);
3851 if (reply->min_prefer > reply->send_prefer)
3852 reply->min_prefer = reply->send_prefer;
3854 if (reply->min_valid > reply->send_valid)
3855 reply->min_valid = reply->send_valid;
3867 if (reply->host != NULL)
3869 reply->client_id->len);
3873 if (reply->lease != NULL) {
3875 reply->lease->prefer = reply->send_prefer;
3876 reply->lease->valid = reply->send_valid;
3884 reply->lease->soft_lifetime_end_time =
MAX_TIME;
3886 reply->lease->soft_lifetime_end_time =
3894 log_fatal(
"reply_process_is_addressed: Unable to "
3895 "attach lease to new IA: %s",
3896 isc_result_totext(status));
3902 if (reply->lease->ia == NULL) {
3909 reply->packet->options, reply->reply_ia,
3913 for (i = reply->packet->class_count; i > 0; i--) {
3915 reply->packet->options,
3916 reply->reply_ia, scope,
3917 reply->packet->classes[i - 1]->group,
3925 if (reply->host != NULL)
3927 reply->packet->options,
3928 reply->reply_ia, scope,
3929 reply->host->group,
group, NULL);
3932 if (data.data != NULL)
3936 reply->client_resources++;
3943reply_process_send_addr(
struct reply_state *reply,
struct iaddr *addr) {
3952 log_error(
"reply_process_send_addr: out of memory"
3953 "allocating new IAADDR buffer.");
3954 status = ISC_R_NOMEMORY;
3959 memcpy(
data.buffer->data, addr->
iabuf, 16);
3966 log_error(
"reply_process_send_addr: unable "
3967 "to save IAADDR option");
3968 status = ISC_R_FAILURE;
3972 reply->resources_included =
ISC_TRUE;
3975 if (
data.data != NULL)
3989 switch(alpha->
state) {
3991 switch(beta->
state) {
4012 switch (beta->
state) {
4038 switch (beta->
state) {
4060 log_fatal(
"Triple impossible condition at %s:%d.",
MDL);
4068reply_process_ia_pd(
struct reply_state *reply,
struct option_cache *
ia) {
4078 memset(&ia_data, 0,
sizeof(ia_data));
4085 if ((reply->cursor +
IA_PD_OFFSET + 4) >
sizeof(reply->buf)) {
4086 log_error(
"reply_process_ia_pd: Reply too long for IA.");
4087 return ISC_R_NOSPACE;
4092 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
4094 log_error(
"reply_process_ia_pd: error evaluating ia");
4095 status = ISC_R_FAILURE;
4101 reply->renew =
getULong(ia_data.data + 4);
4102 reply->rebind =
getULong(ia_data.data + 8);
4105 if (
ia_allocate(&reply->ia, iaid, (
char *)reply->client_id.data,
4107 log_error(
"reply_process_ia_pd: no memory for ia.");
4108 status = ISC_R_NOMEMORY;
4115 (
unsigned char *)reply->ia->iaid_duid.data,
4116 reply->ia->iaid_duid.len,
MDL);
4123 status = ISC_R_NOMEMORY;
4128 reply->static_prefixes = 0;
4129 if ((reply->host != NULL) && (reply->host->fixed_prefix != NULL)) {
4132 for (fp = reply->host->fixed_prefix; fp != NULL;
4134 reply->static_prefixes += 1;
4144 ia_cursor = reply->cursor;
4151 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
4155 putULong(reply->buf.data + reply->cursor, iaid);
4159 putULong(reply->buf.data + reply->cursor, reply->renew);
4163 putULong(reply->buf.data + reply->cursor, reply->rebind);
4171 reply->client_valid = reply->client_prefer = 0;
4172 reply->preflen = -1;
4173 for (; oc != NULL ; oc = oc->
next) {
4174 status = reply_process_prefix(reply, oc);
4182 if (status == ISC_R_CANCELED)
4186 (status != ISC_R_ADDRINUSE) &&
4187 (status != ISC_R_ADDRNOTAVAIL))
4197 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
4198 status = find_client_prefix(reply);
4200 if (status == ISC_R_NORESOURCES) {
4201 switch (reply->packet->dhcpv6_msg_type) {
4216 "memory for option state "
4218 status = ISC_R_NOMEMORY;
4223 "No prefixes available "
4224 "for this interface.",
4228 "NoPrefixAvail status "
4230 status = ISC_R_FAILURE;
4238 if (reply->resources_included)
4254 if (status == ISC_R_CANCELED) {
4257 write_to_packet(reply, ia_cursor);
4265 if (reply->static_prefixes != 0) {
4266 char tmp_addr[INET6_ADDRSTRLEN];
4267 log_info(
"%s PD: address %s/%d to client with duid %s "
4270 inet_ntop(AF_INET6, reply->fixed_pref.lo_addr.iabuf,
4271 tmp_addr,
sizeof(tmp_addr)),
4272 reply->fixed_pref.bits,
4274 reply->client_id.data, 60),
4278 write_to_packet(reply, ia_cursor);
4281 (reply->on_star.on_commit != NULL)) {
4283 reply->packet->options,
4285 NULL, reply->on_star.on_commit,
4288 (&reply->on_star.on_commit,
MDL);
4296 if (reply->ia->num_iasubopt != 0) {
4299 char tmp_addr[INET6_ADDRSTRLEN];
4301 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
4302 tmp = reply->ia->iasubopt[i];
4304 log_info(
"%s PD: address %s/%d to client with duid %s"
4305 " iaid = %d valid for %u seconds",
4307 inet_ntop(AF_INET6, &tmp->
addr,
4308 tmp_addr,
sizeof(tmp_addr)),
4311 reply->client_id.data, 60),
4329 (reply->ia->num_iasubopt != 0)) {
4330 int must_commit = 0;
4335 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
4336 tmp = reply->ia->iasubopt[i];
4338 if (tmp->
ia != NULL)
4346 reply->packet->options,
4355 if (!reuse_lease6(reply, tmp)) {
4362 check_pool6_threshold(reply, tmp);
4367 write_to_packet(reply, ia_cursor);
4370 if (reply->old_ia != NULL) {
4371 if (!release_on_roam(reply)) {
4372 ia_id = &reply->old_ia->iaid_duid;
4374 (
unsigned char *)ia_id->
data,
4383 ia_id = &reply->ia->iaid_duid;
4385 ia_id->
len, reply->ia,
MDL);
4394 write_to_packet(reply, ia_cursor);
4395 schedule_lease_timeout_reply(reply);
4399 if (packet_ia != NULL)
4401 if (reply->reply_ia != NULL)
4403 if (ia_data.data != NULL)
4405 if (
data.data != NULL)
4407 if (reply->ia != NULL)
4409 if (reply->old_ia != NULL)
4411 if (reply->lease != NULL)
4413 if (reply->on_star.on_expiry != NULL)
4415 (&reply->on_star.on_expiry,
MDL);
4416 if (reply->on_star.on_release != NULL)
4418 (&reply->on_star.on_release,
MDL);
4425 return((status == ISC_R_CANCELED) ?
ISC_R_SUCCESS : status);
4447static struct group *
4448find_group_by_prefix(
struct reply_state *reply) {
4452 struct iaddr tmp_addr;
4457 reply->fixed_pref.lo_addr,
MDL) != 0) {
4466 memset(&fixed_addr, 0,
sizeof(fixed_addr));
4468 if ((reply->host->fixed_addr != NULL) &&
4471 reply->host->fixed_addr,
MDL))) {
4472 if (fixed_addr.len >= 16) {
4474 memcpy(tmp_addr.iabuf, fixed_addr.data, 16);
4476 tmp_addr,
MDL) != 0) {
4495reply_process_prefix(
struct reply_state *reply,
struct option_cache *pref) {
4496 u_int32_t pref_life, valid_life;
4505 memset(&iapref, 0,
sizeof(iapref));
4506 memset(&data, 0,
sizeof(data));
4513 if ((reply->cursor + 29) >
sizeof(reply->buf)) {
4514 log_error(
"reply_process_prefix: Out of room for prefix.");
4515 return ISC_R_NOSPACE;
4523 log_error(
"reply_process_prefix: error evaluating IAPREFIX.");
4524 status = ISC_R_FAILURE;
4533 valid_life =
getULong(iapref.data + 4);
4535 if ((reply->client_valid == 0) ||
4536 (reply->client_valid > valid_life))
4537 reply->client_valid = valid_life;
4539 if ((reply->client_prefer == 0) ||
4540 (reply->client_prefer > pref_life))
4541 reply->client_prefer = pref_life;
4547 tmp_pref.lo_addr.len = 16;
4548 memset(tmp_pref.lo_addr.iabuf, 0, 16);
4549 if ((iapref.data[8] == 0) &&
4550 (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0)) {
4559 tmp_pref.bits = (
int) iapref.data[8];
4560 if (reply->preflen < 0) {
4562 reply->preflen = tmp_pref.bits;
4564 if (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0) {
4568 memcpy(tmp_pref.lo_addr.iabuf, iapref.data + 9, 16);
4571 if (!prefix_is_owned(reply, &tmp_pref)) {
4576 status = reply_process_try_prefix(reply, &tmp_pref);
4580 (status != ISC_R_ADDRINUSE) &&
4581 (status != ISC_R_ADDRNOTAVAIL))
4584 if (reply->lease == NULL) {
4585 if (reply->packet->dhcpv6_msg_type ==
4587 reply->send_prefer = 0;
4588 reply->send_valid = 0;
4607 }
else if (reply->packet->dhcpv6_msg_type ==
DHCPV6_RENEW) {
4611 log_error(
"reply_process_prefix: No memory "
4612 "for option state wipe.");
4613 status = ISC_R_NOMEMORY;
4619 "Prefix not bound to this "
4620 "interface.", reply->reply_ia)) {
4621 log_error(
"reply_process_prefix: Unable to "
4622 "attach status code.");
4623 status = ISC_R_FAILURE;
4628 status = ISC_R_CANCELED;
4631 log_error(
"It is impossible to lease a client that is "
4632 "not sending a solicit, request, renew, or "
4634 status = ISC_R_FAILURE;
4639 if (reply->static_prefixes > 0) {
4640 if (reply->host == NULL)
4646 memcpy(&reply->fixed_pref, &tmp_pref,
sizeof(tmp_pref));
4649 group = find_group_by_prefix(reply);
4651 if (reply->lease == NULL)
4654 scope = &reply->lease->scope;
4655 group = reply->lease->ipv6_pool->ipv6_pond->group;
4664 if (reply->client_resources != 0) {
4677 reply->packet->options,
4681 log_error(
"reply_process_prefix: unable to "
4682 "evaluate prefs-per-ia value.");
4683 status = ISC_R_FAILURE;
4695 if (reply->client_resources >= limit)
4699 status = reply_process_is_prefixed(reply, scope,
group);
4704 status = reply_process_send_prefix(reply, &tmp_pref);
4707 if (iapref.data != NULL)
4709 if (data.data != NULL)
4711 if (reply->lease != NULL)
4724prefix_is_owned(
struct reply_state *reply,
struct iaddrcidrnet *pref) {
4732 if (reply->static_prefixes > 0) {
4733 for (l = reply->host->fixed_prefix; l != NULL; l = l->
next) {
4742 if ((reply->old_ia == NULL) ||
4743 (reply->old_ia->num_iasubopt == 0))
4746 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4749 tmp = reply->old_ia->iasubopt[i];
4751 if ((pref->
bits == (
int) tmp->
plen) &&
4777reply_process_try_prefix(
struct reply_state *reply,
4779 isc_result_t status = ISC_R_ADDRNOTAVAIL;
4785 if ((reply == NULL) || (reply->shared == NULL) ||
4786 (pref == NULL) || (reply->lease != NULL))
4793 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
4807 return (ISC_R_ADDRNOTAVAIL);
4810 memset(&data_pref, 0,
sizeof(data_pref));
4813 log_error(
"reply_process_try_prefix: out of memory.");
4814 return (ISC_R_NOMEMORY);
4816 data_pref.data = data_pref.buffer->data;
4817 data_pref.buffer->data[0] = (u_int8_t) pref->
bits;
4818 memcpy(data_pref.buffer->data + 1, pref->
lo_addr.
iabuf, 16);
4828 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
4840 status = try_client_v6_prefix(&reply->lease,
pool,
4844 if ( (status ==
ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
4847 if ( (status ==
ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
4861find_client_prefix(
struct reply_state *reply) {
4863 isc_result_t status = ISC_R_NORESOURCES;
4864 struct iasubopt *prefix, *best_prefix = NULL;
4869 if (reply->static_prefixes > 0) {
4872 if (reply->host == NULL)
4875 for (l = reply->host->fixed_prefix; l != NULL; l = l->
next) {
4884 l = reply->host->fixed_prefix;
4886 memcpy(&send_pref, &l->
cidrnet,
sizeof(send_pref));
4891 memcpy(&reply->fixed_pref, &l->
cidrnet,
sizeof(send_pref));
4894 group = find_group_by_prefix(reply);
4899 if (reply->old_ia != NULL) {
4900 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4904 prefix = reply->old_ia->iasubopt[i];
4913 if (((candidate_shared != NULL) &&
4914 (candidate_shared != reply->shared)) ||
4928 best_prefix = prefix_compare(reply, prefix,
4938 if (best_prefix && (reply->preflen > 0)
4940 && (reply->preflen != best_prefix->
plen)
4950 status = pick_v6_prefix(reply);
4951 }
else if (best_prefix != NULL) {
4957 if ((status == ISC_R_NORESOURCES) && (best_prefix != NULL)) {
4959 log_error(
"Reclaiming abandoned prefixes is not yet "
4960 "supported. Treating this as an out of space "
4969 if (reply->lease == NULL)
4972 scope = &reply->lease->scope;
4973 group = reply->lease->ipv6_pool->ipv6_pond->group;
4975 send_pref.lo_addr.len = 16;
4976 memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
4977 send_pref.bits = (
int) reply->lease->plen;
4980 status = reply_process_is_prefixed(reply, scope,
group);
4984 status = reply_process_send_prefix(reply, &send_pref);
4993reply_process_is_prefixed(
struct reply_state *reply,
5004 memset(&data, 0,
sizeof(data));
5013 on_star = &reply->lease->on_star;
5025 reply->packet->options, tmp_options,
5028 if (tmp_options != NULL) {
5038 reply->packet->options, reply->opt_state,
5042 for (i = reply->packet->class_count; i > 0; i--) {
5044 reply->packet->options,
5045 reply->opt_state, scope,
5046 reply->packet->classes[i - 1]->group,
5055 if (reply->host != NULL)
5057 reply->packet->options,
5058 reply->opt_state, scope,
5059 reply->host->group,
group,
5063 if (reply->client_valid == 0)
5066 reply->send_valid = reply->client_valid;
5072 reply->packet->options,
5076 log_error(
"reply_process_is_prefixed: unable to "
5077 "evaluate default prefix time");
5078 status = ISC_R_FAILURE;
5082 reply->send_valid =
getULong(data.data);
5092 time_t test_time =
cur_time + reply->send_valid;
5097 if (reply->client_prefer == 0)
5098 reply->send_prefer = reply->send_valid;
5100 reply->send_prefer = reply->client_prefer;
5102 if ((reply->send_prefer >= reply->send_valid) &&
5104 reply->send_prefer = (reply->send_valid / 2) +
5105 (reply->send_valid / 8);
5111 reply->packet->options,
5115 log_error(
"reply_process_is_prefixed: unable to "
5116 "evaluate preferred prefix time");
5117 status = ISC_R_FAILURE;
5121 reply->send_prefer =
getULong(data.data);
5126 if (reply->min_prefer > reply->send_prefer)
5127 reply->min_prefer = reply->send_prefer;
5129 if (reply->min_valid > reply->send_valid)
5130 reply->min_valid = reply->send_valid;
5133 if (reply->lease != NULL) {
5135 reply->lease->prefer = reply->send_prefer;
5136 reply->lease->valid = reply->send_valid;
5144 reply->lease->soft_lifetime_end_time =
MAX_TIME;
5146 reply->lease->soft_lifetime_end_time =
5154 log_fatal(
"reply_process_is_prefixed: Unable to "
5155 "attach prefix to new IA_PD: %s",
5156 isc_result_totext(status));
5162 if (reply->lease->ia == NULL) {
5169 reply->packet->options, reply->reply_ia,
5173 for (i = reply->packet->class_count; i > 0; i--) {
5175 reply->packet->options,
5176 reply->reply_ia, scope,
5177 reply->packet->classes[i - 1]->group,
5185 if (reply->host != NULL)
5187 reply->packet->options,
5188 reply->reply_ia, scope,
5189 reply->host->group,
group, NULL);
5192 if (data.data != NULL)
5196 reply->client_resources++;
5203reply_process_send_prefix(
struct reply_state *reply,
5213 log_error(
"reply_process_send_prefix: out of memory"
5214 "allocating new IAPREFIX buffer.");
5215 status = ISC_R_NOMEMORY;
5228 log_error(
"reply_process_send_prefix: unable "
5229 "to save IAPREFIX option");
5230 status = ISC_R_FAILURE;
5234 reply->resources_included =
ISC_TRUE;
5237 if (
data.data != NULL)
5245prefix_compare(
struct reply_state *reply,
5252 if (reply->preflen >= 0) {
5253 if ((alpha->
plen == reply->preflen) &&
5254 (beta->
plen != reply->preflen))
5256 if ((beta->
plen == reply->preflen) &&
5257 (alpha->
plen != reply->preflen))
5261 switch(alpha->
state) {
5263 switch(beta->
state) {
5284 switch (beta->
state) {
5310 switch (beta->
state) {
5332 log_fatal(
"Triple impossible condition at %s:%d.",
MDL);
5352 if (!valid_client_msg(
packet, &client_id)) {
5356 lease_to_client(reply_ret,
packet, &client_id, NULL);
5378 if (!valid_client_resp(
packet, &client_id, &server_id)) {
5386 unicast_reject(reply_ret,
packet, &client_id, &server_id);
5391 lease_to_client(reply_ret,
packet, &client_id, &server_id);
5407 const struct packet *chk_packet;
5408 const struct in6_addr *link_addr, *first_link_addr;
5409 struct iaddr tmp_addr;
5411 isc_result_t status;
5413 if ((shared == NULL) || (*shared != NULL) || (
packet == NULL))
5420 first_link_addr = NULL;
5422 while (chk_packet != NULL) {
5424 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
5425 !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
5426 first_link_addr = link_addr;
5437 if (first_link_addr != NULL) {
5438 tmp_addr.len =
sizeof(*first_link_addr);
5439 memcpy(tmp_addr.iabuf,
5440 first_link_addr,
sizeof(*first_link_addr));
5443 log_debug(
"No subnet found for link-address %s.",
5445 return ISC_R_NOTFOUND;
5447 status = shared_network_reference(shared,
5456 status = shared_network_reference(shared,
5460 log_info(
"[L2 Relay] No link address in relay packet "
5461 "assuming L2 relay and using receiving "
5471 log_error(
"No interface and no link address "
5472 "can't determine pool");
5502 struct data_string cli_enc_opt_data, iaaddr, client_id, packet_oro;
5504 struct iaddr cli_addr;
5507 char reply_data[65536];
5514 memset(&client_id, 0,
sizeof(client_id));
5515 if (!valid_client_msg(
packet, &client_id)) {
5524 if ((ia == NULL) && (ta == NULL))
5535 opt_state = cli_enc_opt_state = NULL;
5536 memset(&cli_enc_opt_data, 0,
sizeof(cli_enc_opt_data));
5537 memset(&iaaddr, 0,
sizeof(iaaddr));
5538 memset(&packet_oro, 0,
sizeof(packet_oro));
5559 while(!inappropriate) {
5573 !get_encapsulated_IA_state(&cli_enc_opt_state,
5577 !get_encapsulated_IA_state(&cli_enc_opt_state,
5586 for ( ; oc != NULL ; oc = oc->
next) {
5592 "error evaluating IAADDR.");
5598 memcpy(cli_addr.iabuf, iaaddr.data, 16);
5641 if (!start_reply(
packet, &client_id, NULL, &opt_state, reply)) {
5648 if (inappropriate) {
5650 "Some of the addresses are not on link.",
5656 "All addresses still on link.",
5666 sizeof(reply_data)-reply_ofs,
5668 required_opts, &packet_oro);
5673 reply_ret->
len = reply_ofs;
5674 reply_ret->
buffer = NULL;
5679 memcpy(reply_ret->
buffer->
data, reply, reply_ofs);
5683 if (cli_enc_opt_data.buffer != NULL)
5685 if (iaaddr.buffer != NULL)
5687 if (client_id.
buffer != NULL)
5689 if (packet_oro.buffer != NULL)
5693 if (cli_enc_opt_state != NULL)
5695 if (opt_state != NULL)
5714 if (!valid_client_resp(
packet, &client_id, &server_id)) {
5722 unicast_reject(reply,
packet, &client_id, &server_id);
5727 lease_to_client(reply,
packet, &client_id, &server_id);
5748 if (!valid_client_msg(
packet, &client_id)) {
5752 lease_to_client(reply,
packet, &client_id, NULL);
5758ia_na_match_decline(
const struct data_string *client_id,
5762 char tmp_addr[INET6_ADDRSTRLEN];
5764 log_error(
"Client %s reports address %s is "
5765 "already in use by another host!",
5767 inet_ntop(AF_INET6, iaaddr->
data,
5768 tmp_addr,
sizeof(tmp_addr)));
5769 if (
lease != NULL) {
5777ia_na_nomatch_decline(
const struct data_string *client_id,
5779 u_int32_t *ia_na_id,
5785 char tmp_addr[INET6_ADDRSTRLEN];
5789 log_info(
"Client %s declines address %s, which is not offered to it.",
5791 inet_ntop(AF_INET6, iaaddr->
data, tmp_addr,
sizeof(tmp_addr)));
5796 host_opt_state = NULL;
5798 log_error(
"ia_na_nomatch_decline: out of memory "
5799 "allocating option_state.");
5811 if (reply_len < (*reply_ofs + 16)) {
5813 "out of space for reply packet.");
5821 reply_len-(*reply_ofs)-16,
5823 required_opts_STATUS_CODE, NULL);
5833 putUShort((
unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
5835 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5837 putULong((
unsigned char *)reply_data+(*reply_ofs)+8, 0);
5838 putULong((
unsigned char *)reply_data+(*reply_ofs)+12, 0);
5843 *reply_ofs += (len + 16);
5854 const char *packet_type,
5868 char reply_data[65536];
5871 char status_msg[32];
5873 struct ia_xx *existing_ia_na;
5882 memset(&cli_enc_opt_data, 0,
sizeof(cli_enc_opt_data));
5883 cli_enc_opt_state = NULL;
5884 memset(&iaaddr, 0,
sizeof(iaaddr));
5885 memset(&fixed_addr, 0,
sizeof(fixed_addr));
5906 log_error(
"iterate_over_ia_na: no memory for option_state.");
5919 (
unsigned char *)server_duid.data,
5922 "error saving server identifier.");
5929 (
unsigned char *)client_id->
data,
5933 "error saving client identifier.");
5937 snprintf(status_msg,
sizeof(status_msg),
"%s received.", packet_type);
5946 sizeof(reply_data)-reply_ofs,
5948 required_opts, NULL);
5955 ia != NULL; ia = ia->
next) {
5957 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
5963 iaid =
getULong(cli_enc_opt_data.data);
5981 memset(&iaaddr, 0,
sizeof(iaaddr));
5986 "error evaluating IAADDR.");
6000 cli_enc_opt_state,
MDL)) {
6001 if (packet_host != NULL) {
6007 while (host != NULL) {
6015 "evaluating host address.");
6018 if ((iaaddr.
len >= 16) &&
6019 !memcmp(fixed_addr.data, iaaddr.
data, 16)) {
6033 (
char *)client_id->
data,
6036 log_fatal(
"iterate_over_ia_na: no memory for "
6040 existing_ia_na = NULL;
6042 (
unsigned char *)key.data,
6049 struct in6_addr *in6_addr;
6052 in6_addr = &tmp->
addr;
6053 if (memcmp(in6_addr,
6054 iaaddr.
data, 16) == 0) {
6065 if ((host != NULL) || (
lease != NULL)) {
6066 ia_na_match(client_id, &iaaddr,
lease);
6068 ia_na_nomatch(client_id, &iaaddr,
6069 (u_int32_t *)cli_enc_opt_data.data,
6070 packet, reply_data, &reply_ofs,
6071 sizeof(reply_data));
6074 if (
lease != NULL) {
6086 reply_ret->
len = reply_ofs;
6087 reply_ret->
buffer = NULL;
6092 memcpy(reply_ret->
buffer->
data, reply, reply_ofs);
6095 if (
lease != NULL) {
6098 if (fixed_addr.buffer != NULL) {
6101 if (iaaddr.
buffer != NULL) {
6104 if (cli_enc_opt_state != NULL) {
6107 if (cli_enc_opt_data.buffer != NULL) {
6110 if (opt_state != NULL) {
6137 if (!valid_client_resp(
packet, &client_id, &server_id)) {
6145 unicast_reject(reply,
packet, &client_id, &server_id);
6155 iterate_over_ia_na(reply,
packet, &client_id, &server_id,
6156 "Decline", ia_na_match_decline,
6157 ia_na_nomatch_decline);
6166ia_na_match_release(
const struct data_string *client_id,
6170 char tmp_addr[INET6_ADDRSTRLEN];
6172 log_info(
"Client %s releases address %s",
6174 inet_ntop(AF_INET6, iaaddr->
data, tmp_addr,
sizeof(tmp_addr)));
6175 if (
lease != NULL) {
6183ia_na_nomatch_release(
const struct data_string *client_id,
6185 u_int32_t *ia_na_id,
6191 char tmp_addr[INET6_ADDRSTRLEN];
6195 log_info(
"Client %s releases address %s, which is not leased to it.",
6197 inet_ntop(AF_INET6, iaaddr->
data, tmp_addr,
sizeof(tmp_addr)));
6202 host_opt_state = NULL;
6204 log_error(
"ia_na_nomatch_release: out of memory "
6205 "allocating option_state.");
6210 "Release for non-leased address.",
6218 if (reply_len < (*reply_ofs + 16)) {
6220 "out of space for reply packet.");
6228 reply_len-(*reply_ofs)-16,
6230 required_opts_STATUS_CODE, NULL);
6240 putUShort((
unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
6242 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
6244 putULong((
unsigned char *)reply_data+(*reply_ofs)+8, 0);
6245 putULong((
unsigned char *)reply_data+(*reply_ofs)+12, 0);
6250 *reply_ofs += (len + 16);
6257ia_pd_match_release(
const struct data_string *client_id,
6261 char tmp_addr[INET6_ADDRSTRLEN];
6263 log_info(
"Client %s releases prefix %s/%u",
6265 inet_ntop(AF_INET6, iapref->
data + 9,
6266 tmp_addr,
sizeof(tmp_addr)),
6268 if (prefix != NULL) {
6276ia_pd_nomatch_release(
const struct data_string *client_id,
6278 u_int32_t *ia_pd_id,
6284 char tmp_addr[INET6_ADDRSTRLEN];
6288 log_info(
"Client %s releases prefix %s/%u, which is not leased to it.",
6290 inet_ntop(AF_INET6, iapref->
data + 9,
6291 tmp_addr,
sizeof(tmp_addr)),
6297 host_opt_state = NULL;
6299 log_error(
"ia_pd_nomatch_release: out of memory "
6300 "allocating option_state.");
6305 "Release for non-leased prefix.",
6313 if (reply_len < (*reply_ofs + 16)) {
6315 "out of space for reply packet.");
6323 reply_len-(*reply_ofs)-16,
6325 required_opts_STATUS_CODE, NULL);
6335 putUShort((
unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
6337 memcpy(reply_data+(*reply_ofs)+4, ia_pd_id, 4);
6339 putULong((
unsigned char *)reply_data+(*reply_ofs)+8, 0);
6340 putULong((
unsigned char *)reply_data+(*reply_ofs)+12, 0);
6345 *reply_ofs += (len + 16);
6356 const char *packet_type,
6371 char reply_data[65536];
6374 struct ia_xx *existing_ia_pd;
6382 memset(&reply_new, 0,
sizeof(reply_new));
6384 memset(&cli_enc_opt_data, 0,
sizeof(cli_enc_opt_data));
6385 cli_enc_opt_state = NULL;
6386 memset(&iaprefix, 0,
sizeof(iaprefix));
6392 reply_len =
sizeof(reply_data) - reply_ret->
len;
6406 log_error(
"iterate_over_ia_pd: no memory for option_state.");
6418 ia != NULL; ia = ia->
next) {
6420 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
6426 iaid =
getULong(cli_enc_opt_data.data);
6437 for (; oc != NULL; oc = oc->
next) {
6438 memset(&iaprefix, 0,
sizeof(iaprefix));
6443 "error evaluating IAPREFIX.");
6457 cli_enc_opt_state,
MDL)) {
6458 if (packet_host != NULL) {
6464 while (host != NULL) {
6473 if (memcmp(iaprefix.data + 9,
6478 if ((l != NULL) && (iaprefix.len >= 17))
6489 (
char *)client_id->
data,
6492 log_fatal(
"iterate_over_ia_pd: no memory for "
6496 existing_ia_pd = NULL;
6498 (
unsigned char *)key.data,
6525 if ((host != NULL) || (prefix != NULL)) {
6526 ia_pd_match(client_id, &iaprefix, prefix);
6528 ia_pd_nomatch(client_id, &iaprefix,
6529 (u_int32_t *)cli_enc_opt_data.data,
6530 packet, reply_data, &reply_ofs,
6531 reply_len - reply_ofs);
6534 if (prefix != NULL) {
6549 reply_new.len = reply_ret->
len + reply_ofs;
6553 reply_new.data = reply_new.buffer->data;
6554 memcpy(reply_new.buffer->data,
6556 memcpy(reply_new.buffer->data + reply_ret->
len,
6557 reply_data, reply_ofs);
6563 if (prefix != NULL) {
6566 if (iaprefix.buffer != NULL) {
6569 if (cli_enc_opt_state != NULL) {
6572 if (cli_enc_opt_data.buffer != NULL) {
6575 if (opt_state != NULL) {
6592 if (!valid_client_resp(
packet, &client_id, &server_id)) {
6600 unicast_reject(reply,
packet, &client_id, &server_id);
6605 iterate_over_ia_na(reply,
packet, &client_id, &server_id,
6606 "Release", ia_na_match_release,
6607 ia_na_nomatch_release);
6612 iterate_over_ia_pd(reply,
packet, &client_id, &server_id,
6613 "Release", ia_pd_match_release,
6614 ia_pd_nomatch_release);
6634 if (!valid_client_info_req(
packet, &server_id)) {
6641 memset(&client_id, 0,
sizeof(client_id));
6652 lease_to_client(reply,
packet, &client_id,
6653 server_id.
data != NULL ? &server_id : NULL);
6658 if (client_id.
data != NULL) {
6678 struct packet *enc_packet;
6679 unsigned char msg_type;
6683 char link_addr[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6684 char peer_addr[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6687 static char reply_data[65536];
6695 memset(&a_opt, 0,
sizeof(a_opt));
6696 memset(&packet_ero, 0,
sizeof(packet_ero));
6697 memset(&enc_reply, 0,
sizeof(enc_reply));
6698 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
6707 link_addr,
sizeof(link_addr));
6709 peer_addr,
sizeof(peer_addr));
6710 log_info(
"Relay-forward from %s with link address=%s and "
6711 "peer address=%s missing Relay Message option.",
6719 log_error(
"dhcpv6_forw_relay: error evaluating "
6720 "relayed message.");
6726 log_error(
"dhcpv6_forw_relay: encapsulated packet too short.");
6737 "no memory for encapsulated packet.");
6744 "no memory for encapsulated packet's options.");
6769 enc_opt_data.
len - relaylen,
6781 "unsupported %s message type.",
6785 forw_dhcpv4_query(
packet);
6788 log_error(
"dhcpv6_relay_forw: unsupported %s message type.",
6804 enc_opt_data.
len - msglen,
6816 build_dhcpv6_reply(&enc_reply, enc_packet);
6822 if (enc_reply.data == NULL) {
6844 log_error(
"dhcpv6_relay_forw: no memory for option state.");
6858 log_error(
"dhcpv6_relay_forw: error evaluating "
6863 (
unsigned char *)a_opt.data,
6866 log_error(
"dhcpv6_relay_forw: error saving "
6873#if defined(RELAY_PORT)
6884 log_error(
"dhcpv6_relay_forw: error evaluating "
6885 "Relay Source Port.");
6889 (
unsigned char *)a_opt.data,
6892 log_error(
"dhcpv6_relay_forw: error saving "
6893 "Relay Source Port.");
6906 (
unsigned char *)enc_reply.data,
6909 log_error(
"dhcpv6_relay_forw: error saving Relay MSG.");
6925 (packet_ero.len & 1)) {
6926 log_error(
"dhcpv6_relay_forw: error evaluating ERO.");
6931 for (i = 0; i < packet_ero.len; i += 2) {
6948 "evaluating option %u.", req);
6954 (
unsigned char *)a_opt.data,
6958 log_error(
"dhcpv6_relay_forw: error saving "
6967 sizeof(reply_data) - reply_ofs,
6969 required_opts_agent, &packet_ero);
6974 reply_ret->
len = reply_ofs;
6975 reply_ret->
buffer = NULL;
6980 memcpy(reply_ret->
buffer->
data, reply_data, reply_ofs);
6983 if (opt_state != NULL)
6985 if (a_opt.data != NULL) {
6988 if (packet_ero.data != NULL) {
6991 if (enc_reply.data != NULL) {
6994 if (enc_opt_data.
data != NULL) {
6997 if (enc_packet != NULL) {
7016 struct packet *enc_packet;
7017 unsigned char msg_type;
7021 char link_addr[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
7022 char peer_addr[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
7025 static char reply_data[65536];
7033 memset(&a_opt, 0,
sizeof(a_opt));
7034 memset(&packet_ero, 0,
sizeof(packet_ero));
7035 memset(&enc_reply, 0,
sizeof(enc_reply));
7036 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
7045 link_addr,
sizeof(link_addr));
7047 peer_addr,
sizeof(peer_addr));
7048 log_info(
"Relay-forward from %s with link address=%s and "
7049 "peer address=%s missing Relay Message option.",
7056 log_error(
"dhcp4o6_relay_forw: error evaluating "
7057 "relayed message.");
7063 "encapsulated packet too short.");
7072 "no memory for encapsulated packet.");
7078 "no memory for encapsulated packet's options.");
7103 enc_opt_data.
len - relaylen,
7123 enc_opt_data.
len - msglen,
7130 log_error(
"dhcp4o6_relay_forw: unexpected message of type %d.",
7139 build_dhcpv6_reply(&enc_reply, enc_packet);
7145 if (enc_reply.data == NULL) {
7166 log_error(
"dhcp4o6_relay_forw: no memory for option state.");
7180 log_error(
"dhcp4o6_relay_forw: error evaluating "
7185 (
unsigned char *)a_opt.data,
7188 log_error(
"dhcp4o6_relay_forw: error saving "
7195#if defined(RELAY_PORT)
7206 log_error(
"dhcpv4o6_relay_forw: error evaluating "
7207 "Relay Source Port.");
7211 (
unsigned char *)a_opt.data,
7214 log_error(
"dhcpv4o6_relay_forw: error saving "
7215 "Relay Source Port.");
7228 (
unsigned char *)enc_reply.data,
7231 log_error(
"dhcp4o6_relay_forw: error saving Relay MSG.");
7247 (packet_ero.len & 1)) {
7248 log_error(
"dhcp4o6_relay_forw: error evaluating ERO.");
7253 for (i = 0; i < packet_ero.len; i += 2) {
7270 "evaluating option %u.", req);
7276 (
unsigned char *)a_opt.data,
7280 log_error(
"dhcp4o6_relay_forw: error saving "
7289 sizeof(reply_data) - reply_ofs,
7291 required_opts_agent, &packet_ero);
7296 reply_ret->
len = reply_ofs;
7297 reply_ret->
buffer = NULL;
7302 memcpy(reply_ret->
buffer->
data, reply_data, reply_ofs);
7305 if (opt_state != NULL)
7307 if (a_opt.data != NULL) {
7310 if (packet_ero.data != NULL) {
7313 if (enc_reply.data != NULL) {
7316 if (enc_opt_data.
data != NULL) {
7319 if (enc_packet != NULL) {
7337 struct packet *enc_packet;
7340 static char response_data[65536];
7348 memset(&enc_response, 0,
sizeof(enc_response));
7349 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
7357 log_info(
"DHCPv4-query from %s missing DHCPv4 Message option.",
7364 log_error(
"dhcp4o6_dhcpv4_query: error evaluating "
7370 log_error(
"dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7379 "no memory for encapsulated packet.");
7395 "discarding packet with bogus hlen.");
7401 log_error(
"dhcp4o6_dhcpv4_query: no memory for options.");
7421 memset(&dp, 0,
sizeof dp);
7447 if (enc_response.data == NULL) {
7464 log_error(
"dhcp4o6_dhcpv4_query: no memory for option state.");
7472 (
unsigned char *)enc_response.data,
7475 log_error(
"dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7480 sizeof(response_data) - response_ofs,
7482 required_opts_4o6, NULL);
7487 reply_ret->
len = response_ofs;
7488 reply_ret->
buffer = NULL;
7490 log_fatal(
"dhcp4o6_dhcpv4_query: no memory to store reply.");
7493 memcpy(reply_ret->
buffer->
data, response_data, response_ofs);
7496 if (opt_state != NULL)
7498 if (enc_response.data != NULL) {
7501 if (enc_opt_data.
data != NULL) {
7504 if (enc_packet != NULL) {
7519 struct udp_data4o6 udp_data;
7531 log_error(
"forw_dhcpv4_query: can't find initial message.");
7537 memset(&ds, 0,
sizeof(ds));
7540 "no memory for encapsulating packet.");
7543 ds.data = ds.buffer->data;
7548 memcpy(ds.buffer->data + 16,
7550 memset(&udp_data, 0,
sizeof(udp_data));
7552 memcpy(ds.buffer->data + 32, &udp_data, 4);
7553 memcpy(ds.buffer->data + 36,
7558 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
7560 log_error(
"forw_dhcpv4_query: send(): %m");
7570 log_debug(
"Discarding %s from %s; message type not handled by server",
7577 memset(reply, 0,
sizeof(*reply));
7590 dhcpv6_solicit(reply,
packet);
7597 dhcpv6_request(reply,
packet);
7601 dhcpv6_confirm(reply,
packet);
7605 dhcpv6_renew(reply,
packet);
7609 dhcpv6_rebind(reply,
packet);
7616 dhcpv6_release(reply,
packet);
7620 dhcpv6_decline(reply,
packet);
7627 dhcpv6_information_request(reply,
packet);
7632 dhcp4o6_relay_forw(reply,
packet);
7635 dhcpv6_relay_forw(reply,
packet);
7651 forw_dhcpv4_query(
packet);
7653 dhcp4o6_dhcpv4_query(reply,
packet);
7665 log_info(
"Discarding unknown DHCPv6 message type %d "
7675 char tmp_addr[INET6_ADDRSTRLEN];
7678 memset(&s, 0,
sizeof(s));
7687 "Unknown message type %d from %s port %d",
7696 inet_ntop(AF_INET6, addr,
7697 tmp_addr,
sizeof(tmp_addr)));
7700 inet_ntop(AF_INET6, addr,
7701 tmp_addr,
sizeof(tmp_addr)));
7734 struct sockaddr_in6 to_addr;
7745 build_dhcpv6_reply(&reply,
packet);
7747 if (reply.
data != NULL) {
7751 memset(&to_addr, 0,
sizeof(to_addr));
7752 to_addr.sin6_family = AF_INET6;
7760#if defined (REPLY_TO_SOURCE_PORT)
7771#if defined(RELAY_PORT)
7781 sizeof(to_addr.sin6_addr));
7783 log_info(
"Sending %s to %s port %d",
7786 ntohs(to_addr.sin6_port));
7789 reply.
data, reply.
len, &to_addr);
7790 if (send_ret != reply.
len) {
7791 log_error(
"dhcpv6: send_packet6() sent %d of %d bytes",
7792 send_ret, reply.
len);
7810static void recv_dhcpv4_query(
struct data_string *raw) {
7815 unsigned char msg_type;
7820 struct udp_data4o6 udp_data;
7824 memset(name, 0,
sizeof(name));
7825 memcpy(name, raw->
data, 16);
7827 if (!strcmp(name,
ip->name))
7831 log_error(
"recv_dhcpv4_query: can't find interface %s.",
7839 memset(&udp_data, 0,
sizeof(udp_data));
7840 memcpy(&udp_data, raw->
data + 32, 4);
7848 "short packet from %s, len %d, dropped",
7858 log_error(
"recv_dhcpv4_query: no memory for packet.");
7863 log_error(
"recv_dhcpv4_query: no memory for options.");
7874 msg_type = raw->
data[36];
7891 raw->
len - 36 - relaylen,
7911 raw->
len - 36 - msglen,
7919 log_error(
"recv_dhcpv4_query: unexpected message of type %d.",
7933 memset(&ds, 0,
sizeof(ds));
7940 "Unknown message type %d from %s",
7946 char tmp_addr[INET6_ADDRSTRLEN];
7951 inet_ntop(AF_INET6, addr,
7952 tmp_addr,
sizeof(tmp_addr)));
7955 inet_ntop(AF_INET6, addr,
7956 tmp_addr,
sizeof(tmp_addr)));
7970 build_dhcpv6_reply(&reply,
packet);
7972 if (reply.
data == NULL) {
7980 len = reply.
len + 36;
7981 memset(&ds, 0,
sizeof(ds));
7983 log_error(
"recv_dhcpv4_query: no memory.");
7987 ds.data = ds.buffer->data;
7990 memcpy(ds.buffer->data, name, 16);
7991 memcpy(ds.buffer->data + 16,
iaddr.
iabuf, 16);
7993 memcpy(ds.buffer->data + 32, &udp_data, 4);
7994 memcpy(ds.buffer->data + 36, reply.
data, reply.
len);
8001 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
8003 log_error(
"recv_dhcpv4_query: send(): %m");
8018 host_reference(&hold, *hp,
MDL);
8019 host_dereference(hp,
MDL);
8021 while (seek != NULL) {
8024 else if (fixed_matches_shared(seek, shared))
8030 if ((seek == NULL) && (nofixed != NULL))
8034 host_reference(hp, seek,
MDL);
8047 memset(&addr, 0,
sizeof(addr));
8052 if (addr.len < 16) {
8058 memcpy(fixed.iabuf, addr.data, 16);
8096 struct reply_state reply;
8097 memset(&reply, 0x0,
sizeof(
struct reply_state));
8100 if (shared_network_from_packet6(&reply.shared,
packet)
8102 log_error(
"unicast_reject: could not locate client.");
8110 if (start_reply(
packet, client_id, server_id, &reply.opt_state,
8111 &reply.buf.reply)) {
8114 "Unicast not allowed by server.",
8116 log_error(
"unicast_reject: Unable to set status code.");
8126 unicast_reject_opts,
8130 reply_ret->
len = reply.cursor;
8131 reply_ret->
buffer = NULL;
8133 reply.cursor,
MDL)) {
8135 "No memory to store Reply.");
8146 if (reply.shared != NULL)
8147 shared_network_dereference(&reply.shared,
MDL);
8148 if (reply.opt_state != NULL)
8150 if (reply.packet != NULL)
8152 if (reply.client_id.
data != NULL)
8183 "No memory for option state.");
8188 if (((shared_network_from_requested_addr(&shared,
packet)
8191 || (shared == NULL)) {
8195 "cannot attribute packet to a network.");
8207 log_debug(
"is_unicast_option_defined: option found : %d", is_defined);
8209 if (shared != NULL) {
8210 shared_network_dereference(&shared,
MDL);
8213 if (opt_state != NULL) {
8217 return (is_defined);
8236shared_network_from_requested_addr (
struct shared_network **shared,
8240 isc_result_t status = ISC_R_FAILURE;
8251 log_debug(
"share_network_from_request_addr: nothing to match");
8252 return (ISC_R_FAILURE);
8256 log_debug(
"shared_network_from_requested_addr:"
8259 status = shared_network_reference(shared,
8262 log_debug(
"shared_network_from_requested_addr:"
8263 " found shared network %s for address %s.",
8264 ((*shared)->name ? (*shared)->name :
"unnamed"),
8269 return (ISC_R_FAILURE);
8291get_first_ia_addr_val (
struct packet*
packet,
int addr_type,
8297 int addr_opt_offset;
8299 int addr_opt_data_len;
8302 isc_result_t status = ISC_R_FAILURE;
8306 switch (addr_type) {
8310 addr_opt_data_len = 24;
8316 addr_opt_data_len = 24;
8322 addr_opt_data_len = 25;
8327 log_error (
"get_first_ia_addr_val: invalid opt type %d",
8329 return (ISC_R_FAILURE);
8334 ia != NULL && oc == NULL; ia = ia->
next) {
8335 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
8337 packet, ia, addr_opt_offset)) {
8339 " couldn't unroll enclosing option");
8340 return (ISC_R_FAILURE);
8356 memset(&iaddr_str, 0,
sizeof(iaddr_str));
8361 "error evaluating IA_XX option.");
8363 if (iaddr_str.len != addr_opt_data_len) {
8364 log_error(
"shared_network_from_requested_addr:"
8365 " invalid length %d, expected %d",
8366 iaddr_str.len, addr_opt_data_len);
8370 iaddr_str.data + ip_addr_offset, 16);
8413set_reply_tee_times(
struct reply_state* reply,
unsigned ia_cursor)
8421 set_tee_times = (oc &&
8424 reply->packet->options,
8436 reply->packet->options,
8446 if (
data.data != NULL)
8448 }
else if (set_tee_times) {
8454 reply->renew = reply->min_prefer / 2;
8460 putULong(reply->buf.data + ia_cursor + 8, reply->renew);
8471 reply->packet->options,
8481 if (
data.data != NULL)
8483 }
else if (set_tee_times) {
8489 reply->rebind = (reply->min_prefer / 5) * 4;
8495 putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
8505release_on_roam(
struct reply_state* reply) {
8506 struct ia_xx* old_ia = reply->old_ia;
8520 if (
lease->ipv6_pool->shared_network == reply->shared) {
8529 log_info(
"Client: %s roamed to new network,"
8530 " releasing lease: %s%s",
8532 reply->client_id.data, 60),
8549 static char prefix_buf[16];
8552 sprintf(prefix_buf,
"/%-d",
lease->plen);
8555 return (prefix_buf);
8569void ddns_update_static6(
struct reply_state* reply) {
8577 reply->packet->options,
8578 reply->opt_state, NULL,
8588 reply->packet->options,
8589 reply->opt_state, NULL,
8604 memcpy(iasub->
addr.s6_addr, reply->fixed.data, 16);
8611 log_fatal(
"Out of memory for binding scope.");
8616 ddns_updates(reply->packet, NULL, NULL, iasub, NULL, reply->opt_state);
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
void data_string_forget(struct data_string *data, const char *file, int line)
int option_state_allocate(struct option_state **ptr, const char *file, int line)
int option_state_dereference(struct option_state **ptr, const char *file, int line)
int packet_reference(struct packet **ptr, struct packet *bp, const char *file, int line)
int packet_dereference(struct packet **ptr, const char *file, int line)
int binding_scope_reference(struct binding_scope **ptr, struct binding_scope *bp, const char *file, int line)
int binding_scope_allocate(struct binding_scope **ptr, const char *file, int line)
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
int packet_allocate(struct packet **ptr, const char *file, int line)
void delete_option(struct universe *universe, struct option_state *options, int code)
int append_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
int parse_options(struct packet *packet)
int save_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
int get_option_int(int *result, struct universe *universe, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct option_state *options, struct binding_scope **scope, unsigned code, const char *file, int line)
int store_options6(char *buf, int buflen, struct option_state *opt_state, struct packet *packet, const int *required_opts, struct data_string *oro)
int packet6_len_okay(const char *packet, int len)
int parse_option_buffer(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *universe)
int validate_packet(struct packet *packet)
u_int32_t getUShort(const unsigned char *)
void putUShort(unsigned char *, u_int32_t)
u_int32_t getULong(const unsigned char *)
u_int32_t getUChar(const unsigned char *)
void putULong(unsigned char *, u_int32_t)
void bootp(struct packet *packet)
void dhcp(struct packet *packet)
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
#define IASUBOPT_NA_PREF_OFFSET
#define DHCPV6_RELAY_REPL
#define D6O_RELAY_SOURCE_PORT
#define IASUBOPT_PD_PREFLEN_OFFSET
#define DHCP4O6_QUERY_UNICAST
#define DHCPV6_RELAY_FORW
#define D6O_RECONF_ACCEPT
#define IASUBOPT_NA_VALID_OFFSET
#define REPLY_OPTIONS_INDEX
#define IASUBOPT_PD_PREF_OFFSET
#define DHCPV6_LEASEQUERY
#define DHCPV6_DHCPV4_QUERY
#define IASUBOPT_PD_PREFIX_OFFSET
#define IASUBOPT_NA_ADDR_OFFSET
#define DHCPV6_INFORMATION_REQUEST
#define STATUS_NoAddrsAvail
#define DHCPV6_RECONFIGURE
#define STATUS_UseMulticast
#define STATUS_NoPrefixAvail
#define IASUBOPT_PD_VALID_OFFSET
#define DHCPV6_DHCPV4_RESPONSE
#define DHCPV6_LEASEQUERY_REPLY
#define DHCP_FIXED_NON_UDP
#define DHO_DHCP_MESSAGE_TYPE
#define DHO_DHCP_RENEWAL_TIME
#define DHO_DHCP_REBINDING_TIME
#define SV_UPDATE_STATIC_LEASES
#define DEFAULT_DEFAULT_LEASE_TIME
const char * pin6_addr(const struct in6_addr *)
isc_result_t ia_add_iasubopt(struct ia_xx *ia, struct iasubopt *iasubopt, const char *file, int line)
#define SV_DHCPV6_SET_TEE_TIMES
#define DEFAULT_CACHE_THRESHOLD
void dhcpv6_leasequery(struct data_string *, struct packet *)
#define FIND_POND6_PERCENT(count, percent)
isc_boolean_t ipv6_in_pool(const struct in6_addr *addr, const struct ipv6_pool *pool)
isc_result_t get_client_id(struct packet *, struct data_string *)
#define SV_LOG_THRESHOLD_LOW
isc_result_t iasubopt_reference(struct iasubopt **iasubopt, struct iasubopt *src, const char *file, int line)
isc_result_t generate_new_server_duid(void)
#define print_hex_3(len, data, limit)
int find_hosts6(struct host_decl **host, struct packet *packet, const struct data_string *client_id, char *file, int line)
isc_result_t decline_lease6(struct ipv6_pool *pool, struct iasubopt *lease)
isc_boolean_t lease6_usable(struct iasubopt *lease)
Check if address is available to a lease.
void set_server_duid(struct data_string *new_duid)
void copy_server_duid(struct data_string *ds, const char *file, int line)
isc_result_t ia_allocate(struct ia_xx **ia, u_int32_t iaid, const char *duid, unsigned int duid_len, const char *file, int line)
void schedule_lease_timeout(struct ipv6_pool *pool)
#define SV_LIMIT_PREFS_PER_IA
isc_result_t create_prefix6(struct ipv6_pool *pool, struct iasubopt **pref, unsigned int *attempts, const struct data_string *uid, time_t soft_lifetime_end_time)
int find_grouped_subnet(struct subnet **, struct shared_network *, struct iaddr, const char *, int)
void set_server_duid_type(int type)
#define SV_CACHE_THRESHOLD
void change_host_uid(struct host_decl *host, const char *data, int len)
int ddns_updates(struct packet *, struct lease *, struct lease *, struct iasubopt *, struct iasubopt *, struct option_state *)
int commit_leases_timed(void)
struct universe server_universe
isc_result_t set_server_duid_from_option(void)
isc_result_t ia_dereference(struct ia_xx **ia, const char *file, int line)
struct universe dhcp_universe
#define SV_LIMIT_ADDRS_PER_IA
isc_result_t ia_make_key(struct data_string *key, u_int32_t iaid, const char *duid, unsigned int duid_len, const char *file, int line)
isc_boolean_t lease6_exists(const struct ipv6_pool *pool, const struct in6_addr *addr)
isc_result_t create_lease6(struct ipv6_pool *pool, struct iasubopt **addr, unsigned int *attempts, const struct data_string *uid, time_t soft_lifetime_end_time)
int find_hosts_by_option(struct host_decl **, struct packet *, struct option_state *, const char *, int)
isc_result_t renew_lease6(struct ipv6_pool *pool, struct iasubopt *lease)
Renew a lease in the pool.
#define SV_LOG_THRESHOLD_HIGH
isc_result_t release_lease6(struct ipv6_pool *pool, struct iasubopt *lease)
#define print_hex_2(len, data, limit)
isc_result_t find_ipv6_pool(struct ipv6_pool **pool, u_int16_t type, const struct in6_addr *addr)
int write_ia(const struct ia_xx *)
ssize_t send_packet6(struct interface_info *, const unsigned char *, size_t, struct sockaddr_in6 *)
isc_boolean_t server_duid_isset(void)
void classify_client(struct packet *)
isc_result_t iasubopt_dereference(struct iasubopt **iasubopt, const char *file, int line)
isc_boolean_t prefix6_exists(const struct ipv6_pool *pool, const struct in6_addr *pref, u_int8_t plen)
#define SV_PREFER_LIFETIME
isc_result_t add_lease6(struct ipv6_pool *pool, struct iasubopt *lease, time_t valid_lifetime_end_time)
int permitted(struct packet *, struct permit *)
void dhcpv6(struct packet *)
#define SV_DEFAULT_LEASE_TIME
isc_result_t ia_reference(struct ia_xx **ia, struct ia_xx *src, const char *file, int line)
#define print_hex_1(len, data, limit)
struct interface_info * interfaces
int execute_statements(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct executable_statement *statements, struct on_star *on_star)
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
isc_boolean_t is_cidr_mask_valid(const struct iaddr *addr, int bits)
const char * piaddr(const struct iaddr addr)
int addr_eq(struct iaddr addr1, struct iaddr addr2)
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
struct group * root_group
struct __omapi_object omapi_object_t
int log_error(const char *,...) __attribute__((__format__(__printf__
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
#define DHCP_R_INVALIDARG
const unsigned char * data
unsigned char options[DHCP_MAX_OPTION_LEN]
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
unsigned char transaction_id[3]
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
unsigned char link_address[16]
unsigned char peer_address[16]
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
struct iaddrcidrnetlist * fixed_prefix
struct option_cache * fixed_addr
struct host_decl * n_ipaddr
struct iasubopt ** iasubopt
struct iaddrcidrnet cidrnet
struct iaddrcidrnetlist * next
time_t hard_lifetime_end_time
struct binding_scope * scope
struct ipv6_pool * ipv6_pool
time_t soft_lifetime_end_time
struct interface_info * next
struct hardware hw_address
struct shared_network * shared_network
struct permit * permit_list
struct shared_network * shared_network
isc_uint64_t num_abandoned
struct ipv6_pool ** ipv6_pools
isc_uint64_t low_threshold
struct permit * prohibit_list
struct ipv6_pond * ipv6_pond
struct shared_network * shared_network
struct lease_state * state
struct dhcp_ddns_cb * ddns_cb
struct binding_scope * scope
struct executable_statement * on_commit
struct option_cache * next
struct in6_addr dhcpv6_link_address
struct packet * dhcpv6_container_packet
unsigned char dhcp4o6_flags[3]
unsigned char dhcpv6_msg_type
unsigned char dhcpv6_hop_count
struct interface_info * interface
isc_boolean_t relay_source_port
struct in6_addr dhcpv6_peer_address
struct option_state * options
struct data_string * dhcp4o6_response
unsigned char dhcpv6_transaction_id[3]
struct subnet * next_sibling
struct shared_network * shared_network
const int dhcpv6_type_name_max
const char * dhcpv6_type_names[]
struct universe dhcpv6_universe
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
int evaluate_boolean_option_cache(int *ignorep, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
int data_string_sprintfa(struct data_string *ds, const char *fmt,...)
struct binding_scope * global_scope