30 struct sockaddr_in6 DHCPv6DestAddr;
36 struct option *clientid_option = NULL;
37 struct option *elapsed_option = NULL;
38 struct option *ia_na_option = NULL;
39 struct option *ia_ta_option = NULL;
40 struct option *ia_pd_option = NULL;
41 struct option *iaaddr_option = NULL;
42 struct option *iaprefix_option = NULL;
43 struct option *oro_option = NULL;
44 struct option *irt_option = NULL;
52 static void dhc6_ia_destroy(
struct dhc6_ia **src,
const char *
file,
int line);
53 static isc_result_t dhc6_parse_ia_na(
struct dhc6_ia **pia,
56 static isc_result_t dhc6_parse_ia_ta(
struct dhc6_ia **pia,
59 static isc_result_t dhc6_parse_ia_pd(
struct dhc6_ia **pia,
62 static isc_result_t dhc6_parse_addrs(
struct dhc6_addr **paddr,
65 static isc_result_t dhc6_parse_prefixes(
struct dhc6_addr **ppref,
69 u_int16_t type,
const char *
id);
77 void do_init6(
void *input);
78 void do_info_request6(
void *input);
79 void do_confirm6(
void *input);
81 static isc_result_t dhc6_add_ia_na(
struct client_state *client,
85 static isc_result_t dhc6_add_ia_ta(
struct client_state *client,
89 static isc_result_t dhc6_add_ia_pd(
struct client_state *client,
93 static isc_boolean_t stopping_finished(
void);
95 void do_select6(
void *input);
96 void do_refresh6(
void *input);
97 static void do_release6(
void *input);
100 static void do_decline6(
void *input);
101 static void start_informed(
struct client_state *client);
104 void start_renew6(
void *input);
105 void start_rebind6(
void *input);
106 void do_depref(
void *input);
107 void do_expire(
void *input);
108 static void make_client6_options(
struct client_state *client,
111 static void script_write_params6(
struct client_state *client,
114 static void script_write_requested6(
struct client_state *client);
115 static isc_boolean_t active_prefix(
struct client_state *client);
117 static int check_timing6(
struct client_state *client, u_int8_t msg_type,
139 ent = getservbyname(
"dhcpv6-client",
"udp");
147 ent = getservbyname(
"dhcpv6-server",
"udp");
154 memset(&DHCPv6DestAddr, 0,
sizeof(DHCPv6DestAddr));
155 DHCPv6DestAddr.sin6_family = AF_INET6;
158 &DHCPv6DestAddr.sin6_addr) <= 0) {
163 if (!option_code_hash_lookup(&clientid_option,
165 log_fatal(
"Unable to find the CLIENTID option definition.");
168 if (!option_code_hash_lookup(&elapsed_option,
170 log_fatal(
"Unable to find the ELAPSED_TIME option definition.");
175 log_fatal(
"Unable to find the IA_NA option definition.");
180 log_fatal(
"Unable to find the IA_TA option definition.");
185 log_fatal(
"Unable to find the IA_PD option definition.");
190 log_fatal(
"Unable to find the IAADDR option definition.");
193 if (!option_code_hash_lookup(&iaprefix_option,
196 log_fatal(
"Unable to find the IAPREFIX option definition.");
201 log_fatal(
"Unable to find the ORO option definition.");
206 log_fatal(
"Unable to find the IRT option definition.");
251 split = (base - 1) / 10;
262 range = (split * 2) + 1;
282 client->
RT = client->
IRT + dhc6_rand(client->
IRT);
286 #if (RAND_MAX >= 0x00ffffff)
288 #elif (RAND_MAX >= 0x0000ffff)
289 xid = (random() << 16) ^ random();
290 #elif (RAND_MAX >= 0x000000ff)
291 xid = (random() << 16) ^ (random() << 8) ^ random();
293 # error "Random number generator of less than 8 bits not supported."
305 struct timeval elapsed, elapsed_plus_rt;
310 if (elapsed.tv_usec < 0) {
312 elapsed.tv_usec += 1000000;
316 elapsed.tv_sec += client->
RT / 100;
317 elapsed.tv_usec += (client->
RT % 100) * 10000;
318 if (elapsed.tv_usec >= 1000000) {
320 elapsed.tv_usec -= 1000000;
326 elapsed_plus_rt.tv_sec = elapsed.tv_sec;
327 elapsed_plus_rt.tv_usec = elapsed.tv_usec;
335 client->
RT += client->
RT + dhc6_rand(client->
RT);
345 if ((client->
MRT != 0) && (client->
RT > client->
MRT))
346 client->
RT = client->
MRT + dhc6_rand(client->
MRT);
352 if (client->
MRD == 0) {
358 elapsed.tv_sec += client->
RT / 100;
359 elapsed.tv_usec += (client->
RT % 100) * 10000;
360 if (elapsed.tv_usec >= 1000000) {
362 elapsed.tv_usec -= 1000000;
364 if (elapsed.tv_sec >= client->
MRD) {
371 client->
RT = client->
MRD - elapsed_plus_rt.tv_sec;
372 client->
RT = (client->
RT * 100) -
373 (elapsed_plus_rt.tv_usec / 10000);
388 memset(&sid, 0,
sizeof(sid));
389 memset(&cid, 0,
sizeof(cid));
392 log_error(
"Response without a server identifier received.");
401 log_error(
"Response without a client identifier.");
411 log_error(
"Local client identifier is missing!");
416 sid.len != cid.len ||
417 memcmp(sid.data, cid.data, sid.len)) {
418 log_error(
"Advertise with matching transaction ID, but "
419 "mismatching client id.");
433 struct dhc6_ia **insert_ia, *ia;
435 copy =
dmalloc(
sizeof(*copy), file, line);
437 log_error(
"Out of memory for v6 lease structure.");
450 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
451 *insert_ia = dhc6_dup_ia(ia, file, line);
453 if (*insert_ia == NULL) {
458 insert_ia = &(*insert_ia)->
next;
468 dhc6_dup_ia(
struct dhc6_ia *ia,
const char *file,
int line)
473 copy =
dmalloc(
sizeof(*ia), file, line);
482 insert_addr = ©->
addrs;
483 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
484 *insert_addr = dhc6_dup_addr(addr, file, line);
486 if (*insert_addr == NULL) {
487 dhc6_ia_destroy(©, file, line);
491 insert_addr = &(*insert_addr)->
next;
505 dhc6_dup_addr(
struct dhc6_addr *addr,
const char *file,
int line)
509 copy =
dmalloc(
sizeof(*addr), file, line);
535 dhc6_leaseify(
struct packet *packet)
543 log_error(
"Out of memory for v6 lease structure.");
550 memset(&ds, 0,
sizeof(ds));
558 log_error(
"Invalid length of DHCPv6 Preference option "
559 "(%d != 1)", ds.len);
564 lease->
pref = ds.data[0];
566 (
unsigned)lease->
pref);
577 if (dhc6_parse_ia_na(&lease->
bindings, packet,
578 lease->
options) != ISC_R_SUCCESS) {
587 if (dhc6_parse_ia_ta(&lease->
bindings, packet,
588 lease->
options) != ISC_R_SUCCESS) {
597 if (dhc6_parse_ia_pd(&lease->
bindings, packet,
598 lease->
options) != ISC_R_SUCCESS) {
618 log_error(
"Invalid SERVERID option cache.");
631 dhc6_parse_ia_na(
struct dhc6_ia **pia,
struct packet *packet,
639 memset(&ds, 0,
sizeof(ds));
642 for ( ; oc != NULL ; oc = oc->
next) {
645 log_error(
"Out of memory allocating IA_NA structure.");
646 return ISC_R_NOMEMORY;
651 memcpy(ia->
iaid, ds.data, 4);
677 log_debug(
"RCV: | !-- INVALID renew/rebind "
678 "times, IA_NA discarded.");
690 "IA_NA option state.");
693 return ISC_R_NOMEMORY;
711 result = dhc6_parse_addrs(&ia->
addrs, packet,
713 if (result != ISC_R_SUCCESS) {
726 log_error(
"Invalid IA_NA option cache.");
730 return ISC_R_UNEXPECTED;
735 return ISC_R_SUCCESS;
739 dhc6_parse_ia_ta(
struct dhc6_ia **pia,
struct packet *packet,
747 memset(&ds, 0,
sizeof(ds));
750 for ( ; oc != NULL ; oc = oc->
next) {
753 log_error(
"Out of memory allocating IA_TA structure.");
754 return ISC_R_NOMEMORY;
759 memcpy(ia->
iaid, ds.data, 4);
775 "IA_TA option state.");
778 return ISC_R_NOMEMORY;
796 result = dhc6_parse_addrs(&ia->
addrs, packet,
798 if (result != ISC_R_SUCCESS) {
811 log_error(
"Invalid IA_TA option cache.");
815 return ISC_R_UNEXPECTED;
820 return ISC_R_SUCCESS;
824 dhc6_parse_ia_pd(
struct dhc6_ia **pia,
struct packet *packet,
832 memset(&ds, 0,
sizeof(ds));
835 for ( ; oc != NULL ; oc = oc->
next) {
838 log_error(
"Out of memory allocating IA_PD structure.");
839 return ISC_R_NOMEMORY;
844 memcpy(ia->
iaid, ds.data, 4);
866 log_debug(
"RCV: | !-- INVALID renew/rebind "
867 "times, IA_PD discarded.");
879 "IA_PD option state.");
882 return ISC_R_NOMEMORY;
900 result = dhc6_parse_prefixes(&ia->
addrs,
903 if (result != ISC_R_SUCCESS) {
916 log_error(
"Invalid IA_PD option cache.");
920 return ISC_R_UNEXPECTED;
925 return ISC_R_SUCCESS;
930 dhc6_parse_addrs(
struct dhc6_addr **paddr,
struct packet *packet,
937 memset(&ds, 0,
sizeof(ds));
940 for ( ; oc != NULL ; oc = oc->
next) {
944 "address structure.");
945 return ISC_R_NOMEMORY;
959 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
961 log_debug(
"RCV: | | | X-- Max lifetime %u.",
969 log_debug(
"RCV: | | | !-- INVALID lifetimes, "
970 "IAADDR discarded. Check your "
971 "server configuration.");
985 "IAADDR option state.");
988 return ISC_R_NOMEMORY;
1011 paddr = &addr->
next;
1013 log_error(
"Invalid IAADDR option cache.");
1017 return ISC_R_UNEXPECTED;
1022 return ISC_R_SUCCESS;
1026 dhc6_parse_prefixes(
struct dhc6_addr **ppfx,
struct packet *packet,
1033 memset(&ds, 0,
sizeof(ds));
1036 for ( ; oc != NULL ; oc = oc->
next) {
1040 "prefix structure.");
1041 return ISC_R_NOMEMORY;
1054 log_debug(
"RCV: | | X-- IAPREFIX %s/%d",
1056 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1058 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1062 if ((pfx->
plen < 4) || (pfx->
plen > 128)) {
1063 log_debug(
"RCV: | | | !-- INVALID prefix "
1064 "length, IAPREFIX discarded. "
1065 "Check your server configuration.");
1075 log_debug(
"RCV: | | | !-- INVALID lifetimes, "
1076 "IAPREFIX discarded. Check your "
1077 "server configuration.");
1091 "IAPREFIX option state.");
1094 return ISC_R_NOMEMORY;
1119 log_error(
"Invalid IAPREFIX option cache.");
1123 return ISC_R_UNEXPECTED;
1128 return ISC_R_SUCCESS;
1138 if (src == NULL || *src == NULL) {
1139 log_error(
"Attempt to destroy null lease.");
1147 for (ia = lease->
bindings ; ia != NULL ; ia = nia) {
1150 dhc6_ia_destroy(&ia, file, line);
1156 dfree(lease, file, line);
1165 dhc6_ia_destroy(
struct dhc6_ia **src,
const char *file,
int line)
1170 if (src == NULL || *src == NULL) {
1171 log_error(
"Attempt to destroy null IA.");
1176 for (addr = ia->
addrs ; addr != NULL ; addr = naddr) {
1182 dfree(addr, file, line);
1188 dfree(ia, file, line);
1199 while (*head != NULL) {
1200 if ((*head)->server_id.len == new->server_id.len &&
1201 memcmp((*head)->server_id.data, new->server_id.data,
1202 new->server_id.len) == 0) {
1208 head= &(*head)->
next;
1227 return lease->
score;
1235 for (i = 0 ; req[i] != NULL ; i++) {
1237 req[i]->
code) == NULL) {
1239 return lease->
score;
1247 for (i = 0 ; req[i] != NULL ; i++) {
1249 req[i]->
code) != NULL)
1254 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
1257 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1258 lease->
score += 100;
1262 return lease->
score;
1274 log_debug(
"PRC: Soliciting for leases (INIT).");
1287 dhc6_retrans_init(client);
1295 if (client->
RT <= client->
IRT)
1296 client->
RT = client->
IRT + (client->
IRT - client->
RT);
1298 if (client->
RT <= client->
IRT)
1299 client->
RT = client->
IRT + 1;
1308 tv.tv_sec =
cur_tv.tv_sec;
1309 tv.tv_usec =
cur_tv.tv_usec;
1311 if (tv.tv_usec >= 1000000) {
1313 tv.tv_usec -= 1000000;
1330 log_debug(
"PRC: Requesting information (INIT).");
1343 dhc6_retrans_init(client);
1352 tv.tv_sec =
cur_tv.tv_sec;
1353 tv.tv_usec =
cur_tv.tv_usec;
1355 if (tv.tv_usec >= 1000000) {
1357 tv.tv_usec -= 1000000;
1359 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1369 unexpired_address_in_lease(
struct dhc6_lease *lease)
1374 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
1375 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1385 log_info(
"PRC: Previous lease is devoid of active addresses."
1386 " Re-initializing.");
1403 !active_prefix(client) ||
1411 log_debug(
"PRC: Confirming active lease (INIT-REBOOT).");
1420 dhc6_retrans_init(client);
1429 tv.tv_sec =
cur_tv.tv_sec;
1430 tv.tv_usec =
cur_tv.tv_usec;
1432 if (tv.tv_usec >= 1000000) {
1434 tv.tv_usec -= 1000000;
1439 add_timeout(&tv, do_refresh6, client, NULL, NULL);
1441 add_timeout(&tv, do_confirm6, client, NULL, NULL);
1448 #define CHK_TIM_SUCCESS 0
1449 #define CHK_TIM_MRC_EXCEEDED 1
1450 #define CHK_TIM_MRD_EXCEEDED 2
1451 #define CHK_TIM_ALLOC_FAILURE 3
1454 check_timing6 (
struct client_state *client, u_int8_t msg_type,
1458 struct timeval elapsed;
1466 }
else if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
1467 log_info(
"Max retransmission count exceeded.");
1468 return(CHK_TIM_MRC_EXCEEDED);
1474 if (elapsed.tv_usec < 0) {
1475 elapsed.tv_sec -= 1;
1476 elapsed.tv_usec += 1000000;
1480 if ((client->
MRD != 0) && (elapsed.tv_sec >= client->
MRD)) {
1481 log_info(
"Max retransmission duration exceeded.");
1482 return(CHK_TIM_MRD_EXCEEDED);
1485 memset(ds, 0,
sizeof(*ds));
1487 log_error(
"Unable to allocate memory for %s.", msg_str);
1488 return(CHK_TIM_ALLOC_FAILURE);
1498 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1499 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1502 client->
elapsed = elapsed.tv_sec * 100;
1503 client->
elapsed += elapsed.tv_usec / 10000;
1507 log_debug(
"XMT: Forming %s, 0 ms elapsed.", msg_str);
1509 log_debug(
"XMT: Forming %s, %u0 ms elapsed.", msg_str,
1514 make_client6_options(client, &client->
sent_options, lease, msg_type);
1516 return(CHK_TIM_SUCCESS);
1523 do_init6(
void *input)
1533 int i, idx, len, send_ret;
1546 switch(check_timing6(client,
DHCPV6_SOLICIT,
"Solicit", NULL, &ds)) {
1547 case CHK_TIM_MRC_EXCEEDED:
1548 case CHK_TIM_ALLOC_FAILURE:
1550 case CHK_TIM_MRD_EXCEEDED:
1557 if (stopping_finished())
1582 memset(&ia, 0,
sizeof(ia));
1584 log_error(
"Unable to allocate memory for IA_NA.");
1588 ia.data = ia.buffer->data;
1602 memcpy(ia.buffer->data,
1606 ia.buffer->data[3] += i;
1615 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1616 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1621 (
char *)ia.buffer->data)) != NULL)) {
1626 memset(&addr, 0,
sizeof(addr));
1627 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1628 old_addr = old_addr->
next) {
1632 "Ignoring. (%s:%d)",
1645 addr.data = addr.buffer->data;
1648 memcpy(addr.buffer->data,
1654 putULong(addr.buffer->data + 16, t1);
1655 putULong(addr.buffer->data + 20, t2);
1657 log_debug(
"XMT: | X-- Request address %s.",
1685 memset(&ia, 0,
sizeof(ia));
1687 log_error(
"Unable to allocate memory for IA_TA.");
1691 ia.data = ia.buffer->data;
1705 memcpy(ia.buffer->data,
1709 ia.buffer->data[3] += i;
1717 (
char *)ia.buffer->data)) != NULL)) {
1722 memset(&addr, 0,
sizeof(addr));
1723 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1724 old_addr = old_addr->
next) {
1728 "Ignoring. (%s:%d)",
1741 addr.data = addr.buffer->data;
1744 memcpy(addr.buffer->data,
1750 putULong(addr.buffer->data + 16, t1);
1751 putULong(addr.buffer->data + 20, t2);
1753 log_debug(
"XMT: | X-- Request address %s.",
1781 memset(&ia, 0,
sizeof(ia));
1783 log_error(
"Unable to allocate memory for IA_PD.");
1787 ia.data = ia.buffer->data;
1801 memcpy(ia.buffer->data,
1805 ia.buffer->data[3] += i;
1814 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1815 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1820 (
char *)ia.buffer->data)) != NULL)) {
1825 memset(&addr, 0,
sizeof(addr));
1826 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1827 old_addr = old_addr->
next) {
1830 "Ignoring. (%s:%d)",
1842 addr.data = addr.buffer->data;
1848 putULong(addr.buffer->data + 4, t2);
1852 memcpy(addr.buffer->data + 9,
1856 log_debug(
"XMT: | X-- Request prefix %s/%u.",
1858 (
unsigned) old_addr->
plen);
1880 log_info(
"XMT: Solicit on %s, interval %ld0ms.",
1882 (
long int)client->
RT);
1885 ds.
data, ds.
len, &DHCPv6DestAddr);
1886 if (send_ret != ds.
len) {
1887 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
1894 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
1895 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
1896 if (tv.tv_usec >= 1000000) {
1898 tv.tv_usec -= 1000000;
1902 dhc6_retrans_advance(client);
1907 do_info_request6(
void *input)
1917 "Info-Request", NULL, &ds)) {
1918 case CHK_TIM_MRC_EXCEEDED:
1919 case CHK_TIM_ALLOC_FAILURE:
1921 case CHK_TIM_MRD_EXCEEDED:
1923 case CHK_TIM_SUCCESS:
1935 log_info(
"XMT: Info-Request on %s, interval %ld0ms.",
1937 (
long int)client->
RT);
1940 ds.
data, ds.
len, &DHCPv6DestAddr);
1941 if (send_ret != ds.
len) {
1942 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
1949 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
1950 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
1951 if (tv.tv_usec >= 1000000) {
1953 tv.tv_usec -= 1000000;
1955 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1957 dhc6_retrans_advance(client);
1964 do_confirm6(
void *input)
1973 if (client->active_lease == NULL)
1991 client->active_lease, &ds)) {
1992 case CHK_TIM_MRC_EXCEEDED:
1993 case CHK_TIM_MRD_EXCEEDED:
1994 start_bound(client);
1996 case CHK_TIM_ALLOC_FAILURE:
1998 case CHK_TIM_SUCCESS:
2010 dhc6_add_ia_na(client, &ds, client->active_lease,
2016 dhc6_add_ia_ta(client, &ds, client->active_lease,
2024 log_info(
"XMT: Confirm on %s, interval %ld0ms.",
2025 client->name ? client->name : client->interface->name,
2026 (
long int)client->RT);
2030 if (send_ret != ds.
len) {
2031 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2038 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2039 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2040 if (tv.tv_usec >= 1000000) {
2042 tv.tv_usec -= 1000000;
2044 add_timeout(&tv, do_confirm6, client, NULL, NULL);
2046 dhc6_retrans_advance(client);
2082 dhc6_retrans_init(client);
2085 do_release6(client);
2091 do_release6(
void *input)
2100 if ((client->active_lease == NULL) || !active_prefix(client))
2104 client->active_lease, &ds)) {
2105 case CHK_TIM_MRC_EXCEEDED:
2106 case CHK_TIM_ALLOC_FAILURE:
2107 case CHK_TIM_MRD_EXCEEDED:
2109 case CHK_TIM_SUCCESS:
2124 dhc6_add_ia_na(client, &ds, client->active_lease,
2130 dhc6_add_ia_pd(client, &ds, client->active_lease,
2137 log_info(
"XMT: Release on %s, interval %ld0ms.",
2138 client->name ? client->name : client->interface->name,
2139 (
long int)client->RT);
2143 if (send_ret != ds.
len) {
2144 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2151 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2152 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2153 if (tv.tv_usec >= 1000000) {
2155 tv.tv_usec -= 1000000;
2157 add_timeout(&tv, do_release6, client, NULL, NULL);
2158 dhc6_retrans_advance(client);
2163 client->active_lease = NULL;
2164 if (stopping_finished())
2172 status_log(
int code,
const char *scope,
const char *additional,
int len)
2174 const char *msg = NULL;
2186 msg =
"NoAddrsAvail";
2198 msg =
"UseMulticast";
2202 msg =
"NoPrefixAvail";
2211 log_info(
"%s status code %s: %s", scope, msg,
2213 (
const unsigned char *)additional, 50));
2215 log_info(
"%s status code %s.", scope, msg);
2221 dhc6_get_status_code(
struct option_state *options,
unsigned *code,
2226 isc_result_t rval = ISC_R_SUCCESS;
2228 if ((options == NULL) || (code == NULL))
2231 if ((msg != NULL) && (msg->
len != 0))
2234 memset(&ds, 0,
sizeof(ds));
2249 if ((msg != NULL) && (ds.
len > 2)) {
2259 return ISC_R_NOTFOUND;
2265 dhc6_check_status(isc_result_t rval,
struct option_state *options,
2266 const char *scope,
unsigned *code)
2269 isc_result_t status;
2271 if ((scope == NULL) || (code == NULL))
2278 if (options != NULL) {
2279 memset(&msg, 0,
sizeof(msg));
2280 status = dhc6_get_status_code(options, code, &msg);
2282 if (status == ISC_R_SUCCESS) {
2283 status_log(*code, scope, (
char *)msg.
data, msg.
len);
2287 rval = ISC_R_FAILURE;
2289 }
else if (status != ISC_R_NOTFOUND)
2300 dhc6_check_advertise(
struct dhc6_lease *lease)
2304 isc_result_t rval = ISC_R_SUCCESS;
2305 int have_addrs = ISC_FALSE;
2309 rval = dhc6_check_status(rval, lease->
options,
"message", &code);
2311 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
2323 log_error(
"dhc6_check_advertise: no type.");
2324 return ISC_R_FAILURE;
2326 rval = dhc6_check_status(rval, ia->
options, scope, &code);
2328 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2333 rval = dhc6_check_status(rval, addr->
options,
2335 have_addrs = ISC_TRUE;
2339 if (have_addrs != ISC_TRUE)
2340 rval = ISC_R_ADDRNOTAVAIL;
2348 static isc_boolean_t
2349 dhc6_init_action(
struct client_state *client, isc_result_t *rvalp,
2355 if (client == NULL) {
2360 if (*rvalp == ISC_R_SUCCESS)
2371 static isc_boolean_t
2372 dhc6_select_action(
struct client_state *client, isc_result_t *rvalp,
2381 if (client == NULL) {
2387 if (rval == ISC_R_SUCCESS)
2481 if ((client == NULL) || (client->
active_lease == NULL))
2486 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2499 static isc_boolean_t
2500 dhc6_reply_action(
struct client_state *client, isc_result_t *rvalp,
2508 if (client == NULL) {
2514 if (rval == ISC_R_SUCCESS)
2564 dhc6_withdraw_lease(client);
2600 static isc_boolean_t
2601 dhc6_stop_action(
struct client_state *client, isc_result_t *rvalp,
2609 if (client == NULL) {
2615 if (rval == ISC_R_SUCCESS)
2630 if (rval == ISC_R_FAILURE)
2631 *rvalp = ISC_R_SUCCESS;
2667 isc_result_t *, unsigned);
2670 isc_result_t rval = ISC_R_SUCCESS;
2675 if ((client == NULL) || (
new == NULL))
2678 switch (client->
state) {
2680 action = dhc6_init_action;
2685 action = dhc6_select_action;
2690 action = dhc6_reply_action;
2695 action = dhc6_stop_action;
2700 return ISC_R_CANCELED;
2707 rval = dhc6_check_status(rval, new->options,
"message", &code);
2708 if (action(client, &rval, code))
2709 return ISC_R_CANCELED;
2711 for (ia = new->bindings ; ia != NULL ; ia = ia->
next) {
2723 log_error(
"dhc6_check_reply: no type.");
2726 rval = dhc6_check_status(rval, ia->
options,
2728 if (action(client, &rval, code))
2729 return ISC_R_CANCELED;
2731 for (addr = ia->
addrs ; addr != NULL ;
2732 addr = addr->
next) {
2737 rval = dhc6_check_status(rval, addr->
options,
2739 if (action(client, &rval, code))
2740 return ISC_R_CANCELED;
2752 switch (client->
state) {
2757 nscore = dhc6_score_lease(client,
new);
2760 (nscore < (sscore / 2))) {
2766 log_error(
"PRC: BAIT AND SWITCH detected. Score of "
2767 "supplied lease (%d) is substantially "
2768 "smaller than the advertised score (%d). "
2769 "Trying other servers.",
2777 return ISC_R_CANCELED;
2801 log_fatal(
"REALLY impossible condition at %s:%d.",
MDL);
2802 return ISC_R_CANCELED;
2814 init_handler(
struct packet *packet,
struct client_state *client)
2827 if (!valid_reply(packet, client)) {
2828 log_error(
"Invalid Advertise - rejecting.");
2832 lease = dhc6_leaseify(packet);
2840 if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
2841 log_debug(
"PRC: Lease failed to satisfy.");
2859 ((lease->
pref == 255) &&
2860 (dhc6_score_lease(client, lease) > 150))) {
2861 log_debug(
"RCV: Advertisement immediately selected.");
2865 log_debug(
"RCV: Advertisement recorded.");
2871 info_request_handler(
struct packet *packet,
struct client_state *client)
2873 isc_result_t check_status;
2882 if (!valid_reply(packet, client)) {
2883 log_error(
"Invalid Reply - rejecting.");
2887 check_status = dhc6_check_status(ISC_R_SUCCESS, packet->
options,
2889 if (check_status != ISC_R_SUCCESS) {
2893 if (check_status != ISC_R_CANCELED)
2903 if (check_status == ISC_R_CANCELED)
2917 log_fatal(
"Out of memory for v6 lease structure.");
2921 start_informed(client);
2927 rapid_commit_handler(
struct packet *packet,
struct client_state *client)
2930 isc_result_t check_status;
2935 init_handler(packet, client);
2943 if (!valid_reply(packet, client)) {
2944 log_error(
"Invalid Reply - rejecting.");
2951 log_error(
"Reply without Rapid-Commit - rejecting.");
2955 lease = dhc6_leaseify(packet);
2963 check_status = dhc6_check_reply(client, lease);
2964 if (check_status != ISC_R_SUCCESS) {
2997 start_bound(client);
3032 struct dhc6_lease **rpos, *rval, **candp, *cand;
3035 if (head == NULL || *head == NULL)
3040 rscore = dhc6_score_lease(client, rval);
3041 candp = &rval->
next;
3044 log_debug(
"PRC: Considering best lease.");
3045 log_debug(
"PRC: X-- Initial candidate %s (s: %d, p: %u).",
3048 rscore, (
unsigned)rval->
pref);
3050 for (; cand != NULL ; candp = &cand->
next, cand = *candp) {
3051 cscore = dhc6_score_lease(client, cand);
3053 log_debug(
"PRC: X-- Candidate %s (s: %d, p: %u).",
3056 cscore, (
unsigned)cand->
pref);
3080 if ((rscore < 150) && (cscore >= 150)) {
3081 log_debug(
"PRC: | X-- Selected, has bindings.");
3082 }
else if (cand->
pref < rval->
pref) {
3083 log_debug(
"PRC: | X-- Rejected, lower preference.");
3085 }
else if (cand->
pref > rval->
pref) {
3086 log_debug(
"PRC: | X-- Selected, higher preference.");
3087 }
else if (cscore > rscore) {
3088 log_debug(
"PRC: | X-- Selected, equal preference, "
3090 }
else if (cscore < rscore) {
3091 log_debug(
"PRC: | X-- Rejected, equal preference, "
3099 log_debug(
"PRC: | X-- Selected, equal preference, "
3100 "equal score, binary lesser server ID.");
3102 log_debug(
"PRC: | X-- Rejected, equal preference, "
3103 "equal score, binary greater server ID.");
3127 log_error(
"Can not enter DHCPv6 SELECTING state with no "
3128 "leases to select from!");
3132 log_debug(
"PRC: Selecting best advertised lease.");
3148 dhc6_retrans_init(client);
3161 do_select6(
void *input)
3173 if (lease == NULL || lease->
bindings == NULL) {
3174 log_error(
"Illegal to attempt selection without selecting "
3179 switch(check_timing6(client,
DHCPV6_REQUEST,
"Request", lease, &ds)) {
3180 case CHK_TIM_MRC_EXCEEDED:
3181 case CHK_TIM_MRD_EXCEEDED:
3196 case CHK_TIM_ALLOC_FAILURE:
3198 case CHK_TIM_SUCCESS:
3221 dhc6_add_ia_na(client, &ds, lease,
3227 dhc6_add_ia_ta(client, &ds, lease,
3233 dhc6_add_ia_pd(client, &ds, lease,
3239 log_info(
"XMT: Request on %s, interval %ld0ms.",
3241 (
long int)client->
RT);
3244 ds.
data, ds.
len, &DHCPv6DestAddr);
3245 if (send_ret != ds.
len) {
3246 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
3253 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
3254 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
3255 if (tv.tv_usec >= 1000000) {
3257 tv.tv_usec -= 1000000;
3261 dhc6_retrans_advance(client);
3275 isc_result_t rval = ISC_R_SUCCESS;
3278 memset(&iads, 0,
sizeof(iads));
3279 memset(&addrds, 0,
sizeof(addrds));
3281 ia != NULL && rval == ISC_R_SUCCESS;
3287 log_error(
"Unable to allocate memory for IA_NA.");
3288 rval = ISC_R_NOMEMORY;
3293 memcpy(iads.buffer->data, ia->
iaid, 4);
3294 iads.data = iads.buffer->data;
3304 #if MAX_TIME > 0xffffffff
3305 if (t1 > 0xffffffff)
3307 if (t2 > 0xffffffff)
3310 putULong(iads.buffer->data + 4, t1);
3311 putULong(iads.buffer->data + 8, t2);
3315 log_debug(
"XMT: | X-- Requested renew +%u",
3317 log_debug(
"XMT: | X-- Requested rebind +%u",
3325 memset(iads.buffer->data + 4, 0, 8);
3335 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3345 log_error(
"Illegal IPv6 address length (%d), "
3346 "ignoring. (%s:%d)",
3352 log_error(
"Unable to allocate memory for "
3354 rval = ISC_R_NOMEMORY;
3358 addrds.data = addrds.buffer->data;
3371 putULong(addrds.buffer->data + 16, t1);
3372 putULong(addrds.buffer->data + 20, t2);
3377 "lifetime +%u", (
unsigned)t1);
3378 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3388 memset(addrds.buffer->data + 16, 0, 8);
3389 log_debug(
"XMT: | X-- Confirm Address %s",
3395 memset(addrds.buffer->data + 16, 0, 8);
3396 log_debug(
"XMT: | X-- Release Address %s",
3402 memset(addrds.buffer->data + 16, 0, 8);
3403 log_debug(
"XMT: | X-- Decline Address %s",
3408 log_fatal(
"Impossible condition at %s:%d.",
3421 if (ia->
addrs == NULL) {
3422 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
3423 rval = ISC_R_FAILURE;
3424 }
else if (rval == ISC_R_SUCCESS) {
3447 isc_result_t rval = ISC_R_SUCCESS;
3450 memset(&iads, 0,
sizeof(iads));
3451 memset(&addrds, 0,
sizeof(addrds));
3453 ia != NULL && rval == ISC_R_SUCCESS;
3459 log_error(
"Unable to allocate memory for IA_TA.");
3460 rval = ISC_R_NOMEMORY;
3465 memcpy(iads.buffer->data, ia->
iaid, 4);
3466 iads.data = iads.buffer->data;
3472 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3482 log_error(
"Illegal IPv6 address length (%d), "
3483 "ignoring. (%s:%d)",
3489 log_error(
"Unable to allocate memory for "
3491 rval = ISC_R_NOMEMORY;
3495 addrds.data = addrds.buffer->data;
3508 putULong(addrds.buffer->data + 16, t1);
3509 putULong(addrds.buffer->data + 20, t2);
3514 "lifetime +%u", (
unsigned)t1);
3515 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3525 memset(addrds.buffer->data + 16, 0, 8);
3526 log_debug(
"XMT: | X-- Confirm Address %s",
3532 memset(addrds.buffer->data + 16, 0, 8);
3533 log_debug(
"XMT: | X-- Release Address %s",
3538 log_fatal(
"Impossible condition at %s:%d.",
3551 if (ia->
addrs == NULL) {
3552 log_debug(
"!!!: V IA_TA has no IAADDRs - removed.");
3553 rval = ISC_R_FAILURE;
3554 }
else if (rval == ISC_R_SUCCESS) {
3577 isc_result_t rval = ISC_R_SUCCESS;
3580 memset(&iads, 0,
sizeof(iads));
3581 memset(&prefds, 0,
sizeof(prefds));
3583 ia != NULL && rval == ISC_R_SUCCESS;
3589 log_error(
"Unable to allocate memory for IA_PD.");
3590 rval = ISC_R_NOMEMORY;
3595 memcpy(iads.buffer->data, ia->
iaid, 4);
3596 iads.data = iads.buffer->data;
3606 #if MAX_TIME > 0xffffffff
3607 if (t1 > 0xffffffff)
3609 if (t2 > 0xffffffff)
3612 putULong(iads.buffer->data + 4, t1);
3613 putULong(iads.buffer->data + 8, t2);
3617 log_debug(
"XMT: | X-- Requested renew +%u",
3619 log_debug(
"XMT: | X-- Requested rebind +%u",
3625 memset(iads.buffer->data + 4, 0, 8);
3635 for (pref = ia->
addrs ; pref != NULL ; pref = pref->
next) {
3646 "ignoring. (%s:%d)",
3651 if (pref->
plen == 0) {
3653 "ignoring. (%s:%d)",
3658 log_error(
"Unable to allocate memory for "
3660 rval = ISC_R_NOMEMORY;
3664 prefds.data = prefds.buffer->data;
3669 memcpy(prefds.buffer->data + 9,
3681 putULong(prefds.buffer->data + 4, t2);
3683 log_debug(
"XMT: | | X-- IAPREFIX %s/%u",
3685 (
unsigned) pref->
plen);
3687 "lifetime +%u", (
unsigned)t1);
3688 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3695 memset(prefds.buffer->data, 0, 8);
3696 log_debug(
"XMT: | X-- Release Prefix %s/%u",
3698 (
unsigned) pref->
plen);
3702 log_fatal(
"Impossible condition at %s:%d.",
3707 iaprefix_option, &prefds);
3715 if (ia->
addrs == NULL) {
3716 log_debug(
"!!!: V IA_PD has no IAPREFIXs - removed.");
3717 rval = ISC_R_FAILURE;
3718 }
else if (rval == ISC_R_SUCCESS) {
3721 ia_pd_option, &iads);
3732 static isc_boolean_t
3733 stopping_finished(
void)
3739 for (client = ip -> client; client; client = client ->
next) {
3753 reply_handler(
struct packet *packet,
struct client_state *client)
3756 isc_result_t check_status;
3764 if (!valid_reply(packet, client)) {
3765 log_error(
"Invalid Reply - rejecting.");
3769 lease = dhc6_leaseify(packet);
3777 check_status = dhc6_check_reply(client, lease);
3778 if (check_status != ISC_R_SUCCESS) {
3784 if (check_status != ISC_R_CANCELED)
3803 if (stopping_finished())
3816 if (check_status == ISC_R_CANCELED)
3832 start_bound(client);
3860 start_bound(client);
3877 dhc6_marshall_values(
const char *prefix,
struct client_state *client,
3884 if ((lease != NULL) && (lease->
options != NULL))
3885 script_write_params6(client, prefix, lease->
options);
3886 if ((ia != NULL) && (ia->
options != NULL))
3887 script_write_params6(client, prefix, ia->
options);
3888 if ((addr != NULL) && (addr->
options != NULL))
3889 script_write_params6(client, prefix, addr->
options);
3895 "ip6_prefix",
"%s/%u",
3897 (
unsigned) addr->
plen);
3906 "ip6_type",
"temporary");
3937 lo_expire=
MAX_TIME, hi_expire=0, tmp;
3938 int has_addrs = ISC_FALSE;
3951 for(ia = lease->bindings ; ia != NULL ; ia = ia->
next) {
3952 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
3955 this_ia_hi_expire = 0;
3957 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3979 if (tmp > this_ia_hi_expire)
3980 this_ia_hi_expire = tmp;
3981 if (tmp < this_ia_lo_expire)
3982 this_ia_lo_expire = tmp;
3984 has_addrs = ISC_TRUE;
3989 if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
3990 use_expire = this_ia_hi_expire;
3992 use_expire = this_ia_lo_expire;
3998 if ((use_expire ==
MAX_TIME) || (use_expire <= 1))
4006 if (ia->
renew == 0) {
4007 tmp = ia->
starts + use_expire;
4008 }
else if (ia->
renew == 0xffffffff)
4019 tmp += use_expire + (use_expire / 2);
4020 }
else if (ia->
rebind == 0xffffffff)
4033 this_ia_hi_expire += ia->
starts;
4034 this_ia_lo_expire += ia->
starts;
4036 if (this_ia_hi_expire > hi_expire)
4037 hi_expire = this_ia_hi_expire;
4038 if (this_ia_lo_expire < lo_expire)
4039 lo_expire = this_ia_lo_expire;
4051 if (has_addrs == ISC_FALSE) {
4060 switch(client->
state) {
4065 if ((rebind >
cur_time) && (renew < rebind)) {
4066 log_debug(
"PRC: Renewal event scheduled in %d seconds, "
4067 "to run for %u seconds.",
4069 (
unsigned)(rebind - renew));
4073 add_timeout(&tv, start_renew6, client, NULL, NULL);
4085 log_debug(
"PRC: Rebind event scheduled in %d seconds, "
4086 "to run for %d seconds.",
4087 (
int)(rebind - cur_time),
4088 (
int)(hi_expire - rebind));
4092 add_timeout(&tv, start_rebind6, client, NULL, NULL);
4113 log_debug(
"PRC: Depreference scheduled in %d seconds.",
4114 (
int)(depref - cur_time));
4120 log_debug(
"PRC: Expiration scheduled in %d seconds.",
4121 (
int)(lo_expire - cur_time));
4122 tv.tv_sec = lo_expire;
4130 find_ia(
struct dhc6_ia *head, u_int16_t type,
const char *
id)
4134 for (ia = head ; ia != NULL ; ia = ia->
next) {
4137 if (memcmp(ia->
iaid,
id, 4) == 0)
4150 for (addr = head ; addr != NULL ; addr = addr->
next) {
4153 address->
len) == 0))
4166 for (pref = head ; pref != NULL ; pref = pref->
next) {
4168 (pref->
plen == plen) &&
4185 struct dhc6_ia *sia, *dia, *tia;
4186 struct dhc6_addr *saddr, *daddr, *taddr;
4189 if ((dst == NULL) || (src == NULL))
4192 for (sia = src->
bindings ; sia != NULL ; sia = sia->
next) {
4196 tia = dhc6_dup_ia(sia,
MDL);
4199 log_fatal(
"Out of memory merging lease - "
4200 "Unable to continue without losing "
4201 "state! (%s:%d)",
MDL);
4208 for (saddr = sia->
addrs ; saddr != NULL ;
4209 saddr = saddr->
next) {
4211 daddr = find_addr(dia->
addrs,
4214 daddr = find_pref(dia->
addrs,
4218 if (daddr == NULL) {
4219 taddr = dhc6_dup_addr(saddr,
MDL);
4224 "Unable to continue "
4255 #if defined (NSUPDATE)
4256 TIME dns_update_offset = 1;
4260 if (lease == NULL) {
4261 log_error(
"Cannot enter bound state unless an active lease "
4270 switch (client->
state) {
4298 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4306 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4311 if (oldia != NULL) {
4313 oldaddr = find_addr(oldia->
addrs,
4316 oldaddr = find_pref(oldia->
addrs,
4322 #if defined (NSUPDATE)
4326 dns_update_offset++);
4333 dhc6_marshall_values(
"old_", client, old,
4335 dhc6_marshall_values(
"new_", client, lease, ia, addr);
4336 script_write_requested6(client);
4340 start_decline6(client);
4346 if (ia->
addrs == NULL) {
4350 dhc6_marshall_values(
"old_", client, old,
4353 oldia->
addrs : NULL);
4355 dhc6_marshall_values(
"new_", client, lease, ia,
4357 script_write_requested6(client);
4368 dhc6_marshall_values(
"old_", client, old,
4373 dhc6_marshall_values(
"new_", client, lease, NULL, NULL);
4374 script_write_requested6(client);
4387 dhc6_check_times(client);
4413 dhc6_retrans_init(client);
4417 do_decline6(client);
4424 do_decline6(
void *input)
4429 struct timeval elapsed, tv;
4433 if ((client->active_lease == NULL) || !active_prefix(client))
4436 if ((client->MRC != 0) && (client->txcount > client->MRC)) {
4437 log_info(
"Max retransmission count exceeded.");
4444 if (client->txcount == 0) {
4445 client->start_time.tv_sec =
cur_tv.tv_sec;
4446 client->start_time.tv_usec =
cur_tv.tv_usec;
4450 elapsed.tv_sec =
cur_tv.tv_sec - client->start_time.tv_sec;
4451 elapsed.tv_usec =
cur_tv.tv_usec - client->start_time.tv_usec;
4452 if (elapsed.tv_usec < 0) {
4453 elapsed.tv_sec -= 1;
4454 elapsed.tv_usec += 1000000;
4457 memset(&ds, 0,
sizeof(ds));
4459 log_error(
"Unable to allocate memory for Decline.");
4466 memcpy(ds.
buffer->
data + 1, client->dhcpv6_transaction_id, 3);
4470 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
4471 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
4472 client->elapsed = 0xffff;
4474 client->elapsed = elapsed.tv_sec * 100;
4475 client->elapsed += elapsed.tv_usec / 10000;
4478 client->elapsed = htons(client->elapsed);
4481 make_client6_options(client, &client->sent_options,
4489 dhc6_add_ia_na(client, &ds, client->active_lease,
4495 dhc6_add_ia_pd(client, &ds, client->active_lease,
4502 log_info(
"XMT: Decline on %s, interval %ld0ms.",
4503 client->name ? client->name : client->interface->name,
4504 (
long int)client->RT);
4508 if (send_ret != ds.
len) {
4509 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
4516 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
4517 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
4518 if (tv.tv_usec >= 1000000) {
4520 tv.tv_usec -= 1000000;
4522 add_timeout(&tv, do_decline6, client, NULL, NULL);
4523 dhc6_retrans_advance(client);
4528 client->active_lease = NULL;
4537 bound_handler(
struct packet *packet,
struct client_state *client)
4539 log_debug(
"RCV: Input packets are ignored once bound.");
4547 start_renew6(
void *input)
4553 log_info(
"PRC: Renewing lease on %s.",
4568 dhc6_retrans_init(client);
4571 do_refresh6(client);
4579 do_refresh6(
void *input)
4582 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
4586 struct timeval elapsed, tv;
4590 memset(&ds, 0,
sizeof(ds));
4593 if (lease == NULL) {
4594 log_error(
"Cannot renew without an active binding.");
4605 log_fatal(
"Internal inconsistency (%d) at %s:%d.",
4624 if (((client->
MRC != 0) && (client->
txcount > client->
MRC)) ||
4627 dhc6_check_times(client);
4640 log_error(
"Invalid unicast option length %d.", ds.
len);
4642 memset(&unicast, 0,
sizeof(DHCPv6DestAddr));
4643 unicast.sin6_family = AF_INET6;
4645 memcpy(&unicast.sin6_addr, ds.
data, 16);
4647 dest_addr = &unicast;
4655 memset(&ds, 0,
sizeof(ds));
4657 log_error(
"Unable to allocate memory for packet.");
4677 log_debug(
"XMT: Forming %s, 0 ms elapsed.",
4680 log_debug(
"XMT: Forming %s, %u0 ms elapsed.",
4686 make_client6_options(client, &client->
sent_options, lease,
4696 dhc6_add_ia_na(client, &ds, lease,
4702 dhc6_add_ia_pd(client, &ds, lease,
4708 log_info(
"XMT: %s on %s, interval %ld0ms.",
4711 (
long int)client->
RT);
4715 if (send_ret != ds.
len) {
4716 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
4723 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
4724 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
4725 if (tv.tv_usec >= 1000000) {
4727 tv.tv_usec -= 1000000;
4729 add_timeout(&tv, do_refresh6, client, NULL, NULL);
4731 dhc6_retrans_advance(client);
4740 start_rebind6(
void *input)
4746 log_info(
"PRC: Rebinding lease on %s.",
4761 dhc6_retrans_init(client);
4764 do_refresh6(client);
4774 do_depref(
void *input)
4787 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4788 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4794 dhc6_marshall_values(
"cur_", client, lease,
4796 script_write_requested6(client);
4802 log_info(
"PRC: Address %s depreferred.",
4805 log_info(
"PRC: Prefix %s/%u depreferred.",
4807 (
unsigned) addr->
plen);
4809 #if defined (NSUPDATE)
4820 dhc6_check_times(client);
4827 do_expire(
void *input)
4833 int has_addrs = ISC_FALSE;
4841 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4842 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4848 dhc6_marshall_values(
"old_", client, lease,
4850 script_write_requested6(client);
4856 log_info(
"PRC: Address %s expired.",
4859 log_info(
"PRC: Prefix %s/%u expired.",
4861 (
unsigned) addr->
plen);
4863 #if defined (NSUPDATE)
4878 has_addrs = ISC_TRUE;
4883 if (has_addrs == ISC_FALSE) {
4884 log_info(
"PRC: Bound lease is devoid of active addresses."
4885 " Re-initializing.");
4895 dhc6_check_times(client);
4913 script_write_params6(client,
"old_",
4915 script_write_requested6(client);
4927 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4929 dhc6_marshall_values(
"old_", client,
4931 script_write_requested6(client);
4934 #if defined (NSUPDATE)
4944 refresh_info_request6(
void *input)
4962 isc_boolean_t found = ISC_FALSE;
4967 for (i = 0; req[i] != NULL; i++) {
4968 if (req[i] == irt_option) {
4982 memset(&irt, 0,
sizeof(irt));
4992 if (expire == 0xffffffff)
5000 log_debug(
"PRC: Refresh event scheduled in %u seconds.",
5002 tv.tv_sec = cur_time + expire;
5004 add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5022 script_write_params6(client,
"old_",
5025 script_write_requested6(client);
5036 dhc6_check_irt(client);
5042 informed_handler(
struct packet *packet,
struct client_state *client)
5044 log_debug(
"RCV: Input packets are ignored once bound.");
5058 int buflen, i, oro_len;
5060 if ((op == NULL) || (client == NULL))
5072 const unsigned char *cdata;
5074 cdata = (
unsigned char *)&client->
elapsed;
5087 lease ? lease->
options : NULL,
5104 log_fatal(
"Failure assembling a DUID.");
5116 if (lease == NULL) {
5133 log_error(
"'send dhcp6.oro' syntax is deprecated, please "
5134 "use the 'request' syntax (\"man dhclient.conf\").");
5174 log_fatal(
"Out of memory constructing DHCPv6 ORO.");
5177 for (i = 0 ; req[i] != NULL ; i++) {
5178 if (buflen == oro_len) {
5179 struct buffer *tmpbuf = NULL;
5189 "DHCPv6 ORO buffer.");
5191 memcpy(buffer->
data, tmpbuf->
data, oro_len);
5210 log_fatal(
"Unable to create ORO option cache.");
5234 script_write_params6(
struct client_state *client,
const char *prefix,
5240 if (options == NULL)
5260 static void script_write_requested6(client)
5266 req = client->config->requested_options;
5271 for (i = 0 ; req[i] != NULL ; i++) {
5282 static isc_boolean_t
5293 memset(zeros, 0, 16);
5294 for (ia = lease->
bindings; ia != NULL; ia = ia->
next) {
5297 for (pref = ia->
addrs; pref != NULL; pref = pref->
next) {
5298 if (pref->
plen == 0)
struct timeval start_time
void start_selecting6(struct client_state *client)
int(* encapsulate)(struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *)
struct binding_scope * global_scope
unsigned char dhcpv6_transaction_id[3]
unsigned char dhcpv6_transaction_id[3]
void save_option(struct universe *universe, struct option_state *options, struct option_cache *oc)
const char * piaddr(const struct iaddr addr)
unsigned char dhcpv6_transaction_id[3]
int append_option(struct data_string *dst, struct universe *universe, struct option *option, struct data_string *src)
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)
const char * path_dhclient_db
#define All_DHCP_Relay_Agents_and_Servers
void start_release6(struct client_state *client)
void * dmalloc(unsigned, const char *, int)
int option_cache_dereference(struct option_cache **ptr, const char *file, int line)
void start_info_request6(struct client_state *client)
void cancel_timeout(void(*)(void *) where, void *what)
#define print_hex_1(len, data, limit)
#define DHCP_R_INVALIDARG
#define STATUS_NoAddrsAvail
struct group * on_transmission
int script_go(struct client_state *client)
const char * dhcpv6_type_names[]
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
struct client_state * next
int option_reference(struct option **dest, struct option *src, const char *file, int line)
struct universe dhcp_universe
struct option_state * options
void data_string_forget(struct data_string *data, const char *file, int line)
struct option_cache * next
void delete_option(struct universe *universe, struct option_state *options, int code)
int log_error(const char *,...) __attribute__((__format__(__printf__
#define STATUS_UnspecFail
void client_envadd(struct client_state *client, const char *prefix, const char *name, const char *fmt,...)
void add_timeout(struct timeval *when, void(*)(void *) where, void *what, tvref_t ref, tvunref_t unref)
#define D6O_INFORMATION_REFRESH_TIME
struct dhc6_ia * bindings
struct expression * expression
struct data_string default_duid
struct option_state * options
unsigned char dhcpv6_msg_type
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int parse_option_buffer(struct option_state *options, const unsigned char *buffer, unsigned length, struct universe *universe)
int buffer_reference(struct buffer **ptr, struct buffer *bp, const char *file, int line)
int option_cache_allocate(struct option_cache **cptr, const char *file, int line)
int option_state_reference(struct option_state **ptr, struct option_state *bp, const char *file, int line)
struct option_state * options
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
int option_state_allocate(struct option_state **ptr, const char *file, int line)
const char * path_dhclient_pid
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)
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
void dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line)
struct option ** requested_options
void script_init(struct client_state *client, const char *reason, struct string_list *medium)
int buffer_allocate(struct buffer **ptr, unsigned len, const char *file, int line)
struct data_string server_id
ssize_t send_packet6(struct interface_info *, const unsigned char *, size_t, struct sockaddr_in6 *)
void putULong(unsigned char *, u_int32_t)
struct dhc6_lease * advertised_leases
u_int32_t getUShort(const unsigned char *)
void start_confirm6(struct client_state *client)
void dfree(void *, const char *, int)
struct option_state * sent_options
struct hardware hw_address
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
struct client_state * client
struct option_state * options
struct dhc6_lease * selected_lease
#define _PATH_DHCLIENT6_DB
int int log_info(const char *,...) __attribute__((__format__(__printf__
struct interface_info * interfaces
u_int32_t getULong(const unsigned char *)
struct option ** required_options
void putUChar(unsigned char *, u_int32_t)
#define _PATH_DHCLIENT6_PID
struct universe ** universes
u_int32_t getUChar(const unsigned char *)
int option_state_dereference(struct option_state **ptr, const char *file, int line)
void start_init6(struct client_state *client)
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 *))
void(* v6_handler)(struct packet *, struct client_state *)
void unconfigure6(struct client_state *client, const char *reason)
void client_dns_remove(struct client_state *client, struct iaddr *addr)
struct universe dhcpv6_universe
#define DHCLIENT_DEFAULT_PREFIX_LEN
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
void dhcpv6_client_assignments(void)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
struct client_config * config
void dhclient_schedule_updates(struct client_state *client, struct iaddr *addr, int offset)
int dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
option_code_hash_t * code_hash
void putUShort(unsigned char *, u_int32_t)
const unsigned char * data
struct interface_info * interface
#define DHC6_ADDR_EXPIRED
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
#define DHCPV6_INFORMATION_REQUEST
struct dhc6_lease * old_lease
u_int32_t requested_lease
#define DHC6_ADDR_DEPREFFED
struct dhc6_lease * active_lease
int buffer_dereference(struct buffer **ptr, const char *file, int line)
#define STATUS_UseMulticast
isc_result_t write_client6_lease(struct client_state *client, struct dhc6_lease *lease, int rewrite, int sync)