25 static void send_dhcpv4_response(
struct data_string *raw);
27 static void recv_dhcpv4_query(
struct data_string *raw);
28 static void dhcp4o6_dhcpv4_query(
struct data_string *reply_ret,
65 unsigned client_resources;
66 isc_boolean_t resources_included;
67 isc_boolean_t static_lease;
68 unsigned static_prefixes;
82 u_int32_t renew, rebind, min_prefer, min_valid;
85 u_int32_t client_valid, client_prefer;
88 u_int32_t send_valid, send_prefer;
100 unsigned char data[65536];
108 static int get_encapsulated_IA_state(
struct option_state **enc_opt_state,
114 static isc_result_t shared_network_from_packet6(
struct shared_network **shared,
116 static void seek_shared_host(
struct host_decl **hp,
118 static isc_boolean_t fixed_matches_shared(
struct host_decl *host,
120 static isc_result_t reply_process_ia_na(
struct reply_state *reply,
122 static isc_result_t reply_process_ia_ta(
struct reply_state *reply,
124 static isc_result_t reply_process_addr(
struct reply_state *reply,
126 static isc_boolean_t address_is_owned(
struct reply_state *reply,
128 static isc_boolean_t temporary_is_available(
struct reply_state *reply,
130 static isc_result_t find_client_temporaries(
struct reply_state *reply);
131 static isc_result_t reply_process_try_addr(
struct reply_state *reply,
133 static isc_result_t find_client_address(
struct reply_state *reply);
134 static isc_result_t reply_process_is_addressed(
struct reply_state *reply,
137 static isc_result_t reply_process_send_addr(
struct reply_state *reply,
141 static isc_result_t reply_process_ia_pd(
struct reply_state *reply,
143 static struct group *find_group_by_prefix(
struct reply_state *reply);
144 static isc_result_t reply_process_prefix(
struct reply_state *reply,
146 static isc_boolean_t prefix_is_owned(
struct reply_state *reply,
148 static isc_result_t find_client_prefix(
struct reply_state *reply);
149 static isc_result_t reply_process_try_prefix(
struct reply_state *reply,
151 static isc_result_t reply_process_is_prefixed(
struct reply_state *reply,
154 static isc_result_t reply_process_send_prefix(
struct reply_state *reply,
156 static struct iasubopt *prefix_compare(
struct reply_state *reply,
159 static void schedule_lease_timeout_reply(
struct reply_state *reply);
161 static int eval_prefix_mode(
int thislen,
int preflen,
int prefix_mode);
162 static isc_result_t pick_v6_prefix_helper(
struct reply_state *reply,
169 static isc_boolean_t is_unicast_option_defined(
struct packet *
packet);
170 static isc_result_t shared_network_from_requested_addr (
struct shared_network 173 static isc_result_t get_first_ia_addr_val (
struct packet*
packet,
int addr_type,
177 set_reply_tee_times(
struct reply_state* reply,
unsigned ia_cursor);
196 if (h->type != dhcp4o6_type)
199 cc = recv(dhcp4o6_fd, buf,
sizeof(buf), 0);
202 return ISC_R_UNEXPECTED;
203 memset(&raw, 0,
sizeof(raw));
205 log_error(
"dhcpv4o6_handler: no memory buffer.");
206 return ISC_R_NOMEMORY;
208 raw.data = raw.buffer->data;
210 memcpy(raw.buffer->data, buf, cc);
213 send_dhcpv4_response(&raw);
215 recv_dhcpv4_query(&raw);
220 return ISC_R_SUCCESS;
231 static void send_dhcpv4_response(
struct data_string *raw) {
234 struct sockaddr_in6 to_addr;
235 char pbuf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
238 memset(name, 0,
sizeof(name));
239 memcpy(name, raw->
data, 16);
241 if (!strcmp(name,
ip->name))
245 log_error(
"send_dhcpv4_response: can't find interface %s.",
250 memset(&to_addr, 0,
sizeof(to_addr));
251 to_addr.sin6_family = AF_INET6;
252 memcpy(&to_addr.sin6_addr, raw->
data + 16, 16);
260 log_info(
"send_dhcpv4_response(): sending %s on %s to %s port %d",
263 inet_ntop(AF_INET6, raw->
data + 16, pbuf,
sizeof(pbuf)),
264 ntohs(to_addr.sin6_port));
268 log_error(
"send_dhcpv4_response: send_packet6(): %m");
269 }
else if (send_ret != raw->
len - 32) {
270 log_error(
"send_dhcpv4_response: send_packet6() " 271 "sent %d of %d bytes",
272 send_ret, raw->
len - 32);
283 schedule_lease_timeout_reply(
struct reply_state *reply) {
288 if ((reply == NULL) || (reply->ia == NULL) || (reply->ia->iasubopt == NULL))
292 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
293 tmp = reply->ia->iasubopt[i];
303 duid_time(time_t when) {
340 return (server_duid.data != NULL);
378 isc_result_t ret_val;
391 ret_val = ISC_R_NOTFOUND;
393 memset(&option_duid, 0,
sizeof(option_duid));
397 ret_val = ISC_R_UNEXPECTED;
401 ret_val = ISC_R_SUCCESS;
420 static int server_duid_type =
DUID_LLT;
427 server_duid_type = type;
444 log_error(
"Invalid DUID type %d specified, " 445 "only LL and LLT types supported", server_duid_type);
458 log_error(
"Can not generate DUID from interfaces which do not have hardware addresses, please configure server-duid!");
462 return ISC_R_UNEXPECTED;
468 memset(&generated_duid, 0,
sizeof(generated_duid));
470 time_val = duid_time(time(NULL));
473 generated_duid.len,
MDL)) {
476 generated_duid.data = generated_duid.buffer->data;
478 putUShort(generated_duid.buffer->data + 2,
480 putULong(generated_duid.buffer->data + 4, time_val);
481 memcpy(generated_duid.buffer->data + 8,
483 }
else if (server_duid_type ==
DUID_LL) {
486 generated_duid.len,
MDL)) {
489 generated_duid.data = generated_duid.buffer->data;
491 putUShort(generated_duid.buffer->data + 2,
493 memcpy(generated_duid.buffer->data + 4,
496 log_fatal(
"Unsupported server DUID type %d.", server_duid_type);
502 return ISC_R_SUCCESS;
515 if ((client_id->
data != NULL) || (client_id->
len != 0)) {
521 return ISC_R_NOTFOUND;
527 return ISC_R_FAILURE;
530 return ISC_R_SUCCESS;
547 memset(client_id, 0,
sizeof(*client_id));
555 "client identifier missing",
560 log_error(
"Error processing %s from %s; " 561 "unable to evaluate Client Identifier",
571 log_debug(
"Discarding %s from %s; packet sent unicast " 586 "server identifier found " 587 "(CLIENTID %s, SERVERID %s)",
591 client_id->
data, 60),
596 "server identifier found " 600 client_id->
data, 60),
614 if (client_id->
len > 0) {
644 memset(client_id, 0,
sizeof(*client_id));
645 memset(server_id, 0,
sizeof(*server_id));
652 "client identifier missing",
657 log_error(
"Error processing %s from %s; " 658 "unable to evaluate Client Identifier",
667 "server identifier missing (CLIENTID %s)",
676 log_error(
"Error processing %s from %s; " 677 "unable to evaluate Server Identifier (CLIENTID %s)",
683 if ((server_duid.len != server_id->
len) ||
684 (memcmp(server_duid.data, server_id->
data, server_duid.len) != 0)) {
686 "not our server identifier " 687 "(CLIENTID %s, SERVERID %s, server DUID %s)",
692 print_hex_3(server_duid.len, server_duid.data, 60));
701 if (server_id->
len > 0) {
704 if (client_id->
len > 0) {
727 char client_id_str[80];
731 memset(server_id, 0,
sizeof(*server_id));
732 memset(&client_id, 0,
sizeof(client_id));
743 snprintf(client_id_str,
sizeof(client_id_str),
" (CLIENTID %s)",
747 client_id_str[0] =
'\0';
754 log_debug(
"Discarding %s from %s; packet sent unicast%s",
763 "IA_NA option present%s",
771 "IA_TA option present%s",
779 "IA_PD option present%s",
790 log_error(
"Error processing %s from %s; " 791 "unable to evaluate Server Identifier%s",
796 if ((server_duid.len != server_id->
len) ||
797 (memcmp(server_duid.data, server_id->
data,
798 server_duid.len) != 0)) {
800 "not our server identifier " 801 "(SERVERID %s, server DUID %s)%s",
805 server_id->
data, 60),
807 server_duid.data, 60),
818 if (server_id->
len > 0) {
829 static const int required_opts[] = {
836 static const int required_opts_solicit[] = {
848 static const int required_opts_agent[] = {
853 static const int required_opts_IA[] = {
858 static const int required_opts_IA_PD[] = {
863 static const int required_opts_STATUS_CODE[] = {
868 static const int required_opts_4o6[] = {
874 static const int unicast_reject_opts[] = {
889 get_encapsulated_IA_state(
struct option_state **enc_opt_state,
898 memset(enc_opt_data, 0,
sizeof(*enc_opt_data));
903 "error evaluating raw option.");
906 if (enc_opt_data->
len < offset) {
907 log_error(
"get_encapsulated_IA_state: raw option too small.");
916 *enc_opt_state = NULL;
918 log_error(
"get_encapsulated_IA_state: no memory for options.");
923 enc_opt_data->
data + offset,
924 enc_opt_data->
len - offset,
926 log_error(
"get_encapsulated_IA_state: error parsing options.");
936 set_status_code(u_int16_t status_code,
const char *status_message,
942 memset(&d, 0,
sizeof(d));
943 d.len =
sizeof(status_code) + strlen(status_message);
945 log_fatal(
"set_status_code: no memory for status code.");
947 d.data = d.buffer->data;
949 memcpy(d.buffer->data +
sizeof(status_code),
950 status_message, d.len -
sizeof(status_code));
952 d.buffer, (
unsigned char *)d.data, d.len,
954 log_error(
"set_status_code: error saving status code.");
963 void check_pool6_threshold(
struct reply_state *reply,
967 isc_uint64_t used, count, high_threshold;
968 int poolhigh = 0, poollow = 0;
969 char *shared_name =
"no name";
970 char tmp_addr[INET6_ADDRSTRLEN];
972 if ((
lease->ipv6_pool == NULL) || (
lease->ipv6_pool->ipv6_pond == NULL))
974 pond =
lease->ipv6_pool->ipv6_pond;
1004 log_error(
"Pool threshold reset - shared subnet: %s; " 1005 "address: %s; low threshold %llu/%llu.",
1007 inet_ntop(AF_INET6, &
lease->addr,
1008 tmp_addr,
sizeof(tmp_addr)),
1009 (
long long unsigned)(used),
1010 (
long long unsigned)(count));
1017 NULL, reply->packet->options, reply->opt_state,
1025 if ((poolhigh <= 0) || (poolhigh > 100)) {
1032 if (used < high_threshold) {
1038 log_error(
"Pool threshold exceeded - shared subnet: %s; " 1039 "address: %s; high threshold %d%% %llu/%llu.",
1041 inet_ntop(AF_INET6, &
lease->addr, tmp_addr,
sizeof(tmp_addr)),
1042 poolhigh, (
long long unsigned)(used),
1043 (
long long unsigned)(count));
1048 NULL, reply->packet->options, reply->opt_state,
1060 if (poollow < poolhigh) {
1078 const unsigned char *server_id_data;
1086 log_error(
"start_reply: no memory for option_state.");
1154 if (server_id == NULL) {
1155 server_id_data = server_duid.data;
1156 server_id_len = server_duid.len;
1158 server_id_data = server_id->
data;
1159 server_id_len = server_id->
len;
1162 NULL, (
unsigned char *)server_id_data,
1165 "error saving server identifier.");
1170 if (client_id->
buffer != NULL) {
1173 (
unsigned char *)client_id->
data,
1177 "client identifier.");
1193 NULL, (
unsigned char *)
"", 0,
1196 "error saving RECONF_ACCEPT option.");
1214 try_client_v6_address(
struct iasubopt **addr,
1218 struct in6_addr tmp_addr;
1219 isc_result_t result;
1221 if (requested_addr->
len <
sizeof(tmp_addr)) {
1224 memcpy(&tmp_addr, requested_addr->
data,
sizeof(tmp_addr));
1225 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) {
1226 return ISC_R_FAILURE;
1234 return ISC_R_ADDRNOTAVAIL;
1238 return ISC_R_ADDRINUSE;
1241 result = iasubopt_allocate(addr,
MDL);
1242 if (result != ISC_R_SUCCESS) {
1245 (*addr)->addr = tmp_addr;
1250 if (result != ISC_R_SUCCESS) {
1279 pick_v6_address(
struct reply_state *reply)
1285 unsigned int attempts;
1286 char tmp_buf[INET6_ADDRSTRLEN];
1288 isc_uint64_t total = 0;
1289 isc_uint64_t active = 0;
1290 isc_uint64_t abandoned = 0;
1291 int jumbo_range = 0;
1292 char *shared_name = (reply->shared->name ?
1293 reply->shared->name :
"(no name)");
1299 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
1303 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
1313 log_debug(
"Unable to pick client address: " 1314 "no IPv6 pools on this shared network");
1315 return ISC_R_NORESOURCES;
1329 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
1330 isc_result_t result = ISC_R_FAILURE;
1344 &reply->ia->iaid_duid,
1346 if (result == ISC_R_SUCCESS) {
1364 tmp_buf,
sizeof(tmp_buf)));
1365 return (ISC_R_SUCCESS);
1373 }
while (i != start_pool);
1375 if (result == ISC_R_NORESOURCES) {
1387 if (jumbo_range != 0) {
1388 log_debug(
"Unable to pick client address: " 1389 "no addresses available - shared network %s: " 1390 " 2^64-1 < total, %llu active, %llu abandoned",
1391 shared_name, (
long long unsigned)(active - abandoned),
1392 (
long long unsigned)(abandoned));
1394 log_debug(
"Unable to pick client address: " 1395 "no addresses available - shared network %s: " 1396 "%llu total, %llu active, %llu abandoned",
1397 shared_name, (
long long unsigned)(total),
1398 (
long long unsigned)(active - abandoned),
1399 (
long long unsigned)(abandoned));
1402 return ISC_R_NORESOURCES;
1414 try_client_v6_prefix(
struct iasubopt **pref,
1419 struct in6_addr tmp_pref;
1421 isc_result_t result;
1423 if (requested_pref->
len <
sizeof(tmp_plen) +
sizeof(tmp_pref)) {
1427 tmp_plen = (
int) requested_pref->
data[0];
1428 if ((tmp_plen < 3) || (tmp_plen > 128)) {
1429 return ISC_R_FAILURE;
1432 memcpy(&tmp_pref, requested_pref->
data + 1,
sizeof(tmp_pref));
1433 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_pref)) {
1434 return ISC_R_FAILURE;
1438 memcpy(&ia.iabuf, &tmp_pref, 16);
1440 return ISC_R_FAILURE;
1444 ((
int)tmp_plen !=
pool->units)) {
1445 return ISC_R_ADDRNOTAVAIL;
1449 return ISC_R_ADDRINUSE;
1452 result = iasubopt_allocate(pref,
MDL);
1453 if (result != ISC_R_SUCCESS) {
1457 (*pref)->addr = tmp_pref;
1458 (*pref)->plen = tmp_plen;
1462 if (result != ISC_R_SUCCESS) {
1509 pick_v6_prefix(
struct reply_state *reply) {
1513 isc_result_t result;
1519 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
1523 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
1533 log_debug(
"Unable to pick client prefix: " 1534 "no IPv6 pools on this shared network");
1535 return ISC_R_NORESOURCES;
1538 if (reply->preflen <= 0) {
1541 result = pick_v6_prefix_helper(reply,
PLM_IGNORE);
1547 result = pick_v6_prefix_helper(reply,
PLM_EXACT);
1548 if (result != ISC_R_SUCCESS) {
1549 result = pick_v6_prefix_helper(reply,
1556 result = pick_v6_prefix_helper(reply,
PLM_EXACT);
1563 result = pick_v6_prefix_helper(reply,
PLM_EXACT);
1564 if (result != ISC_R_SUCCESS) {
1565 result = pick_v6_prefix_helper(reply,
1572 result = pick_v6_prefix_helper(reply,
PLM_IGNORE);
1577 if (result == ISC_R_SUCCESS) {
1578 char tmp_buf[INET6_ADDRSTRLEN];
1581 inet_ntop(AF_INET6, &(reply->lease->addr),
1582 tmp_buf,
sizeof(tmp_buf)),
1583 (
unsigned)(reply->lease->plen));
1584 return (ISC_R_SUCCESS);
1591 log_debug(
"Unable to pick client prefix: no prefixes available");
1592 return ISC_R_NORESOURCES;
1619 pick_v6_prefix_helper(
struct reply_state *reply,
int prefix_mode) {
1623 unsigned int attempts;
1624 struct iasubopt **pref = &reply->lease;
1626 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
1633 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
1635 (eval_prefix_mode(p->
units, reply->preflen,
1636 prefix_mode) == 1) &&
1638 &reply->ia->iaid_duid,
1639 cur_time + 120) == ISC_R_SUCCESS)) {
1640 return (ISC_R_SUCCESS);
1645 return ISC_R_NORESOURCES;
1663 eval_prefix_mode(
int len,
int preflen,
int prefix_mode) {
1665 switch (prefix_mode) {
1667 use_it = (len == preflen);
1671 use_it = (len >= preflen);
1675 use_it = (len <= preflen);
1726 static struct reply_state reply;
1731 memset(&packet_oro, 0,
sizeof(packet_oro));
1734 if (shared_network_from_packet6(&reply.shared,
1735 packet) != ISC_R_SUCCESS)
1744 if (!start_reply(
packet, client_id, server_id, &reply.opt_state,
1760 log_error(
"lease_to_client: error evaluating ORO.");
1771 seek_shared_host(&reply.host, reply.shared);
1778 for (; oc != NULL ; oc = oc->
next) {
1779 isc_result_t status;
1782 reply.client_resources = 0;
1783 reply.resources_included = ISC_FALSE;
1785 status = reply_process_ia_na(&reply, oc);
1791 if ((status != ISC_R_SUCCESS) &&
1792 (status != ISC_R_NORESOURCES))
1796 for (; oc != NULL ; oc = oc->
next) {
1797 isc_result_t status;
1800 reply.client_resources = 0;
1801 reply.resources_included = ISC_FALSE;
1803 status = reply_process_ia_ta(&reply, oc);
1809 if ((status != ISC_R_SUCCESS) &&
1810 (status != ISC_R_NORESOURCES))
1817 for (; oc != NULL ; oc = oc->
next) {
1818 isc_result_t status;
1821 reply.client_resources = 0;
1822 reply.resources_included = ISC_FALSE;
1824 status = reply_process_ia_pd(&reply, oc);
1830 if ((status != ISC_R_SUCCESS) &&
1831 (status != ISC_R_NORESOURCES))
1839 if ((reply.ia_count == 0) && (reply.pd_count == 0)) {
1840 if (reply.packet->dhcpv6_msg_type !=
1850 reply.packet->options,
1856 for (i = reply.packet->class_count; i > 0; i--) {
1859 reply.packet->options,
1862 reply.packet->classes[i - 1]->group,
1863 reply.shared->group, NULL);
1867 if (reply.host != NULL)
1870 reply.packet->options,
1874 reply.shared->group, NULL);
1909 reply.cursor +=
store_options6((
char *)reply.buf.data + reply.cursor,
1910 sizeof(reply.buf) - reply.cursor,
1911 reply.opt_state, reply.packet,
1912 required_opts_solicit,
1916 reply_ret->
len = reply.cursor;
1917 reply_ret->
buffer = NULL;
1921 memcpy(reply_ret->
buffer->
data, reply.buf.data, reply.cursor);
1929 if (reply.shared != NULL)
1930 shared_network_dereference(&reply.shared,
MDL);
1931 if (reply.host != NULL)
1932 host_dereference(&reply.host,
MDL);
1933 if (reply.opt_state != NULL)
1935 if (reply.packet != NULL)
1937 if (reply.client_id.data != NULL)
1939 if (packet_oro.buffer != NULL)
1941 reply.renew = reply.rebind = reply.min_prefer = reply.min_valid = 0;
1949 reply_process_ia_na(
struct reply_state *reply,
struct option_cache *ia) {
1950 isc_result_t status = ISC_R_SUCCESS;
1959 memset(&ia_data, 0,
sizeof(ia_data));
1966 if ((reply->cursor +
IA_NA_OFFSET + 4) >
sizeof(reply->buf)) {
1967 log_error(
"reply_process_ia_na: Reply too long for IA.");
1968 return ISC_R_NOSPACE;
1973 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
1975 log_error(
"reply_process_ia_na: error evaluating ia");
1976 status = ISC_R_FAILURE;
1982 reply->renew =
getULong(ia_data.data + 4);
1983 reply->rebind =
getULong(ia_data.data + 8);
1986 if (
ia_allocate(&reply->ia, iaid, (
char *)reply->client_id.data,
1987 reply->client_id.len,
MDL) != ISC_R_SUCCESS) {
1988 log_error(
"reply_process_ia_na: no memory for ia.");
1989 status = ISC_R_NOMEMORY;
1996 (
unsigned char *)reply->ia->iaid_duid.data,
1997 reply->ia->iaid_duid.len,
MDL);
2004 status = ISC_R_NOMEMORY;
2009 if ((reply->host != NULL) && (reply->host->fixed_addr != NULL)) {
2010 struct iaddr tmp_addr;
2014 reply->host->fixed_addr,
MDL)) {
2015 log_error(
"reply_process_ia_na: unable to evaluate " 2017 status = ISC_R_FAILURE;
2021 if (reply->fixed.len < 16) {
2022 log_error(
"reply_process_ia_na: invalid fixed address.");
2029 memcpy(tmp_addr.iabuf, reply->fixed.data, 16);
2032 tmp_addr,
MDL) == 0)
2035 reply->static_lease = ISC_TRUE;
2037 reply->static_lease = ISC_FALSE;
2045 ia_cursor = reply->cursor;
2052 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
2056 putULong(reply->buf.data + reply->cursor, iaid);
2060 putULong(reply->buf.data + reply->cursor, reply->renew);
2064 putULong(reply->buf.data + reply->cursor, reply->rebind);
2078 reply->client_valid = reply->client_prefer = 0;
2079 for (; oc != NULL ; oc = oc->
next) {
2080 status = reply_process_addr(reply, oc);
2088 if (status == ISC_R_CANCELED)
2091 if ((status != ISC_R_SUCCESS) &&
2092 (status != ISC_R_ADDRINUSE) &&
2093 (status != ISC_R_ADDRNOTAVAIL))
2103 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
2104 status = find_client_address(reply);
2106 if (status == ISC_R_NORESOURCES) {
2107 switch (reply->packet->dhcpv6_msg_type) {
2130 "memory for option state " 2132 status = ISC_R_NOMEMORY;
2137 "No addresses available " 2138 "for this interface.",
2140 log_error(
"reply_process_ia_na: Unable " 2141 "to set NoAddrsAvail status " 2143 status = ISC_R_FAILURE;
2147 status = ISC_R_SUCCESS;
2167 if (reply->resources_included)
2168 status = ISC_R_SUCCESS;
2175 if (status != ISC_R_SUCCESS)
2179 reply->cursor +=
store_options6((
char *)reply->buf.data + reply->cursor,
2180 sizeof(reply->buf) - reply->cursor,
2181 reply->reply_ia, reply->packet,
2182 required_opts_IA, NULL);
2185 putUShort(reply->buf.data + ia_cursor + 2,
2186 reply->cursor - (ia_cursor + 4));
2189 set_reply_tee_times(reply, ia_cursor);
2195 if (status == ISC_R_CANCELED)
2202 if (reply->static_lease) {
2203 char tmp_addr[INET6_ADDRSTRLEN];
2204 log_info(
"%s NA: address %s to client with duid %s iaid = %d " 2207 inet_ntop(AF_INET6, reply->fixed.data, tmp_addr,
2210 reply->client_id.data, 60),
2214 (reply->on_star.on_commit != NULL)) {
2216 reply->packet->options,
2217 reply->opt_state, NULL,
2218 reply->on_star.on_commit, NULL);
2220 (&reply->on_star.on_commit,
MDL);
2228 if (reply->ia->num_iasubopt != 0) {
2231 char tmp_addr[INET6_ADDRSTRLEN];
2233 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2234 tmp = reply->ia->iasubopt[i];
2236 log_info(
"%s NA: address %s to client with duid %s " 2237 "iaid = %d valid for %u seconds",
2239 inet_ntop(AF_INET6, &tmp->
addr,
2240 tmp_addr,
sizeof(tmp_addr)),
2242 reply->client_id.data, 60),
2256 if ((reply->ia->num_iasubopt != 0) &&
2262 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2263 tmp = reply->ia->iasubopt[i];
2265 if (tmp->
ia != NULL)
2277 reply->packet->options,
2286 #if defined (NSUPDATE) 2295 reply->packet->options,
2300 tmp, NULL, reply->opt_state);
2304 check_pool6_threshold(reply, tmp);
2308 if (reply->old_ia != NULL) {
2309 ia_id = &reply->old_ia->iaid_duid;
2311 (
unsigned char *)ia_id->
data,
2318 ia_id = &reply->ia->iaid_duid;
2320 ia_id->
len, reply->ia,
MDL);
2324 schedule_lease_timeout_reply(reply);
2328 if (packet_ia != NULL)
2330 if (reply->reply_ia != NULL)
2332 if (ia_data.data != NULL)
2334 if (
data.data != NULL)
2336 if (reply->ia != NULL)
2338 if (reply->old_ia != NULL)
2340 if (reply->lease != NULL)
2342 if (reply->fixed.data != NULL)
2344 if (reply->subnet != NULL)
2345 subnet_dereference(&reply->subnet,
MDL);
2346 if (reply->on_star.on_expiry != NULL)
2348 (&reply->on_star.on_expiry,
MDL);
2349 if (reply->on_star.on_release != NULL)
2351 (&reply->on_star.on_release,
MDL);
2358 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
2368 reply_process_addr(
struct reply_state *reply,
struct option_cache *addr) {
2369 u_int32_t pref_life, valid_life;
2373 struct iaddr tmp_addr;
2376 isc_result_t status = ISC_R_SUCCESS;
2379 memset(&iaaddr, 0,
sizeof(iaaddr));
2387 if ((reply->cursor + 28) >
sizeof(reply->buf)) {
2388 log_error(
"reply_process_addr: Out of room for address.");
2389 return ISC_R_NOSPACE;
2397 log_error(
"reply_process_addr: error evaluating IAADDR.");
2398 status = ISC_R_FAILURE;
2403 pref_life =
getULong(iaaddr.data + 16);
2404 valid_life =
getULong(iaaddr.data + 20);
2406 if ((reply->client_valid == 0) ||
2407 (reply->client_valid > valid_life))
2408 reply->client_valid = valid_life;
2410 if ((reply->client_prefer == 0) ||
2411 (reply->client_prefer > pref_life))
2412 reply->client_prefer = pref_life;
2419 memset(tmp_addr.iabuf, 0, 16);
2420 if (!memcmp(iaaddr.data, tmp_addr.iabuf, 16)) {
2426 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2431 for (
subnet = reply->shared->subnets ;
subnet != NULL ;
2464 log_error(
"reply_process_addr: No memory for " 2465 "option state wipe.");
2466 status = ISC_R_NOMEMORY;
2472 "Address not for use on this " 2473 "link.", reply->reply_ia)) {
2474 log_error(
"reply_process_addr: Failure " 2475 "setting status code.");
2476 status = ISC_R_FAILURE;
2481 status = ISC_R_CANCELED;
2493 if ((reply->packet->dhcpv6_msg_type !=
DHCPV6_RENEW) &&
2495 log_error(
"It is impossible to lease a client that is " 2496 "not sending a solicit, request, renew, or " 2498 status = ISC_R_FAILURE;
2502 reply->send_prefer = reply->send_valid = 0;
2507 if (!address_is_owned(reply, &tmp_addr)) {
2518 status = reply_process_try_addr(reply, &tmp_addr);
2525 if ((status != ISC_R_SUCCESS) &&
2526 (status != ISC_R_ADDRINUSE) &&
2527 (status != ISC_R_ADDRNOTAVAIL))
2535 if (reply->lease == NULL) {
2536 if (reply->packet->dhcpv6_msg_type ==
2538 reply->send_prefer = 0;
2539 reply->send_valid = 0;
2556 }
else if (reply->packet->dhcpv6_msg_type ==
DHCPV6_RENEW) {
2560 log_error(
"reply_process_addr: No memory for " 2561 "option state wipe.");
2562 status = ISC_R_NOMEMORY;
2568 "Address not bound to this " 2569 "interface.", reply->reply_ia)) {
2570 log_error(
"reply_process_addr: Unable to " 2571 "attach status code.");
2572 status = ISC_R_FAILURE;
2577 status = ISC_R_CANCELED;
2580 log_error(
"It is impossible to lease a client that is " 2581 "not sending a solicit, request, renew, or " 2583 status = ISC_R_FAILURE;
2588 if (reply->static_lease) {
2589 if (reply->host == NULL)
2593 group = reply->subnet->group;
2595 if (reply->lease == NULL)
2598 scope = &reply->lease->scope;
2599 group = reply->lease->ipv6_pool->ipv6_pond->group;
2608 if (reply->client_resources != 0) {
2621 reply->packet->options,
2625 log_error(
"reply_process_addr: unable to " 2626 "evaluate addrs-per-ia value.");
2627 status = ISC_R_FAILURE;
2639 if (reply->client_resources >= limit)
2643 status = reply_process_is_addressed(reply, scope,
group);
2644 if (status != ISC_R_SUCCESS)
2648 status = reply_process_send_addr(reply, &tmp_addr);
2651 if (iaaddr.data != NULL)
2653 if (
data.data != NULL)
2655 if (reply->lease != NULL)
2667 static isc_boolean_t
2668 address_is_owned(
struct reply_state *reply,
struct iaddr *addr) {
2675 if (reply->static_lease) {
2676 if (reply->fixed.data == NULL)
2679 if (memcmp(addr->
iabuf, reply->fixed.data, 16) == 0)
2685 if ((reply->old_ia == NULL) || (reply->old_ia->num_iasubopt == 0))
2688 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
2691 tmp = reply->old_ia->iasubopt[i];
2693 if (memcmp(
addr->iabuf, &tmp->
addr, 16) == 0) {
2718 reply_process_ia_ta(
struct reply_state *reply,
struct option_cache *
ia) {
2719 isc_result_t status = ISC_R_SUCCESS;
2726 u_int32_t pref_life, valid_life;
2727 struct iaddr tmp_addr;
2731 memset(&ia_data, 0,
sizeof(ia_data));
2732 memset(&data, 0,
sizeof(data));
2733 memset(&iaaddr, 0,
sizeof(iaaddr));
2736 if ((reply->cursor +
IA_TA_OFFSET + 4) >
sizeof(reply->buf)) {
2737 log_error(
"reply_process_ia_ta: Reply too long for IA.");
2738 return ISC_R_NOSPACE;
2743 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
2745 log_error(
"reply_process_ia_ta: error evaluating ia");
2746 status = ISC_R_FAILURE;
2754 if (
ia_allocate(&reply->ia, iaid, (
char *)reply->client_id.data,
2755 reply->client_id.len,
MDL) != ISC_R_SUCCESS) {
2756 log_error(
"reply_process_ia_ta: no memory for ia.");
2757 status = ISC_R_NOMEMORY;
2764 (
unsigned char *)reply->ia->iaid_duid.data,
2765 reply->ia->iaid_duid.len,
MDL);
2772 status = ISC_R_NOMEMORY;
2779 reply->static_lease = ISC_FALSE;
2787 ia_cursor = reply->cursor;
2794 putUShort(reply->buf.data + reply->cursor, 0x04u);
2798 putULong(reply->buf.data + reply->cursor, iaid);
2806 reply->client_valid = reply->client_prefer = 0;
2808 for (; oc != NULL; oc = oc->
next) {
2809 memset(&iaaddr, 0,
sizeof(iaaddr));
2812 reply->packet->options, NULL,
2816 "evaluating IAADDR.");
2817 status = ISC_R_FAILURE;
2821 pref_life =
getULong(iaaddr.data + 16);
2822 valid_life =
getULong(iaaddr.data + 20);
2824 if ((reply->client_valid == 0) ||
2825 (reply->client_valid > valid_life))
2826 reply->client_valid = valid_life;
2828 if ((reply->client_prefer == 0) ||
2829 (reply->client_prefer > pref_life))
2830 reply->client_prefer = pref_life;
2833 if (status == ISC_R_CANCELED)
2837 memcpy(tmp_addr.iabuf, iaaddr.data, 16);
2838 if (!temporary_is_available(reply, &tmp_addr))
2840 status = reply_process_is_addressed(reply,
2841 &reply->lease->scope,
2842 reply->lease->ipv6_pool->ipv6_pond->group);
2843 if (status != ISC_R_SUCCESS)
2845 status = reply_process_send_addr(reply, &tmp_addr);
2846 if (status != ISC_R_SUCCESS)
2848 if (reply->lease != NULL)
2856 status = ISC_R_NOMEMORY;
2859 status = ISC_R_CANCELED;
2860 reply->client_resources = 0;
2861 reply->resources_included = ISC_FALSE;
2862 if (reply->lease != NULL)
2870 if (reply->client_resources != 0)
2872 status = find_client_temporaries(reply);
2873 if (status == ISC_R_NORESOURCES) {
2874 switch (reply->packet->dhcpv6_msg_type) {
2895 "memory for option state wipe.");
2896 status = ISC_R_NOMEMORY;
2901 "No addresses available " 2902 "for this interface.",
2904 log_error(
"reply_process_ia_ta: Unable " 2905 "to set NoAddrsAvail status code.");
2906 status = ISC_R_FAILURE;
2910 status = ISC_R_SUCCESS;
2919 if (reply->resources_included)
2920 status = ISC_R_SUCCESS;
2925 }
else if (status != ISC_R_SUCCESS)
2929 reply->cursor +=
store_options6((
char *)reply->buf.data + reply->cursor,
2930 sizeof(reply->buf) - reply->cursor,
2931 reply->reply_ia, reply->packet,
2932 required_opts_IA, NULL);
2935 putUShort(reply->buf.data + ia_cursor + 2,
2936 reply->cursor - (ia_cursor + 4));
2942 if (status == ISC_R_CANCELED)
2948 if (reply->ia->num_iasubopt != 0) {
2951 char tmp_addr[INET6_ADDRSTRLEN];
2953 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2954 tmp = reply->ia->iasubopt[i];
2956 log_info(
"%s TA: address %s to client with duid %s " 2957 "iaid = %d valid for %u seconds",
2959 inet_ntop(AF_INET6, &tmp->
addr,
2960 tmp_addr,
sizeof(tmp_addr)),
2962 reply->client_id.data, 60),
2976 if ((reply->ia->num_iasubopt != 0) &&
2982 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
2983 tmp = reply->ia->iasubopt[i];
2985 if (tmp->
ia != NULL)
2997 reply->packet->options,
3006 #if defined (NSUPDATE) 3015 reply->packet->options,
3020 tmp, NULL, reply->opt_state);
3024 check_pool6_threshold(reply, tmp);
3028 if (reply->old_ia != NULL) {
3029 ia_id = &reply->old_ia->iaid_duid;
3031 (
unsigned char *)ia_id->
data,
3038 ia_id = &reply->ia->iaid_duid;
3040 ia_id->
len, reply->ia,
MDL);
3044 schedule_lease_timeout_reply(reply);
3048 if (packet_ia != NULL)
3050 if (iaaddr.data != NULL)
3052 if (reply->reply_ia != NULL)
3054 if (ia_data.data != NULL)
3056 if (
data.data != NULL)
3058 if (reply->ia != NULL)
3060 if (reply->old_ia != NULL)
3062 if (reply->lease != NULL)
3070 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
3076 static isc_boolean_t
3077 temporary_is_available(
struct reply_state *reply,
struct iaddr *addr) {
3078 struct in6_addr tmp_addr;
3084 memcpy(&tmp_addr, addr->
iabuf,
sizeof(tmp_addr));
3090 if (IN6_IS_ADDR_UNSPECIFIED(&tmp_addr))
3096 for (
subnet = reply->shared->subnets ;
subnet != NULL ;
3110 if (address_is_owned(reply, addr))
3116 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3139 if (iasubopt_allocate(&reply->lease,
MDL) != ISC_R_SUCCESS)
3141 reply->lease->addr = tmp_addr;
3142 reply->lease->plen = 0;
3154 find_client_temporaries(
struct reply_state *reply) {
3158 isc_result_t status = ISC_R_NORESOURCES;;
3159 unsigned int attempts;
3160 struct iaddr send_addr;
3166 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3170 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
3180 log_debug(
"Unable to get client addresses: " 3181 "no IPv6 pools on this shared network");
3182 return ISC_R_NORESOURCES;
3192 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3199 for (i = 0; (p = pond->
ipv6_pools[i]) != NULL; i++) {
3208 &reply->client_id,
cur_time + 120);
3209 if (status != ISC_R_SUCCESS) {
3210 log_debug(
"Unable to get a temporary address.");
3214 status = reply_process_is_addressed(reply,
3215 &reply->lease->scope,
3217 if (status != ISC_R_SUCCESS) {
3221 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3222 status = reply_process_send_addr(reply, &send_addr);
3223 if (status != ISC_R_SUCCESS) {
3235 if (reply->lease != NULL) {
3246 reply_process_try_addr(
struct reply_state *reply,
struct iaddr *addr) {
3247 isc_result_t status = ISC_R_ADDRNOTAVAIL;
3253 if ((reply == NULL) || (reply->shared == NULL) ||
3254 (addr == NULL) || (reply->lease != NULL))
3261 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3265 for (i = 0; ; i++) {
3267 if ((
pool == NULL) ||
3277 return (ISC_R_ADDRNOTAVAIL);
3280 memset(&data_addr, 0,
sizeof(data_addr));
3281 data_addr.len = addr->
len;
3282 data_addr.data = addr->
iabuf;
3295 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
3306 status = try_client_v6_address(&reply->lease,
pool,
3308 if (status == ISC_R_SUCCESS)
3312 if (status == ISC_R_SUCCESS)
3327 find_client_address(
struct reply_state *reply) {
3328 struct iaddr send_addr;
3329 isc_result_t status = ISC_R_NORESOURCES;
3335 if (reply->static_lease) {
3336 if (reply->host == NULL)
3340 memcpy(send_addr.iabuf, reply->fixed.data, 16);
3343 group = reply->subnet->group;
3347 if (reply->old_ia != NULL) {
3348 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
3352 lease = reply->old_ia->iasubopt[i];
3353 candidate_shared =
lease->ipv6_pool->shared_network;
3354 pond =
lease->ipv6_pool->ipv6_pond;
3361 if ((candidate_shared != reply->shared) ||
3371 best_lease = lease_compare(
lease, best_lease);
3379 status = pick_v6_address(reply);
3380 }
else if (best_lease != NULL) {
3382 status = ISC_R_SUCCESS;
3386 if ((status == ISC_R_NORESOURCES) && (best_lease != NULL)) {
3388 log_error(
"Best match for DUID %s is an abandoned address," 3389 " This may be a result of multiple clients attempting" 3390 " to use this DUID",
3392 reply->client_id.data, 60));
3397 if (status != ISC_R_SUCCESS)
3400 if (reply->lease == NULL)
3407 scope = &reply->lease->scope;
3408 group = reply->lease->ipv6_pool->ipv6_pond->group;
3411 memcpy(send_addr.iabuf, &reply->lease->addr, 16);
3414 status = reply_process_is_addressed(reply, scope,
group);
3415 if (status != ISC_R_SUCCESS)
3418 status = reply_process_send_addr(reply, &send_addr);
3427 reply_process_is_addressed(
struct reply_state *reply,
3430 isc_result_t status = ISC_R_SUCCESS;
3438 memset(&data, 0,
sizeof(data));
3447 on_star = &reply->lease->on_star;
3459 reply->packet->options, tmp_options,
3462 if (tmp_options != NULL) {
3472 reply->packet->options, reply->opt_state,
3476 for (i = reply->packet->class_count; i > 0; i--) {
3478 reply->packet->options,
3479 reply->opt_state, scope,
3480 reply->packet->classes[i - 1]->group,
3489 if (reply->host != NULL)
3491 reply->packet->options,
3492 reply->opt_state, scope,
3493 reply->host->group,
group,
3497 if (reply->client_valid == 0)
3500 reply->send_valid = reply->client_valid;
3506 reply->packet->options,
3510 log_error(
"reply_process_is_addressed: unable to " 3511 "evaluate default lease time");
3512 status = ISC_R_FAILURE;
3516 reply->send_valid =
getULong(data.data);
3526 time_t test_time =
cur_time + reply->send_valid;
3531 if (reply->client_prefer == 0)
3532 reply->send_prefer = reply->send_valid;
3534 reply->send_prefer = reply->client_prefer;
3536 if ((reply->send_prefer >= reply->send_valid) &&
3538 reply->send_prefer = (reply->send_valid / 2) +
3539 (reply->send_valid / 8);
3545 reply->packet->options,
3549 log_error(
"reply_process_is_addressed: unable to " 3550 "evaluate preferred lease time");
3551 status = ISC_R_FAILURE;
3555 reply->send_prefer =
getULong(data.data);
3560 if (reply->min_prefer > reply->send_prefer)
3561 reply->min_prefer = reply->send_prefer;
3563 if (reply->min_valid > reply->send_valid)
3564 reply->min_valid = reply->send_valid;
3576 if (reply->host != NULL)
3578 reply->client_id->len);
3582 if (reply->lease != NULL) {
3584 reply->lease->prefer = reply->send_prefer;
3585 reply->lease->valid = reply->send_valid;
3593 reply->lease->soft_lifetime_end_time =
MAX_TIME;
3595 reply->lease->soft_lifetime_end_time =
3602 if (status != ISC_R_SUCCESS) {
3603 log_fatal(
"reply_process_is_addressed: Unable to " 3604 "attach lease to new IA: %s",
3605 isc_result_totext(status));
3611 if (reply->lease->ia == NULL) {
3618 reply->packet->options, reply->reply_ia,
3622 for (i = reply->packet->class_count; i > 0; i--) {
3624 reply->packet->options,
3625 reply->reply_ia, scope,
3626 reply->packet->classes[i - 1]->group,
3634 if (reply->host != NULL)
3636 reply->packet->options,
3637 reply->reply_ia, scope,
3638 reply->host->group,
group, NULL);
3641 if (data.data != NULL)
3644 if (status == ISC_R_SUCCESS)
3645 reply->client_resources++;
3652 reply_process_send_addr(
struct reply_state *reply,
struct iaddr *addr) {
3653 isc_result_t status = ISC_R_SUCCESS;
3661 log_error(
"reply_process_send_addr: out of memory" 3662 "allocating new IAADDR buffer.");
3663 status = ISC_R_NOMEMORY;
3668 memcpy(
data.buffer->data, addr->
iabuf, 16);
3675 log_error(
"reply_process_send_addr: unable " 3676 "to save IAADDR option");
3677 status = ISC_R_FAILURE;
3681 reply->resources_included = ISC_TRUE;
3684 if (
data.data != NULL)
3698 switch(alpha->
state) {
3700 switch(beta->
state) {
3721 switch (beta->
state) {
3747 switch (beta->
state) {
3769 log_fatal(
"Triple impossible condition at %s:%d.",
MDL);
3777 reply_process_ia_pd(
struct reply_state *reply,
struct option_cache *
ia) {
3778 isc_result_t status = ISC_R_SUCCESS;
3787 memset(&ia_data, 0,
sizeof(ia_data));
3794 if ((reply->cursor +
IA_PD_OFFSET + 4) >
sizeof(reply->buf)) {
3795 log_error(
"reply_process_ia_pd: Reply too long for IA.");
3796 return ISC_R_NOSPACE;
3801 if (!get_encapsulated_IA_state(&packet_ia, &ia_data, reply->packet,
3803 log_error(
"reply_process_ia_pd: error evaluating ia");
3804 status = ISC_R_FAILURE;
3810 reply->renew =
getULong(ia_data.data + 4);
3811 reply->rebind =
getULong(ia_data.data + 8);
3814 if (
ia_allocate(&reply->ia, iaid, (
char *)reply->client_id.data,
3815 reply->client_id.len,
MDL) != ISC_R_SUCCESS) {
3816 log_error(
"reply_process_ia_pd: no memory for ia.");
3817 status = ISC_R_NOMEMORY;
3824 (
unsigned char *)reply->ia->iaid_duid.data,
3825 reply->ia->iaid_duid.len,
MDL);
3832 status = ISC_R_NOMEMORY;
3837 reply->static_prefixes = 0;
3838 if ((reply->host != NULL) && (reply->host->fixed_prefix != NULL)) {
3841 for (fp = reply->host->fixed_prefix; fp != NULL;
3843 reply->static_prefixes += 1;
3853 ia_cursor = reply->cursor;
3860 putUShort(reply->buf.data + reply->cursor, 0x0Cu);
3864 putULong(reply->buf.data + reply->cursor, iaid);
3868 putULong(reply->buf.data + reply->cursor, reply->renew);
3872 putULong(reply->buf.data + reply->cursor, reply->rebind);
3880 reply->client_valid = reply->client_prefer = 0;
3881 reply->preflen = -1;
3882 for (; oc != NULL ; oc = oc->
next) {
3883 status = reply_process_prefix(reply, oc);
3891 if (status == ISC_R_CANCELED)
3894 if ((status != ISC_R_SUCCESS) &&
3895 (status != ISC_R_ADDRINUSE) &&
3896 (status != ISC_R_ADDRNOTAVAIL))
3906 if ((status != ISC_R_CANCELED) && (reply->client_resources == 0)) {
3907 status = find_client_prefix(reply);
3909 if (status == ISC_R_NORESOURCES) {
3910 switch (reply->packet->dhcpv6_msg_type) {
3925 "memory for option state " 3927 status = ISC_R_NOMEMORY;
3932 "No prefixes available " 3933 "for this interface.",
3937 "NoPrefixAvail status " 3939 status = ISC_R_FAILURE;
3943 status = ISC_R_SUCCESS;
3947 if (reply->resources_included)
3948 status = ISC_R_SUCCESS;
3955 if (status != ISC_R_SUCCESS)
3959 reply->cursor +=
store_options6((
char *)reply->buf.data + reply->cursor,
3960 sizeof(reply->buf) - reply->cursor,
3961 reply->reply_ia, reply->packet,
3962 required_opts_IA_PD, NULL);
3965 putUShort(reply->buf.data + ia_cursor + 2,
3966 reply->cursor - (ia_cursor + 4));
3969 set_reply_tee_times(reply, ia_cursor);
3975 if (status == ISC_R_CANCELED)
3982 if (reply->static_prefixes != 0) {
3983 char tmp_addr[INET6_ADDRSTRLEN];
3984 log_info(
"%s PD: address %s/%d to client with duid %s " 3987 inet_ntop(AF_INET6, reply->fixed_pref.lo_addr.iabuf,
3988 tmp_addr,
sizeof(tmp_addr)),
3989 reply->fixed_pref.bits,
3991 reply->client_id.data, 60),
3994 (reply->on_star.on_commit != NULL)) {
3996 reply->packet->options,
3998 NULL, reply->on_star.on_commit,
4001 (&reply->on_star.on_commit,
MDL);
4009 if (reply->ia->num_iasubopt != 0) {
4012 char tmp_addr[INET6_ADDRSTRLEN];
4014 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
4015 tmp = reply->ia->iasubopt[i];
4017 log_info(
"%s PD: address %s/%d to client with duid %s" 4018 " iaid = %d valid for %u seconds",
4020 inet_ntop(AF_INET6, &tmp->
addr,
4021 tmp_addr,
sizeof(tmp_addr)),
4024 reply->client_id.data, 60),
4038 (reply->ia->num_iasubopt != 0)) {
4043 for (i = 0 ; i < reply->ia->num_iasubopt ; i++) {
4044 tmp = reply->ia->iasubopt[i];
4046 if (tmp->
ia != NULL)
4058 reply->packet->options,
4068 check_pool6_threshold(reply, tmp);
4072 if (reply->old_ia != NULL) {
4073 ia_id = &reply->old_ia->iaid_duid;
4075 (
unsigned char *)ia_id->
data,
4082 ia_id = &reply->ia->iaid_duid;
4084 ia_id->
len, reply->ia,
MDL);
4088 schedule_lease_timeout_reply(reply);
4092 if (packet_ia != NULL)
4094 if (reply->reply_ia != NULL)
4096 if (ia_data.data != NULL)
4098 if (
data.data != NULL)
4100 if (reply->ia != NULL)
4102 if (reply->old_ia != NULL)
4104 if (reply->lease != NULL)
4106 if (reply->on_star.on_expiry != NULL)
4108 (&reply->on_star.on_expiry,
MDL);
4109 if (reply->on_star.on_release != NULL)
4111 (&reply->on_star.on_release,
MDL);
4118 return((status == ISC_R_CANCELED) ? ISC_R_SUCCESS : status);
4140 static struct group *
4141 find_group_by_prefix(
struct reply_state *reply) {
4145 struct iaddr tmp_addr;
4150 reply->fixed_pref.lo_addr,
MDL) != 0) {
4159 memset(&fixed_addr, 0,
sizeof(fixed_addr));
4161 if ((reply->host->fixed_addr != NULL) &&
4164 reply->host->fixed_addr,
MDL))) {
4165 if (fixed_addr.len >= 16) {
4167 memcpy(tmp_addr.iabuf, fixed_addr.data, 16);
4169 tmp_addr,
MDL) != 0) {
4188 reply_process_prefix(
struct reply_state *reply,
struct option_cache *pref) {
4189 u_int32_t pref_life, valid_life;
4194 isc_result_t status = ISC_R_SUCCESS;
4198 memset(&iapref, 0,
sizeof(iapref));
4199 memset(&data, 0,
sizeof(data));
4206 if ((reply->cursor + 29) >
sizeof(reply->buf)) {
4207 log_error(
"reply_process_prefix: Out of room for prefix.");
4208 return ISC_R_NOSPACE;
4216 log_error(
"reply_process_prefix: error evaluating IAPREFIX.");
4217 status = ISC_R_FAILURE;
4226 valid_life =
getULong(iapref.data + 4);
4228 if ((reply->client_valid == 0) ||
4229 (reply->client_valid > valid_life))
4230 reply->client_valid = valid_life;
4232 if ((reply->client_prefer == 0) ||
4233 (reply->client_prefer > pref_life))
4234 reply->client_prefer = pref_life;
4240 tmp_pref.lo_addr.len = 16;
4241 memset(tmp_pref.lo_addr.iabuf, 0, 16);
4242 if ((iapref.data[8] == 0) &&
4243 (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0)) {
4252 tmp_pref.bits = (
int) iapref.data[8];
4253 if (reply->preflen < 0) {
4255 reply->preflen = tmp_pref.bits;
4257 if (memcmp(iapref.data + 9, tmp_pref.lo_addr.iabuf, 16) == 0) {
4261 memcpy(tmp_pref.lo_addr.iabuf, iapref.data + 9, 16);
4264 if (!prefix_is_owned(reply, &tmp_pref)) {
4269 status = reply_process_try_prefix(reply, &tmp_pref);
4272 if ((status != ISC_R_SUCCESS) &&
4273 (status != ISC_R_ADDRINUSE) &&
4274 (status != ISC_R_ADDRNOTAVAIL))
4277 if (reply->lease == NULL) {
4278 if (reply->packet->dhcpv6_msg_type ==
4280 reply->send_prefer = 0;
4281 reply->send_valid = 0;
4300 }
else if (reply->packet->dhcpv6_msg_type ==
DHCPV6_RENEW) {
4304 log_error(
"reply_process_prefix: No memory " 4305 "for option state wipe.");
4306 status = ISC_R_NOMEMORY;
4312 "Prefix not bound to this " 4313 "interface.", reply->reply_ia)) {
4314 log_error(
"reply_process_prefix: Unable to " 4315 "attach status code.");
4316 status = ISC_R_FAILURE;
4321 status = ISC_R_CANCELED;
4324 log_error(
"It is impossible to lease a client that is " 4325 "not sending a solicit, request, renew, or " 4327 status = ISC_R_FAILURE;
4332 if (reply->static_prefixes > 0) {
4333 if (reply->host == NULL)
4339 memcpy(&reply->fixed_pref, &tmp_pref,
sizeof(tmp_pref));
4342 group = find_group_by_prefix(reply);
4344 if (reply->lease == NULL)
4347 scope = &reply->lease->scope;
4348 group = reply->lease->ipv6_pool->ipv6_pond->group;
4357 if (reply->client_resources != 0) {
4370 reply->packet->options,
4374 log_error(
"reply_process_prefix: unable to " 4375 "evaluate prefs-per-ia value.");
4376 status = ISC_R_FAILURE;
4388 if (reply->client_resources >= limit)
4392 status = reply_process_is_prefixed(reply, scope,
group);
4393 if (status != ISC_R_SUCCESS)
4397 status = reply_process_send_prefix(reply, &tmp_pref);
4400 if (iapref.data != NULL)
4402 if (data.data != NULL)
4404 if (reply->lease != NULL)
4416 static isc_boolean_t
4417 prefix_is_owned(
struct reply_state *reply,
struct iaddrcidrnet *pref) {
4425 if (reply->static_prefixes > 0) {
4426 for (l = reply->host->fixed_prefix; l != NULL; l = l->
next) {
4435 if ((reply->old_ia == NULL) ||
4436 (reply->old_ia->num_iasubopt == 0))
4439 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4442 tmp = reply->old_ia->iasubopt[i];
4444 if ((pref->
bits == (
int) tmp->
plen) &&
4470 reply_process_try_prefix(
struct reply_state *reply,
4472 isc_result_t status = ISC_R_ADDRNOTAVAIL;
4478 if ((reply == NULL) || (reply->shared == NULL) ||
4479 (pref == NULL) || (reply->lease != NULL))
4486 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
4500 return (ISC_R_ADDRNOTAVAIL);
4503 memset(&data_pref, 0,
sizeof(data_pref));
4506 log_error(
"reply_process_try_prefix: out of memory.");
4507 return (ISC_R_NOMEMORY);
4509 data_pref.data = data_pref.buffer->data;
4510 data_pref.buffer->data[0] = (u_int8_t) pref->
bits;
4511 memcpy(data_pref.buffer->data + 1, pref->
lo_addr.
iabuf, 16);
4521 for (pond = reply->shared->ipv6_pond; pond != NULL; pond = pond->
next) {
4533 status = try_client_v6_prefix(&reply->lease,
pool,
4537 if ( (status == ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
4540 if ( (status == ISC_R_SUCCESS) || (status == ISC_R_ADDRINUSE) )
4554 find_client_prefix(
struct reply_state *reply) {
4556 isc_result_t status = ISC_R_NORESOURCES;
4557 struct iasubopt *prefix, *best_prefix = NULL;
4562 if (reply->static_prefixes > 0) {
4565 if (reply->host == NULL)
4568 for (l = reply->host->fixed_prefix; l != NULL; l = l->
next) {
4577 l = reply->host->fixed_prefix;
4579 memcpy(&send_pref, &l->
cidrnet,
sizeof(send_pref));
4584 memcpy(&reply->fixed_pref, &l->
cidrnet,
sizeof(send_pref));
4587 group = find_group_by_prefix(reply);
4592 if (reply->old_ia != NULL) {
4593 for (i = 0 ; i < reply->old_ia->num_iasubopt ; i++) {
4597 prefix = reply->old_ia->iasubopt[i];
4606 if (((candidate_shared != NULL) &&
4607 (candidate_shared != reply->shared)) ||
4621 best_prefix = prefix_compare(reply, prefix,
4630 status = pick_v6_prefix(reply);
4631 }
else if (best_prefix != NULL) {
4633 status = ISC_R_SUCCESS;
4637 if ((status == ISC_R_NORESOURCES) && (best_prefix != NULL)) {
4639 log_error(
"Reclaiming abandoned prefixes is not yet " 4640 "supported. Treating this as an out of space " 4646 if (status != ISC_R_SUCCESS)
4649 if (reply->lease == NULL)
4652 scope = &reply->lease->scope;
4653 group = reply->lease->ipv6_pool->ipv6_pond->group;
4655 send_pref.lo_addr.len = 16;
4656 memcpy(send_pref.lo_addr.iabuf, &reply->lease->addr, 16);
4657 send_pref.bits = (
int) reply->lease->plen;
4660 status = reply_process_is_prefixed(reply, scope,
group);
4661 if (status != ISC_R_SUCCESS)
4664 status = reply_process_send_prefix(reply, &send_pref);
4673 reply_process_is_prefixed(
struct reply_state *reply,
4676 isc_result_t status = ISC_R_SUCCESS;
4684 memset(&data, 0,
sizeof(data));
4693 on_star = &reply->lease->on_star;
4705 reply->packet->options, tmp_options,
4708 if (tmp_options != NULL) {
4718 reply->packet->options, reply->opt_state,
4722 for (i = reply->packet->class_count; i > 0; i--) {
4724 reply->packet->options,
4725 reply->opt_state, scope,
4726 reply->packet->classes[i - 1]->group,
4735 if (reply->host != NULL)
4737 reply->packet->options,
4738 reply->opt_state, scope,
4739 reply->host->group,
group,
4743 if (reply->client_valid == 0)
4746 reply->send_valid = reply->client_valid;
4752 reply->packet->options,
4756 log_error(
"reply_process_is_prefixed: unable to " 4757 "evaluate default prefix time");
4758 status = ISC_R_FAILURE;
4762 reply->send_valid =
getULong(data.data);
4772 time_t test_time =
cur_time + reply->send_valid;
4777 if (reply->client_prefer == 0)
4778 reply->send_prefer = reply->send_valid;
4780 reply->send_prefer = reply->client_prefer;
4782 if ((reply->send_prefer >= reply->send_valid) &&
4784 reply->send_prefer = (reply->send_valid / 2) +
4785 (reply->send_valid / 8);
4791 reply->packet->options,
4795 log_error(
"reply_process_is_prefixed: unable to " 4796 "evaluate preferred prefix time");
4797 status = ISC_R_FAILURE;
4801 reply->send_prefer =
getULong(data.data);
4806 if (reply->min_prefer > reply->send_prefer)
4807 reply->min_prefer = reply->send_prefer;
4809 if (reply->min_valid > reply->send_valid)
4810 reply->min_valid = reply->send_valid;
4813 if (reply->lease != NULL) {
4815 reply->lease->prefer = reply->send_prefer;
4816 reply->lease->valid = reply->send_valid;
4824 reply->lease->soft_lifetime_end_time =
MAX_TIME;
4826 reply->lease->soft_lifetime_end_time =
4833 if (status != ISC_R_SUCCESS) {
4834 log_fatal(
"reply_process_is_prefixed: Unable to " 4835 "attach prefix to new IA_PD: %s",
4836 isc_result_totext(status));
4842 if (reply->lease->ia == NULL) {
4849 reply->packet->options, reply->reply_ia,
4853 for (i = reply->packet->class_count; i > 0; i--) {
4855 reply->packet->options,
4856 reply->reply_ia, scope,
4857 reply->packet->classes[i - 1]->group,
4865 if (reply->host != NULL)
4867 reply->packet->options,
4868 reply->reply_ia, scope,
4869 reply->host->group,
group, NULL);
4872 if (data.data != NULL)
4875 if (status == ISC_R_SUCCESS)
4876 reply->client_resources++;
4883 reply_process_send_prefix(
struct reply_state *reply,
4885 isc_result_t status = ISC_R_SUCCESS;
4893 log_error(
"reply_process_send_prefix: out of memory" 4894 "allocating new IAPREFIX buffer.");
4895 status = ISC_R_NOMEMORY;
4908 log_error(
"reply_process_send_prefix: unable " 4909 "to save IAPREFIX option");
4910 status = ISC_R_FAILURE;
4914 reply->resources_included = ISC_TRUE;
4917 if (
data.data != NULL)
4925 prefix_compare(
struct reply_state *reply,
4932 if (reply->preflen >= 0) {
4933 if ((alpha->
plen == reply->preflen) &&
4934 (beta->
plen != reply->preflen))
4936 if ((beta->
plen == reply->preflen) &&
4937 (alpha->
plen != reply->preflen))
4941 switch(alpha->
state) {
4943 switch(beta->
state) {
4964 switch (beta->
state) {
4990 switch (beta->
state) {
5012 log_fatal(
"Triple impossible condition at %s:%d.",
MDL);
5032 if (!valid_client_msg(
packet, &client_id)) {
5036 lease_to_client(reply_ret,
packet, &client_id, NULL);
5058 if (!valid_client_resp(
packet, &client_id, &server_id)) {
5065 is_unicast_option_defined(
packet) == ISC_FALSE) {
5066 unicast_reject(reply_ret,
packet, &client_id, &server_id);
5071 lease_to_client(reply_ret,
packet, &client_id, &server_id);
5087 const struct packet *chk_packet;
5088 const struct in6_addr *link_addr, *first_link_addr;
5089 struct iaddr tmp_addr;
5091 isc_result_t status;
5093 if ((shared == NULL) || (*shared != NULL) || (
packet == NULL))
5100 first_link_addr = NULL;
5102 while (chk_packet != NULL) {
5104 if (!IN6_IS_ADDR_UNSPECIFIED(link_addr) &&
5105 !IN6_IS_ADDR_LINKLOCAL(link_addr)) {
5106 first_link_addr = link_addr;
5117 if (first_link_addr != NULL) {
5118 tmp_addr.len =
sizeof(*first_link_addr);
5119 memcpy(tmp_addr.iabuf,
5120 first_link_addr,
sizeof(*first_link_addr));
5123 log_debug(
"No subnet found for link-address %s.",
5125 return ISC_R_NOTFOUND;
5127 status = shared_network_reference(shared,
5136 status = shared_network_reference(shared,
5140 log_info(
"[L2 Relay] No link address in relay packet " 5141 "assuming L2 relay and using receiving " 5151 log_error(
"No interface and no link address " 5152 "can't determine pool");
5182 struct data_string cli_enc_opt_data, iaaddr, client_id, packet_oro;
5184 struct iaddr cli_addr;
5186 isc_boolean_t inappropriate, has_addrs;
5187 char reply_data[65536];
5194 memset(&client_id, 0,
sizeof(client_id));
5195 if (!valid_client_msg(
packet, &client_id)) {
5204 if ((ia == NULL) && (ta == NULL))
5215 opt_state = cli_enc_opt_state = NULL;
5216 memset(&cli_enc_opt_data, 0,
sizeof(cli_enc_opt_data));
5217 memset(&iaaddr, 0,
sizeof(iaaddr));
5218 memset(&packet_oro, 0,
sizeof(packet_oro));
5225 if ((shared_network_from_packet6(&shared,
packet) != ISC_R_SUCCESS) ||
5237 has_addrs = inappropriate = ISC_FALSE;
5239 while(!inappropriate) {
5243 if ((pass ==
D6O_IA_NA) && (ia == NULL)) {
5253 !get_encapsulated_IA_state(&cli_enc_opt_state,
5257 !get_encapsulated_IA_state(&cli_enc_opt_state,
5266 for ( ; oc != NULL ; oc = oc->
next) {
5272 "error evaluating IAADDR.");
5278 memcpy(cli_addr.iabuf, iaaddr.data, 16);
5283 has_addrs = ISC_TRUE;
5302 inappropriate = ISC_TRUE;
5321 if (!start_reply(
packet, &client_id, NULL, &opt_state, reply)) {
5328 if (inappropriate) {
5330 "Some of the addresses are not on link.",
5336 "All addresses still on link.",
5346 sizeof(reply_data)-reply_ofs,
5348 required_opts, &packet_oro);
5353 reply_ret->
len = reply_ofs;
5354 reply_ret->
buffer = NULL;
5359 memcpy(reply_ret->
buffer->
data, reply, reply_ofs);
5363 if (cli_enc_opt_data.buffer != NULL)
5365 if (iaaddr.buffer != NULL)
5367 if (client_id.
buffer != NULL)
5369 if (packet_oro.buffer != NULL)
5373 if (cli_enc_opt_state != NULL)
5375 if (opt_state != NULL)
5394 if (!valid_client_resp(
packet, &client_id, &server_id)) {
5401 is_unicast_option_defined(
packet) == ISC_FALSE) {
5402 unicast_reject(reply,
packet, &client_id, &server_id);
5407 lease_to_client(reply,
packet, &client_id, &server_id);
5428 if (!valid_client_msg(
packet, &client_id)) {
5432 lease_to_client(reply,
packet, &client_id, NULL);
5438 ia_na_match_decline(
const struct data_string *client_id,
5442 char tmp_addr[INET6_ADDRSTRLEN];
5444 log_error(
"Client %s reports address %s is " 5445 "already in use by another host!",
5447 inet_ntop(AF_INET6, iaaddr->
data,
5448 tmp_addr,
sizeof(tmp_addr)));
5449 if (
lease != NULL) {
5457 ia_na_nomatch_decline(
const struct data_string *client_id,
5459 u_int32_t *ia_na_id,
5465 char tmp_addr[INET6_ADDRSTRLEN];
5469 log_info(
"Client %s declines address %s, which is not offered to it.",
5471 inet_ntop(AF_INET6, iaaddr->
data, tmp_addr,
sizeof(tmp_addr)));
5476 host_opt_state = NULL;
5478 log_error(
"ia_na_nomatch_decline: out of memory " 5479 "allocating option_state.");
5491 if (reply_len < (*reply_ofs + 16)) {
5493 "out of space for reply packet.");
5501 reply_len-(*reply_ofs)-16,
5503 required_opts_STATUS_CODE, NULL);
5513 putUShort((
unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
5515 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5517 putULong((
unsigned char *)reply_data+(*reply_ofs)+8, 0);
5518 putULong((
unsigned char *)reply_data+(*reply_ofs)+12, 0);
5523 *reply_ofs += (len + 16);
5534 const char *packet_type,
5535 void (*ia_na_match)(),
5536 void (*ia_na_nomatch)())
5548 char reply_data[65536];
5551 char status_msg[32];
5553 struct ia_xx *existing_ia_na;
5562 memset(&cli_enc_opt_data, 0,
sizeof(cli_enc_opt_data));
5563 cli_enc_opt_state = NULL;
5564 memset(&iaaddr, 0,
sizeof(iaaddr));
5565 memset(&fixed_addr, 0,
sizeof(fixed_addr));
5586 log_error(
"iterate_over_ia_na: no memory for option_state.");
5599 (
unsigned char *)server_duid.data,
5602 "error saving server identifier.");
5609 (
unsigned char *)client_id->
data,
5613 "error saving client identifier.");
5617 snprintf(status_msg,
sizeof(status_msg),
"%s received.", packet_type);
5626 sizeof(reply_data)-reply_ofs,
5628 required_opts, NULL);
5635 ia != NULL; ia = ia->
next) {
5637 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
5643 iaid =
getULong(cli_enc_opt_data.data);
5661 memset(&iaaddr, 0,
sizeof(iaaddr));
5666 "error evaluating IAADDR.");
5680 cli_enc_opt_state,
MDL)) {
5681 if (packet_host != NULL) {
5687 while (host != NULL) {
5695 "evaluating host address.");
5698 if ((iaaddr.
len >= 16) &&
5699 !memcmp(fixed_addr.data, iaaddr.
data, 16)) {
5713 (
char *)client_id->
data,
5715 MDL) != ISC_R_SUCCESS) {
5716 log_fatal(
"iterate_over_ia_na: no memory for " 5720 existing_ia_na = NULL;
5722 (
unsigned char *)key.data,
5729 struct in6_addr *in6_addr;
5732 in6_addr = &tmp->
addr;
5733 if (memcmp(in6_addr,
5734 iaaddr.
data, 16) == 0) {
5745 if ((host != NULL) || (
lease != NULL)) {
5746 ia_na_match(client_id, &iaaddr,
lease);
5748 ia_na_nomatch(client_id, &iaaddr,
5749 (u_int32_t *)cli_enc_opt_data.data,
5750 packet, reply_data, &reply_ofs,
5751 sizeof(reply_data));
5754 if (
lease != NULL) {
5766 reply_ret->
len = reply_ofs;
5767 reply_ret->
buffer = NULL;
5772 memcpy(reply_ret->
buffer->
data, reply, reply_ofs);
5775 if (
lease != NULL) {
5778 if (fixed_addr.buffer != NULL) {
5781 if (iaaddr.
buffer != NULL) {
5784 if (cli_enc_opt_state != NULL) {
5787 if (cli_enc_opt_data.buffer != NULL) {
5790 if (opt_state != NULL) {
5817 if (!valid_client_resp(
packet, &client_id, &server_id)) {
5824 is_unicast_option_defined(
packet) == ISC_FALSE) {
5825 unicast_reject(reply,
packet, &client_id, &server_id);
5835 iterate_over_ia_na(reply,
packet, &client_id, &server_id,
5836 "Decline", ia_na_match_decline,
5837 ia_na_nomatch_decline);
5846 ia_na_match_release(
const struct data_string *client_id,
5850 char tmp_addr[INET6_ADDRSTRLEN];
5852 log_info(
"Client %s releases address %s",
5854 inet_ntop(AF_INET6, iaaddr->
data, tmp_addr,
sizeof(tmp_addr)));
5855 if (
lease != NULL) {
5863 ia_na_nomatch_release(
const struct data_string *client_id,
5865 u_int32_t *ia_na_id,
5871 char tmp_addr[INET6_ADDRSTRLEN];
5875 log_info(
"Client %s releases address %s, which is not leased to it.",
5877 inet_ntop(AF_INET6, iaaddr->
data, tmp_addr,
sizeof(tmp_addr)));
5882 host_opt_state = NULL;
5884 log_error(
"ia_na_nomatch_release: out of memory " 5885 "allocating option_state.");
5890 "Release for non-leased address.",
5898 if (reply_len < (*reply_ofs + 16)) {
5900 "out of space for reply packet.");
5908 reply_len-(*reply_ofs)-16,
5910 required_opts_STATUS_CODE, NULL);
5920 putUShort((
unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
5922 memcpy(reply_data+(*reply_ofs)+4, ia_na_id, 4);
5924 putULong((
unsigned char *)reply_data+(*reply_ofs)+8, 0);
5925 putULong((
unsigned char *)reply_data+(*reply_ofs)+12, 0);
5930 *reply_ofs += (len + 16);
5937 ia_pd_match_release(
const struct data_string *client_id,
5941 char tmp_addr[INET6_ADDRSTRLEN];
5943 log_info(
"Client %s releases prefix %s/%u",
5945 inet_ntop(AF_INET6, iapref->
data + 9,
5946 tmp_addr,
sizeof(tmp_addr)),
5948 if (prefix != NULL) {
5956 ia_pd_nomatch_release(
const struct data_string *client_id,
5958 u_int32_t *ia_pd_id,
5964 char tmp_addr[INET6_ADDRSTRLEN];
5968 log_info(
"Client %s releases prefix %s/%u, which is not leased to it.",
5970 inet_ntop(AF_INET6, iapref->
data + 9,
5971 tmp_addr,
sizeof(tmp_addr)),
5977 host_opt_state = NULL;
5979 log_error(
"ia_pd_nomatch_release: out of memory " 5980 "allocating option_state.");
5985 "Release for non-leased prefix.",
5993 if (reply_len < (*reply_ofs + 16)) {
5995 "out of space for reply packet.");
6003 reply_len-(*reply_ofs)-16,
6005 required_opts_STATUS_CODE, NULL);
6015 putUShort((
unsigned char *)reply_data+(*reply_ofs)+2, len + 12);
6017 memcpy(reply_data+(*reply_ofs)+4, ia_pd_id, 4);
6019 putULong((
unsigned char *)reply_data+(*reply_ofs)+8, 0);
6020 putULong((
unsigned char *)reply_data+(*reply_ofs)+12, 0);
6025 *reply_ofs += (len + 16);
6036 const char *packet_type,
6037 void (*ia_pd_match)(),
6038 void (*ia_pd_nomatch)())
6051 char reply_data[65536];
6054 struct ia_xx *existing_ia_pd;
6062 memset(&reply_new, 0,
sizeof(reply_new));
6064 memset(&cli_enc_opt_data, 0,
sizeof(cli_enc_opt_data));
6065 cli_enc_opt_state = NULL;
6066 memset(&iaprefix, 0,
sizeof(iaprefix));
6072 reply_len =
sizeof(reply_data) - reply_ret->
len;
6086 log_error(
"iterate_over_ia_pd: no memory for option_state.");
6098 ia != NULL; ia = ia->
next) {
6100 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
6106 iaid =
getULong(cli_enc_opt_data.data);
6117 for (; oc != NULL; oc = oc->
next) {
6118 memset(&iaprefix, 0,
sizeof(iaprefix));
6123 "error evaluating IAPREFIX.");
6137 cli_enc_opt_state,
MDL)) {
6138 if (packet_host != NULL) {
6144 while (host != NULL) {
6153 if (memcmp(iaprefix.data + 9,
6158 if ((l != NULL) && (iaprefix.len >= 17))
6169 (
char *)client_id->
data,
6171 MDL) != ISC_R_SUCCESS) {
6172 log_fatal(
"iterate_over_ia_pd: no memory for " 6176 existing_ia_pd = NULL;
6178 (
unsigned char *)key.data,
6205 if ((host != NULL) || (prefix != NULL)) {
6206 ia_pd_match(client_id, &iaprefix, prefix);
6208 ia_pd_nomatch(client_id, &iaprefix,
6209 (u_int32_t *)cli_enc_opt_data.data,
6210 packet, reply_data, &reply_ofs,
6211 reply_len - reply_ofs);
6214 if (prefix != NULL) {
6229 reply_new.len = reply_ret->
len + reply_ofs;
6233 reply_new.data = reply_new.buffer->data;
6234 memcpy(reply_new.buffer->data,
6236 memcpy(reply_new.buffer->data + reply_ret->
len,
6237 reply_data, reply_ofs);
6243 if (prefix != NULL) {
6246 if (iaprefix.buffer != NULL) {
6249 if (cli_enc_opt_state != NULL) {
6252 if (cli_enc_opt_data.buffer != NULL) {
6255 if (opt_state != NULL) {
6272 if (!valid_client_resp(
packet, &client_id, &server_id)) {
6279 is_unicast_option_defined(
packet) == ISC_FALSE) {
6280 unicast_reject(reply,
packet, &client_id, &server_id);
6285 iterate_over_ia_na(reply,
packet, &client_id, &server_id,
6286 "Release", ia_na_match_release,
6287 ia_na_nomatch_release);
6292 iterate_over_ia_pd(reply,
packet, &client_id, &server_id,
6293 "Release", ia_pd_match_release,
6294 ia_pd_nomatch_release);
6314 if (!valid_client_info_req(
packet, &server_id)) {
6321 memset(&client_id, 0,
sizeof(client_id));
6332 lease_to_client(reply,
packet, &client_id,
6333 server_id.
data != NULL ? &server_id : NULL);
6338 if (client_id.
data != NULL) {
6358 struct packet *enc_packet;
6359 unsigned char msg_type;
6363 char link_addr[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6364 char peer_addr[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6367 static char reply_data[65536];
6375 memset(&a_opt, 0,
sizeof(a_opt));
6376 memset(&packet_ero, 0,
sizeof(packet_ero));
6377 memset(&enc_reply, 0,
sizeof(enc_reply));
6378 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
6387 link_addr,
sizeof(link_addr));
6389 peer_addr,
sizeof(peer_addr));
6390 log_info(
"Relay-forward from %s with link address=%s and " 6391 "peer address=%s missing Relay Message option.",
6399 log_error(
"dhcpv6_forw_relay: error evaluating " 6400 "relayed message.");
6406 log_error(
"dhcpv6_forw_relay: encapsulated packet too short.");
6417 "no memory for encapsulated packet.");
6424 "no memory for encapsulated packet's options.");
6449 enc_opt_data.
len - relaylen,
6461 "unsupported %s message type.",
6465 forw_dhcpv4_query(
packet);
6468 log_error(
"dhcpv6_relay_forw: unsupported %s message type.",
6484 enc_opt_data.
len - msglen,
6496 build_dhcpv6_reply(&enc_reply, enc_packet);
6502 if (enc_reply.data == NULL) {
6524 log_error(
"dhcpv6_relay_forw: no memory for option state.");
6538 log_error(
"dhcpv6_relay_forw: error evaluating " 6543 (
unsigned char *)a_opt.data,
6546 log_error(
"dhcpv6_relay_forw: error saving " 6557 (
unsigned char *)enc_reply.data,
6560 log_error(
"dhcpv6_relay_forw: error saving Relay MSG.");
6576 (packet_ero.len & 1)) {
6577 log_error(
"dhcpv6_relay_forw: error evaluating ERO.");
6582 for (i = 0; i < packet_ero.len; i += 2) {
6599 "evaluating option %u.", req);
6605 (
unsigned char *)a_opt.data,
6609 log_error(
"dhcpv6_relay_forw: error saving " 6618 sizeof(reply_data) - reply_ofs,
6620 required_opts_agent, &packet_ero);
6625 reply_ret->
len = reply_ofs;
6626 reply_ret->
buffer = NULL;
6631 memcpy(reply_ret->
buffer->
data, reply_data, reply_ofs);
6634 if (opt_state != NULL)
6636 if (a_opt.data != NULL) {
6639 if (packet_ero.data != NULL) {
6642 if (enc_reply.data != NULL) {
6645 if (enc_opt_data.
data != NULL) {
6648 if (enc_packet != NULL) {
6667 struct packet *enc_packet;
6668 unsigned char msg_type;
6672 char link_addr[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6673 char peer_addr[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
6676 static char reply_data[65536];
6684 memset(&a_opt, 0,
sizeof(a_opt));
6685 memset(&packet_ero, 0,
sizeof(packet_ero));
6686 memset(&enc_reply, 0,
sizeof(enc_reply));
6687 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
6696 link_addr,
sizeof(link_addr));
6698 peer_addr,
sizeof(peer_addr));
6699 log_info(
"Relay-forward from %s with link address=%s and " 6700 "peer address=%s missing Relay Message option.",
6707 log_error(
"dhcp4o6_relay_forw: error evaluating " 6708 "relayed message.");
6714 "encapsulated packet too short.");
6723 "no memory for encapsulated packet.");
6729 "no memory for encapsulated packet's options.");
6754 enc_opt_data.
len - relaylen,
6774 enc_opt_data.
len - msglen,
6781 log_error(
"dhcp4o6_relay_forw: unexpected message of type %d.",
6790 build_dhcpv6_reply(&enc_reply, enc_packet);
6796 if (enc_reply.data == NULL) {
6817 log_error(
"dhcp4o6_relay_forw: no memory for option state.");
6831 log_error(
"dhcp4o6_relay_forw: error evaluating " 6836 (
unsigned char *)a_opt.data,
6839 log_error(
"dhcp4o6_relay_forw: error saving " 6850 (
unsigned char *)enc_reply.data,
6853 log_error(
"dhcp4o6_relay_forw: error saving Relay MSG.");
6869 (packet_ero.len & 1)) {
6870 log_error(
"dhcp4o6_relay_forw: error evaluating ERO.");
6875 for (i = 0; i < packet_ero.len; i += 2) {
6892 "evaluating option %u.", req);
6898 (
unsigned char *)a_opt.data,
6902 log_error(
"dhcp4o6_relay_forw: error saving " 6911 sizeof(reply_data) - reply_ofs,
6913 required_opts_agent, &packet_ero);
6918 reply_ret->
len = reply_ofs;
6919 reply_ret->
buffer = NULL;
6924 memcpy(reply_ret->
buffer->
data, reply_data, reply_ofs);
6927 if (opt_state != NULL)
6929 if (a_opt.data != NULL) {
6932 if (packet_ero.data != NULL) {
6935 if (enc_reply.data != NULL) {
6938 if (enc_opt_data.
data != NULL) {
6941 if (enc_packet != NULL) {
6959 struct packet *enc_packet;
6962 static char response_data[65536];
6970 memset(&enc_response, 0,
sizeof(enc_response));
6971 memset(&enc_opt_data, 0,
sizeof(enc_opt_data));
6979 log_info(
"DHCPv4-query from %s missing DHCPv4 Message option.",
6986 log_error(
"dhcp4o6_dhcpv4_query: error evaluating " 6992 log_error(
"dhcp4o6_dhcpv4_query: DHCPv4 packet too short.");
7001 "no memory for encapsulated packet.");
7017 "discarding packet with bogus hlen.");
7023 log_error(
"dhcp4o6_dhcpv4_query: no memory for options.");
7043 memset(&dp, 0,
sizeof dp);
7069 if (enc_response.data == NULL) {
7086 log_error(
"dhcp4o6_dhcpv4_query: no memory for option state.");
7094 (
unsigned char *)enc_response.data,
7097 log_error(
"dhcp4o6_dhcpv4_query: error saving DHCPv4 MSG.");
7102 sizeof(response_data) - response_ofs,
7104 required_opts_4o6, NULL);
7109 reply_ret->
len = response_ofs;
7110 reply_ret->
buffer = NULL;
7112 log_fatal(
"dhcp4o6_dhcpv4_query: no memory to store reply.");
7115 memcpy(reply_ret->
buffer->
data, response_data, response_ofs);
7118 if (opt_state != NULL)
7120 if (enc_response.data != NULL) {
7123 if (enc_opt_data.
data != NULL) {
7126 if (enc_packet != NULL) {
7152 log_error(
"forw_dhcpv4_query: can't find initial message.");
7158 memset(&ds, 0,
sizeof(ds));
7161 "no memory for encapsulating packet.");
7164 ds.data = ds.buffer->data;
7169 memcpy(ds.buffer->data + 16,
7171 memcpy(ds.buffer->data + 32,
7176 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
7178 log_error(
"forw_dhcpv4_query: send(): %m");
7188 log_debug(
"Discarding %s from %s; message type not handled by server",
7195 memset(reply, 0,
sizeof(*reply));
7208 dhcpv6_solicit(reply,
packet);
7215 dhcpv6_request(reply,
packet);
7219 dhcpv6_confirm(reply,
packet);
7223 dhcpv6_renew(reply,
packet);
7227 dhcpv6_rebind(reply,
packet);
7234 dhcpv6_release(reply,
packet);
7238 dhcpv6_decline(reply,
packet);
7245 dhcpv6_information_request(reply,
packet);
7250 dhcp4o6_relay_forw(reply,
packet);
7253 dhcpv6_relay_forw(reply,
packet);
7269 forw_dhcpv4_query(
packet);
7271 dhcp4o6_dhcpv4_query(reply,
packet);
7283 log_info(
"Discarding unknown DHCPv6 message type %d " 7293 char tmp_addr[INET6_ADDRSTRLEN];
7296 memset(&s, 0,
sizeof(s));
7305 "Unknown message type %d from %s port %d",
7314 inet_ntop(AF_INET6, addr,
7315 tmp_addr,
sizeof(tmp_addr)));
7318 inet_ntop(AF_INET6, addr,
7319 tmp_addr,
sizeof(tmp_addr)));
7352 struct sockaddr_in6 to_addr;
7363 build_dhcpv6_reply(&reply,
packet);
7365 if (reply.
data != NULL) {
7369 memset(&to_addr, 0,
sizeof(to_addr));
7370 to_addr.sin6_family = AF_INET6;
7378 #if defined (REPLY_TO_SOURCE_PORT) 7390 sizeof(to_addr.sin6_addr));
7392 log_info(
"Sending %s to %s port %d",
7395 ntohs(to_addr.sin6_port));
7398 reply.
data, reply.
len, &to_addr);
7399 if (send_ret != reply.
len) {
7400 log_error(
"dhcpv6: send_packet6() sent %d of %d bytes",
7401 send_ret, reply.
len);
7419 static void recv_dhcpv4_query(
struct data_string *raw) {
7424 unsigned char msg_type;
7432 memset(name, 0,
sizeof(name));
7433 memcpy(name, raw->
data, 16);
7435 if (!strcmp(name,
ip->name))
7439 log_error(
"recv_dhcpv4_query: can't find interface %s.",
7453 "short packet from %s, len %d, dropped",
7463 log_error(
"recv_dhcpv4_query: no memory for packet.");
7468 log_error(
"recv_dhcpv4_query: no memory for options.");
7479 msg_type = raw->
data[32];
7496 raw->
len - 32 - relaylen,
7516 raw->
len - 32 - msglen,
7524 log_error(
"recv_dhcpv4_query: unexpected message of type %d.",
7538 memset(&ds, 0,
sizeof(ds));
7545 "Unknown message type %d from %s",
7551 char tmp_addr[INET6_ADDRSTRLEN];
7556 inet_ntop(AF_INET6, addr,
7557 tmp_addr,
sizeof(tmp_addr)));
7560 inet_ntop(AF_INET6, addr,
7561 tmp_addr,
sizeof(tmp_addr)));
7575 build_dhcpv6_reply(&reply,
packet);
7579 if (reply.
data == NULL)
7585 len = reply.
len + 32;
7586 memset(&ds, 0,
sizeof(ds));
7588 log_error(
"recv_dhcpv4_query: no memory.");
7591 ds.data = ds.buffer->data;
7594 memcpy(ds.buffer->data, name, 16);
7595 memcpy(ds.buffer->data + 16,
iaddr.
iabuf, 16);
7596 memcpy(ds.buffer->data + 32, reply.
data, reply.
len);
7597 cc = send(dhcp4o6_fd, ds.data, ds.len, 0);
7599 log_error(
"recv_dhcpv4_query: send(): %m");
7614 host_reference(&hold, *hp,
MDL);
7615 host_dereference(hp,
MDL);
7617 while (seek != NULL) {
7620 else if (fixed_matches_shared(seek, shared))
7626 if ((seek == NULL) && (nofixed != NULL))
7630 host_reference(hp, seek,
MDL);
7633 static isc_boolean_t
7637 isc_boolean_t matched;
7643 memset(&addr, 0,
sizeof(addr));
7648 if (addr.len < 16) {
7654 memcpy(fixed.iabuf, addr.data, 16);
7656 matched = ISC_FALSE;
7692 struct reply_state reply;
7693 memset(&reply, 0x0,
sizeof(
struct reply_state));
7696 if (shared_network_from_packet6(&reply.shared,
packet)
7698 log_error(
"unicast_reject: could not locate client.");
7706 if (start_reply(
packet, client_id, server_id, &reply.opt_state,
7707 &reply.buf.reply)) {
7710 "Unicast not allowed by server.",
7712 log_error(
"unicast_reject: Unable to set status code.");
7722 unicast_reject_opts,
7726 reply_ret->
len = reply.cursor;
7727 reply_ret->
buffer = NULL;
7729 reply.cursor,
MDL)) {
7731 "No memory to store Reply.");
7742 if (reply.shared != NULL)
7743 shared_network_dereference(&reply.shared,
MDL);
7744 if (reply.opt_state != NULL)
7746 if (reply.packet != NULL)
7748 if (reply.client_id.
data != NULL)
7772 isc_boolean_t is_defined = ISC_FALSE;
7779 "No memory for option state.");
7784 if (((shared_network_from_requested_addr(&shared,
packet)
7785 != ISC_R_SUCCESS) &&
7786 (shared_network_from_packet6(&shared,
packet) != ISC_R_SUCCESS))
7787 || (shared == NULL)) {
7791 "cannot attribute packet to a network.");
7802 is_defined = (oc != NULL ? ISC_TRUE : ISC_FALSE);
7803 log_debug(
"is_unicast_option_defined: option found : %d", is_defined);
7805 if (shared != NULL) {
7806 shared_network_dereference(&shared,
MDL);
7809 if (opt_state != NULL) {
7813 return (is_defined);
7832 shared_network_from_requested_addr (
struct shared_network **shared,
7836 isc_result_t status = ISC_R_FAILURE;
7845 != ISC_R_SUCCESS)) {
7847 log_debug(
"share_network_from_request_addr: nothing to match");
7848 return (ISC_R_FAILURE);
7852 log_debug(
"shared_network_from_requested_addr:" 7855 status = shared_network_reference(shared,
7858 log_debug(
"shared_network_from_requested_addr:" 7859 " found shared network %s for address %s.",
7860 ((*shared)->name ? (*shared)->name :
"unnamed"),
7865 return (ISC_R_FAILURE);
7887 get_first_ia_addr_val (
struct packet*
packet,
int addr_type,
7893 int addr_opt_offset;
7895 int addr_opt_data_len;
7898 isc_result_t status = ISC_R_FAILURE;
7902 switch (addr_type) {
7906 addr_opt_data_len = 24;
7912 addr_opt_data_len = 24;
7918 addr_opt_data_len = 25;
7923 log_error (
"get_first_ia_addr_val: invalid opt type %d",
7925 return (ISC_R_FAILURE);
7930 ia != NULL && oc == NULL; ia = ia->
next) {
7931 if (!get_encapsulated_IA_state(&cli_enc_opt_state,
7933 packet, ia, addr_opt_offset)) {
7935 " couldn't unroll enclosing option");
7936 return (ISC_R_FAILURE);
7952 memset(&iaddr_str, 0,
sizeof(iaddr_str));
7957 "error evaluating IA_XX option.");
7959 if (iaddr_str.len != addr_opt_data_len) {
7960 log_error(
"shared_network_from_requested_addr:" 7961 " invalid length %d, expected %d",
7962 iaddr_str.len, addr_opt_data_len);
7966 iaddr_str.data + ip_addr_offset, 16);
7967 status = ISC_R_SUCCESS;
8009 set_reply_tee_times(
struct reply_state* reply,
unsigned ia_cursor)
8017 set_tee_times = (oc &&
8020 reply->packet->options,
8032 reply->packet->options,
8042 if (
data.data != NULL)
8044 }
else if (set_tee_times) {
8050 reply->renew = reply->min_prefer / 2;
8056 putULong(reply->buf.data + ia_cursor + 8, reply->renew);
8067 reply->packet->options,
8077 if (
data.data != NULL)
8079 }
else if (set_tee_times) {
8085 reply->rebind = (reply->min_prefer / 5) * 4;
8091 putULong(reply->buf.data + ia_cursor + 12, reply->rebind);
struct iaddrcidrnet cidrnet
#define DHCP_FIXED_NON_UDP
isc_result_t renew_lease6(struct ipv6_pool *pool, struct iasubopt *lease)
Renew a lease in the pool.
int find_grouped_subnet(struct subnet **, struct shared_network *, struct iaddr, const char *, int)
unsigned char peer_address[16]
struct binding_scope * global_scope
isc_result_t add_lease6(struct ipv6_pool *pool, struct iasubopt *lease, time_t valid_lifetime_end_time)
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)
int executable_statement_dereference(struct executable_statement **ptr, const char *file, int line)
struct shared_network * shared_network
const char * piaddr(const struct iaddr addr)
unsigned char dhcpv6_transaction_id[3]
isc_boolean_t server_duid_isset(void)
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
void dhcpv6_leasequery(struct data_string *, struct packet *)
isc_result_t ia_dereference(struct ia_xx **ia, const char *file, int line)
int data_string_sprintfa(struct data_string *ds, const char *fmt,...)
struct universe server_universe
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)
isc_boolean_t lease6_usable(struct iasubopt *lease)
Check if address is available to a lease.
int find_hosts_by_option(struct host_decl **, struct packet *, struct option_state *, const char *, int)
#define print_hex_1(len, data, limit)
#define DHCP_R_INVALIDARG
#define STATUS_NoAddrsAvail
const char * dhcpv6_type_names[]
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
#define DHCPV6_RECONFIGURE
#define SV_PREFER_LIFETIME
struct universe dhcp_universe
void data_string_forget(struct data_string *data, const char *file, int line)
struct option_cache * next
void bootp(struct packet *packet)
struct shared_network * shared_network
struct option_cache * fixed_addr
struct group * root_group
void delete_option(struct universe *universe, struct option_state *options, int code)
int log_error(const char *,...) __attribute__((__format__(__printf__
struct binding_scope * scope
struct ipv6_pond * ipv6_pond
void copy_server_duid(struct data_string *ds, const char *file, int line)
#define DHO_DHCP_REBINDING_TIME
#define DHCPV6_DHCPV4_QUERY
struct permit * prohibit_list
struct option_state * options
unsigned char dhcpv6_hop_count
unsigned char link_address[16]
unsigned char dhcpv6_msg_type
isc_boolean_t lease6_exists(const struct ipv6_pool *pool, const struct in6_addr *addr)
void log_fatal(const char *,...) __attribute__((__format__(__printf__
#define DHCPV6_RELAY_REPL
#define DHCPV6_LEASEQUERY
int parse_option_buffer(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *universe)
#define SV_LOG_THRESHOLD_HIGH
isc_result_t decline_lease6(struct ipv6_pool *pool, struct iasubopt *lease)
int find_hosts6(struct host_decl **host, struct packet *packet, const struct data_string *client_id, char *file, int line)
struct iaddr subnet_number(struct iaddr addr, struct iaddr mask)
int find_subnet(struct subnet **sp, struct iaddr addr, const char *file, int line)
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)
void change_host_uid(struct host_decl *host, const char *data, int len)
isc_result_t release_lease6(struct ipv6_pool *pool, struct iasubopt *lease)
void schedule_lease_timeout(struct ipv6_pool *pool)
int option_state_allocate(struct option_state **ptr, const char *file, int line)
time_t hard_lifetime_end_time
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)
#define STATUS_NoPrefixAvail
#define DHCPV6_DHCPV4_RESPONSE
int packet_reference(struct packet **ptr, struct packet *bp, const char *file, int line)
struct ipv6_pool * ipv6_pool
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
struct interface_info * interface
ssize_t send_packet6(struct interface_info *, const unsigned char *, size_t, struct sockaddr_in6 *)
void putULong(unsigned char *, u_int32_t)
struct iaddrcidrnetlist * next
#define DEFAULT_DEFAULT_LEASE_TIME
#define DHCPV6_RELAY_FORW
int save_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
u_int32_t getUShort(const unsigned char *)
void set_server_duid(struct data_string *new_duid)
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)
struct host_decl * n_ipaddr
#define SV_DHCPV6_SET_TEE_TIMES
struct hardware hw_address
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
#define print_hex_3(len, data, limit)
int permitted(struct packet *, struct permit *)
void set_server_duid_type(int type)
int int log_info(const char *,...) __attribute__((__format__(__printf__
struct ipv6_pool ** ipv6_pools
int packet6_len_okay(const char *packet, int len)
int parse_options(struct packet *packet)
struct interface_info * interfaces
unsigned char dhcp4o6_flags[3]
u_int32_t getULong(const unsigned char *)
struct shared_network * shared_network
int validate_packet(struct packet *packet)
int addr_eq(struct iaddr addr1, struct iaddr addr2)
isc_boolean_t ipv6_in_pool(const struct in6_addr *addr, const struct ipv6_pool *pool)
#define DHCPV6_LEASEQUERY_REPLY
isc_result_t get_client_id(struct packet *, struct data_string *)
#define DHCP4O6_QUERY_UNICAST
int store_options6(char *buf, int buflen, struct option_state *opt_state, struct packet *packet, const int *required_opts, struct data_string *oro)
int append_option_buffer(struct universe *universe, struct option_state *options, struct buffer *bp, unsigned char *buffer, unsigned length, unsigned code, int terminatep)
#define FIND_POND6_PERCENT(count, percent)
u_int32_t getUChar(const unsigned char *)
struct data_string * dhcp4o6_response
struct iaddrcidrnetlist * fixed_prefix
int option_state_dereference(struct option_state **ptr, const char *file, int line)
void dhcpv6(struct packet *)
int commit_leases_timed(void)
const int dhcpv6_type_name_max
isc_boolean_t is_cidr_mask_valid(const struct iaddr *addr, int bits)
isc_uint64_t low_threshold
struct interface_info * next
struct universe dhcpv6_universe
isc_boolean_t prefix6_exists(const struct ipv6_pool *pool, const struct in6_addr *pref, u_int8_t plen)
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)
#define print_hex_2(len, data, limit)
int packet_dereference(struct packet **ptr, const char *file, int line)
int ddns_updates(struct packet *, struct lease *, struct lease *, struct iasubopt *, struct iasubopt *, struct option_state *)
int packet_allocate(struct packet **ptr, const char *file, int line)
isc_result_t iasubopt_dereference(struct iasubopt **iasubopt, const char *file, int line)
#define SV_LOG_THRESHOLD_LOW
isc_uint64_t num_abandoned
isc_result_t set_server_duid_from_option(void)
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)
struct subnet * next_sibling
isc_result_t ia_add_iasubopt(struct ia_xx *ia, struct iasubopt *iasubopt, const char *file, int line)
unsigned char transaction_id[3]
time_t soft_lifetime_end_time
#define SV_DEFAULT_LEASE_TIME
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
#define REPLY_OPTIONS_INDEX
void dhcp(struct packet *packet)
struct iasubopt ** iasubopt
int write_ia(const struct ia_xx *)
#define DHO_DHCP_RENEWAL_TIME
struct in6_addr dhcpv6_peer_address
void putUShort(unsigned char *, u_int32_t)
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)
struct shared_network * shared_network
isc_result_t ia_reference(struct ia_xx **ia, struct ia_xx *src, const char *file, int line)
struct executable_statement * on_commit
#define SV_LIMIT_ADDRS_PER_IA
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
const unsigned char * data
#define DHO_DHCP_MESSAGE_TYPE
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)
isc_result_t generate_new_server_duid(void)
struct binding_scope * scope
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
struct permit * permit_list
#define D6O_RECONF_ACCEPT
#define DHCPV6_INFORMATION_REQUEST
struct in6_addr dhcpv6_link_address
unsigned char options[FLEXIBLE_ARRAY_MEMBER]
void classify_client(struct packet *)
#define SV_LIMIT_PREFS_PER_IA
unsigned char options[DHCP_MAX_OPTION_LEN]
#define STATUS_UseMulticast
struct packet * dhcpv6_container_packet
isc_result_t iasubopt_reference(struct iasubopt **iasubopt, struct iasubopt *src, const char *file, int line)