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,
57 static isc_result_t dhc6_parse_ia_ta(
struct dhc6_ia **pia,
61 static isc_result_t dhc6_parse_ia_pd(
struct dhc6_ia **pia,
65 static isc_result_t dhc6_parse_addrs(
struct dhc6_addr **paddr,
68 static isc_result_t dhc6_parse_prefixes(
struct dhc6_addr **ppref,
72 u_int16_t type,
const char *
id);
80 void do_init6(
void *input);
81 void do_info_request6(
void *input);
82 void do_confirm6(
void *input);
84 static isc_result_t dhc6_create_iaid(
struct client_state *client,
90 static isc_result_t dhc6_bare_ia_xx(
struct client_state *client,
94 static isc_result_t dhc6_add_ia_na(
struct client_state *client,
100 static isc_result_t dhc6_add_ia_ta(
struct client_state *client,
106 static isc_result_t dhc6_add_ia_pd(
struct client_state *client,
112 static isc_boolean_t stopping_finished(
void);
114 void do_select6(
void *input);
115 void do_refresh6(
void *input);
116 static void do_release6(
void *input);
118 static void start_decline6(
struct client_state *client);
119 static void do_decline6(
void *input);
120 static void start_informed(
struct client_state *client);
123 void start_renew6(
void *input);
124 void start_rebind6(
void *input);
125 void do_depref(
void *input);
126 void do_expire(
void *input);
127 static void make_client6_options(
struct client_state *client,
130 static void script_write_params6(
struct client_state *client,
133 static void script_write_requested6(
struct client_state *client);
134 static isc_boolean_t active_prefix(
struct client_state *client);
136 static int check_timing6(
struct client_state *client, u_int8_t msg_type,
142 static isc_result_t dhc6_check_status(isc_result_t rval,
165 ent = getservbyname(
"dhcpv6-client",
"udp");
173 ent = getservbyname(
"dhcpv6-server",
"udp");
180 memset(&DHCPv6DestAddr, 0,
sizeof(DHCPv6DestAddr));
181 DHCPv6DestAddr.sin6_family = AF_INET6;
184 &DHCPv6DestAddr.sin6_addr) <= 0) {
189 if (!option_code_hash_lookup(&clientid_option,
191 log_fatal(
"Unable to find the CLIENTID option definition.");
194 if (!option_code_hash_lookup(&elapsed_option,
196 log_fatal(
"Unable to find the ELAPSED_TIME option definition.");
201 log_fatal(
"Unable to find the IA_NA option definition.");
206 log_fatal(
"Unable to find the IA_TA option definition.");
211 log_fatal(
"Unable to find the IA_PD option definition.");
216 log_fatal(
"Unable to find the IAADDR option definition.");
219 if (!option_code_hash_lookup(&iaprefix_option,
222 log_fatal(
"Unable to find the IAPREFIX option definition.");
227 log_fatal(
"Unable to find the ORO option definition.");
232 log_fatal(
"Unable to find the IRT option definition.");
277 split = (base - 1) / 10;
288 range = (split * 2) + 1;
308 client->
RT = client->
IRT + dhc6_rand(client->
IRT);
312 #if (RAND_MAX >= 0x00ffffff) 314 #elif (RAND_MAX >= 0x0000ffff) 315 xid = (random() << 16) ^ random();
316 #elif (RAND_MAX >= 0x000000ff) 317 xid = (random() << 16) ^ (random() << 8) ^ random();
319 # error "Random number generator of less than 8 bits not supported." 331 struct timeval elapsed, elapsed_plus_rt;
336 if (elapsed.tv_usec < 0) {
338 elapsed.tv_usec += 1000000;
342 elapsed.tv_sec += client->
RT / 100;
343 elapsed.tv_usec += (client->
RT % 100) * 10000;
344 if (elapsed.tv_usec >= 1000000) {
346 elapsed.tv_usec -= 1000000;
352 elapsed_plus_rt.tv_sec = elapsed.tv_sec;
353 elapsed_plus_rt.tv_usec = elapsed.tv_usec;
361 client->
RT += client->
RT + dhc6_rand(client->
RT);
371 if ((client->
MRT != 0) && (client->
RT > client->
MRT))
372 client->
RT = client->
MRT + dhc6_rand(client->
MRT);
378 if (client->
MRD == 0) {
384 elapsed.tv_sec += client->
RT / 100;
385 elapsed.tv_usec += (client->
RT % 100) * 10000;
386 if (elapsed.tv_usec >= 1000000) {
388 elapsed.tv_usec -= 1000000;
390 if (elapsed.tv_sec >= client->
MRD) {
397 client->
RT = client->
MRD - elapsed_plus_rt.tv_sec;
398 client->
RT = (client->
RT * 100) -
399 (elapsed_plus_rt.tv_usec / 10000);
414 memset(&sid, 0,
sizeof(sid));
415 memset(&cid, 0,
sizeof(cid));
418 log_error(
"Response without a server identifier received.");
427 log_error(
"Response without a client identifier.");
437 log_error(
"Local client identifier is missing!");
442 sid.len != cid.len ||
443 memcmp(sid.data, cid.data, sid.len)) {
444 log_error(
"Advertise with matching transaction ID, but " 445 "mismatching client id.");
450 if (sid.data != NULL)
452 if (cid.data != NULL)
465 struct dhc6_ia **insert_ia, *ia;
467 copy =
dmalloc(
sizeof(*copy), file, line);
469 log_error(
"Out of memory for v6 lease structure.");
482 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
483 *insert_ia = dhc6_dup_ia(ia, file, line);
485 if (*insert_ia == NULL) {
490 insert_ia = &(*insert_ia)->
next;
500 dhc6_dup_ia(
struct dhc6_ia *ia,
const char *file,
int line)
505 copy =
dmalloc(
sizeof(*ia), file, line);
507 log_error(
"Out of memory for v6 duplicate IA structure.");
518 insert_addr = ©->
addrs;
519 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
520 *insert_addr = dhc6_dup_addr(addr, file, line);
522 if (*insert_addr == NULL) {
523 dhc6_ia_destroy(©, file, line);
527 insert_addr = &(*insert_addr)->
next;
541 dhc6_dup_addr(
struct dhc6_addr *addr,
const char *file,
int line)
545 copy =
dmalloc(
sizeof(*addr), file, line);
577 dhc6_leaseify(
struct packet *packet,
struct client_state* client)
586 log_error(
"Out of memory for v6 lease structure.");
593 memset(&ds, 0,
sizeof(ds));
601 log_error(
"Invalid length of DHCPv6 Preference option " 602 "(%d != 1)", ds.len);
607 lease->
pref = ds.data[0];
609 (
unsigned)lease->
pref);
625 if ((dhc6_get_status_code(lease->
options, &code, NULL) == ISC_R_SUCCESS)
636 if (dhc6_parse_ia_na(&lease->
bindings, packet,
637 lease->
options, code) != ISC_R_SUCCESS) {
646 if (dhc6_parse_ia_ta(&lease->
bindings, packet,
647 lease->
options, code) != ISC_R_SUCCESS) {
656 if (dhc6_parse_ia_pd(&lease->
bindings, packet,
657 lease->
options, code) != ISC_R_SUCCESS) {
677 log_error(
"Invalid SERVERID option cache.");
695 dhc6_parse_ia_na(
struct dhc6_ia **pia,
struct packet *packet,
704 memset(&ds, 0,
sizeof(ds));
707 for ( ; oc != NULL ; oc = oc->
next) {
710 log_error(
"Out of memory allocating IA_NA structure.");
711 return ISC_R_NOMEMORY;
716 memcpy(ia->
iaid, ds.data, 4);
742 log_debug(
"RCV: | !-- INVALID renew/rebind " 743 "times, IA_NA discarded.");
755 "IA_NA option state.");
758 return ISC_R_NOMEMORY;
776 result = dhc6_parse_addrs(&ia->
addrs, packet,
778 if (result != ISC_R_SUCCESS) {
791 if ((ia->
addrs == NULL) ||
794 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
798 "no addrs, IA_NA discarded.");
799 dhc6_ia_destroy(&ia,
MDL);
808 log_error(
"Invalid IA_NA option cache.");
812 return ISC_R_UNEXPECTED;
817 return ISC_R_SUCCESS;
821 dhc6_parse_ia_ta(
struct dhc6_ia **pia,
struct packet *packet,
830 memset(&ds, 0,
sizeof(ds));
833 for ( ; oc != NULL ; oc = oc->
next) {
836 log_error(
"Out of memory allocating IA_TA structure.");
837 return ISC_R_NOMEMORY;
842 memcpy(ia->
iaid, ds.data, 4);
858 "IA_TA option state.");
861 return ISC_R_NOMEMORY;
879 result = dhc6_parse_addrs(&ia->
addrs, packet,
881 if (result != ISC_R_SUCCESS) {
894 if ((ia->
addrs == NULL) ||
897 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
901 "no addrs, IA_TA discarded.");
902 dhc6_ia_destroy(&ia,
MDL);
911 log_error(
"Invalid IA_TA option cache.");
915 return ISC_R_UNEXPECTED;
920 return ISC_R_SUCCESS;
924 dhc6_parse_ia_pd(
struct dhc6_ia **pia,
struct packet *packet,
933 memset(&ds, 0,
sizeof(ds));
936 for ( ; oc != NULL ; oc = oc->
next) {
939 log_error(
"Out of memory allocating IA_PD structure.");
940 return ISC_R_NOMEMORY;
945 memcpy(ia->
iaid, ds.data, 4);
967 log_debug(
"RCV: | !-- INVALID renew/rebind " 968 "times, IA_PD discarded.");
980 "IA_PD option state.");
983 return ISC_R_NOMEMORY;
1001 result = dhc6_parse_prefixes(&ia->
addrs,
1004 if (result != ISC_R_SUCCESS) {
1017 if ((ia->
addrs == NULL) ||
1020 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
1021 == ISC_R_SUCCESS) &&
1024 "no prefix, IA_PD discarded.");
1025 dhc6_ia_destroy(&ia,
MDL);
1029 while (*pia != NULL)
1030 pia = &(*pia)->
next;
1034 log_error(
"Invalid IA_PD option cache.");
1038 return ISC_R_UNEXPECTED;
1043 return ISC_R_SUCCESS;
1048 dhc6_parse_addrs(
struct dhc6_addr **paddr,
struct packet *packet,
1054 isc_result_t rval = ISC_R_SUCCESS;
1057 memset(&ds, 0,
sizeof(ds));
1060 for ( ; oc != NULL ; oc = oc->
next) {
1064 "address structure.");
1065 return ISC_R_NOMEMORY;
1079 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1081 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1089 log_debug(
"RCV: | | | !-- INVALID lifetimes, " 1090 "IAADDR discarded. Check your " 1091 "server configuration.");
1105 "IAADDR option state.");
1108 return ISC_R_NOMEMORY;
1134 rval = dhc6_check_status(ISC_R_SUCCESS,
1137 if (rval != ISC_R_SUCCESS) {
1139 " issue, IAADDR discarded.");
1148 paddr = &addr->
next;
1150 log_error(
"Invalid IAADDR option cache.");
1154 return ISC_R_UNEXPECTED;
1159 return ISC_R_SUCCESS;
1163 dhc6_parse_prefixes(
struct dhc6_addr **ppfx,
struct packet *packet,
1169 isc_result_t rval = ISC_R_SUCCESS;
1172 memset(&ds, 0,
sizeof(ds));
1175 for ( ; oc != NULL ; oc = oc->
next) {
1179 "prefix structure.");
1180 return ISC_R_NOMEMORY;
1193 log_debug(
"RCV: | | X-- IAPREFIX %s/%d",
1195 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1197 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1201 if ((pfx->
plen < 4) || (pfx->
plen > 128)) {
1202 log_debug(
"RCV: | | | !-- INVALID prefix " 1203 "length, IAPREFIX discarded. " 1204 "Check your server configuration.");
1214 log_debug(
"RCV: | | | !-- INVALID lifetimes, " 1215 "IAPREFIX discarded. Check your " 1216 "server configuration.");
1230 "IAPREFIX option state.");
1233 return ISC_R_NOMEMORY;
1259 rval = dhc6_check_status(ISC_R_SUCCESS,
1262 if (rval != ISC_R_SUCCESS) {
1264 " issue IAPREFIX discarded.");
1275 log_error(
"Invalid IAPREFIX option cache.");
1279 return ISC_R_UNEXPECTED;
1284 return ISC_R_SUCCESS;
1294 if (src == NULL || *src == NULL) {
1295 log_error(
"Attempt to destroy null lease.");
1303 for (ia = lease->
bindings ; ia != NULL ; ia = nia) {
1306 dhc6_ia_destroy(&ia, file, line);
1312 dfree(lease, file, line);
1321 dhc6_ia_destroy(
struct dhc6_ia **src,
const char *file,
int line)
1326 if (src == NULL || *src == NULL) {
1327 log_error(
"Attempt to destroy null IA.");
1332 for (addr = ia->
addrs ; addr != NULL ; addr = naddr) {
1338 dfree(addr, file, line);
1344 dfree(ia, file, line);
1355 while (*head != NULL) {
1356 if ((*head)->server_id.len == new->server_id.len &&
1357 memcmp((*head)->server_id.data, new->server_id.data,
1358 new->server_id.len) == 0) {
1364 head= &(*head)->
next;
1393 #ifdef USE_ORIGINAL_CLIENT_LEASE_WEIGHTS 1394 #define SCORE_BINDING 50 1395 #define SCORE_ADDRESS 100 1397 #define SCORE_BINDING 10000 1398 #define SCORE_ADDRESS 100 1401 #define SCORE_OPTION 1 1403 #define SCORE_MIN (SCORE_BINDING + SCORE_ADDRESS) 1414 return lease->
score;
1416 lease->
score = SCORE_OPTION;
1422 for (i = 0 ; req[i] != NULL ; i++) {
1424 req[i]->
code) == NULL) {
1426 return lease->
score;
1434 for (i = 0 ; req[i] != NULL ; i++) {
1436 req[i]->
code) != NULL)
1437 lease->
score += SCORE_OPTION;
1441 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
1442 lease->
score += SCORE_BINDING;
1444 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1445 lease->
score += SCORE_ADDRESS;
1449 return lease->
score;
1461 log_debug(
"PRC: Soliciting for leases (INIT).");
1474 dhc6_retrans_init(client);
1482 if (client->
RT <= client->
IRT)
1483 client->
RT = client->
IRT + (client->
IRT - client->
RT);
1485 if (client->
RT <= client->
IRT)
1486 client->
RT = client->
IRT + 1;
1495 tv.tv_sec =
cur_tv.tv_sec;
1496 tv.tv_usec =
cur_tv.tv_usec;
1498 if (tv.tv_usec >= 1000000) {
1500 tv.tv_usec -= 1000000;
1517 log_debug(
"PRC: Requesting information (INIT).");
1530 dhc6_retrans_init(client);
1539 tv.tv_sec =
cur_tv.tv_sec;
1540 tv.tv_usec =
cur_tv.tv_usec;
1542 if (tv.tv_usec >= 1000000) {
1544 tv.tv_usec -= 1000000;
1546 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1556 unexpired_address_in_lease(
struct dhc6_lease *lease)
1561 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
1562 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1572 log_info(
"PRC: Previous lease is devoid of active addresses." 1573 " Re-initializing.");
1590 !active_prefix(client) ||
1598 log_debug(
"PRC: Confirming active lease (INIT-REBOOT).");
1607 dhc6_retrans_init(client);
1616 tv.tv_sec =
cur_tv.tv_sec;
1617 tv.tv_usec =
cur_tv.tv_usec;
1619 if (tv.tv_usec >= 1000000) {
1621 tv.tv_usec -= 1000000;
1637 add_timeout(&tv, do_refresh6, client, NULL, NULL);
1639 add_timeout(&tv, do_confirm6, client, NULL, NULL);
1646 #define CHK_TIM_SUCCESS 0 1647 #define CHK_TIM_MRC_EXCEEDED 1 1648 #define CHK_TIM_MRD_EXCEEDED 2 1649 #define CHK_TIM_ALLOC_FAILURE 3 1652 check_timing6 (
struct client_state *client, u_int8_t msg_type,
1656 struct timeval elapsed;
1664 }
else if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
1665 log_info(
"Max retransmission count exceeded.");
1666 return(CHK_TIM_MRC_EXCEEDED);
1672 if (elapsed.tv_usec < 0) {
1673 elapsed.tv_sec -= 1;
1674 elapsed.tv_usec += 1000000;
1678 if ((client->
MRD != 0) && (elapsed.tv_sec >= client->
MRD)) {
1679 log_info(
"Max retransmission duration exceeded.");
1680 return(CHK_TIM_MRD_EXCEEDED);
1683 memset(ds, 0,
sizeof(*ds));
1685 log_error(
"Unable to allocate memory for %s.", msg_str);
1686 return(CHK_TIM_ALLOC_FAILURE);
1696 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1697 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1700 client->
elapsed = elapsed.tv_sec * 100;
1701 client->
elapsed += elapsed.tv_usec / 10000;
1705 log_debug(
"XMT: Forming %s, 0 ms elapsed.", msg_str);
1707 log_debug(
"XMT: Forming %s, %u0 ms elapsed.", msg_str,
1712 make_client6_options(client, &client->
sent_options, lease, msg_type);
1714 return(CHK_TIM_SUCCESS);
1736 int start_idx, copy_len;
1738 memset(ia, 0,
sizeof(*ia));
1740 return (ISC_R_NOMEMORY);
1762 return (ISC_R_SUCCESS);
1795 struct option *type_option;
1800 type_string =
"IA_NA";
1801 type_option = ia_na_option;
1805 type_string =
"IA_TA";
1806 type_option = ia_ta_option;
1810 type_string =
"IA_PD";
1811 type_option = ia_pd_option;
1815 return (ISC_R_FAILURE);
1818 for (i = 0; wanted != 0; i++) {
1819 rval = dhc6_create_iaid(client, &ia, i, len);
1820 if (rval != ISC_R_SUCCESS) {
1821 log_error(
"Unable to allocate memory for %s.",
1848 log_debug(
"XMT: | X-- Request renew in +%u",
1850 log_debug(
"XMT: | X-- Request rebind in +%u",
1862 return (ISC_R_SUCCESS);
1869 do_init6(
void *input)
1892 switch(check_timing6(client,
DHCPV6_SOLICIT,
"Solicit", NULL, &ds)) {
1893 case CHK_TIM_MRC_EXCEEDED:
1894 case CHK_TIM_ALLOC_FAILURE:
1896 case CHK_TIM_MRD_EXCEEDED:
1903 if (stopping_finished())
1928 if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
1929 log_error(
"Unable to allocate memory for IA_NA.");
1941 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1942 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1952 memset(&addr, 0,
sizeof(addr));
1953 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1954 old_addr = old_addr->
next) {
1958 "Ignoring. (%s:%d)",
1971 addr.data = addr.buffer->data;
1974 memcpy(addr.buffer->data,
1980 putULong(addr.buffer->data + 16, t1);
1981 putULong(addr.buffer->data + 20, t2);
1983 log_debug(
"XMT: | X-- Request address %s.",
2011 if (dhc6_create_iaid(client, &ia, i, 4) != ISC_R_SUCCESS) {
2012 log_error(
"Unable to allocate memory for IA_TA.");
2028 memset(&addr, 0,
sizeof(addr));
2029 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2030 old_addr = old_addr->
next) {
2034 "Ignoring. (%s:%d)",
2047 addr.data = addr.buffer->data;
2050 memcpy(addr.buffer->data,
2056 putULong(addr.buffer->data + 16, t1);
2057 putULong(addr.buffer->data + 20, t2);
2059 log_debug(
"XMT: | X-- Request address %s.",
2087 memset(&ia, 0,
sizeof(ia));
2088 if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
2089 log_error(
"Unable to allocate memory for IA_PD.");
2101 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
2102 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
2112 memset(&addr, 0,
sizeof(addr));
2113 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2114 old_addr = old_addr->
next) {
2117 "Ignoring. (%s:%d)",
2129 addr.data = addr.buffer->data;
2135 putULong(addr.buffer->data + 4, t2);
2139 memcpy(addr.buffer->data + 9,
2143 log_debug(
"XMT: | X-- Request prefix %s/%u.",
2145 (
unsigned) old_addr->
plen);
2167 log_info(
"XMT: Solicit on %s, interval %ld0ms.",
2169 (
long int)client->
RT);
2172 ds.
data, ds.
len, &DHCPv6DestAddr);
2173 if (send_ret != ds.
len) {
2174 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2181 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2182 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2183 if (tv.tv_usec >= 1000000) {
2185 tv.tv_usec -= 1000000;
2189 dhc6_retrans_advance(client);
2194 do_info_request6(
void *input)
2204 "Info-Request", NULL, &ds)) {
2205 case CHK_TIM_MRC_EXCEEDED:
2206 case CHK_TIM_ALLOC_FAILURE:
2208 case CHK_TIM_MRD_EXCEEDED:
2210 case CHK_TIM_SUCCESS:
2222 log_info(
"XMT: Info-Request on %s, interval %ld0ms.",
2224 (
long int)client->
RT);
2227 ds.
data, ds.
len, &DHCPv6DestAddr);
2228 if (send_ret != ds.
len) {
2229 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2236 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2237 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2238 if (tv.tv_usec >= 1000000) {
2240 tv.tv_usec -= 1000000;
2242 add_timeout(&tv, do_info_request6, client, NULL, NULL);
2244 dhc6_retrans_advance(client);
2251 do_confirm6(
void *input)
2255 int send_ret, added;
2260 if (client->active_lease == NULL)
2278 client->active_lease, &ds)) {
2279 case CHK_TIM_MRC_EXCEEDED:
2280 case CHK_TIM_MRD_EXCEEDED:
2281 start_bound(client);
2283 case CHK_TIM_ALLOC_FAILURE:
2285 case CHK_TIM_SUCCESS:
2297 dhc6_add_ia_na(client, &ds, client->active_lease,
2303 dhc6_add_ia_ta(client, &ds, client->active_lease,
2311 log_info(
"XMT: Confirm on %s, interval %ld0ms.",
2312 client->name ? client->name : client->interface->name,
2313 (
long int)client->RT);
2317 if (send_ret != ds.
len) {
2318 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2325 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2326 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2327 if (tv.tv_usec >= 1000000) {
2329 tv.tv_usec -= 1000000;
2331 add_timeout(&tv, do_confirm6, client, NULL, NULL);
2333 dhc6_retrans_advance(client);
2369 dhc6_retrans_init(client);
2372 do_release6(client);
2378 do_release6(
void *input)
2382 int send_ret, added;
2387 if ((client->active_lease == NULL) || !active_prefix(client))
2391 client->active_lease, &ds)) {
2392 case CHK_TIM_MRC_EXCEEDED:
2393 case CHK_TIM_ALLOC_FAILURE:
2394 case CHK_TIM_MRD_EXCEEDED:
2396 case CHK_TIM_SUCCESS:
2411 dhc6_add_ia_na(client, &ds, client->active_lease,
2417 dhc6_add_ia_pd(client, &ds, client->active_lease,
2424 log_info(
"XMT: Release on %s, interval %ld0ms.",
2425 client->name ? client->name : client->interface->name,
2426 (
long int)client->RT);
2430 if (send_ret != ds.
len) {
2431 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2438 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2439 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2440 if (tv.tv_usec >= 1000000) {
2442 tv.tv_usec -= 1000000;
2444 add_timeout(&tv, do_release6, client, NULL, NULL);
2445 dhc6_retrans_advance(client);
2450 client->active_lease = NULL;
2451 if (stopping_finished())
2459 status_log(
int code,
const char *scope,
const char *additional,
int len)
2461 const char *msg = NULL;
2473 msg =
"NoAddrsAvail";
2485 msg =
"UseMulticast";
2489 msg =
"NoPrefixAvail";
2498 log_info(
"%s status code %s: %s", scope, msg,
2500 (
const unsigned char *)additional, 50));
2502 log_info(
"%s status code %s.", scope, msg);
2508 dhc6_get_status_code(
struct option_state *options,
unsigned *code,
2513 isc_result_t rval = ISC_R_SUCCESS;
2515 if ((options == NULL) || (code == NULL))
2518 if ((msg != NULL) && (msg->
len != 0))
2521 memset(&ds, 0,
sizeof(ds));
2536 if ((msg != NULL) && (ds.
len > 2)) {
2546 return ISC_R_NOTFOUND;
2552 dhc6_check_status(isc_result_t rval,
struct option_state *options,
2553 const char *scope,
unsigned *code)
2556 isc_result_t status;
2558 if ((scope == NULL) || (code == NULL))
2565 if (options != NULL) {
2566 memset(&msg, 0,
sizeof(msg));
2567 status = dhc6_get_status_code(options, code, &msg);
2569 if (status == ISC_R_SUCCESS) {
2570 status_log(*code, scope, (
char *)msg.
data, msg.
len);
2574 rval = ISC_R_FAILURE;
2576 }
else if (status != ISC_R_NOTFOUND)
2593 dhc6_check_advertise(
struct dhc6_lease *lease)
2596 isc_result_t rval = ISC_R_SUCCESS;
2597 int have_addrs = ISC_FALSE;
2600 int got_na = 0, got_ta = 0, got_pd = 0;
2602 rval = dhc6_check_status(rval, lease->
options,
"message", &code);
2604 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
2619 log_error(
"dhc6_check_advertise: no type.");
2620 return ISC_R_FAILURE;
2625 rval = dhc6_check_status(rval, ia->
options, scope, &code);
2626 if (rval != ISC_R_SUCCESS)
2634 if (ia->
addrs != NULL) {
2635 have_addrs = ISC_TRUE;
2642 if ((have_addrs != ISC_TRUE) ||
2644 ((got_na < wanted_ia_na) ||
2645 (got_ta < wanted_ia_ta) ||
2646 (got_pd < wanted_ia_pd))))
2647 rval = ISC_R_ADDRNOTAVAIL;
2655 static isc_boolean_t
2656 dhc6_init_action(
struct client_state *client, isc_result_t *rvalp,
2662 if (client == NULL) {
2667 if (*rvalp == ISC_R_SUCCESS)
2678 static isc_boolean_t
2679 dhc6_select_action(
struct client_state *client, isc_result_t *rvalp,
2688 if (client == NULL) {
2694 if (rval == ISC_R_SUCCESS)
2788 if ((client == NULL) || (client->
active_lease == NULL))
2793 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2806 static isc_boolean_t
2807 dhc6_reply_action(
struct client_state *client, isc_result_t *rvalp,
2815 if (client == NULL) {
2821 if (rval == ISC_R_SUCCESS)
2871 dhc6_withdraw_lease(client);
2907 static isc_boolean_t
2908 dhc6_stop_action(
struct client_state *client, isc_result_t *rvalp,
2916 if (client == NULL) {
2922 if (rval == ISC_R_SUCCESS)
2937 if (rval == ISC_R_FAILURE)
2938 *rvalp = ISC_R_SUCCESS;
2974 isc_result_t *, unsigned);
2976 isc_result_t rval = ISC_R_SUCCESS;
2980 int have_addrs = ISC_FALSE;
2981 int got_na = 0, got_ta = 0, got_pd = 0;
2983 if ((client == NULL) || (
new == NULL))
2986 switch (client->
state) {
2988 action = dhc6_init_action;
2993 action = dhc6_select_action;
2998 action = dhc6_reply_action;
3003 action = dhc6_stop_action;
3008 return ISC_R_CANCELED;
3015 rval = dhc6_check_status(rval, new->options,
"message", &code);
3016 if (action(client, &rval, code))
3017 return ISC_R_CANCELED;
3019 for (ia = new->bindings ; ia != NULL ; ia = ia->
next) {
3034 log_error(
"dhc6_check_reply: no type.");
3037 rval = dhc6_check_status(rval, ia->
options, scope, &code);
3039 if (action(client, &rval, code))
3040 return ISC_R_CANCELED;
3042 if (ia->
addrs != NULL) {
3043 have_addrs = ISC_TRUE;
3060 if ((have_addrs != ISC_TRUE) ||
3062 ((got_na < wanted_ia_na) ||
3064 (got_pd < wanted_ia_pd)))) {
3065 rval = ISC_R_FAILURE;
3067 return ISC_R_CANCELED;
3075 switch (client->
state) {
3080 nscore = dhc6_score_lease(client,
new);
3083 (nscore < (sscore / 2))) {
3089 log_error(
"PRC: BAIT AND SWITCH detected. Score of " 3090 "supplied lease (%d) is substantially " 3091 "smaller than the advertised score (%d). " 3092 "Trying other servers.",
3100 return ISC_R_CANCELED;
3124 log_fatal(
"REALLY impossible condition at %s:%d.",
MDL);
3125 return ISC_R_CANCELED;
3137 init_handler(
struct packet *packet,
struct client_state *client)
3150 if (!valid_reply(packet, client)) {
3151 log_error(
"Invalid Advertise - rejecting.");
3155 lease = dhc6_leaseify(packet, client);
3163 if (dhc6_check_advertise(lease) != ISC_R_SUCCESS) {
3164 log_debug(
"PRC: Lease failed to satisfy.");
3182 ((lease->
pref == 255) &&
3183 (dhc6_score_lease(client, lease) > SCORE_MIN))) {
3184 log_debug(
"RCV: Advertisement immediately selected.");
3188 log_debug(
"RCV: Advertisement recorded.");
3194 info_request_handler(
struct packet *packet,
struct client_state *client)
3196 isc_result_t check_status;
3205 if (!valid_reply(packet, client)) {
3206 log_error(
"Invalid Reply - rejecting.");
3210 check_status = dhc6_check_status(ISC_R_SUCCESS, packet->
options,
3213 if (check_status != ISC_R_SUCCESS) {
3217 if (check_status != ISC_R_CANCELED)
3227 if (check_status == ISC_R_CANCELED)
3241 log_fatal(
"Out of memory for v6 lease structure.");
3251 start_informed(client);
3257 rapid_commit_handler(
struct packet *packet,
struct client_state *client)
3260 isc_result_t check_status;
3265 init_handler(packet, client);
3273 if (!valid_reply(packet, client)) {
3274 log_error(
"Invalid Reply - rejecting.");
3281 log_error(
"Reply without Rapid-Commit - rejecting.");
3285 lease = dhc6_leaseify(packet, client);
3293 check_status = dhc6_check_reply(client, lease);
3294 if (check_status != ISC_R_SUCCESS) {
3327 start_bound(client);
3362 struct dhc6_lease **rpos, *rval, **candp, *cand;
3365 if (head == NULL || *head == NULL)
3370 rscore = dhc6_score_lease(client, rval);
3371 candp = &rval->
next;
3374 log_debug(
"PRC: Considering best lease.");
3375 log_debug(
"PRC: X-- Initial candidate %s (s: %d, p: %u).",
3378 rscore, (
unsigned)rval->
pref);
3380 for (; cand != NULL ; candp = &cand->
next, cand = *candp) {
3381 cscore = dhc6_score_lease(client, cand);
3383 log_debug(
"PRC: X-- Candidate %s (s: %d, p: %u).",
3386 cscore, (
unsigned)cand->
pref);
3410 if ((rscore < SCORE_MIN) && (cscore >= SCORE_MIN)) {
3411 log_debug(
"PRC: | X-- Selected, has bindings.");
3412 }
else if (cand->
pref < rval->
pref) {
3413 log_debug(
"PRC: | X-- Rejected, lower preference.");
3415 }
else if (cand->
pref > rval->
pref) {
3416 log_debug(
"PRC: | X-- Selected, higher preference.");
3417 }
else if (cscore > rscore) {
3418 log_debug(
"PRC: | X-- Selected, equal preference, " 3420 }
else if (cscore < rscore) {
3421 log_debug(
"PRC: | X-- Rejected, equal preference, " 3429 log_debug(
"PRC: | X-- Selected, equal preference, " 3430 "equal score, binary lesser server ID.");
3432 log_debug(
"PRC: | X-- Rejected, equal preference, " 3433 "equal score, binary greater server ID.");
3457 log_error(
"Can not enter DHCPv6 SELECTING state with no " 3458 "leases to select from!");
3462 log_debug(
"PRC: Selecting best advertised lease.");
3478 dhc6_retrans_init(client);
3491 do_select6(
void *input)
3497 int send_ret, added;
3503 if (lease == NULL || lease->
bindings == NULL) {
3504 log_error(
"Illegal to attempt selection without selecting " 3509 switch(check_timing6(client,
DHCPV6_REQUEST,
"Request", lease, &ds)) {
3510 case CHK_TIM_MRC_EXCEEDED:
3511 case CHK_TIM_MRD_EXCEEDED:
3526 case CHK_TIM_ALLOC_FAILURE:
3528 case CHK_TIM_SUCCESS:
3556 wanted_ia_na, &added) != ISC_R_SUCCESS) ||
3557 (dhc6_bare_ia_xx(client, &ds, wanted_ia_na - added,
3564 wanted_ia_ta, &added) != ISC_R_SUCCESS) ||
3565 (dhc6_bare_ia_xx(client, &ds, wanted_ia_ta - added,
3572 wanted_ia_pd, &added) != ISC_R_SUCCESS) ||
3573 (dhc6_bare_ia_xx(client, &ds, wanted_ia_pd - added,
3579 log_info(
"XMT: Request on %s, interval %ld0ms.",
3581 (
long int)client->
RT);
3584 ds.
data, ds.
len, &DHCPv6DestAddr);
3585 if (send_ret != ds.
len) {
3586 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
3593 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
3594 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
3595 if (tv.tv_usec >= 1000000) {
3597 tv.tv_usec -= 1000000;
3601 dhc6_retrans_advance(client);
3614 dhc6_count_ia(
struct dhc6_lease *lease, u_int16_t ia_type)
3619 for (ia = lease->
bindings; ia != NULL; ia = ia->
next) {
3656 int wanted,
int *added)
3662 isc_result_t rval = ISC_R_SUCCESS;
3667 memset(&iads, 0,
sizeof(iads));
3668 memset(&addrds, 0,
sizeof(addrds));
3670 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3679 log_error(
"Unable to allocate memory for IA_NA.");
3680 rval = ISC_R_NOMEMORY;
3685 memcpy(iads.buffer->data, ia->
iaid, 4);
3686 iads.data = iads.buffer->data;
3696 #if MAX_TIME > 0xffffffff 3697 if (t1 > 0xffffffff)
3699 if (t2 > 0xffffffff)
3702 putULong(iads.buffer->data + 4, t1);
3703 putULong(iads.buffer->data + 8, t2);
3707 log_debug(
"XMT: | X-- Requested renew +%u",
3709 log_debug(
"XMT: | X-- Requested rebind +%u",
3717 memset(iads.buffer->data + 4, 0, 8);
3727 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3737 log_error(
"Illegal IPv6 address length (%d), " 3738 "ignoring. (%s:%d)",
3744 log_error(
"Unable to allocate memory for " 3746 rval = ISC_R_NOMEMORY;
3750 addrds.data = addrds.buffer->data;
3763 putULong(addrds.buffer->data + 16, t1);
3764 putULong(addrds.buffer->data + 20, t2);
3769 "lifetime +%u", (
unsigned)t1);
3770 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3780 memset(addrds.buffer->data + 16, 0, 8);
3781 log_debug(
"XMT: | X-- Confirm Address %s",
3787 memset(addrds.buffer->data + 16, 0, 8);
3788 log_debug(
"XMT: | X-- Release Address %s",
3794 memset(addrds.buffer->data + 16, 0, 8);
3795 log_debug(
"XMT: | X-- Decline Address %s",
3800 log_fatal(
"Impossible condition at %s:%d.",
3813 if (ia->
addrs == NULL) {
3814 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
3815 rval = ISC_R_FAILURE;
3816 }
else if (rval == ISC_R_SUCCESS) {
3825 if (rval == ISC_R_SUCCESS)
3859 int wanted,
int *added)
3865 isc_result_t rval = ISC_R_SUCCESS;
3870 memset(&iads, 0,
sizeof(iads));
3871 memset(&addrds, 0,
sizeof(addrds));
3873 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3882 log_error(
"Unable to allocate memory for IA_TA.");
3883 rval = ISC_R_NOMEMORY;
3888 memcpy(iads.buffer->data, ia->
iaid, 4);
3889 iads.data = iads.buffer->data;
3895 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3905 log_error(
"Illegal IPv6 address length (%d), " 3906 "ignoring. (%s:%d)",
3912 log_error(
"Unable to allocate memory for " 3914 rval = ISC_R_NOMEMORY;
3918 addrds.data = addrds.buffer->data;
3931 putULong(addrds.buffer->data + 16, t1);
3932 putULong(addrds.buffer->data + 20, t2);
3937 "lifetime +%u", (
unsigned)t1);
3938 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3948 memset(addrds.buffer->data + 16, 0, 8);
3949 log_debug(
"XMT: | X-- Confirm Address %s",
3955 memset(addrds.buffer->data + 16, 0, 8);
3956 log_debug(
"XMT: | X-- Release Address %s",
3961 log_fatal(
"Impossible condition at %s:%d.",
3974 if (ia->
addrs == NULL) {
3975 log_debug(
"!!!: V IA_TA has no IAADDRs - removed.");
3976 rval = ISC_R_FAILURE;
3977 }
else if (rval == ISC_R_SUCCESS) {
3986 if (rval == ISC_R_SUCCESS)
4020 int wanted,
int *added)
4026 isc_result_t rval = ISC_R_SUCCESS;
4031 memset(&iads, 0,
sizeof(iads));
4032 memset(&prefds, 0,
sizeof(prefds));
4034 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
4043 log_error(
"Unable to allocate memory for IA_PD.");
4044 rval = ISC_R_NOMEMORY;
4049 memcpy(iads.buffer->data, ia->
iaid, 4);
4050 iads.data = iads.buffer->data;
4060 #if MAX_TIME > 0xffffffff 4061 if (t1 > 0xffffffff)
4063 if (t2 > 0xffffffff)
4066 putULong(iads.buffer->data + 4, t1);
4067 putULong(iads.buffer->data + 8, t2);
4071 log_debug(
"XMT: | X-- Requested renew +%u",
4073 log_debug(
"XMT: | X-- Requested rebind +%u",
4079 memset(iads.buffer->data + 4, 0, 8);
4089 for (pref = ia->
addrs ; pref != NULL ; pref = pref->
next) {
4100 "ignoring. (%s:%d)",
4105 if (pref->
plen == 0) {
4107 "ignoring. (%s:%d)",
4112 log_error(
"Unable to allocate memory for " 4114 rval = ISC_R_NOMEMORY;
4118 prefds.data = prefds.buffer->data;
4123 memcpy(prefds.buffer->data + 9,
4135 putULong(prefds.buffer->data + 4, t2);
4137 log_debug(
"XMT: | | X-- IAPREFIX %s/%u",
4139 (
unsigned) pref->
plen);
4141 "lifetime +%u", (
unsigned)t1);
4142 log_debug(
"XMT: | | | X-- Max lifetime +%u",
4149 memset(prefds.buffer->data, 0, 8);
4150 log_debug(
"XMT: | X-- Release Prefix %s/%u",
4152 (
unsigned) pref->
plen);
4156 log_fatal(
"Impossible condition at %s:%d.",
4161 iaprefix_option, &prefds);
4169 if (ia->
addrs == NULL) {
4170 log_debug(
"!!!: V IA_PD has no IAPREFIXs - removed.");
4171 rval = ISC_R_FAILURE;
4172 }
else if (rval == ISC_R_SUCCESS) {
4175 ia_pd_option, &iads);
4181 if (rval == ISC_R_SUCCESS)
4189 static isc_boolean_t
4190 stopping_finished(
void)
4196 for (client = ip -> client; client; client = client ->
next) {
4210 reply_handler(
struct packet *packet,
struct client_state *client)
4213 isc_result_t check_status;
4221 if (!valid_reply(packet, client)) {
4222 log_error(
"Invalid Reply - rejecting.");
4226 lease = dhc6_leaseify(packet, client);
4234 check_status = dhc6_check_reply(client, lease);
4235 if (check_status != ISC_R_SUCCESS) {
4241 if (check_status != ISC_R_CANCELED)
4260 if (stopping_finished())
4273 if (check_status == ISC_R_CANCELED)
4289 start_bound(client);
4317 start_bound(client);
4334 dhc6_marshall_values(
const char *prefix,
struct client_state *client,
4341 if ((lease != NULL) && (lease->
options != NULL))
4342 script_write_params6(client, prefix, lease->
options);
4343 if ((ia != NULL) && (ia->
options != NULL))
4344 script_write_params6(client, prefix, ia->
options);
4345 if ((addr != NULL) && (addr->
options != NULL))
4346 script_write_params6(client, prefix, addr->
options);
4352 "ip6_prefix",
"%s/%u",
4354 (
unsigned) addr->
plen);
4363 "ip6_type",
"temporary");
4394 lo_expire=
MAX_TIME, hi_expire=0, max_ia_starts = 0, tmp;
4395 int has_addrs = ISC_FALSE;
4408 for(ia = lease->bindings ; ia != NULL ; ia = ia->
next) {
4409 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
4412 this_ia_hi_expire = 0;
4414 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4436 if (tmp > this_ia_hi_expire)
4437 this_ia_hi_expire = tmp;
4438 if (tmp < this_ia_lo_expire)
4439 this_ia_lo_expire = tmp;
4441 has_addrs = ISC_TRUE;
4446 if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
4447 use_expire = this_ia_hi_expire;
4449 use_expire = this_ia_lo_expire;
4455 if ((use_expire ==
MAX_TIME) || (use_expire <= 1))
4472 if (ia->
starts > max_ia_starts)
4473 max_ia_starts = ia->
starts;
4475 if (ia->
renew == 0) {
4477 }
else if (ia->
renew == 0xffffffff)
4487 tmp = use_expire + (use_expire / 2);
4488 }
else if (ia->
rebind == 0xffffffff)
4501 this_ia_hi_expire += ia->
starts;
4502 this_ia_lo_expire += ia->
starts;
4504 if (this_ia_hi_expire > hi_expire)
4505 hi_expire = this_ia_hi_expire;
4506 if (this_ia_lo_expire < lo_expire)
4507 lo_expire = this_ia_lo_expire;
4519 if (has_addrs == ISC_FALSE) {
4533 renew += max_ia_starts;
4535 rebind += max_ia_starts;
4537 switch(client->
state) {
4542 if ((rebind >
cur_time) && (renew < rebind)) {
4543 log_debug(
"PRC: Renewal event scheduled in %d seconds, " 4544 "to run for %u seconds.",
4546 (
unsigned)(rebind - renew));
4550 add_timeout(&tv, start_renew6, client, NULL, NULL);
4562 log_debug(
"PRC: Rebind event scheduled in %d seconds, " 4563 "to run for %d seconds.",
4564 (
int)(rebind - cur_time),
4565 (
int)(hi_expire - rebind));
4569 add_timeout(&tv, start_rebind6, client, NULL, NULL);
4590 log_debug(
"PRC: Depreference scheduled in %d seconds.",
4591 (
int)(depref - cur_time));
4597 log_debug(
"PRC: Expiration scheduled in %d seconds.",
4598 (
int)(lo_expire - cur_time));
4599 tv.tv_sec = lo_expire;
4607 find_ia(
struct dhc6_ia *head, u_int16_t type,
const char *
id)
4611 for (ia = head ; ia != NULL ; ia = ia->
next) {
4614 if (memcmp(ia->
iaid,
id, 4) == 0)
4627 for (addr = head ; addr != NULL ; addr = addr->
next) {
4630 address->
len) == 0))
4643 for (pref = head ; pref != NULL ; pref = pref->
next) {
4645 (pref->
plen == plen) &&
4676 struct dhc6_ia *sia, *dia, *tia, **eia;
4677 struct dhc6_addr *saddr, *daddr, *taddr;
4680 if ((dst == NULL) || (src == NULL))
4683 for (sia = src->
bindings ; sia != NULL ; sia = sia->
next) {
4687 tia = dhc6_dup_ia(sia,
MDL);
4690 log_fatal(
"Out of memory merging lease - " 4691 "Unable to continue without losing " 4692 "state! (%s:%d)",
MDL);
4704 eia = &(*eia)->
next) {
4710 for (saddr = sia->
addrs ; saddr != NULL ;
4711 saddr = saddr->
next) {
4713 daddr = find_addr(dia->
addrs,
4716 daddr = find_pref(dia->
addrs,
4720 if (daddr == NULL) {
4721 taddr = dhc6_dup_addr(saddr,
MDL);
4726 "Unable to continue " 4757 #if defined (NSUPDATE) 4758 TIME dns_update_offset = 1;
4762 if (lease == NULL) {
4763 log_error(
"Cannot enter bound state unless an active lease " 4772 switch (client->
state) {
4800 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4808 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4813 if (oldia != NULL) {
4815 oldaddr = find_addr(oldia->
addrs,
4818 oldaddr = find_pref(oldia->
addrs,
4824 #if defined (NSUPDATE) 4828 dns_update_offset++);
4835 dhc6_marshall_values(
"old_", client, old,
4837 dhc6_marshall_values(
"new_", client, lease, ia, addr);
4838 script_write_requested6(client);
4842 start_decline6(client);
4848 if (ia->
addrs == NULL) {
4852 dhc6_marshall_values(
"old_", client, old,
4855 oldia->
addrs : NULL);
4857 dhc6_marshall_values(
"new_", client, lease, ia,
4859 script_write_requested6(client);
4870 dhc6_marshall_values(
"old_", client, old,
4875 dhc6_marshall_values(
"new_", client, lease, NULL, NULL);
4876 script_write_requested6(client);
4894 dhc6_check_times(client);
4920 dhc6_retrans_init(client);
4924 do_decline6(client);
4931 do_decline6(
void *input)
4935 struct timeval elapsed, tv;
4936 int send_ret, added;
4940 if ((client->
active_lease == NULL) || !active_prefix(client))
4943 if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
4944 log_info(
"Max retransmission count exceeded.");
4959 if (elapsed.tv_usec < 0) {
4960 elapsed.tv_sec -= 1;
4961 elapsed.tv_usec += 1000000;
4964 memset(&ds, 0,
sizeof(ds));
4966 log_error(
"Unable to allocate memory for Decline.");
4977 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
4978 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
4981 client->
elapsed = elapsed.tv_sec * 100;
4982 client->
elapsed += elapsed.tv_usec / 10000;
5009 log_info(
"XMT: Decline on %s, interval %ld0ms.",
5011 (
long int)client->
RT);
5015 if (send_ret != ds.
len) {
5016 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
5023 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5024 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5025 if (tv.tv_usec >= 1000000) {
5027 tv.tv_usec -= 1000000;
5029 add_timeout(&tv, do_decline6, client, NULL, NULL);
5030 dhc6_retrans_advance(client);
5044 bound_handler(
struct packet *packet,
struct client_state *client)
5046 log_debug(
"RCV: Input packets are ignored once bound.");
5054 start_renew6(
void *input)
5060 log_info(
"PRC: Renewing lease on %s.",
5075 dhc6_retrans_init(client);
5078 do_refresh6(client);
5086 do_refresh6(
void *input)
5089 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
5093 struct timeval elapsed, tv;
5094 int send_ret, added;
5097 memset(&ds, 0,
sizeof(ds));
5100 if (lease == NULL) {
5101 log_error(
"Cannot renew without an active binding.");
5112 log_fatal(
"Internal inconsistency (%d) at %s:%d.",
5131 if (((client->
MRC != 0) && (client->
txcount > client->
MRC)) ||
5134 dhc6_check_times(client);
5147 log_error(
"Invalid unicast option length %d.", ds.
len);
5149 memset(&unicast, 0,
sizeof(DHCPv6DestAddr));
5150 unicast.sin6_family = AF_INET6;
5152 memcpy(&unicast.sin6_addr, ds.
data, 16);
5154 dest_addr = &unicast;
5162 memset(&ds, 0,
sizeof(ds));
5164 log_error(
"Unable to allocate memory for packet.");
5184 log_debug(
"XMT: Forming %s, 0 ms elapsed.",
5187 log_debug(
"XMT: Forming %s, %u0 ms elapsed.",
5193 make_client6_options(client, &client->
sent_options, lease,
5207 ((dhc6_add_ia_na(client, &ds, lease, client->
refresh_type,
5208 wanted_ia_na, &added) != ISC_R_SUCCESS) ||
5209 (dhc6_bare_ia_xx(client, &ds, wanted_ia_na - added,
5215 ((dhc6_add_ia_pd(client, &ds, lease, client->
refresh_type,
5216 wanted_ia_pd, &added) != ISC_R_SUCCESS) ||
5217 (dhc6_bare_ia_xx(client, &ds, wanted_ia_pd - added,
5223 log_info(
"XMT: %s on %s, interval %ld0ms.",
5226 (
long int)client->
RT);
5230 if (send_ret != ds.
len) {
5231 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
5238 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5239 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5240 if (tv.tv_usec >= 1000000) {
5242 tv.tv_usec -= 1000000;
5244 add_timeout(&tv, do_refresh6, client, NULL, NULL);
5246 dhc6_retrans_advance(client);
5255 start_rebind6(
void *input)
5261 log_info(
"PRC: Rebinding lease on %s.",
5276 dhc6_retrans_init(client);
5279 do_refresh6(client);
5289 do_depref(
void *input)
5302 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
5303 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5309 dhc6_marshall_values(
"cur_", client, lease,
5311 script_write_requested6(client);
5317 log_info(
"PRC: Address %s depreferred.",
5320 log_info(
"PRC: Prefix %s/%u depreferred.",
5322 (
unsigned) addr->
plen);
5324 #if defined (NSUPDATE) 5335 dhc6_check_times(client);
5342 do_expire(
void *input)
5348 int has_addrs = ISC_FALSE;
5349 int ia_has_addrs = ISC_FALSE;
5358 ia_has_addrs = ISC_FALSE;
5359 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5365 dhc6_marshall_values(
"old_", client, lease,
5367 script_write_requested6(client);
5373 log_info(
"PRC: Address %s expired.",
5376 log_info(
"PRC: Prefix %s/%u expired.",
5378 (
unsigned) addr->
plen);
5380 #if defined (NSUPDATE) 5395 ia_has_addrs = ISC_TRUE;
5396 has_addrs = ISC_TRUE;
5402 if (ia_has_addrs == ISC_TRUE) {
5404 tia = &(*tia)->
next;
5410 dhc6_ia_destroy(&ia,
MDL);
5417 if (has_addrs == ISC_FALSE) {
5418 log_info(
"PRC: Bound lease is devoid of active addresses." 5419 " Re-initializing.");
5429 dhc6_check_times(client);
5447 script_write_params6(client,
"old_",
5449 script_write_requested6(client);
5461 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5463 dhc6_marshall_values(
"old_", client,
5465 script_write_requested6(client);
5468 #if defined (NSUPDATE) 5478 refresh_info_request6(
void *input)
5496 isc_boolean_t found = ISC_FALSE;
5501 for (i = 0; req[i] != NULL; i++) {
5502 if (req[i] == irt_option) {
5520 memset(&irt, 0,
sizeof(irt));
5530 if (expire == 0xffffffff)
5538 log_debug(
"PRC: Refresh event scheduled in %u seconds.",
5540 tv.tv_sec = cur_time + expire;
5542 add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5560 script_write_params6(client,
"old_",
5563 script_write_requested6(client);
5579 dhc6_check_irt(client);
5585 informed_handler(
struct packet *packet,
struct client_state *client)
5587 log_debug(
"RCV: Input packets are ignored once bound.");
5601 int buflen, i, oro_len;
5603 if ((op == NULL) || (client == NULL))
5615 const unsigned char *cdata;
5617 cdata = (
unsigned char *)&client->
elapsed;
5630 lease ? lease->
options : NULL,
5647 log_fatal(
"Failure assembling a DUID.");
5659 if (lease == NULL) {
5676 log_error(
"'send dhcp6.oro' syntax is deprecated, please " 5677 "use the 'request' syntax (\"man dhclient.conf\").");
5717 log_fatal(
"Out of memory constructing DHCPv6 ORO.");
5720 for (i = 0 ; req[i] != NULL ; i++) {
5721 if (buflen == oro_len) {
5722 struct buffer *tmpbuf = NULL;
5732 "DHCPv6 ORO buffer.");
5734 memcpy(buffer->
data, tmpbuf->
data, oro_len);
5753 log_fatal(
"Unable to create ORO option cache.");
5777 script_write_params6(
struct client_state *client,
const char *prefix,
5783 if (options == NULL)
5803 static void script_write_requested6(client)
5809 req = client->config->requested_options;
5814 for (i = 0 ; req[i] != NULL ; i++) {
5825 static isc_boolean_t
5836 memset(zeros, 0, 16);
5837 for (ia = lease->
bindings; ia != NULL; ia = ia->
next) {
5840 for (pref = ia->
addrs; pref != NULL; pref = pref->
next) {
5841 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]
struct group * on_receipt
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
#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)
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)