30struct sockaddr_in6 DHCPv6DestAddr;
36struct option *clientid_option = NULL;
37struct option *elapsed_option = NULL;
38struct option *ia_na_option = NULL;
39struct option *ia_ta_option = NULL;
40struct option *ia_pd_option = NULL;
41struct option *iaaddr_option = NULL;
42struct option *iaprefix_option = NULL;
43struct option *oro_option = NULL;
44struct option *irt_option = NULL;
52static void dhc6_ia_destroy(
struct dhc6_ia **src,
const char *
file,
int line);
53static isc_result_t dhc6_parse_ia_na(
struct dhc6_ia **pia,
57static isc_result_t dhc6_parse_ia_ta(
struct dhc6_ia **pia,
61static isc_result_t dhc6_parse_ia_pd(
struct dhc6_ia **pia,
65static isc_result_t dhc6_parse_addrs(
struct dhc6_addr **paddr,
68static isc_result_t dhc6_parse_prefixes(
struct dhc6_addr **ppref,
72 u_int16_t type,
const char *
id);
80void do_init6(
void *
input);
81void do_info_request6(
void *
input);
82void do_confirm6(
void *
input);
84static isc_result_t dhc6_create_iaid(
struct client_state *client,
90static isc_result_t dhc6_bare_ia_xx(
struct client_state *client,
94static isc_result_t dhc6_add_ia_na(
struct client_state *client,
100static isc_result_t dhc6_add_ia_ta(
struct client_state *client,
106static isc_result_t dhc6_add_ia_pd(
struct client_state *client,
114void do_select6(
void *
input);
115void do_refresh6(
void *
input);
116static void do_release6(
void *
input);
119static void do_decline6(
void *
input);
123void start_renew6(
void *
input);
124void start_rebind6(
void *
input);
125void do_depref(
void *
input);
126void do_expire(
void *
input);
127static void make_client6_options(
struct client_state *client,
130static void script_write_params6(
struct client_state *client,
133static void script_write_requested6(
struct client_state *client);
136static int check_timing6(
struct client_state *client, u_int8_t msg_type,
142static isc_result_t dhc6_check_status(isc_result_t rval,
148static isc_result_t dhc6_add_ia_na_decline(
struct client_state *client,
156extern int prefix_len_hint;
174 ent = getservbyname(
"dhcpv6-client",
"udp");
182 ent = getservbyname(
"dhcpv6-server",
"udp");
189 memset(&DHCPv6DestAddr, 0,
sizeof(DHCPv6DestAddr));
190 DHCPv6DestAddr.sin6_family = AF_INET6;
193 &DHCPv6DestAddr.sin6_addr) <= 0) {
198 if (!option_code_hash_lookup(&clientid_option,
200 log_fatal(
"Unable to find the CLIENTID option definition.");
203 if (!option_code_hash_lookup(&elapsed_option,
205 log_fatal(
"Unable to find the ELAPSED_TIME option definition.");
210 log_fatal(
"Unable to find the IA_NA option definition.");
215 log_fatal(
"Unable to find the IA_TA option definition.");
220 log_fatal(
"Unable to find the IA_PD option definition.");
223 if (!option_code_hash_lookup(&iaaddr_option,
dhcpv6_universe.code_hash,
225 log_fatal(
"Unable to find the IAADDR option definition.");
228 if (!option_code_hash_lookup(&iaprefix_option,
231 log_fatal(
"Unable to find the IAPREFIX option definition.");
236 log_fatal(
"Unable to find the ORO option definition.");
241 log_fatal(
"Unable to find the IRT option definition.");
286 split = (base - 1) / 10;
297 range = (split * 2) + 1;
317 client->
RT = client->
IRT + dhc6_rand(client->
IRT);
321#if (RAND_MAX >= 0x00ffffff)
323#elif (RAND_MAX >= 0x0000ffff)
324 xid = (random() << 16) ^ random();
325#elif (RAND_MAX >= 0x000000ff)
326 xid = (random() << 16) ^ (random() << 8) ^ random();
328# error "Random number generator of less than 8 bits not supported."
340 struct timeval elapsed, elapsed_plus_rt;
345 if (elapsed.tv_usec < 0) {
347 elapsed.tv_usec += 1000000;
351 elapsed.tv_sec += client->
RT / 100;
352 elapsed.tv_usec += (client->
RT % 100) * 10000;
353 if (elapsed.tv_usec >= 1000000) {
355 elapsed.tv_usec -= 1000000;
361 elapsed_plus_rt.tv_sec = elapsed.tv_sec;
362 elapsed_plus_rt.tv_usec = elapsed.tv_usec;
370 client->
RT += client->
RT + dhc6_rand(client->
RT);
380 if ((client->
MRT != 0) && (client->
RT > client->
MRT))
381 client->
RT = client->
MRT + dhc6_rand(client->
MRT);
387 if (client->
MRD == 0) {
393 elapsed.tv_sec += client->
RT / 100;
394 elapsed.tv_usec += (client->
RT % 100) * 10000;
395 if (elapsed.tv_usec >= 1000000) {
397 elapsed.tv_usec -= 1000000;
399 if (elapsed.tv_sec >= client->
MRD) {
406 client->
RT = client->
MRD - elapsed_plus_rt.tv_sec;
407 client->
RT = (client->
RT * 100) -
408 (elapsed_plus_rt.tv_usec / 10000);
423 memset(&sid, 0,
sizeof(sid));
424 memset(&cid, 0,
sizeof(cid));
427 log_error(
"Response without a server identifier received.");
436 log_error(
"Response without a client identifier.");
446 log_error(
"Local client identifier is missing!");
451 sid.len != cid.len ||
452 memcmp(sid.data, cid.data, sid.len)) {
453 log_error(
"Advertise with matching transaction ID, but "
454 "mismatching client id.");
459 if (sid.data != NULL)
461 if (cid.data != NULL)
474 struct dhc6_ia **insert_ia, *ia;
478 log_error(
"Out of memory for v6 lease structure.");
485 memcpy(
copy->dhcpv6_transaction_id,
lease->dhcpv6_transaction_id,
486 sizeof(
copy->dhcpv6_transaction_id));
490 insert_ia = &
copy->bindings;
491 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
492 *insert_ia = dhc6_dup_ia(ia,
file,
line);
494 if (*insert_ia == NULL) {
499 insert_ia = &(*insert_ia)->
next;
516 log_error(
"Out of memory for v6 duplicate IA structure.");
527 insert_addr = &
copy->addrs;
528 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
529 *insert_addr = dhc6_dup_addr(addr,
file,
line);
531 if (*insert_addr == NULL) {
536 insert_addr = &(*insert_addr)->
next;
595 log_error(
"Out of memory for v6 lease structure.");
602 memset(&ds, 0,
sizeof(ds));
610 log_error(
"Invalid length of DHCPv6 Preference option "
611 "(%d != 1)", ds.len);
616 lease->pref = ds.data[0];
618 (
unsigned)
lease->pref);
683 lease->server_id.len == 0) {
686 log_error(
"Invalid SERVERID option cache.");
692 lease->server_id.data, 52));
713 memset(&ds, 0,
sizeof(ds));
716 for ( ; oc != NULL ; oc = oc->
next) {
719 log_error(
"Out of memory allocating IA_NA structure.");
720 return ISC_R_NOMEMORY;
725 memcpy(ia->
iaid, ds.data, 4);
751 log_debug(
"RCV: | !-- INVALID renew/rebind "
752 "times, IA_NA discarded.");
764 "IA_NA option state.");
767 return ISC_R_NOMEMORY;
800 if ((ia->
addrs == NULL) ||
803 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
807 "no addrs, IA_NA discarded.");
808 dhc6_ia_destroy(&ia,
MDL);
817 log_error(
"Invalid IA_NA option cache.");
820 return ISC_R_UNEXPECTED;
838 memset(&ds, 0,
sizeof(ds));
841 for ( ; oc != NULL ; oc = oc->
next) {
844 log_error(
"Out of memory allocating IA_TA structure.");
845 return ISC_R_NOMEMORY;
850 memcpy(ia->
iaid, ds.data, 4);
866 "IA_TA option state.");
869 return ISC_R_NOMEMORY;
902 if ((ia->
addrs == NULL) ||
905 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
909 "no addrs, IA_TA discarded.");
910 dhc6_ia_destroy(&ia,
MDL);
919 log_error(
"Invalid IA_TA option cache.");
922 return ISC_R_UNEXPECTED;
940 memset(&ds, 0,
sizeof(ds));
943 for ( ; oc != NULL ; oc = oc->
next) {
946 log_error(
"Out of memory allocating IA_PD structure.");
947 return ISC_R_NOMEMORY;
952 memcpy(ia->
iaid, ds.data, 4);
974 log_debug(
"RCV: | !-- INVALID renew/rebind "
975 "times, IA_PD discarded.");
987 "IA_PD option state.");
990 return ISC_R_NOMEMORY;
1008 result = dhc6_parse_prefixes(&ia->
addrs,
1024 if ((ia->
addrs == NULL) ||
1027 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
1031 "no prefix, IA_PD discarded.");
1032 dhc6_ia_destroy(&ia,
MDL);
1036 while (*pia != NULL)
1037 pia = &(*pia)->
next;
1041 log_error(
"Invalid IA_PD option cache.");
1044 return ISC_R_UNEXPECTED;
1063 memset(&ds, 0,
sizeof(ds));
1066 for ( ; oc != NULL ; oc = oc->
next) {
1070 "address structure.");
1071 return ISC_R_NOMEMORY;
1085 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1087 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1095 log_debug(
"RCV: | | | !-- INVALID lifetimes, "
1096 "IAADDR discarded. Check your "
1097 "server configuration.");
1111 "IAADDR option state.");
1114 return ISC_R_NOMEMORY;
1145 " issue, IAADDR discarded.");
1154 paddr = &addr->
next;
1156 log_error(
"Invalid IAADDR option cache.");
1159 return ISC_R_UNEXPECTED;
1177 memset(&ds, 0,
sizeof(ds));
1180 for ( ; oc != NULL ; oc = oc->
next) {
1184 "prefix structure.");
1185 return ISC_R_NOMEMORY;
1198 log_debug(
"RCV: | | X-- IAPREFIX %s/%d",
1200 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1202 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1206 if ((pfx->
plen < 4) || (pfx->
plen > 128)) {
1207 log_debug(
"RCV: | | | !-- INVALID prefix "
1208 "length, IAPREFIX discarded. "
1209 "Check your server configuration.");
1219 log_debug(
"RCV: | | | !-- INVALID lifetimes, "
1220 "IAPREFIX discarded. Check your "
1221 "server configuration.");
1235 "IAPREFIX option state.");
1238 return ISC_R_NOMEMORY;
1269 " issue IAPREFIX discarded.");
1280 log_error(
"Invalid IAPREFIX option cache.");
1283 return ISC_R_UNEXPECTED;
1298 if (src == NULL || *src == NULL) {
1299 log_error(
"Attempt to destroy null lease.");
1305 for (ia =
lease->bindings ; ia != NULL ; ia = nia) {
1311 if (
lease->options != NULL)
1328 if (src == NULL || *src == NULL) {
1329 log_error(
"Attempt to destroy null IA.");
1334 for (addr = ia->
addrs ; addr != NULL ; addr = naddr) {
1357 while (*head != NULL) {
1358 if ((*head)->server_id.len == new->server_id.len &&
1359 memcmp((*head)->server_id.data, new->server_id.data,
1360 new->server_id.len) == 0) {
1361 new->next = (*head)->next;
1366 head= &(*head)->
next;
1395#ifdef USE_ORIGINAL_CLIENT_LEASE_WEIGHTS
1396#define SCORE_BINDING 50
1397#define SCORE_ADDRESS 100
1399#define SCORE_BINDING 10000
1400#define SCORE_ADDRESS 100
1403#define SCORE_OPTION 1
1405#define SCORE_MIN (SCORE_BINDING + SCORE_ADDRESS)
1416 return lease->score;
1418 lease->score = SCORE_OPTION;
1424 for (i = 0 ; req[i] != NULL ; i++) {
1426 req[i]->code) == NULL) {
1428 return lease->score;
1436 for (i = 0 ; req[i] != NULL ; i++) {
1438 req[i]->code) != NULL)
1439 lease->score += SCORE_OPTION;
1443 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
1444 lease->score += SCORE_BINDING;
1446 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1447 lease->score += SCORE_ADDRESS;
1451 return lease->score;
1463 log_debug(
"PRC: Soliciting for leases (INIT).");
1476 dhc6_retrans_init(client);
1484 if (client->
RT <= client->
IRT)
1485 client->
RT = client->
IRT + (client->
IRT - client->
RT);
1487 if (client->
RT <= client->
IRT)
1488 client->
RT = client->
IRT + 1;
1497 tv.tv_sec =
cur_tv.tv_sec;
1498 tv.tv_usec =
cur_tv.tv_usec;
1500 if (tv.tv_usec >= 1000000) {
1502 tv.tv_usec -= 1000000;
1519 log_debug(
"PRC: Requesting information (INIT).");
1532 dhc6_retrans_init(client);
1541 tv.tv_sec =
cur_tv.tv_sec;
1542 tv.tv_usec =
cur_tv.tv_usec;
1544 if (tv.tv_usec >= 1000000) {
1546 tv.tv_usec -= 1000000;
1548 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1566 !active_prefix(client) ||
1574 log_debug(
"PRC: Confirming active lease (INIT-REBOOT).");
1583 dhc6_retrans_init(client);
1592 tv.tv_sec =
cur_tv.tv_sec;
1593 tv.tv_usec =
cur_tv.tv_usec;
1595 if (tv.tv_usec >= 1000000) {
1597 tv.tv_usec -= 1000000;
1613 add_timeout(&tv, do_refresh6, client, NULL, NULL);
1615 add_timeout(&tv, do_confirm6, client, NULL, NULL);
1622#define CHK_TIM_SUCCESS 0
1623#define CHK_TIM_MRC_EXCEEDED 1
1624#define CHK_TIM_MRD_EXCEEDED 2
1625#define CHK_TIM_ALLOC_FAILURE 3
1628check_timing6 (
struct client_state *client, u_int8_t msg_type,
1632 struct timeval elapsed;
1640 }
else if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
1641 log_info(
"Max retransmission count exceeded.");
1642 return(CHK_TIM_MRC_EXCEEDED);
1648 if (elapsed.tv_usec < 0) {
1649 elapsed.tv_sec -= 1;
1650 elapsed.tv_usec += 1000000;
1654 if ((client->
MRD != 0) && (elapsed.tv_sec >= client->
MRD)) {
1655 log_info(
"Max retransmission duration exceeded.");
1656 return(CHK_TIM_MRD_EXCEEDED);
1659 memset(ds, 0,
sizeof(*ds));
1661 log_error(
"Unable to allocate memory for %s.", msg_str);
1662 return(CHK_TIM_ALLOC_FAILURE);
1672 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1673 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1676 client->
elapsed = elapsed.tv_sec * 100;
1677 client->
elapsed += elapsed.tv_usec / 10000;
1681 log_debug(
"XMT: Forming %s, 0 ms elapsed.", msg_str);
1683 log_debug(
"XMT: Forming %s, %u0 ms elapsed.", msg_str,
1690 return(CHK_TIM_SUCCESS);
1712 int start_idx, copy_len;
1714 memset(ia, 0,
sizeof(*ia));
1716 return (ISC_R_NOMEMORY);
1771 struct option *type_option;
1776 type_string =
"IA_NA";
1777 type_option = ia_na_option;
1781 type_string =
"IA_TA";
1782 type_option = ia_ta_option;
1786 type_string =
"IA_PD";
1787 type_option = ia_pd_option;
1789 if (prefix_len_hint > 0) {
1795 return (ISC_R_FAILURE);
1798 for (i = 0; wanted != 0; i++) {
1799 rval = dhc6_create_iaid(client, &ia, i, len);
1801 log_error(
"Unable to allocate memory for %s.",
1828 log_debug(
"XMT: | X-- Request renew in +%u",
1830 log_debug(
"XMT: | X-- Request rebind in +%u",
1834 if (ia_type ==
D6O_IA_PD && prefix_len_hint > 0) {
1842 log_debug(
"XMT: | | X-- Request prefix ::/%u.",
1861do_init6(
void *
input)
1884 switch(check_timing6(client,
DHCPV6_SOLICIT,
"Solicit", NULL, &ds)) {
1885 case CHK_TIM_MRC_EXCEEDED:
1886 case CHK_TIM_ALLOC_FAILURE:
1888 case CHK_TIM_MRD_EXCEEDED:
1895 if (stopping_finished())
1920 if (dhc6_create_iaid(client, &ia, i, 12) !=
ISC_R_SUCCESS) {
1921 log_error(
"Unable to allocate memory for IA_NA.");
1933 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1934 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1944 memset(&addr, 0,
sizeof(addr));
1945 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1946 old_addr = old_addr->
next) {
1950 "Ignoring. (%s:%d)",
1963 addr.data = addr.buffer->data;
1966 memcpy(addr.buffer->data,
1972 putULong(addr.buffer->data + 16, t1);
1973 putULong(addr.buffer->data + 20, t2);
1975 log_debug(
"XMT: | X-- Request address %s.",
2004 log_error(
"Unable to allocate memory for IA_TA.");
2020 memset(&addr, 0,
sizeof(addr));
2021 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2022 old_addr = old_addr->
next) {
2026 "Ignoring. (%s:%d)",
2039 addr.data = addr.buffer->data;
2042 memcpy(addr.buffer->data,
2048 putULong(addr.buffer->data + 16, t1);
2049 putULong(addr.buffer->data + 20, t2);
2051 log_debug(
"XMT: | X-- Request address %s.",
2079 memset(&ia, 0,
sizeof(ia));
2080 if (dhc6_create_iaid(client, &ia, i, 12) !=
ISC_R_SUCCESS) {
2081 log_error(
"Unable to allocate memory for IA_PD.");
2093 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
2094 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
2104 memset(&addr, 0,
sizeof(addr));
2105 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2106 old_addr = old_addr->
next) {
2109 "Ignoring. (%s:%d)",
2121 addr.data = addr.buffer->data;
2127 putULong(addr.buffer->data + 4, t2);
2131 memcpy(addr.buffer->data + 9,
2135 log_debug(
"XMT: | X-- Request prefix %s/%u.",
2137 (
unsigned) old_addr->
plen);
2151 }
else if (prefix_len_hint > 0) {
2152 memset(&addr, 0,
sizeof(addr));
2161 addr.data = addr.buffer->data;
2164 putUChar(addr.buffer->data + 8, prefix_len_hint);
2165 log_debug(
"XMT: | | X-- Request prefix ::/%u.",
2178 log_info(
"XMT: Solicit on %s, interval %ld0ms.",
2180 (
long int)client->
RT);
2183 ds.
data, ds.
len, &DHCPv6DestAddr);
2184 if (send_ret != ds.
len) {
2185 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2192 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2193 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2194 if (tv.tv_usec >= 1000000) {
2196 tv.tv_usec -= 1000000;
2200 dhc6_retrans_advance(client);
2205do_info_request6(
void *
input)
2215 "Info-Request", NULL, &ds)) {
2216 case CHK_TIM_MRC_EXCEEDED:
2217 case CHK_TIM_ALLOC_FAILURE:
2219 case CHK_TIM_MRD_EXCEEDED:
2221 case CHK_TIM_SUCCESS:
2233 log_info(
"XMT: Info-Request on %s, interval %ld0ms.",
2235 (
long int)client->
RT);
2238 ds.
data, ds.
len, &DHCPv6DestAddr);
2239 if (send_ret != ds.
len) {
2240 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2247 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2248 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2249 if (tv.tv_usec >= 1000000) {
2251 tv.tv_usec -= 1000000;
2253 add_timeout(&tv, do_info_request6, client, NULL, NULL);
2255 dhc6_retrans_advance(client);
2262do_confirm6(
void *
input)
2266 int send_ret, added;
2290 case CHK_TIM_MRC_EXCEEDED:
2291 case CHK_TIM_MRD_EXCEEDED:
2292 start_bound(client);
2294 case CHK_TIM_ALLOC_FAILURE:
2296 case CHK_TIM_SUCCESS:
2322 log_info(
"XMT: Confirm on %s, interval %ld0ms.",
2324 (
long int)client->
RT);
2328 if (send_ret != ds.
len) {
2329 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2336 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2337 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2338 if (tv.tv_usec >= 1000000) {
2340 tv.tv_usec -= 1000000;
2342 add_timeout(&tv, do_confirm6, client, NULL, NULL);
2344 dhc6_retrans_advance(client);
2380 dhc6_retrans_init(client);
2383 do_release6(client);
2389do_release6(
void *
input)
2393 int send_ret, added;
2398 if ((client->
active_lease == NULL) || !active_prefix(client))
2403 case CHK_TIM_MRC_EXCEEDED:
2404 case CHK_TIM_ALLOC_FAILURE:
2405 case CHK_TIM_MRD_EXCEEDED:
2407 case CHK_TIM_SUCCESS:
2435 log_info(
"XMT: Release on %s, interval %ld0ms.",
2437 (
long int)client->
RT);
2441 if (send_ret != ds.
len) {
2442 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2449 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2450 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2451 if (tv.tv_usec >= 1000000) {
2453 tv.tv_usec -= 1000000;
2455 add_timeout(&tv, do_release6, client, NULL, NULL);
2456 dhc6_retrans_advance(client);
2462 if (stopping_finished())
2470status_log(
int code,
const char *scope,
const char *additional,
int len)
2472 const char *msg = NULL;
2484 msg =
"NoAddrsAvail";
2496 msg =
"UseMulticast";
2500 msg =
"NoPrefixAvail";
2509 log_info(
"%s status code %s: %s", scope, msg,
2511 (
const unsigned char *)additional, 50));
2513 log_info(
"%s status code %s.", scope, msg);
2519dhc6_get_status_code(
struct option_state *options,
unsigned *code,
2526 if ((options == NULL) || (code == NULL))
2529 if ((msg != NULL) && (msg->
len != 0))
2532 memset(&ds, 0,
sizeof(ds));
2547 if ((msg != NULL) && (ds.
len > 2)) {
2557 return ISC_R_NOTFOUND;
2563dhc6_check_status(isc_result_t rval,
struct option_state *options,
2564 const char *scope,
unsigned *code)
2567 isc_result_t status;
2569 if ((scope == NULL) || (code == NULL))
2576 if (options != NULL) {
2577 memset(&msg, 0,
sizeof(msg));
2578 status = dhc6_get_status_code(options, code, &msg);
2581 status_log(*code, scope, (
char *)msg.
data, msg.
len);
2585 rval = ISC_R_FAILURE;
2587 }
else if (status != ISC_R_NOTFOUND)
2611 int got_na = 0, got_ta = 0, got_pd = 0;
2613 rval = dhc6_check_status(rval,
lease->options,
"message", &code);
2615 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
2630 log_error(
"dhc6_check_advertise: no type.");
2631 return ISC_R_FAILURE;
2636 rval = dhc6_check_status(rval, ia->
options, scope, &code);
2645 if (ia->
addrs != NULL) {
2658 rval = ISC_R_ADDRNOTAVAIL;
2667dhc6_init_action(
struct client_state *client, isc_result_t *rvalp,
2673 if (client == NULL) {
2690dhc6_select_action(
struct client_state *client, isc_result_t *rvalp,
2699 if (client == NULL) {
2799 if ((client == NULL) || (client->
active_lease == NULL))
2804 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2818dhc6_reply_action(
struct client_state *client, isc_result_t *rvalp,
2826 if (client == NULL) {
2882 dhc6_withdraw_lease(client);
2919dhc6_stop_action(
struct client_state *client, isc_result_t *rvalp,
2927 if (client == NULL) {
2948 if (rval == ISC_R_FAILURE)
2979dhc6_decline_action(
struct client_state *client, isc_result_t *rvalp,
2987 if (client == NULL) {
3026 isc_result_t *, unsigned);
3033 int got_na = 0, got_ta = 0, got_pd = 0;
3035 if ((client == NULL) || (
new == NULL))
3038 switch (client->
state) {
3040 action = dhc6_init_action;
3045 action = dhc6_select_action;
3050 action = dhc6_reply_action;
3054 action = dhc6_stop_action;
3058 action = dhc6_decline_action;
3063 return ISC_R_CANCELED;
3070 rval = dhc6_check_status(rval, new->options,
"message", &code);
3071 if (action(client, &rval, code))
3072 return ISC_R_CANCELED;
3074 for (ia = new->bindings ; ia != NULL ; ia = ia->
next) {
3089 log_error(
"dhc6_check_reply: no type.");
3092 rval = dhc6_check_status(rval, ia->
options, scope, &code);
3094 if (action(client, &rval, code))
3095 return ISC_R_CANCELED;
3097 if (ia->
addrs != NULL) {
3120 rval = ISC_R_FAILURE;
3122 return ISC_R_CANCELED;
3130 switch (client->
state) {
3135 nscore = dhc6_score_lease(client,
new);
3138 (nscore < (sscore / 2))) {
3144 log_error(
"PRC: BAIT AND SWITCH detected. Score of "
3145 "supplied lease (%d) is substantially "
3146 "smaller than the advertised score (%d). "
3147 "Trying other servers.",
3155 return ISC_R_CANCELED;
3179 log_fatal(
"REALLY impossible condition at %s:%d.",
MDL);
3180 return ISC_R_CANCELED;
3205 if (!valid_reply(
packet, client)) {
3206 log_error(
"Invalid Advertise - rejecting.");
3219 log_debug(
"PRC: Lease failed to satisfy.");
3224 int lease_score = dhc6_score_lease(client,
lease);
3225#ifdef ENFORCE_DHCPV6_CLIENT_REQUIRE
3226 if (lease_score == 0) {
3227 log_debug(
"RCV:Advertised lease scored 0, toss it.");
3246 ((
lease->pref == 255) && (lease_score > SCORE_MIN))) {
3247 log_debug(
"RCV: Advertisement immediately selected.");
3251 log_debug(
"RCV: Advertisement recorded.");
3259 isc_result_t check_status;
3268 if (!valid_reply(
packet, client)) {
3269 log_error(
"Invalid Reply - rejecting.");
3280 if (check_status != ISC_R_CANCELED)
3290 if (check_status == ISC_R_CANCELED)
3304 log_fatal(
"Out of memory for v6 lease structure.");
3314 start_informed(client);
3323 isc_result_t check_status;
3328 init_handler(
packet, client);
3336 if (!valid_reply(
packet, client)) {
3337 log_error(
"Invalid Reply - rejecting.");
3344 log_error(
"Reply without Rapid-Commit - rejecting.");
3356 check_status = dhc6_check_reply(client,
lease);
3390 start_bound(client);
3425 struct dhc6_lease **rpos, *rval, **candp, *cand;
3428 if (head == NULL || *head == NULL)
3433 rscore = dhc6_score_lease(client, rval);
3434 candp = &rval->
next;
3437 log_debug(
"PRC: Considering best lease.");
3438 log_debug(
"PRC: X-- Initial candidate %s (s: %d, p: %u).",
3441 rscore, (
unsigned)rval->
pref);
3443 for (; cand != NULL ; candp = &cand->
next, cand = *candp) {
3444 cscore = dhc6_score_lease(client, cand);
3446 log_debug(
"PRC: X-- Candidate %s (s: %d, p: %u).",
3449 cscore, (
unsigned)cand->
pref);
3473 if ((rscore < SCORE_MIN) && (cscore >= SCORE_MIN)) {
3474 log_debug(
"PRC: | X-- Selected, has bindings.");
3475 }
else if (cand->
pref < rval->
pref) {
3476 log_debug(
"PRC: | X-- Rejected, lower preference.");
3478 }
else if (cand->
pref > rval->
pref) {
3479 log_debug(
"PRC: | X-- Selected, higher preference.");
3480 }
else if (cscore > rscore) {
3481 log_debug(
"PRC: | X-- Selected, equal preference, "
3483 }
else if (cscore < rscore) {
3484 log_debug(
"PRC: | X-- Rejected, equal preference, "
3492 log_debug(
"PRC: | X-- Selected, equal preference, "
3493 "equal score, binary lesser server ID.");
3495 log_debug(
"PRC: | X-- Rejected, equal preference, "
3496 "equal score, binary greater server ID.");
3520 log_error(
"Can not enter DHCPv6 SELECTING state with no "
3521 "leases to select from!");
3525 log_debug(
"PRC: Selecting best advertised lease.");
3541 dhc6_retrans_init(client);
3554do_select6(
void *
input)
3560 int send_ret, added;
3566 if (
lease == NULL ||
lease->bindings == NULL) {
3567 log_error(
"Illegal to attempt selection without selecting "
3573 case CHK_TIM_MRC_EXCEEDED:
3574 case CHK_TIM_MRD_EXCEEDED:
3577 lease->server_id.data, 56));
3589 case CHK_TIM_ALLOC_FAILURE:
3591 case CHK_TIM_SUCCESS:
3642 log_info(
"XMT: Request on %s, interval %ld0ms.",
3644 (
long int)client->
RT);
3647 ds.
data, ds.
len, &DHCPv6DestAddr);
3648 if (send_ret != ds.
len) {
3649 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
3656 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
3657 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
3658 if (tv.tv_usec >= 1000000) {
3660 tv.tv_usec -= 1000000;
3664 dhc6_retrans_advance(client);
3682 for (ia =
lease->bindings; ia != NULL; ia = ia->
next) {
3719 int wanted,
int *added)
3730 memset(&iads, 0,
sizeof(iads));
3731 memset(&addrds, 0,
sizeof(addrds));
3732 for (ia =
lease->bindings, i = 0;
3733 ia != NULL && rval ==
ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3742 log_error(
"Unable to allocate memory for IA_NA.");
3743 rval = ISC_R_NOMEMORY;
3748 memcpy(iads.buffer->data, ia->
iaid, 4);
3749 iads.data = iads.buffer->data;
3759#if MAX_TIME > 0xffffffff
3760 if (t1 > 0xffffffff)
3762 if (t2 > 0xffffffff)
3765 putULong(iads.buffer->data + 4, t1);
3766 putULong(iads.buffer->data + 8, t2);
3770 log_debug(
"XMT: | X-- Requested renew +%u",
3772 log_debug(
"XMT: | X-- Requested rebind +%u",
3780 memset(iads.buffer->data + 4, 0, 8);
3790 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3800 log_error(
"Illegal IPv6 address length (%d), "
3801 "ignoring. (%s:%d)",
3807 log_error(
"Unable to allocate memory for "
3809 rval = ISC_R_NOMEMORY;
3813 addrds.data = addrds.buffer->data;
3826 putULong(addrds.buffer->data + 16, t1);
3827 putULong(addrds.buffer->data + 20, t2);
3832 "lifetime +%u", (
unsigned)t1);
3833 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3843 memset(addrds.buffer->data + 16, 0, 8);
3844 log_debug(
"XMT: | X-- Confirm Address %s",
3850 memset(addrds.buffer->data + 16, 0, 8);
3851 log_debug(
"XMT: | X-- Release Address %s",
3857 memset(addrds.buffer->data + 16, 0, 8);
3858 log_debug(
"XMT: | X-- Decline Address %s",
3863 log_fatal(
"Impossible condition at %s:%d.",
3876 if (ia->
addrs == NULL) {
3877 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
3878 rval = ISC_R_FAILURE;
3922 int wanted,
int *added)
3933 memset(&iads, 0,
sizeof(iads));
3934 memset(&addrds, 0,
sizeof(addrds));
3935 for (ia =
lease->bindings, i = 0;
3936 ia != NULL && rval ==
ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3945 log_error(
"Unable to allocate memory for IA_TA.");
3946 rval = ISC_R_NOMEMORY;
3951 memcpy(iads.buffer->data, ia->
iaid, 4);
3952 iads.data = iads.buffer->data;
3958 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3968 log_error(
"Illegal IPv6 address length (%d), "
3969 "ignoring. (%s:%d)",
3975 log_error(
"Unable to allocate memory for "
3977 rval = ISC_R_NOMEMORY;
3981 addrds.data = addrds.buffer->data;
3994 putULong(addrds.buffer->data + 16, t1);
3995 putULong(addrds.buffer->data + 20, t2);
4000 "lifetime +%u", (
unsigned)t1);
4001 log_debug(
"XMT: | | | X-- Max lifetime +%u",
4011 memset(addrds.buffer->data + 16, 0, 8);
4012 log_debug(
"XMT: | X-- Confirm Address %s",
4018 memset(addrds.buffer->data + 16, 0, 8);
4019 log_debug(
"XMT: | X-- Release Address %s",
4024 log_fatal(
"Impossible condition at %s:%d.",
4037 if (ia->
addrs == NULL) {
4038 log_debug(
"!!!: V IA_TA has no IAADDRs - removed.");
4039 rval = ISC_R_FAILURE;
4083 int wanted,
int *added)
4094 memset(&iads, 0,
sizeof(iads));
4095 memset(&prefds, 0,
sizeof(prefds));
4096 for (ia =
lease->bindings, i = 0;
4097 ia != NULL && rval ==
ISC_R_SUCCESS && (wanted == 0 || i < wanted);
4106 log_error(
"Unable to allocate memory for IA_PD.");
4107 rval = ISC_R_NOMEMORY;
4112 memcpy(iads.buffer->data, ia->
iaid, 4);
4113 iads.data = iads.buffer->data;
4123#if MAX_TIME > 0xffffffff
4124 if (t1 > 0xffffffff)
4126 if (t2 > 0xffffffff)
4129 putULong(iads.buffer->data + 4, t1);
4130 putULong(iads.buffer->data + 8, t2);
4134 log_debug(
"XMT: | X-- Requested renew +%u",
4136 log_debug(
"XMT: | X-- Requested rebind +%u",
4142 memset(iads.buffer->data + 4, 0, 8);
4152 for (pref = ia->
addrs ; pref != NULL ; pref = pref->
next) {
4163 "ignoring. (%s:%d)",
4168 if (pref->
plen == 0) {
4170 "ignoring. (%s:%d)",
4175 log_error(
"Unable to allocate memory for "
4177 rval = ISC_R_NOMEMORY;
4181 prefds.data = prefds.buffer->data;
4186 memcpy(prefds.buffer->data + 9,
4198 putULong(prefds.buffer->data + 4, t2);
4200 log_debug(
"XMT: | | X-- IAPREFIX %s/%u",
4202 (
unsigned) pref->
plen);
4204 "lifetime +%u", (
unsigned)t1);
4205 log_debug(
"XMT: | | | X-- Max lifetime +%u",
4212 memset(prefds.buffer->data, 0, 8);
4213 log_debug(
"XMT: | X-- Release Prefix %s/%u",
4215 (
unsigned) pref->
plen);
4219 log_fatal(
"Impossible condition at %s:%d.",
4224 iaprefix_option, &prefds);
4232 if (ia->
addrs == NULL) {
4233 log_debug(
"!!!: V IA_PD has no IAPREFIXs - removed.");
4234 rval = ISC_R_FAILURE;
4238 ia_pd_option, &iads);
4253stopping_finished(
void)
4259 for (client =
ip -> client; client; client = client ->
next) {
4276 isc_result_t check_status;
4284 if (!valid_reply(
packet, client)) {
4285 log_error(
"Invalid Reply - rejecting.");
4297 check_status = dhc6_check_reply(client,
lease);
4304 if (check_status != ISC_R_CANCELED)
4321 if (stopping_finished()) {
4332 int live_cnt = drop_declined_addrs(client->
active_lease);
4333 if (live_cnt == 0) {
4348 if (check_status == ISC_R_CANCELED)
4364 start_bound(client);
4392 start_bound(client);
4409dhc6_marshall_values(
const char *prefix,
struct client_state *client,
4416 if ((
lease != NULL) && (
lease->options != NULL))
4417 script_write_params6(client, prefix,
lease->options);
4418 if ((ia != NULL) && (ia->
options != NULL))
4419 script_write_params6(client, prefix, ia->
options);
4420 if ((addr != NULL) && (addr->
options != NULL))
4421 script_write_params6(client, prefix, addr->
options);
4427 "ip6_prefix",
"%s/%u",
4429 (
unsigned) addr->
plen);
4438 "ip6_type",
"temporary");
4469 lo_expire=
MAX_TIME, hi_expire=0, max_ia_starts = 0, tmp;
4484 for(ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4485 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
4488 this_ia_hi_expire = 0;
4490 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4516 if (tmp > this_ia_hi_expire)
4517 this_ia_hi_expire = tmp;
4518 if (tmp < this_ia_lo_expire)
4519 this_ia_lo_expire = tmp;
4526 if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
4527 use_expire = this_ia_hi_expire;
4529 use_expire = this_ia_lo_expire;
4535 if ((use_expire ==
MAX_TIME) || (use_expire <= 1))
4552 if (ia->
starts > max_ia_starts)
4553 max_ia_starts = ia->
starts;
4555 if (ia->
renew == 0) {
4557 }
else if (ia->
renew == 0xffffffff)
4567 tmp = use_expire + (use_expire / 2);
4568 }
else if (ia->
rebind == 0xffffffff)
4581 this_ia_hi_expire += ia->
starts;
4582 this_ia_lo_expire += ia->
starts;
4584 if (this_ia_hi_expire > hi_expire)
4585 hi_expire = this_ia_hi_expire;
4586 if (this_ia_lo_expire < lo_expire)
4587 lo_expire = this_ia_lo_expire;
4613 renew += max_ia_starts;
4615 rebind += max_ia_starts;
4617 switch(client->
state) {
4622 if ((rebind >
cur_time) && (renew < rebind)) {
4623 log_debug(
"PRC: Renewal event scheduled in %d seconds, "
4624 "to run for %u seconds.",
4626 (
unsigned)(rebind - renew));
4630 add_timeout(&tv, start_renew6, client, NULL, NULL);
4642 log_debug(
"PRC: Rebind event scheduled in %d seconds, "
4643 "to run for %d seconds.",
4645 (
int)(hi_expire - rebind));
4649 add_timeout(&tv, start_rebind6, client, NULL, NULL);
4662 if (has_preferred_addrs) {
4663 log_fatal(
"Impossible condition, state %d at %s:%d.",
4673 log_debug(
"PRC: Depreference scheduled in %d seconds.",
4680 log_debug(
"PRC: Expiration scheduled in %d seconds.",
4682 tv.tv_sec = lo_expire;
4690find_ia(
struct dhc6_ia *head, u_int16_t type,
const char *
id)
4694 for (ia = head ; ia != NULL ; ia = ia->
next) {
4697 if (memcmp(ia->
iaid,
id, 4) == 0)
4710 for (addr = head ; addr != NULL ; addr = addr->
next) {
4726 for (pref = head ; pref != NULL ; pref = pref->
next) {
4759 struct dhc6_ia *sia, *dia, *tia, **eia;
4760 struct dhc6_addr *saddr, *daddr, *taddr;
4763 if ((dst == NULL) || (src == NULL))
4766 for (sia = src->
bindings ; sia != NULL ; sia = sia->
next) {
4770 tia = dhc6_dup_ia(sia,
MDL);
4773 log_fatal(
"Out of memory merging lease - "
4774 "Unable to continue without losing "
4775 "state! (%s:%d)",
MDL);
4787 eia = &(*eia)->
next) {
4793 for (saddr = sia->
addrs ; saddr != NULL ;
4794 saddr = saddr->
next) {
4796 daddr = find_addr(dia->
addrs,
4799 daddr = find_pref(dia->
addrs,
4803 if (daddr == NULL) {
4804 taddr = dhc6_dup_addr(saddr,
MDL);
4809 "Unable to continue "
4840 int decline_cnt = 0;
4841#if defined (NSUPDATE)
4842 TIME dns_update_offset = 1;
4846 if (
lease == NULL) {
4847 log_error(
"Cannot enter bound state unless an active lease "
4856 switch (client->
state) {
4884 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4892 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4897 if (oldia != NULL) {
4899 oldaddr = find_addr(oldia->
addrs,
4902 oldaddr = find_pref(oldia->
addrs,
4908#if defined (NSUPDATE)
4912 dns_update_offset++);
4919 dhc6_marshall_values(
"old_", client, old,
4921 dhc6_marshall_values(
"new_", client,
lease, ia, addr);
4922 script_write_requested6(client);
4938 start_decline6(client);
4943 if (ia->
addrs == NULL) {
4947 dhc6_marshall_values(
"old_", client, old,
4950 oldia->
addrs : NULL);
4952 dhc6_marshall_values(
"new_", client,
lease, ia,
4954 script_write_requested6(client);
4961 if (
lease->bindings == NULL) {
4965 dhc6_marshall_values(
"old_", client, old,
4970 dhc6_marshall_values(
"new_", client,
lease, NULL, NULL);
4971 script_write_requested6(client);
4989 dhc6_check_times(client);
4998 log_debug(
"RCV: Input packets are ignored once bound.");
5025 dhc6_retrans_init(client);
5029 do_decline6(client);
5039do_decline6(
void *
input)
5044 struct timeval elapsed, tv;
5051 if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
5052 log_info(
"Max retransmission count exceeded.");
5067 if (elapsed.tv_usec < 0) {
5068 elapsed.tv_sec -= 1;
5069 elapsed.tv_usec += 1000000;
5072 memset(&ds, 0,
sizeof(ds));
5074 log_error(
"Unable to allocate memory for Decline.");
5085 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
5086 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
5089 client->
elapsed = elapsed.tv_sec * 100;
5090 client->
elapsed += elapsed.tv_usec / 10000;
5103 if (dhc6_add_ia_na_decline(client, &ds, client->
active_lease)
5110 log_info(
"XMT: Decline on %s, interval %ld0ms.",
5112 (
long int)client->
RT);
5116 if (send_ret != ds.
len) {
5117 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
5124 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5125 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5126 if (tv.tv_usec >= 1000000) {
5128 tv.tv_usec -= 1000000;
5130 add_timeout(&tv, do_decline6, client, NULL, NULL);
5131 dhc6_retrans_advance(client);
5150start_renew6(
void *
input)
5156 log_info(
"PRC: Renewing lease on %s.",
5171 dhc6_retrans_init(client);
5174 do_refresh6(client);
5182do_refresh6(
void *
input)
5185 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
5189 struct timeval elapsed, tv;
5190 int send_ret, added;
5193 memset(&ds, 0,
sizeof(ds));
5196 if (
lease == NULL) {
5197 log_error(
"Cannot renew without an active binding.");
5208 log_fatal(
"Internal inconsistency (%d) at %s:%d.",
5227 if (((client->
MRC != 0) && (client->
txcount > client->
MRC)) ||
5230 dhc6_check_times(client);
5243 log_error(
"Invalid unicast option length %d.", ds.
len);
5245 memset(&unicast, 0,
sizeof(DHCPv6DestAddr));
5246 unicast.sin6_family = AF_INET6;
5248 memcpy(&unicast.sin6_addr, ds.
data, 16);
5250 dest_addr = &unicast;
5258 memset(&ds, 0,
sizeof(ds));
5260 log_error(
"Unable to allocate memory for packet.");
5280 log_debug(
"XMT: Forming %s, 0 ms elapsed.",
5283 log_debug(
"XMT: Forming %s, %u0 ms elapsed.",
5319 log_info(
"XMT: %s on %s, interval %ld0ms.",
5322 (
long int)client->
RT);
5326 if (send_ret != ds.
len) {
5327 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
5334 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5335 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5336 if (tv.tv_usec >= 1000000) {
5338 tv.tv_usec -= 1000000;
5340 add_timeout(&tv, do_refresh6, client, NULL, NULL);
5342 dhc6_retrans_advance(client);
5351start_rebind6(
void *
input)
5357 log_info(
"PRC: Rebinding lease on %s.",
5372 dhc6_retrans_init(client);
5375 do_refresh6(client);
5385do_depref(
void *
input)
5398 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
5399 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5405 dhc6_marshall_values(
"cur_", client,
lease,
5407 script_write_requested6(client);
5413 log_info(
"PRC: Address %s depreferred.",
5416 log_info(
"PRC: Prefix %s/%u depreferred.",
5418 (
unsigned) addr->
plen);
5420#if defined (NSUPDATE)
5431 dhc6_check_times(client);
5438do_expire(
void *
input)
5453 for (ia =
lease->bindings, tia = &
lease->bindings; ia != NULL ; ) {
5455 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5461 dhc6_marshall_values(
"old_", client,
lease,
5463 script_write_requested6(client);
5469 log_info(
"PRC: Address %s expired.",
5472 log_info(
"PRC: Prefix %s/%u expired.",
5474 (
unsigned) addr->
plen);
5476#if defined (NSUPDATE)
5500 tia = &(*tia)->
next;
5506 dhc6_ia_destroy(&ia,
MDL);
5514 log_info(
"PRC: Bound lease is devoid of active addresses."
5515 " Re-initializing.");
5525 dhc6_check_times(client);
5543 script_write_params6(client,
"old_",
5545 script_write_requested6(client);
5557 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5559 dhc6_marshall_values(
"old_", client,
5561 script_write_requested6(client);
5564#if defined (NSUPDATE)
5574refresh_info_request6(
void *
input)
5597 for (i = 0; req[i] != NULL; i++) {
5598 if (req[i] == irt_option) {
5616 memset(&irt, 0,
sizeof(irt));
5626 if (expire == 0xffffffff)
5634 log_debug(
"PRC: Refresh event scheduled in %u seconds.",
5638 add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5656 script_write_params6(client,
"old_",
5659 script_write_requested6(client);
5675 dhc6_check_irt(client);
5683 log_debug(
"RCV: Input packets are ignored once bound.");
5697 int buflen, i, oro_len;
5699 if ((op == NULL) || (client == NULL))
5711 const unsigned char *cdata;
5713 cdata = (
unsigned char *)&client->
elapsed;
5743 log_fatal(
"Failure assembling a DUID.");
5755 if (
lease == NULL) {
5772 log_error(
"'send dhcp6.oro' syntax is deprecated, please "
5773 "use the 'request' syntax (\"man dhclient.conf\").");
5813 log_fatal(
"Out of memory constructing DHCPv6 ORO.");
5816 for (i = 0 ; req[i] != NULL ; i++) {
5817 if (buflen == oro_len) {
5818 struct buffer *tmpbuf = NULL;
5828 "DHCPv6 ORO buffer.");
5849 log_fatal(
"Unable to create ORO option cache.");
5873script_write_params6(
struct client_state *client,
const char *prefix,
5879 if (options == NULL)
5899static void script_write_requested6(
client)
5910 for (i = 0 ; req[i] != NULL ; i++) {
5932 memset(zeros, 0, 16);
5933 for (ia =
lease->bindings; ia != NULL; ia = ia->
next) {
5936 for (pref = ia->
addrs; pref != NULL; pref = pref->
next) {
5937 if (pref->
plen == 0)
5965 memset(&iads, 0,
sizeof(iads));
5966 memset(&addrds, 0,
sizeof(addrds));
5972 int start_new_ia = 1;
5973 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5987 rval = ISC_R_NOMEMORY;
5992 memcpy(iads.buffer->data, ia->
iaid, 4);
5993 iads.data = iads.buffer->data;
5997 memset(iads.buffer->data + 4, 0, 8);
6004 log_error(
"Illegal IPv6 address length (%d), "
6005 "ignoring. (%s:%d)",
6011 log_error(
"Unable to allocate memory for "
6013 rval = ISC_R_NOMEMORY;
6017 addrds.data = addrds.buffer->data;
6024 memset(addrds.buffer->data + 16, 0, 8);
6025 log_debug(
"XMT: | X-- Decline Address %s",
6037 if (ia->
addrs == NULL) {
6038 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
6039 rval = ISC_R_FAILURE;
6063 for (ia =
lease->bindings; ia != NULL; ia = ia->
next) {
6076 for (addr = ia->
addrs ; addr != NULL ; ) {
6085 if (ia->
addrs == addr) {
6087 prev_addr = addr->
next;
6114 if (
lease == NULL) {
6118 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
6119 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
6127 log_debug(
"PRC: Previous lease is devoid of active addresses.");
int buffer_reference(struct buffer **ptr, struct buffer *bp, const char *file, int line)
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_reference(struct option_state **ptr, struct option_state *bp, 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)
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
int buffer_dereference(struct buffer **ptr, const char *file, int line)
void add_timeout(struct timeval *when, void *where, void *what, tvref_t ref, tvunref_t unref)
void cancel_timeout(void *where, void *what)
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
void delete_option(struct universe *universe, struct option_state *options, int code)
void option_space_foreach(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 universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *))
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
int append_option(struct data_string *dst, struct universe *universe, struct option *option, struct data_string *src)
int parse_option_buffer(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *universe)
#define _PATH_DHCLIENT6_DB
#define _PATH_DHCLIENT6_PID
u_int32_t getUShort(const unsigned char *)
void putUShort(unsigned char *, u_int32_t)
u_int32_t getULong(const unsigned char *)
void putUChar(unsigned char *, u_int32_t)
u_int32_t getUChar(const unsigned char *)
void putULong(unsigned char *, u_int32_t)
struct element * copy(struct element *e)
int script_go(struct client_state *client)
Calls external script.
int dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
isc_result_t write_client6_lease(struct client_state *client, struct dhc6_lease *lease, int rewrite, int sync)
const char * path_dhclient_db
void client_option_envadd(struct option_cache *oc, 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 universe *u, void *stuff)
void client_envadd(struct client_state *client, const char *prefix, const char *name, const char *fmt,...)
struct data_string default_duid
void script_init(struct client_state *client, const char *reason, struct string_list *medium)
Initializes basic variables for a script.
const char * path_dhclient_pid
#define IASUBOPT_PD_PREFLEN_OFFSET
#define D6O_INFORMATION_REFRESH_TIME
#define STATUS_UnspecFail
#define All_DHCP_Relay_Agents_and_Servers
#define DHCPV6_INFORMATION_REQUEST
#define STATUS_NoAddrsAvail
#define STATUS_UseMulticast
#define STATUS_NoPrefixAvail
void unconfigure6(struct client_state *client, const char *reason)
void dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line)
void start_info_request6(struct client_state *client)
void start_selecting6(struct client_state *client)
#define DHC6_ADDR_EXPIRED
#define DHC6_ADDR_DEPREFFED
void start_release6(struct client_state *client)
void client_dns_remove(struct client_state *client, struct iaddr *addr)
void dhclient_schedule_updates(struct client_state *client, struct iaddr *addr, int offset)
void dhcpv6_client_assignments(void)
struct universe dhcp_universe
void start_confirm6(struct client_state *client)
ssize_t send_packet6(struct interface_info *, const unsigned char *, size_t, struct sockaddr_in6 *)
#define DHC6_ADDR_DECLINED
void start_init6(struct client_state *client)
#define print_hex_1(len, data, limit)
struct interface_info * interfaces
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)
const char * piaddr(const struct iaddr addr)
void * dmalloc(size_t, const char *, int)
void dfree(void *, const char *, int)
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
struct option ** required_options
struct group * on_transmission
u_int32_t requested_lease
struct option ** requested_options
struct group * on_receipt
struct dhc6_lease * active_lease
void(* v6_handler)(struct packet *, struct client_state *)
struct client_config * config
struct dhc6_lease * advertised_leases
struct dhc6_lease * selected_lease
struct interface_info * interface
struct client_state * next
struct option_state * sent_options
struct dhc6_lease * old_lease
unsigned char dhcpv6_transaction_id[3]
struct timeval start_time
const unsigned char * data
struct option_state * options
struct option_state * options
struct dhc6_ia * bindings
struct data_string server_id
struct option_state * options
struct client_state * client
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
struct hardware hw_address
struct option_cache * next
struct expression * expression
unsigned char dhcpv6_msg_type
struct option_state * options
unsigned char dhcpv6_transaction_id[3]
int option_reference(struct option **dest, struct option *src, const char *file, int line)
const char * dhcpv6_type_names[]
struct universe dhcpv6_universe
struct universe ** universes
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 make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
struct binding_scope * global_scope
int make_const_option_cache(struct option_cache **oc, struct buffer **buffer, u_int8_t *data, unsigned len, struct option *option, const char *file, int line)