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;
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;
329 client->
RT += client->
RT + dhc6_rand(client->
RT);
339 if ((client->
MRT != 0) && (client->
RT > client->
MRT))
340 client->
RT = client->
MRT + dhc6_rand(client->
MRT);
346 if (client->
MRD == 0) {
352 elapsed.tv_sec += client->
RT / 100;
353 elapsed.tv_usec += (client->
RT % 100) * 10000;
354 if (elapsed.tv_usec >= 1000000) {
356 elapsed.tv_usec -= 1000000;
358 if (elapsed.tv_sec >= client->
MRD) {
362 client->
RT = client->
MRD +
364 client->
RT = client->
RT * 100 +
378 memset(&sid, 0,
sizeof(sid));
379 memset(&cid, 0,
sizeof(cid));
382 log_error(
"Response without a server identifier received.");
391 log_error(
"Response without a client identifier.");
401 log_error(
"Local client identifier is missing!");
406 sid.len != cid.len ||
407 memcmp(sid.data, cid.data, sid.len)) {
408 log_error(
"Advertise with matching transaction ID, but " 409 "mismatching client id.");
423 struct dhc6_ia **insert_ia, *ia;
425 copy =
dmalloc(
sizeof(*copy), file, line);
427 log_error(
"Out of memory for v6 lease structure.");
440 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
441 *insert_ia = dhc6_dup_ia(ia, file, line);
443 if (*insert_ia == NULL) {
448 insert_ia = &(*insert_ia)->
next;
458 dhc6_dup_ia(
struct dhc6_ia *ia,
const char *file,
int line)
463 copy =
dmalloc(
sizeof(*ia), file, line);
472 insert_addr = ©->
addrs;
473 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
474 *insert_addr = dhc6_dup_addr(addr, file, line);
476 if (*insert_addr == NULL) {
477 dhc6_ia_destroy(©, file, line);
481 insert_addr = &(*insert_addr)->
next;
495 dhc6_dup_addr(
struct dhc6_addr *addr,
const char *file,
int line)
499 copy =
dmalloc(
sizeof(*addr), file, line);
525 dhc6_leaseify(
struct packet *packet)
533 log_error(
"Out of memory for v6 lease structure.");
540 memset(&ds, 0,
sizeof(ds));
548 log_error(
"Invalid length of DHCPv6 Preference option " 549 "(%d != 1)", ds.len);
554 lease->
pref = ds.data[0];
556 (
unsigned)lease->
pref);
567 if (dhc6_parse_ia_na(&lease->
bindings, packet,
568 lease->
options) != ISC_R_SUCCESS) {
577 if (dhc6_parse_ia_ta(&lease->
bindings, packet,
578 lease->
options) != ISC_R_SUCCESS) {
587 if (dhc6_parse_ia_pd(&lease->
bindings, packet,
588 lease->
options) != ISC_R_SUCCESS) {
608 log_error(
"Invalid SERVERID option cache.");
621 dhc6_parse_ia_na(
struct dhc6_ia **pia,
struct packet *packet,
629 memset(&ds, 0,
sizeof(ds));
632 for ( ; oc != NULL ; oc = oc->
next) {
635 log_error(
"Out of memory allocating IA_NA structure.");
636 return ISC_R_NOMEMORY;
641 memcpy(ia->
iaid, ds.data, 4);
667 log_debug(
"RCV: | !-- INVALID renew/rebind " 668 "times, IA_NA discarded.");
680 "IA_NA option state.");
683 return ISC_R_NOMEMORY;
701 result = dhc6_parse_addrs(&ia->
addrs, packet,
703 if (result != ISC_R_SUCCESS) {
716 log_error(
"Invalid IA_NA option cache.");
720 return ISC_R_UNEXPECTED;
725 return ISC_R_SUCCESS;
729 dhc6_parse_ia_ta(
struct dhc6_ia **pia,
struct packet *packet,
737 memset(&ds, 0,
sizeof(ds));
740 for ( ; oc != NULL ; oc = oc->
next) {
743 log_error(
"Out of memory allocating IA_TA structure.");
744 return ISC_R_NOMEMORY;
749 memcpy(ia->
iaid, ds.data, 4);
765 "IA_TA option state.");
768 return ISC_R_NOMEMORY;
786 result = dhc6_parse_addrs(&ia->
addrs, packet,
788 if (result != ISC_R_SUCCESS) {
801 log_error(
"Invalid IA_TA option cache.");
805 return ISC_R_UNEXPECTED;
810 return ISC_R_SUCCESS;
814 dhc6_parse_ia_pd(
struct dhc6_ia **pia,
struct packet *packet,
822 memset(&ds, 0,
sizeof(ds));
825 for ( ; oc != NULL ; oc = oc->
next) {
828 log_error(
"Out of memory allocating IA_PD structure.");
829 return ISC_R_NOMEMORY;
834 memcpy(ia->
iaid, ds.data, 4);
856 log_debug(
"RCV: | !-- INVALID renew/rebind " 857 "times, IA_PD discarded.");
869 "IA_PD option state.");
872 return ISC_R_NOMEMORY;
890 result = dhc6_parse_prefixes(&ia->
addrs,
893 if (result != ISC_R_SUCCESS) {
906 log_error(
"Invalid IA_PD option cache.");
910 return ISC_R_UNEXPECTED;
915 return ISC_R_SUCCESS;
920 dhc6_parse_addrs(
struct dhc6_addr **paddr,
struct packet *packet,
927 memset(&ds, 0,
sizeof(ds));
930 for ( ; oc != NULL ; oc = oc->
next) {
934 "address structure.");
935 return ISC_R_NOMEMORY;
949 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
951 log_debug(
"RCV: | | | X-- Max lifetime %u.",
959 log_debug(
"RCV: | | | !-- INVALID lifetimes, " 960 "IAADDR discarded. Check your " 961 "server configuration.");
975 "IAADDR option state.");
978 return ISC_R_NOMEMORY;
1001 paddr = &addr->
next;
1003 log_error(
"Invalid IAADDR option cache.");
1007 return ISC_R_UNEXPECTED;
1012 return ISC_R_SUCCESS;
1016 dhc6_parse_prefixes(
struct dhc6_addr **ppfx,
struct packet *packet,
1023 memset(&ds, 0,
sizeof(ds));
1026 for ( ; oc != NULL ; oc = oc->
next) {
1030 "prefix structure.");
1031 return ISC_R_NOMEMORY;
1044 log_debug(
"RCV: | | X-- IAPREFIX %s/%d",
1046 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1048 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1052 if ((pfx->
plen < 4) || (pfx->
plen > 128)) {
1053 log_debug(
"RCV: | | | !-- INVALID prefix " 1054 "length, IAPREFIX discarded. " 1055 "Check your server configuration.");
1065 log_debug(
"RCV: | | | !-- INVALID lifetimes, " 1066 "IAPREFIX discarded. Check your " 1067 "server configuration.");
1081 "IAPREFIX option state.");
1084 return ISC_R_NOMEMORY;
1109 log_error(
"Invalid IAPREFIX option cache.");
1113 return ISC_R_UNEXPECTED;
1118 return ISC_R_SUCCESS;
1128 if (src == NULL || *src == NULL) {
1129 log_error(
"Attempt to destroy null lease.");
1137 for (ia = lease->
bindings ; ia != NULL ; ia = nia) {
1140 dhc6_ia_destroy(&ia, file, line);
1146 dfree(lease, file, line);
1155 dhc6_ia_destroy(
struct dhc6_ia **src,
const char *file,
int line)
1160 if (src == NULL || *src == NULL) {
1161 log_error(
"Attempt to destroy null IA.");
1166 for (addr = ia->
addrs ; addr != NULL ; addr = naddr) {
1172 dfree(addr, file, line);
1178 dfree(ia, file, line);
1189 while (*head != NULL) {
1190 if ((*head)->server_id.len == new->server_id.len &&
1191 memcmp((*head)->server_id.data, new->server_id.data,
1192 new->server_id.len) == 0) {
1198 head= &(*head)->
next;
1217 return lease->
score;
1225 for (i = 0 ; req[i] != NULL ; i++) {
1227 req[i]->
code) == NULL) {
1229 return lease->
score;
1237 for (i = 0 ; req[i] != NULL ; i++) {
1239 req[i]->
code) != NULL)
1244 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
1247 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1248 lease->
score += 100;
1252 return lease->
score;
1264 log_debug(
"PRC: Soliciting for leases (INIT).");
1277 dhc6_retrans_init(client);
1285 if (client->
RT <= client->
IRT)
1286 client->
RT = client->
IRT + (client->
IRT - client->
RT);
1288 if (client->
RT <= client->
IRT)
1289 client->
RT = client->
IRT + 1;
1298 tv.tv_sec =
cur_tv.tv_sec;
1299 tv.tv_usec =
cur_tv.tv_usec;
1301 if (tv.tv_usec >= 1000000) {
1303 tv.tv_usec -= 1000000;
1320 log_debug(
"PRC: Requesting information (INIT).");
1333 dhc6_retrans_init(client);
1342 tv.tv_sec =
cur_tv.tv_sec;
1343 tv.tv_usec =
cur_tv.tv_usec;
1345 if (tv.tv_usec >= 1000000) {
1347 tv.tv_usec -= 1000000;
1349 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1359 unexpired_address_in_lease(
struct dhc6_lease *lease)
1364 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
1365 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1375 log_info(
"PRC: Previous lease is devoid of active addresses." 1376 " Re-initializing.");
1393 !active_prefix(client) ||
1401 log_debug(
"PRC: Confirming active lease (INIT-REBOOT).");
1410 dhc6_retrans_init(client);
1419 tv.tv_sec =
cur_tv.tv_sec;
1420 tv.tv_usec =
cur_tv.tv_usec;
1422 if (tv.tv_usec >= 1000000) {
1424 tv.tv_usec -= 1000000;
1429 add_timeout(&tv, do_refresh6, client, NULL, NULL);
1431 add_timeout(&tv, do_confirm6, client, NULL, NULL);
1438 #define CHK_TIM_SUCCESS 0 1439 #define CHK_TIM_MRC_EXCEEDED 1 1440 #define CHK_TIM_MRD_EXCEEDED 2 1441 #define CHK_TIM_ALLOC_FAILURE 3 1444 check_timing6 (
struct client_state *client, u_int8_t msg_type,
1448 struct timeval elapsed;
1456 }
else if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
1457 log_info(
"Max retransmission count exceeded.");
1458 return(CHK_TIM_MRC_EXCEEDED);
1464 if (elapsed.tv_usec < 0) {
1465 elapsed.tv_sec -= 1;
1466 elapsed.tv_usec += 1000000;
1470 if ((client->
MRD != 0) && (elapsed.tv_sec > client->
MRD)) {
1471 log_info(
"Max retransmission duration exceeded.");
1472 return(CHK_TIM_MRD_EXCEEDED);
1475 memset(ds, 0,
sizeof(*ds));
1477 log_error(
"Unable to allocate memory for %s.", msg_str);
1478 return(CHK_TIM_ALLOC_FAILURE);
1488 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1489 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1492 client->
elapsed = elapsed.tv_sec * 100;
1493 client->
elapsed += elapsed.tv_usec / 10000;
1497 log_debug(
"XMT: Forming %s, 0 ms elapsed.", msg_str);
1499 log_debug(
"XMT: Forming %s, %u0 ms elapsed.", msg_str,
1504 make_client6_options(client, &client->
sent_options, lease, msg_type);
1506 return(CHK_TIM_SUCCESS);
1513 do_init6(
void *input)
1523 int i, idx, len, send_ret;
1536 switch(check_timing6(client,
DHCPV6_SOLICIT,
"Solicit", NULL, &ds)) {
1537 case CHK_TIM_MRC_EXCEEDED:
1538 case CHK_TIM_ALLOC_FAILURE:
1540 case CHK_TIM_MRD_EXCEEDED:
1547 if (stopping_finished())
1572 memset(&ia, 0,
sizeof(ia));
1574 log_error(
"Unable to allocate memory for IA_NA.");
1578 ia.data = ia.buffer->data;
1592 memcpy(ia.buffer->data,
1596 ia.buffer->data[3] += i;
1605 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1606 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1611 (
char *)ia.buffer->data)) != NULL)) {
1616 memset(&addr, 0,
sizeof(addr));
1617 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1618 old_addr = old_addr->
next) {
1622 "Ignoring. (%s:%d)",
1635 addr.data = addr.buffer->data;
1638 memcpy(addr.buffer->data,
1644 putULong(addr.buffer->data + 16, t1);
1645 putULong(addr.buffer->data + 20, t2);
1647 log_debug(
"XMT: | X-- Request address %s.",
1675 memset(&ia, 0,
sizeof(ia));
1677 log_error(
"Unable to allocate memory for IA_TA.");
1681 ia.data = ia.buffer->data;
1695 memcpy(ia.buffer->data,
1699 ia.buffer->data[3] += i;
1707 (
char *)ia.buffer->data)) != NULL)) {
1712 memset(&addr, 0,
sizeof(addr));
1713 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1714 old_addr = old_addr->
next) {
1718 "Ignoring. (%s:%d)",
1731 addr.data = addr.buffer->data;
1734 memcpy(addr.buffer->data,
1740 putULong(addr.buffer->data + 16, t1);
1741 putULong(addr.buffer->data + 20, t2);
1743 log_debug(
"XMT: | X-- Request address %s.",
1771 memset(&ia, 0,
sizeof(ia));
1773 log_error(
"Unable to allocate memory for IA_PD.");
1777 ia.data = ia.buffer->data;
1791 memcpy(ia.buffer->data,
1795 ia.buffer->data[3] += i;
1804 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1805 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1810 (
char *)ia.buffer->data)) != NULL)) {
1815 memset(&addr, 0,
sizeof(addr));
1816 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1817 old_addr = old_addr->
next) {
1820 "Ignoring. (%s:%d)",
1832 addr.data = addr.buffer->data;
1838 putULong(addr.buffer->data + 4, t2);
1842 memcpy(addr.buffer->data + 9,
1846 log_debug(
"XMT: | X-- Request prefix %s/%u.",
1848 (
unsigned) old_addr->
plen);
1870 log_info(
"XMT: Solicit on %s, interval %ld0ms.",
1872 (
long int)client->
RT);
1875 ds.
data, ds.
len, &DHCPv6DestAddr);
1876 if (send_ret != ds.
len) {
1877 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
1884 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
1885 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
1886 if (tv.tv_usec >= 1000000) {
1888 tv.tv_usec -= 1000000;
1892 dhc6_retrans_advance(client);
1897 do_info_request6(
void *input)
1907 "Info-Request", NULL, &ds)) {
1908 case CHK_TIM_MRC_EXCEEDED:
1909 case CHK_TIM_ALLOC_FAILURE:
1911 case CHK_TIM_MRD_EXCEEDED:
1913 case CHK_TIM_SUCCESS:
1925 log_info(
"XMT: Info-Request on %s, interval %ld0ms.",
1927 (
long int)client->
RT);
1930 ds.
data, ds.
len, &DHCPv6DestAddr);
1931 if (send_ret != ds.
len) {
1932 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
1939 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
1940 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
1941 if (tv.tv_usec >= 1000000) {
1943 tv.tv_usec -= 1000000;
1945 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1947 dhc6_retrans_advance(client);
1954 do_confirm6(
void *input)
1963 if (client->active_lease == NULL)
1981 client->active_lease, &ds)) {
1982 case CHK_TIM_MRC_EXCEEDED:
1983 case CHK_TIM_MRD_EXCEEDED:
1984 start_bound(client);
1986 case CHK_TIM_ALLOC_FAILURE:
1988 case CHK_TIM_SUCCESS:
2000 dhc6_add_ia_na(client, &ds, client->active_lease,
2006 dhc6_add_ia_ta(client, &ds, client->active_lease,
2014 log_info(
"XMT: Confirm on %s, interval %ld0ms.",
2015 client->name ? client->name : client->interface->name,
2016 (
long int)client->RT);
2020 if (send_ret != ds.
len) {
2021 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2028 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2029 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2030 if (tv.tv_usec >= 1000000) {
2032 tv.tv_usec -= 1000000;
2034 add_timeout(&tv, do_confirm6, client, NULL, NULL);
2036 dhc6_retrans_advance(client);
2072 dhc6_retrans_init(client);
2075 do_release6(client);
2081 do_release6(
void *input)
2090 if ((client->active_lease == NULL) || !active_prefix(client))
2094 client->active_lease, &ds)) {
2095 case CHK_TIM_MRC_EXCEEDED:
2096 case CHK_TIM_ALLOC_FAILURE:
2097 case CHK_TIM_MRD_EXCEEDED:
2099 case CHK_TIM_SUCCESS:
2114 dhc6_add_ia_na(client, &ds, client->active_lease,
2120 dhc6_add_ia_pd(client, &ds, client->active_lease,
2127 log_info(
"XMT: Release on %s, interval %ld0ms.",
2128 client->name ? client->name : client->interface->name,
2129 (
long int)client->RT);
2133 if (send_ret != ds.
len) {
2134 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2141 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2142 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2143 if (tv.tv_usec >= 1000000) {
2145 tv.tv_usec -= 1000000;
2147 add_timeout(&tv, do_release6, client, NULL, NULL);
2148 dhc6_retrans_advance(client);
2153 client->active_lease = NULL;
2154 if (stopping_finished())
2162 status_log(
int code,
const char *scope,
const char *additional,
int len)
2164 const char *msg = NULL;
2176 msg =
"NoAddrsAvail";
2188 msg =
"UseMulticast";
2192 msg =
"NoPrefixAvail";
2201 log_info(
"%s status code %s: %s", scope, msg,
2203 (
const unsigned char *)additional, 50));
2205 log_info(
"%s status code %s.", scope, msg);
2211 dhc6_get_status_code(
struct option_state *options,
unsigned *code,
2216 isc_result_t rval = ISC_R_SUCCESS;
2218 if ((options == NULL) || (code == NULL))
2221 if ((msg != NULL) && (msg->
len != 0))
2224 memset(&ds, 0,
sizeof(ds));
2239 if ((msg != NULL) && (ds.
len > 2)) {
2249 return ISC_R_NOTFOUND;
2255 dhc6_check_status(isc_result_t rval,
struct option_state *options,
2256 const char *scope,
unsigned *code)
2259 isc_result_t status;
2261 if ((scope == NULL) || (code == NULL))
2268 if (options != NULL) {
2269 memset(&msg, 0,
sizeof(msg));
2270 status = dhc6_get_status_code(options, code, &msg);
2272 if (status == ISC_R_SUCCESS) {
2273 status_log(*code, scope, (
char *)msg.
data, msg.
len);
2277 rval = ISC_R_FAILURE;
2279 }
else if (status != ISC_R_NOTFOUND)
2290 dhc6_check_advertise(
struct dhc6_lease *lease)
2294 isc_result_t rval = ISC_R_SUCCESS;
2295 int have_addrs = ISC_FALSE;
2299 rval = dhc6_check_status(rval, lease->
options,
"message", &code);
2301 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
2313 log_error(
"dhc6_check_advertise: no type.");
2314 return ISC_R_FAILURE;
2316 rval = dhc6_check_status(rval, ia->
options, scope, &code);
2318 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2323 rval = dhc6_check_status(rval, addr->
options,
2325 have_addrs = ISC_TRUE;
2329 if (have_addrs != ISC_TRUE)
2330 rval = ISC_R_ADDRNOTAVAIL;
2338 static isc_boolean_t
2339 dhc6_init_action(
struct client_state *client, isc_result_t *rvalp,
2345 if (client == NULL) {
2350 if (*rvalp == ISC_R_SUCCESS)
2361 static isc_boolean_t
2362 dhc6_select_action(
struct client_state *client, isc_result_t *rvalp,
2371 if (client == NULL) {
2377 if (rval == ISC_R_SUCCESS)
2471 if ((client == NULL) || (client->
active_lease == NULL))
2476 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2489 static isc_boolean_t
2490 dhc6_reply_action(
struct client_state *client, isc_result_t *rvalp,
2498 if (client == NULL) {
2504 if (rval == ISC_R_SUCCESS)
2554 dhc6_withdraw_lease(client);
2590 static isc_boolean_t
2591 dhc6_stop_action(
struct client_state *client, isc_result_t *rvalp,
2599 if (client == NULL) {
2605 if (rval == ISC_R_SUCCESS)
2620 if (rval == ISC_R_FAILURE)
2621 *rvalp = ISC_R_SUCCESS;
2657 isc_result_t *, unsigned);
2660 isc_result_t rval = ISC_R_SUCCESS;
2665 if ((client == NULL) || (
new == NULL))
2668 switch (client->
state) {
2670 action = dhc6_init_action;
2675 action = dhc6_select_action;
2680 action = dhc6_reply_action;
2685 action = dhc6_stop_action;
2690 return ISC_R_CANCELED;
2697 rval = dhc6_check_status(rval, new->options,
"message", &code);
2698 if (action(client, &rval, code))
2699 return ISC_R_CANCELED;
2701 for (ia = new->bindings ; ia != NULL ; ia = ia->
next) {
2713 log_error(
"dhc6_check_reply: no type.");
2716 rval = dhc6_check_status(rval, ia->
options,
2718 if (action(client, &rval, code))
2719 return ISC_R_CANCELED;
2721 for (addr = ia->
addrs ; addr != NULL ;
2722 addr = addr->
next) {
2727 rval = dhc6_check_status(rval, addr->
options,
2729 if (action(client, &rval, code))
2730 return ISC_R_CANCELED;
2742 switch (client->
state) {
2747 nscore = dhc6_score_lease(client,
new);
2750 (nscore < (sscore / 2))) {
2756 log_error(
"PRC: BAIT AND SWITCH detected. Score of " 2757 "supplied lease (%d) is substantially " 2758 "smaller than the advertised score (%d). " 2759 "Trying other servers.",
2767 return ISC_R_CANCELED;
2791 log_fatal(
"REALLY impossible condition at %s:%d.",
MDL);
2792 return ISC_R_CANCELED;
2804 init_handler(
struct packet *packet,
struct client_state *client)
2817 if (!valid_reply(packet, client)) {
2818 log_error(
"Invalid Advertise - rejecting.");
2822 lease = dhc6_leaseify(packet);
2824 if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
2825 log_debug(
"PRC: Lease failed to satisfy.");
2843 ((lease->
pref == 255) &&
2844 (dhc6_score_lease(client, lease) > 150))) {
2845 log_debug(
"RCV: Advertisement immediately selected.");
2849 log_debug(
"RCV: Advertisement recorded.");
2855 info_request_handler(
struct packet *packet,
struct client_state *client)
2857 isc_result_t check_status;
2866 if (!valid_reply(packet, client)) {
2867 log_error(
"Invalid Reply - rejecting.");
2871 check_status = dhc6_check_status(ISC_R_SUCCESS, packet->
options,
2873 if (check_status != ISC_R_SUCCESS) {
2877 if (check_status != ISC_R_CANCELED)
2887 if (check_status == ISC_R_CANCELED)
2901 log_fatal(
"Out of memory for v6 lease structure.");
2905 start_informed(client);
2911 rapid_commit_handler(
struct packet *packet,
struct client_state *client)
2914 isc_result_t check_status;
2919 init_handler(packet, client);
2927 if (!valid_reply(packet, client)) {
2928 log_error(
"Invalid Reply - rejecting.");
2935 log_error(
"Reply without Rapid-Commit - rejecting.");
2939 lease = dhc6_leaseify(packet);
2947 check_status = dhc6_check_reply(client, lease);
2948 if (check_status != ISC_R_SUCCESS) {
2981 start_bound(client);
3016 struct dhc6_lease **rpos, *rval, **candp, *cand;
3019 if (head == NULL || *head == NULL)
3024 rscore = dhc6_score_lease(client, rval);
3025 candp = &rval->
next;
3028 log_debug(
"PRC: Considering best lease.");
3029 log_debug(
"PRC: X-- Initial candidate %s (s: %d, p: %u).",
3032 rscore, (
unsigned)rval->
pref);
3034 for (; cand != NULL ; candp = &cand->
next, cand = *candp) {
3035 cscore = dhc6_score_lease(client, cand);
3037 log_debug(
"PRC: X-- Candidate %s (s: %d, p: %u).",
3040 cscore, (
unsigned)cand->
pref);
3064 if ((rscore < 150) && (cscore >= 150)) {
3065 log_debug(
"PRC: | X-- Selected, has bindings.");
3066 }
else if (cand->
pref < rval->
pref) {
3067 log_debug(
"PRC: | X-- Rejected, lower preference.");
3069 }
else if (cand->
pref > rval->
pref) {
3070 log_debug(
"PRC: | X-- Selected, higher preference.");
3071 }
else if (cscore > rscore) {
3072 log_debug(
"PRC: | X-- Selected, equal preference, " 3074 }
else if (cscore < rscore) {
3075 log_debug(
"PRC: | X-- Rejected, equal preference, " 3083 log_debug(
"PRC: | X-- Selected, equal preference, " 3084 "equal score, binary lesser server ID.");
3086 log_debug(
"PRC: | X-- Rejected, equal preference, " 3087 "equal score, binary greater server ID.");
3111 log_error(
"Can not enter DHCPv6 SELECTING state with no " 3112 "leases to select from!");
3116 log_debug(
"PRC: Selecting best advertised lease.");
3132 dhc6_retrans_init(client);
3145 do_select6(
void *input)
3157 if (lease == NULL || lease->
bindings == NULL) {
3158 log_error(
"Illegal to attempt selection without selecting " 3163 switch(check_timing6(client,
DHCPV6_REQUEST,
"Request", lease, &ds)) {
3164 case CHK_TIM_MRC_EXCEEDED:
3165 case CHK_TIM_MRD_EXCEEDED:
3180 case CHK_TIM_ALLOC_FAILURE:
3182 case CHK_TIM_SUCCESS:
3205 dhc6_add_ia_na(client, &ds, lease,
3211 dhc6_add_ia_ta(client, &ds, lease,
3217 dhc6_add_ia_pd(client, &ds, lease,
3223 log_info(
"XMT: Request on %s, interval %ld0ms.",
3225 (
long int)client->
RT);
3228 ds.
data, ds.
len, &DHCPv6DestAddr);
3229 if (send_ret != ds.
len) {
3230 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
3237 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
3238 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
3239 if (tv.tv_usec >= 1000000) {
3241 tv.tv_usec -= 1000000;
3245 dhc6_retrans_advance(client);
3259 isc_result_t rval = ISC_R_SUCCESS;
3262 memset(&iads, 0,
sizeof(iads));
3263 memset(&addrds, 0,
sizeof(addrds));
3265 ia != NULL && rval == ISC_R_SUCCESS;
3271 log_error(
"Unable to allocate memory for IA_NA.");
3272 rval = ISC_R_NOMEMORY;
3277 memcpy(iads.buffer->data, ia->
iaid, 4);
3278 iads.data = iads.buffer->data;
3288 #if MAX_TIME > 0xffffffff 3289 if (t1 > 0xffffffff)
3291 if (t2 > 0xffffffff)
3294 putULong(iads.buffer->data + 4, t1);
3295 putULong(iads.buffer->data + 8, t2);
3299 log_debug(
"XMT: | X-- Requested renew +%u",
3301 log_debug(
"XMT: | X-- Requested rebind +%u",
3309 memset(iads.buffer->data + 4, 0, 8);
3319 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3329 log_error(
"Illegal IPv6 address length (%d), " 3330 "ignoring. (%s:%d)",
3336 log_error(
"Unable to allocate memory for " 3338 rval = ISC_R_NOMEMORY;
3342 addrds.data = addrds.buffer->data;
3355 putULong(addrds.buffer->data + 16, t1);
3356 putULong(addrds.buffer->data + 20, t2);
3361 "lifetime +%u", (
unsigned)t1);
3362 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3372 memset(addrds.buffer->data + 16, 0, 8);
3373 log_debug(
"XMT: | X-- Confirm Address %s",
3379 memset(addrds.buffer->data + 16, 0, 8);
3380 log_debug(
"XMT: | X-- Release Address %s",
3386 memset(addrds.buffer->data + 16, 0, 8);
3387 log_debug(
"XMT: | X-- Decline Address %s",
3392 log_fatal(
"Impossible condition at %s:%d.",
3405 if (ia->
addrs == NULL) {
3406 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
3407 rval = ISC_R_FAILURE;
3408 }
else if (rval == ISC_R_SUCCESS) {
3431 isc_result_t rval = ISC_R_SUCCESS;
3434 memset(&iads, 0,
sizeof(iads));
3435 memset(&addrds, 0,
sizeof(addrds));
3437 ia != NULL && rval == ISC_R_SUCCESS;
3443 log_error(
"Unable to allocate memory for IA_TA.");
3444 rval = ISC_R_NOMEMORY;
3449 memcpy(iads.buffer->data, ia->
iaid, 4);
3450 iads.data = iads.buffer->data;
3456 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3466 log_error(
"Illegal IPv6 address length (%d), " 3467 "ignoring. (%s:%d)",
3473 log_error(
"Unable to allocate memory for " 3475 rval = ISC_R_NOMEMORY;
3479 addrds.data = addrds.buffer->data;
3492 putULong(addrds.buffer->data + 16, t1);
3493 putULong(addrds.buffer->data + 20, t2);
3498 "lifetime +%u", (
unsigned)t1);
3499 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3509 memset(addrds.buffer->data + 16, 0, 8);
3510 log_debug(
"XMT: | X-- Confirm Address %s",
3516 memset(addrds.buffer->data + 16, 0, 8);
3517 log_debug(
"XMT: | X-- Release Address %s",
3522 log_fatal(
"Impossible condition at %s:%d.",
3535 if (ia->
addrs == NULL) {
3536 log_debug(
"!!!: V IA_TA has no IAADDRs - removed.");
3537 rval = ISC_R_FAILURE;
3538 }
else if (rval == ISC_R_SUCCESS) {
3561 isc_result_t rval = ISC_R_SUCCESS;
3564 memset(&iads, 0,
sizeof(iads));
3565 memset(&prefds, 0,
sizeof(prefds));
3567 ia != NULL && rval == ISC_R_SUCCESS;
3573 log_error(
"Unable to allocate memory for IA_PD.");
3574 rval = ISC_R_NOMEMORY;
3579 memcpy(iads.buffer->data, ia->
iaid, 4);
3580 iads.data = iads.buffer->data;
3590 #if MAX_TIME > 0xffffffff 3591 if (t1 > 0xffffffff)
3593 if (t2 > 0xffffffff)
3596 putULong(iads.buffer->data + 4, t1);
3597 putULong(iads.buffer->data + 8, t2);
3601 log_debug(
"XMT: | X-- Requested renew +%u",
3603 log_debug(
"XMT: | X-- Requested rebind +%u",
3609 memset(iads.buffer->data + 4, 0, 8);
3619 for (pref = ia->
addrs ; pref != NULL ; pref = pref->
next) {
3630 "ignoring. (%s:%d)",
3635 if (pref->
plen == 0) {
3637 "ignoring. (%s:%d)",
3642 log_error(
"Unable to allocate memory for " 3644 rval = ISC_R_NOMEMORY;
3648 prefds.data = prefds.buffer->data;
3653 memcpy(prefds.buffer->data + 9,
3665 putULong(prefds.buffer->data + 4, t2);
3667 log_debug(
"XMT: | | X-- IAPREFIX %s/%u",
3669 (
unsigned) pref->
plen);
3671 "lifetime +%u", (
unsigned)t1);
3672 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3679 memset(prefds.buffer->data, 0, 8);
3680 log_debug(
"XMT: | X-- Release Prefix %s/%u",
3682 (
unsigned) pref->
plen);
3686 log_fatal(
"Impossible condition at %s:%d.",
3691 iaprefix_option, &prefds);
3699 if (ia->
addrs == NULL) {
3700 log_debug(
"!!!: V IA_PD has no IAPREFIXs - removed.");
3701 rval = ISC_R_FAILURE;
3702 }
else if (rval == ISC_R_SUCCESS) {
3705 ia_pd_option, &iads);
3716 static isc_boolean_t
3717 stopping_finished(
void)
3723 for (client = ip -> client; client; client = client ->
next) {
3737 reply_handler(
struct packet *packet,
struct client_state *client)
3740 isc_result_t check_status;
3748 if (!valid_reply(packet, client)) {
3749 log_error(
"Invalid Reply - rejecting.");
3753 lease = dhc6_leaseify(packet);
3761 check_status = dhc6_check_reply(client, lease);
3762 if (check_status != ISC_R_SUCCESS) {
3768 if (check_status != ISC_R_CANCELED)
3787 if (stopping_finished())
3800 if (check_status == ISC_R_CANCELED)
3816 start_bound(client);
3844 start_bound(client);
3861 dhc6_marshall_values(
const char *prefix,
struct client_state *client,
3868 if ((lease != NULL) && (lease->
options != NULL))
3869 script_write_params6(client, prefix, lease->
options);
3870 if ((ia != NULL) && (ia->
options != NULL))
3871 script_write_params6(client, prefix, ia->
options);
3872 if ((addr != NULL) && (addr->
options != NULL))
3873 script_write_params6(client, prefix, addr->
options);
3879 "ip6_prefix",
"%s/%u",
3881 (
unsigned) addr->
plen);
3893 "ip6_type",
"temporary");
3924 lo_expire=
MAX_TIME, hi_expire=0, tmp;
3925 int has_addrs = ISC_FALSE;
3938 for(ia = lease->bindings ; ia != NULL ; ia = ia->
next) {
3939 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
3942 this_ia_hi_expire = 0;
3944 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3966 if (tmp > this_ia_hi_expire)
3967 this_ia_hi_expire = tmp;
3968 if (tmp < this_ia_lo_expire)
3969 this_ia_lo_expire = tmp;
3971 has_addrs = ISC_TRUE;
3976 if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
3977 use_expire = this_ia_hi_expire;
3979 use_expire = this_ia_lo_expire;
3985 if ((use_expire ==
MAX_TIME) || (use_expire <= 1))
3993 if (ia->
renew == 0) {
3994 tmp = ia->
starts + use_expire;
3995 }
else if (ia->
renew == 0xffffffff)
4006 tmp += use_expire + (use_expire / 2);
4007 }
else if (ia->
rebind == 0xffffffff)
4020 this_ia_hi_expire += ia->
starts;
4021 this_ia_lo_expire += ia->
starts;
4023 if (this_ia_hi_expire > hi_expire)
4024 hi_expire = this_ia_hi_expire;
4025 if (this_ia_lo_expire < lo_expire)
4026 lo_expire = this_ia_lo_expire;
4038 if (has_addrs == ISC_FALSE) {
4047 switch(client->
state) {
4052 if ((rebind >
cur_time) && (renew < rebind)) {
4053 log_debug(
"PRC: Renewal event scheduled in %d seconds, " 4054 "to run for %u seconds.",
4056 (
unsigned)(rebind - renew));
4060 add_timeout(&tv, start_renew6, client, NULL, NULL);
4072 log_debug(
"PRC: Rebind event scheduled in %d seconds, " 4073 "to run for %d seconds.",
4074 (
int)(rebind - cur_time),
4075 (
int)(hi_expire - rebind));
4079 add_timeout(&tv, start_rebind6, client, NULL, NULL);
4100 log_debug(
"PRC: Depreference scheduled in %d seconds.",
4101 (
int)(depref - cur_time));
4107 log_debug(
"PRC: Expiration scheduled in %d seconds.",
4108 (
int)(lo_expire - cur_time));
4109 tv.tv_sec = lo_expire;
4117 find_ia(
struct dhc6_ia *head, u_int16_t type,
const char *
id)
4121 for (ia = head ; ia != NULL ; ia = ia->
next) {
4124 if (memcmp(ia->
iaid,
id, 4) == 0)
4137 for (addr = head ; addr != NULL ; addr = addr->
next) {
4140 address->
len) == 0))
4153 for (pref = head ; pref != NULL ; pref = pref->
next) {
4155 (pref->
plen == plen) &&
4172 struct dhc6_ia *sia, *dia, *tia;
4173 struct dhc6_addr *saddr, *daddr, *taddr;
4176 if ((dst == NULL) || (src == NULL))
4179 for (sia = src->
bindings ; sia != NULL ; sia = sia->
next) {
4183 tia = dhc6_dup_ia(sia,
MDL);
4186 log_fatal(
"Out of memory merging lease - " 4187 "Unable to continue without losing " 4188 "state! (%s:%d)",
MDL);
4195 for (saddr = sia->
addrs ; saddr != NULL ;
4196 saddr = saddr->
next) {
4198 daddr = find_addr(dia->
addrs,
4201 daddr = find_pref(dia->
addrs,
4205 if (daddr == NULL) {
4206 taddr = dhc6_dup_addr(saddr,
MDL);
4211 "Unable to continue " 4242 #if defined (NSUPDATE) 4243 TIME dns_update_offset = 1;
4247 if (lease == NULL) {
4248 log_error(
"Cannot enter bound state unless an active lease " 4257 switch (client->
state) {
4285 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4293 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4294 if (oldia != NULL) {
4296 oldaddr = find_addr(oldia->
addrs,
4299 oldaddr = find_pref(oldia->
addrs,
4305 #if defined (NSUPDATE) 4309 dns_update_offset++);
4316 dhc6_marshall_values(
"old_", client, old,
4318 dhc6_marshall_values(
"new_", client, lease, ia, addr);
4319 script_write_requested6(client);
4323 start_decline6(client);
4329 if (ia->
addrs == NULL) {
4333 dhc6_marshall_values(
"old_", client, old,
4336 oldia->
addrs : NULL);
4338 dhc6_marshall_values(
"new_", client, lease, ia,
4340 script_write_requested6(client);
4351 dhc6_marshall_values(
"old_", client, old,
4356 dhc6_marshall_values(
"new_", client, lease, NULL, NULL);
4357 script_write_requested6(client);
4370 dhc6_check_times(client);
4396 dhc6_retrans_init(client);
4400 do_decline6(client);
4407 do_decline6(
void *input)
4412 struct timeval elapsed, tv;
4416 if ((client->active_lease == NULL) || !active_prefix(client))
4419 if ((client->MRC != 0) && (client->txcount > client->MRC)) {
4420 log_info(
"Max retransmission count exceeded.");
4427 if (client->txcount == 0) {
4428 client->start_time.tv_sec =
cur_tv.tv_sec;
4429 client->start_time.tv_usec =
cur_tv.tv_usec;
4433 elapsed.tv_sec =
cur_tv.tv_sec - client->start_time.tv_sec;
4434 elapsed.tv_usec =
cur_tv.tv_usec - client->start_time.tv_usec;
4435 if (elapsed.tv_usec < 0) {
4436 elapsed.tv_sec -= 1;
4437 elapsed.tv_usec += 1000000;
4440 memset(&ds, 0,
sizeof(ds));
4442 log_error(
"Unable to allocate memory for Decline.");
4449 memcpy(ds.
buffer->
data + 1, client->dhcpv6_transaction_id, 3);
4453 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
4454 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
4455 client->elapsed = 0xffff;
4457 client->elapsed = elapsed.tv_sec * 100;
4458 client->elapsed += elapsed.tv_usec / 10000;
4461 client->elapsed = htons(client->elapsed);
4464 make_client6_options(client, &client->sent_options,
4472 dhc6_add_ia_na(client, &ds, client->active_lease,
4478 dhc6_add_ia_pd(client, &ds, client->active_lease,
4485 log_info(
"XMT: Decline on %s, interval %ld0ms.",
4486 client->name ? client->name : client->interface->name,
4487 (
long int)client->RT);
4491 if (send_ret != ds.
len) {
4492 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
4499 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
4500 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
4501 if (tv.tv_usec >= 1000000) {
4503 tv.tv_usec -= 1000000;
4505 add_timeout(&tv, do_decline6, client, NULL, NULL);
4506 dhc6_retrans_advance(client);
4511 client->active_lease = NULL;
4520 bound_handler(
struct packet *packet,
struct client_state *client)
4522 log_debug(
"RCV: Input packets are ignored once bound.");
4530 start_renew6(
void *input)
4536 log_info(
"PRC: Renewing lease on %s.",
4551 dhc6_retrans_init(client);
4554 do_refresh6(client);
4562 do_refresh6(
void *input)
4565 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
4569 struct timeval elapsed, tv;
4573 memset(&ds, 0,
sizeof(ds));
4576 if (lease == NULL) {
4577 log_error(
"Cannot renew without an active binding.");
4588 log_fatal(
"Internal inconsistency (%d) at %s:%d.",
4607 if (((client->
MRC != 0) && (client->
txcount > client->
MRC)) ||
4610 dhc6_check_times(client);
4623 log_error(
"Invalid unicast option length %d.", ds.
len);
4625 memset(&unicast, 0,
sizeof(DHCPv6DestAddr));
4626 unicast.sin6_family = AF_INET6;
4628 memcpy(&unicast.sin6_addr, ds.
data, 16);
4630 dest_addr = &unicast;
4638 memset(&ds, 0,
sizeof(ds));
4640 log_error(
"Unable to allocate memory for packet.");
4660 log_debug(
"XMT: Forming %s, 0 ms elapsed.",
4663 log_debug(
"XMT: Forming %s, %u0 ms elapsed.",
4669 make_client6_options(client, &client->
sent_options, lease,
4679 dhc6_add_ia_na(client, &ds, lease,
4685 dhc6_add_ia_pd(client, &ds, lease,
4691 log_info(
"XMT: %s on %s, interval %ld0ms.",
4694 (
long int)client->
RT);
4698 if (send_ret != ds.
len) {
4699 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
4706 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
4707 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
4708 if (tv.tv_usec >= 1000000) {
4710 tv.tv_usec -= 1000000;
4712 add_timeout(&tv, do_refresh6, client, NULL, NULL);
4714 dhc6_retrans_advance(client);
4723 start_rebind6(
void *input)
4729 log_info(
"PRC: Rebinding lease on %s.",
4744 dhc6_retrans_init(client);
4747 do_refresh6(client);
4757 do_depref(
void *input)
4770 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4771 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4777 dhc6_marshall_values(
"cur_", client, lease,
4779 script_write_requested6(client);
4785 log_info(
"PRC: Address %s depreferred.",
4788 log_info(
"PRC: Prefix %s/%u depreferred.",
4790 (
unsigned) addr->
plen);
4792 #if defined (NSUPDATE) 4803 dhc6_check_times(client);
4810 do_expire(
void *input)
4816 int has_addrs = ISC_FALSE;
4824 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4825 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4831 dhc6_marshall_values(
"old_", client, lease,
4833 script_write_requested6(client);
4839 log_info(
"PRC: Address %s expired.",
4842 log_info(
"PRC: Prefix %s/%u expired.",
4844 (
unsigned) addr->
plen);
4846 #if defined (NSUPDATE) 4861 has_addrs = ISC_TRUE;
4866 if (has_addrs == ISC_FALSE) {
4867 log_info(
"PRC: Bound lease is devoid of active addresses." 4868 " Re-initializing.");
4878 dhc6_check_times(client);
4896 script_write_params6(client,
"old_",
4898 script_write_requested6(client);
4910 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4912 dhc6_marshall_values(
"old_", client,
4914 script_write_requested6(client);
4917 #if defined (NSUPDATE) 4927 refresh_info_request6(
void *input)
4945 isc_boolean_t found = ISC_FALSE;
4950 for (i = 0; req[i] != NULL; i++) {
4951 if (req[i] == irt_option) {
4965 memset(&irt, 0,
sizeof(irt));
4975 if (expire == 0xffffffff)
4983 log_debug(
"PRC: Refresh event scheduled in %u seconds.",
4985 tv.tv_sec = cur_time + expire;
4987 add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5005 script_write_params6(client,
"old_",
5008 script_write_requested6(client);
5019 dhc6_check_irt(client);
5025 informed_handler(
struct packet *packet,
struct client_state *client)
5027 log_debug(
"RCV: Input packets are ignored once bound.");
5041 int buflen, i, oro_len;
5043 if ((op == NULL) || (client == NULL))
5055 const unsigned char *cdata;
5057 cdata = (
unsigned char *)&client->
elapsed;
5070 lease ? lease->
options : NULL,
5087 log_fatal(
"Failure assembling a DUID.");
5099 if (lease == NULL) {
5116 log_error(
"'send dhcp6.oro' syntax is deprecated, please " 5117 "use the 'request' syntax (\"man dhclient.conf\").");
5157 log_fatal(
"Out of memory constructing DHCPv6 ORO.");
5160 for (i = 0 ; req[i] != NULL ; i++) {
5161 if (buflen == oro_len) {
5162 struct buffer *tmpbuf = NULL;
5172 "DHCPv6 ORO buffer.");
5174 memcpy(buffer->
data, tmpbuf->
data, oro_len);
5193 log_fatal(
"Unable to create ORO option cache.");
5217 script_write_params6(
struct client_state *client,
const char *prefix,
5223 if (options == NULL)
5243 static void script_write_requested6(client)
5254 for (i = 0 ; req[i] != NULL ; i++) {
5265 static isc_boolean_t
5276 memset(zeros, 0, 16);
5277 for (ia = lease->
bindings; ia != NULL; ia = ia->
next) {
5280 for (pref = ia->
addrs; pref != NULL; pref = pref->
next) {
5281 if (pref->
plen == 0)
struct timeval start_time
void start_selecting6(struct client_state *client)
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__
void(* v6_handler)(struct packet *, struct client_state *)
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 unconfigure6(struct client_state *client, const char *reason)
void client_dns_remove(struct client_state *client, struct iaddr *addr)
struct universe dhcpv6_universe
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
int(* encapsulate)(struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *)
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)