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,
146 static int dhc6_score_lease(
struct client_state *client,
148 static isc_result_t dhc6_add_ia_na_decline(
struct client_state *client,
152 static isc_boolean_t unexpired_address_in_lease(
struct dhc6_lease *
lease);
156 extern int prefix_len_hint;
174 ent = getservbyname(
"dhcpv6-client",
"udp");
182 ent = getservbyname(
"dhcpv6-server",
"udp");
189 memset(&DHCPv6DestAddr, 0,
sizeof(DHCPv6DestAddr));
190 DHCPv6DestAddr.sin6_family = AF_INET6;
193 &DHCPv6DestAddr.sin6_addr) <= 0) {
198 if (!option_code_hash_lookup(&clientid_option,
200 log_fatal(
"Unable to find the CLIENTID option definition.");
203 if (!option_code_hash_lookup(&elapsed_option,
205 log_fatal(
"Unable to find the ELAPSED_TIME option definition.");
210 log_fatal(
"Unable to find the IA_NA option definition.");
215 log_fatal(
"Unable to find the IA_TA option definition.");
220 log_fatal(
"Unable to find the IA_PD option definition.");
225 log_fatal(
"Unable to find the IAADDR option definition.");
228 if (!option_code_hash_lookup(&iaprefix_option,
231 log_fatal(
"Unable to find the IAPREFIX option definition.");
236 log_fatal(
"Unable to find the ORO option definition.");
241 log_fatal(
"Unable to find the IRT option definition.");
286 split = (base - 1) / 10;
297 range = (split * 2) + 1;
317 client->
RT = client->
IRT + dhc6_rand(client->
IRT);
321 #if (RAND_MAX >= 0x00ffffff)
323 #elif (RAND_MAX >= 0x0000ffff)
324 xid = (random() << 16) ^ random();
325 #elif (RAND_MAX >= 0x000000ff)
326 xid = (random() << 16) ^ (random() << 8) ^ random();
328 # error "Random number generator of less than 8 bits not supported."
340 struct timeval elapsed, elapsed_plus_rt;
345 if (elapsed.tv_usec < 0) {
347 elapsed.tv_usec += 1000000;
351 elapsed.tv_sec += client->
RT / 100;
352 elapsed.tv_usec += (client->
RT % 100) * 10000;
353 if (elapsed.tv_usec >= 1000000) {
355 elapsed.tv_usec -= 1000000;
361 elapsed_plus_rt.tv_sec = elapsed.tv_sec;
362 elapsed_plus_rt.tv_usec = elapsed.tv_usec;
370 client->
RT += client->
RT + dhc6_rand(client->
RT);
380 if ((client->
MRT != 0) && (client->
RT > client->
MRT))
381 client->
RT = client->
MRT + dhc6_rand(client->
MRT);
387 if (client->
MRD == 0) {
393 elapsed.tv_sec += client->
RT / 100;
394 elapsed.tv_usec += (client->
RT % 100) * 10000;
395 if (elapsed.tv_usec >= 1000000) {
397 elapsed.tv_usec -= 1000000;
399 if (elapsed.tv_sec >= client->
MRD) {
406 client->
RT = client->
MRD - elapsed_plus_rt.tv_sec;
407 client->
RT = (client->
RT * 100) -
408 (elapsed_plus_rt.tv_usec / 10000);
423 memset(&sid, 0,
sizeof(sid));
424 memset(&cid, 0,
sizeof(cid));
427 log_error(
"Response without a server identifier received.");
436 log_error(
"Response without a client identifier.");
446 log_error(
"Local client identifier is missing!");
451 sid.len != cid.len ||
452 memcmp(sid.data, cid.data, sid.len)) {
453 log_error(
"Advertise with matching transaction ID, but "
454 "mismatching client id.");
459 if (sid.data != NULL)
461 if (cid.data != NULL)
474 struct dhc6_ia **insert_ia, *ia;
476 copy =
dmalloc(
sizeof(*copy), file, line);
478 log_error(
"Out of memory for v6 lease structure.");
491 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
492 *insert_ia = dhc6_dup_ia(ia, file, line);
494 if (*insert_ia == NULL) {
499 insert_ia = &(*insert_ia)->
next;
509 dhc6_dup_ia(
struct dhc6_ia *ia,
const char *file,
int line)
514 copy =
dmalloc(
sizeof(*ia), file, line);
516 log_error(
"Out of memory for v6 duplicate IA structure.");
527 insert_addr = ©->
addrs;
528 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
529 *insert_addr = dhc6_dup_addr(addr, file, line);
531 if (*insert_addr == NULL) {
532 dhc6_ia_destroy(©, file, line);
536 insert_addr = &(*insert_addr)->
next;
550 dhc6_dup_addr(
struct dhc6_addr *addr,
const char *file,
int line)
554 copy =
dmalloc(
sizeof(*addr), file, line);
586 dhc6_leaseify(
struct packet *packet,
struct client_state* client)
595 log_error(
"Out of memory for v6 lease structure.");
602 memset(&ds, 0,
sizeof(ds));
610 log_error(
"Invalid length of DHCPv6 Preference option "
611 "(%d != 1)", ds.len);
616 lease->
pref = ds.data[0];
618 (
unsigned)lease->
pref);
645 if (dhc6_parse_ia_na(&lease->
bindings, packet,
655 if (dhc6_parse_ia_ta(&lease->
bindings, packet,
665 if (dhc6_parse_ia_pd(&lease->
bindings, packet,
686 log_error(
"Invalid SERVERID option cache.");
704 dhc6_parse_ia_na(
struct dhc6_ia **pia,
struct packet *packet,
713 memset(&ds, 0,
sizeof(ds));
716 for ( ; oc != NULL ; oc = oc->
next) {
719 log_error(
"Out of memory allocating IA_NA structure.");
720 return ISC_R_NOMEMORY;
725 memcpy(ia->
iaid, ds.data, 4);
751 log_debug(
"RCV: | !-- INVALID renew/rebind "
752 "times, IA_NA discarded.");
764 "IA_NA option state.");
767 return ISC_R_NOMEMORY;
785 result = dhc6_parse_addrs(&ia->
addrs, packet,
800 if ((ia->
addrs == NULL) ||
803 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
807 "no addrs, IA_NA discarded.");
808 dhc6_ia_destroy(&ia,
MDL);
817 log_error(
"Invalid IA_NA option cache.");
821 return ISC_R_UNEXPECTED;
830 dhc6_parse_ia_ta(
struct dhc6_ia **pia,
struct packet *packet,
839 memset(&ds, 0,
sizeof(ds));
842 for ( ; oc != NULL ; oc = oc->
next) {
845 log_error(
"Out of memory allocating IA_TA structure.");
846 return ISC_R_NOMEMORY;
851 memcpy(ia->
iaid, ds.data, 4);
867 "IA_TA option state.");
870 return ISC_R_NOMEMORY;
888 result = dhc6_parse_addrs(&ia->
addrs, packet,
903 if ((ia->
addrs == NULL) ||
906 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
910 "no addrs, IA_TA discarded.");
911 dhc6_ia_destroy(&ia,
MDL);
920 log_error(
"Invalid IA_TA option cache.");
924 return ISC_R_UNEXPECTED;
933 dhc6_parse_ia_pd(
struct dhc6_ia **pia,
struct packet *packet,
942 memset(&ds, 0,
sizeof(ds));
945 for ( ; oc != NULL ; oc = oc->
next) {
948 log_error(
"Out of memory allocating IA_PD structure.");
949 return ISC_R_NOMEMORY;
954 memcpy(ia->
iaid, ds.data, 4);
976 log_debug(
"RCV: | !-- INVALID renew/rebind "
977 "times, IA_PD discarded.");
989 "IA_PD option state.");
992 return ISC_R_NOMEMORY;
1010 result = dhc6_parse_prefixes(&ia->
addrs,
1026 if ((ia->
addrs == NULL) ||
1029 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
1033 "no prefix, IA_PD discarded.");
1034 dhc6_ia_destroy(&ia,
MDL);
1038 while (*pia != NULL)
1039 pia = &(*pia)->
next;
1043 log_error(
"Invalid IA_PD option cache.");
1047 return ISC_R_UNEXPECTED;
1057 dhc6_parse_addrs(
struct dhc6_addr **paddr,
struct packet *packet,
1066 memset(&ds, 0,
sizeof(ds));
1069 for ( ; oc != NULL ; oc = oc->
next) {
1073 "address structure.");
1074 return ISC_R_NOMEMORY;
1088 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1090 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1098 log_debug(
"RCV: | | | !-- INVALID lifetimes, "
1099 "IAADDR discarded. Check your "
1100 "server configuration.");
1114 "IAADDR option state.");
1117 return ISC_R_NOMEMORY;
1148 " issue, IAADDR discarded.");
1157 paddr = &addr->
next;
1159 log_error(
"Invalid IAADDR option cache.");
1163 return ISC_R_UNEXPECTED;
1172 dhc6_parse_prefixes(
struct dhc6_addr **ppfx,
struct packet *packet,
1181 memset(&ds, 0,
sizeof(ds));
1184 for ( ; oc != NULL ; oc = oc->
next) {
1188 "prefix structure.");
1189 return ISC_R_NOMEMORY;
1202 log_debug(
"RCV: | | X-- IAPREFIX %s/%d",
1204 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1206 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1210 if ((pfx->
plen < 4) || (pfx->
plen > 128)) {
1211 log_debug(
"RCV: | | | !-- INVALID prefix "
1212 "length, IAPREFIX discarded. "
1213 "Check your server configuration.");
1223 log_debug(
"RCV: | | | !-- INVALID lifetimes, "
1224 "IAPREFIX discarded. Check your "
1225 "server configuration.");
1239 "IAPREFIX option state.");
1242 return ISC_R_NOMEMORY;
1273 " issue IAPREFIX discarded.");
1284 log_error(
"Invalid IAPREFIX option cache.");
1288 return ISC_R_UNEXPECTED;
1303 if (src == NULL || *src == NULL) {
1304 log_error(
"Attempt to destroy null lease.");
1312 for (ia = lease->
bindings ; ia != NULL ; ia = nia) {
1315 dhc6_ia_destroy(&ia, file, line);
1321 dfree(lease, file, line);
1330 dhc6_ia_destroy(
struct dhc6_ia **src,
const char *file,
int line)
1335 if (src == NULL || *src == NULL) {
1336 log_error(
"Attempt to destroy null IA.");
1341 for (addr = ia->
addrs ; addr != NULL ; addr = naddr) {
1347 dfree(addr, file, line);
1353 dfree(ia, file, line);
1364 while (*head != NULL) {
1365 if ((*head)->server_id.len == new->server_id.len &&
1366 memcmp((*head)->server_id.data, new->server_id.data,
1367 new->server_id.len) == 0) {
1373 head= &(*head)->
next;
1402 #ifdef USE_ORIGINAL_CLIENT_LEASE_WEIGHTS
1403 #define SCORE_BINDING 50
1404 #define SCORE_ADDRESS 100
1406 #define SCORE_BINDING 10000
1407 #define SCORE_ADDRESS 100
1410 #define SCORE_OPTION 1
1412 #define SCORE_MIN (SCORE_BINDING + SCORE_ADDRESS)
1423 return lease->
score;
1425 lease->
score = SCORE_OPTION;
1431 for (i = 0 ; req[i] != NULL ; i++) {
1433 req[i]->
code) == NULL) {
1435 return lease->
score;
1443 for (i = 0 ; req[i] != NULL ; i++) {
1445 req[i]->
code) != NULL)
1446 lease->
score += SCORE_OPTION;
1450 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
1451 lease->
score += SCORE_BINDING;
1453 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1454 lease->
score += SCORE_ADDRESS;
1458 return lease->
score;
1470 log_debug(
"PRC: Soliciting for leases (INIT).");
1483 dhc6_retrans_init(client);
1491 if (client->
RT <= client->
IRT)
1492 client->
RT = client->
IRT + (client->
IRT - client->
RT);
1494 if (client->
RT <= client->
IRT)
1495 client->
RT = client->
IRT + 1;
1504 tv.tv_sec =
cur_tv.tv_sec;
1505 tv.tv_usec =
cur_tv.tv_usec;
1507 if (tv.tv_usec >= 1000000) {
1509 tv.tv_usec -= 1000000;
1526 log_debug(
"PRC: Requesting information (INIT).");
1539 dhc6_retrans_init(client);
1548 tv.tv_sec =
cur_tv.tv_sec;
1549 tv.tv_usec =
cur_tv.tv_usec;
1551 if (tv.tv_usec >= 1000000) {
1553 tv.tv_usec -= 1000000;
1555 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1573 !active_prefix(client) ||
1581 log_debug(
"PRC: Confirming active lease (INIT-REBOOT).");
1590 dhc6_retrans_init(client);
1599 tv.tv_sec =
cur_tv.tv_sec;
1600 tv.tv_usec =
cur_tv.tv_usec;
1602 if (tv.tv_usec >= 1000000) {
1604 tv.tv_usec -= 1000000;
1620 add_timeout(&tv, do_refresh6, client, NULL, NULL);
1622 add_timeout(&tv, do_confirm6, client, NULL, NULL);
1629 #define CHK_TIM_SUCCESS 0
1630 #define CHK_TIM_MRC_EXCEEDED 1
1631 #define CHK_TIM_MRD_EXCEEDED 2
1632 #define CHK_TIM_ALLOC_FAILURE 3
1635 check_timing6 (
struct client_state *client, u_int8_t msg_type,
1639 struct timeval elapsed;
1647 }
else if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
1648 log_info(
"Max retransmission count exceeded.");
1649 return(CHK_TIM_MRC_EXCEEDED);
1655 if (elapsed.tv_usec < 0) {
1656 elapsed.tv_sec -= 1;
1657 elapsed.tv_usec += 1000000;
1661 if ((client->
MRD != 0) && (elapsed.tv_sec >= client->
MRD)) {
1662 log_info(
"Max retransmission duration exceeded.");
1663 return(CHK_TIM_MRD_EXCEEDED);
1666 memset(ds, 0,
sizeof(*ds));
1668 log_error(
"Unable to allocate memory for %s.", msg_str);
1669 return(CHK_TIM_ALLOC_FAILURE);
1679 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1680 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1683 client->
elapsed = elapsed.tv_sec * 100;
1684 client->
elapsed += elapsed.tv_usec / 10000;
1688 log_debug(
"XMT: Forming %s, 0 ms elapsed.", msg_str);
1690 log_debug(
"XMT: Forming %s, %u0 ms elapsed.", msg_str,
1695 make_client6_options(client, &client->
sent_options, lease, msg_type);
1697 return(CHK_TIM_SUCCESS);
1719 int start_idx, copy_len;
1721 memset(ia, 0,
sizeof(*ia));
1723 return (ISC_R_NOMEMORY);
1778 struct option *type_option;
1783 type_string =
"IA_NA";
1784 type_option = ia_na_option;
1788 type_string =
"IA_TA";
1789 type_option = ia_ta_option;
1793 type_string =
"IA_PD";
1794 type_option = ia_pd_option;
1796 if (prefix_len_hint > 0) {
1802 return (ISC_R_FAILURE);
1805 for (i = 0; wanted != 0; i++) {
1806 rval = dhc6_create_iaid(client, &ia, i, len);
1808 log_error(
"Unable to allocate memory for %s.",
1835 log_debug(
"XMT: | X-- Request renew in +%u",
1837 log_debug(
"XMT: | X-- Request rebind in +%u",
1841 if (ia_type ==
D6O_IA_PD && prefix_len_hint > 0) {
1849 log_debug(
"XMT: | | X-- Request prefix ::/%u.",
1868 do_init6(
void *input)
1891 switch(check_timing6(client,
DHCPV6_SOLICIT,
"Solicit", NULL, &ds)) {
1892 case CHK_TIM_MRC_EXCEEDED:
1893 case CHK_TIM_ALLOC_FAILURE:
1895 case CHK_TIM_MRD_EXCEEDED:
1902 if (stopping_finished())
1927 if (dhc6_create_iaid(client, &ia, i, 12) !=
ISC_R_SUCCESS) {
1928 log_error(
"Unable to allocate memory for IA_NA.");
1940 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1941 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1951 memset(&addr, 0,
sizeof(addr));
1952 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1953 old_addr = old_addr->
next) {
1957 "Ignoring. (%s:%d)",
1970 addr.data = addr.buffer->data;
1973 memcpy(addr.buffer->data,
1979 putULong(addr.buffer->data + 16, t1);
1980 putULong(addr.buffer->data + 20, t2);
1982 log_debug(
"XMT: | X-- Request address %s.",
2011 log_error(
"Unable to allocate memory for IA_TA.");
2027 memset(&addr, 0,
sizeof(addr));
2028 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2029 old_addr = old_addr->
next) {
2033 "Ignoring. (%s:%d)",
2046 addr.data = addr.buffer->data;
2049 memcpy(addr.buffer->data,
2055 putULong(addr.buffer->data + 16, t1);
2056 putULong(addr.buffer->data + 20, t2);
2058 log_debug(
"XMT: | X-- Request address %s.",
2086 memset(&ia, 0,
sizeof(ia));
2087 if (dhc6_create_iaid(client, &ia, i, 12) !=
ISC_R_SUCCESS) {
2088 log_error(
"Unable to allocate memory for IA_PD.");
2100 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
2101 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
2111 memset(&addr, 0,
sizeof(addr));
2112 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2113 old_addr = old_addr->
next) {
2116 "Ignoring. (%s:%d)",
2128 addr.data = addr.buffer->data;
2134 putULong(addr.buffer->data + 4, t2);
2138 memcpy(addr.buffer->data + 9,
2142 log_debug(
"XMT: | X-- Request prefix %s/%u.",
2144 (
unsigned) old_addr->
plen);
2158 }
else if (prefix_len_hint > 0) {
2159 memset(&addr, 0,
sizeof(addr));
2168 addr.data = addr.buffer->data;
2171 putUChar(addr.buffer->data + 8, prefix_len_hint);
2172 log_debug(
"XMT: | | X-- Request prefix ::/%u.",
2185 log_info(
"XMT: Solicit on %s, interval %ld0ms.",
2187 (
long int)client->
RT);
2190 ds.
data, ds.
len, &DHCPv6DestAddr);
2191 if (send_ret != ds.
len) {
2192 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2199 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2200 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2201 if (tv.tv_usec >= 1000000) {
2203 tv.tv_usec -= 1000000;
2207 dhc6_retrans_advance(client);
2212 do_info_request6(
void *input)
2222 "Info-Request", NULL, &ds)) {
2223 case CHK_TIM_MRC_EXCEEDED:
2224 case CHK_TIM_ALLOC_FAILURE:
2226 case CHK_TIM_MRD_EXCEEDED:
2228 case CHK_TIM_SUCCESS:
2240 log_info(
"XMT: Info-Request on %s, interval %ld0ms.",
2242 (
long int)client->
RT);
2245 ds.
data, ds.
len, &DHCPv6DestAddr);
2246 if (send_ret != ds.
len) {
2247 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2254 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2255 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2256 if (tv.tv_usec >= 1000000) {
2258 tv.tv_usec -= 1000000;
2260 add_timeout(&tv, do_info_request6, client, NULL, NULL);
2262 dhc6_retrans_advance(client);
2269 do_confirm6(
void *input)
2273 int send_ret, added;
2278 if (client->active_lease == NULL)
2296 client->active_lease, &ds)) {
2297 case CHK_TIM_MRC_EXCEEDED:
2298 case CHK_TIM_MRD_EXCEEDED:
2299 start_bound(client);
2301 case CHK_TIM_ALLOC_FAILURE:
2303 case CHK_TIM_SUCCESS:
2315 dhc6_add_ia_na(client, &ds, client->active_lease,
2321 dhc6_add_ia_ta(client, &ds, client->active_lease,
2329 log_info(
"XMT: Confirm on %s, interval %ld0ms.",
2330 client->name ? client->name : client->interface->name,
2331 (
long int)client->RT);
2335 if (send_ret != ds.
len) {
2336 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2343 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2344 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2345 if (tv.tv_usec >= 1000000) {
2347 tv.tv_usec -= 1000000;
2349 add_timeout(&tv, do_confirm6, client, NULL, NULL);
2351 dhc6_retrans_advance(client);
2387 dhc6_retrans_init(client);
2390 do_release6(client);
2396 do_release6(
void *input)
2400 int send_ret, added;
2405 if ((client->active_lease == NULL) || !active_prefix(client))
2409 client->active_lease, &ds)) {
2410 case CHK_TIM_MRC_EXCEEDED:
2411 case CHK_TIM_ALLOC_FAILURE:
2412 case CHK_TIM_MRD_EXCEEDED:
2414 case CHK_TIM_SUCCESS:
2429 dhc6_add_ia_na(client, &ds, client->active_lease,
2435 dhc6_add_ia_pd(client, &ds, client->active_lease,
2442 log_info(
"XMT: Release on %s, interval %ld0ms.",
2443 client->name ? client->name : client->interface->name,
2444 (
long int)client->RT);
2448 if (send_ret != ds.
len) {
2449 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2456 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2457 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2458 if (tv.tv_usec >= 1000000) {
2460 tv.tv_usec -= 1000000;
2462 add_timeout(&tv, do_release6, client, NULL, NULL);
2463 dhc6_retrans_advance(client);
2468 client->active_lease = NULL;
2469 if (stopping_finished())
2477 status_log(
int code,
const char *scope,
const char *additional,
int len)
2479 const char *msg = NULL;
2491 msg =
"NoAddrsAvail";
2503 msg =
"UseMulticast";
2507 msg =
"NoPrefixAvail";
2516 log_info(
"%s status code %s: %s", scope, msg,
2518 (
const unsigned char *)additional, 50));
2520 log_info(
"%s status code %s.", scope, msg);
2526 dhc6_get_status_code(
struct option_state *options,
unsigned *code,
2533 if ((options == NULL) || (code == NULL))
2536 if ((msg != NULL) && (msg->
len != 0))
2539 memset(&ds, 0,
sizeof(ds));
2554 if ((msg != NULL) && (ds.
len > 2)) {
2570 dhc6_check_status(isc_result_t rval,
struct option_state *options,
2571 const char *scope,
unsigned *code)
2574 isc_result_t status;
2576 if ((scope == NULL) || (code == NULL))
2583 if (options != NULL) {
2584 memset(&msg, 0,
sizeof(msg));
2585 status = dhc6_get_status_code(options, code, &msg);
2588 status_log(*code, scope, (
char *)msg.
data, msg.
len);
2592 rval = ISC_R_FAILURE;
2611 dhc6_check_advertise(
struct dhc6_lease *lease)
2615 int have_addrs = ISC_FALSE;
2618 int got_na = 0, got_ta = 0, got_pd = 0;
2620 rval = dhc6_check_status(rval, lease->
options,
"message", &code);
2622 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
2637 log_error(
"dhc6_check_advertise: no type.");
2638 return ISC_R_FAILURE;
2643 rval = dhc6_check_status(rval, ia->
options, scope, &code);
2652 if (ia->
addrs != NULL) {
2653 have_addrs = ISC_TRUE;
2660 if ((have_addrs != ISC_TRUE) ||
2662 ((got_na < wanted_ia_na) ||
2663 (got_ta < wanted_ia_ta) ||
2664 (got_pd < wanted_ia_pd))))
2665 rval = ISC_R_ADDRNOTAVAIL;
2673 static isc_boolean_t
2674 dhc6_init_action(
struct client_state *client, isc_result_t *rvalp,
2680 if (client == NULL) {
2696 static isc_boolean_t
2697 dhc6_select_action(
struct client_state *client, isc_result_t *rvalp,
2706 if (client == NULL) {
2806 if ((client == NULL) || (client->
active_lease == NULL))
2811 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2824 static isc_boolean_t
2825 dhc6_reply_action(
struct client_state *client, isc_result_t *rvalp,
2833 if (client == NULL) {
2889 dhc6_withdraw_lease(client);
2925 static isc_boolean_t
2926 dhc6_stop_action(
struct client_state *client, isc_result_t *rvalp,
2934 if (client == NULL) {
2955 if (rval == ISC_R_FAILURE)
2985 static isc_boolean_t
2986 dhc6_decline_action(
struct client_state *client, isc_result_t *rvalp,
2994 if (client == NULL) {
3033 isc_result_t *, unsigned);
3039 int have_addrs = ISC_FALSE;
3040 int got_na = 0, got_ta = 0, got_pd = 0;
3042 if ((client == NULL) || (
new == NULL))
3045 switch (client->
state) {
3047 action = dhc6_init_action;
3052 action = dhc6_select_action;
3057 action = dhc6_reply_action;
3061 action = dhc6_stop_action;
3065 action = dhc6_decline_action;
3070 return ISC_R_CANCELED;
3077 rval = dhc6_check_status(rval, new->options,
"message", &code);
3078 if (action(client, &rval, code))
3079 return ISC_R_CANCELED;
3081 for (ia = new->bindings ; ia != NULL ; ia = ia->
next) {
3096 log_error(
"dhc6_check_reply: no type.");
3099 rval = dhc6_check_status(rval, ia->
options, scope, &code);
3101 if (action(client, &rval, code))
3102 return ISC_R_CANCELED;
3104 if (ia->
addrs != NULL) {
3105 have_addrs = ISC_TRUE;
3122 if ((have_addrs != ISC_TRUE) ||
3124 ((got_na < wanted_ia_na) ||
3126 (got_pd < wanted_ia_pd)))) {
3127 rval = ISC_R_FAILURE;
3129 return ISC_R_CANCELED;
3137 switch (client->
state) {
3142 nscore = dhc6_score_lease(client,
new);
3145 (nscore < (sscore / 2))) {
3151 log_error(
"PRC: BAIT AND SWITCH detected. Score of "
3152 "supplied lease (%d) is substantially "
3153 "smaller than the advertised score (%d). "
3154 "Trying other servers.",
3162 return ISC_R_CANCELED;
3186 log_fatal(
"REALLY impossible condition at %s:%d.",
MDL);
3187 return ISC_R_CANCELED;
3199 init_handler(
struct packet *packet,
struct client_state *client)
3212 if (!valid_reply(packet, client)) {
3213 log_error(
"Invalid Advertise - rejecting.");
3217 lease = dhc6_leaseify(packet, client);
3226 log_debug(
"PRC: Lease failed to satisfy.");
3231 int lease_score = dhc6_score_lease(client, lease);
3232 #ifdef ENFORCE_DHCPV6_CLIENT_REQUIRE
3233 if (lease_score == 0) {
3234 log_debug(
"RCV:Advertised lease scored 0, toss it.");
3253 ((lease->
pref == 255) && (lease_score > SCORE_MIN))) {
3254 log_debug(
"RCV: Advertisement immediately selected.");
3258 log_debug(
"RCV: Advertisement recorded.");
3264 info_request_handler(
struct packet *packet,
struct client_state *client)
3266 isc_result_t check_status;
3275 if (!valid_reply(packet, client)) {
3276 log_error(
"Invalid Reply - rejecting.");
3287 if (check_status != ISC_R_CANCELED)
3297 if (check_status == ISC_R_CANCELED)
3311 log_fatal(
"Out of memory for v6 lease structure.");
3321 start_informed(client);
3327 rapid_commit_handler(
struct packet *packet,
struct client_state *client)
3330 isc_result_t check_status;
3335 init_handler(packet, client);
3343 if (!valid_reply(packet, client)) {
3344 log_error(
"Invalid Reply - rejecting.");
3351 log_error(
"Reply without Rapid-Commit - rejecting.");
3355 lease = dhc6_leaseify(packet, client);
3363 check_status = dhc6_check_reply(client, lease);
3397 start_bound(client);
3432 struct dhc6_lease **rpos, *rval, **candp, *cand;
3435 if (head == NULL || *head == NULL)
3440 rscore = dhc6_score_lease(client, rval);
3441 candp = &rval->
next;
3444 log_debug(
"PRC: Considering best lease.");
3445 log_debug(
"PRC: X-- Initial candidate %s (s: %d, p: %u).",
3448 rscore, (
unsigned)rval->
pref);
3450 for (; cand != NULL ; candp = &cand->
next, cand = *candp) {
3451 cscore = dhc6_score_lease(client, cand);
3453 log_debug(
"PRC: X-- Candidate %s (s: %d, p: %u).",
3456 cscore, (
unsigned)cand->
pref);
3480 if ((rscore < SCORE_MIN) && (cscore >= SCORE_MIN)) {
3481 log_debug(
"PRC: | X-- Selected, has bindings.");
3482 }
else if (cand->
pref < rval->
pref) {
3483 log_debug(
"PRC: | X-- Rejected, lower preference.");
3485 }
else if (cand->
pref > rval->
pref) {
3486 log_debug(
"PRC: | X-- Selected, higher preference.");
3487 }
else if (cscore > rscore) {
3488 log_debug(
"PRC: | X-- Selected, equal preference, "
3490 }
else if (cscore < rscore) {
3491 log_debug(
"PRC: | X-- Rejected, equal preference, "
3499 log_debug(
"PRC: | X-- Selected, equal preference, "
3500 "equal score, binary lesser server ID.");
3502 log_debug(
"PRC: | X-- Rejected, equal preference, "
3503 "equal score, binary greater server ID.");
3527 log_error(
"Can not enter DHCPv6 SELECTING state with no "
3528 "leases to select from!");
3532 log_debug(
"PRC: Selecting best advertised lease.");
3548 dhc6_retrans_init(client);
3561 do_select6(
void *input)
3567 int send_ret, added;
3573 if (lease == NULL || lease->
bindings == NULL) {
3574 log_error(
"Illegal to attempt selection without selecting "
3579 switch(check_timing6(client,
DHCPV6_REQUEST,
"Request", lease, &ds)) {
3580 case CHK_TIM_MRC_EXCEEDED:
3581 case CHK_TIM_MRD_EXCEEDED:
3596 case CHK_TIM_ALLOC_FAILURE:
3598 case CHK_TIM_SUCCESS:
3627 (dhc6_bare_ia_xx(client, &ds, wanted_ia_na - added,
3635 (dhc6_bare_ia_xx(client, &ds, wanted_ia_ta - added,
3643 (dhc6_bare_ia_xx(client, &ds, wanted_ia_pd - added,
3649 log_info(
"XMT: Request on %s, interval %ld0ms.",
3651 (
long int)client->
RT);
3654 ds.
data, ds.
len, &DHCPv6DestAddr);
3655 if (send_ret != ds.
len) {
3656 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
3663 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
3664 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
3665 if (tv.tv_usec >= 1000000) {
3667 tv.tv_usec -= 1000000;
3671 dhc6_retrans_advance(client);
3684 dhc6_count_ia(
struct dhc6_lease *lease, u_int16_t ia_type)
3689 for (ia = lease->
bindings; ia != NULL; ia = ia->
next) {
3726 int wanted,
int *added)
3737 memset(&iads, 0,
sizeof(iads));
3738 memset(&addrds, 0,
sizeof(addrds));
3740 ia != NULL && rval ==
ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3749 log_error(
"Unable to allocate memory for IA_NA.");
3750 rval = ISC_R_NOMEMORY;
3755 memcpy(iads.buffer->data, ia->
iaid, 4);
3756 iads.data = iads.buffer->data;
3766 #if MAX_TIME > 0xffffffff
3767 if (t1 > 0xffffffff)
3769 if (t2 > 0xffffffff)
3772 putULong(iads.buffer->data + 4, t1);
3773 putULong(iads.buffer->data + 8, t2);
3777 log_debug(
"XMT: | X-- Requested renew +%u",
3779 log_debug(
"XMT: | X-- Requested rebind +%u",
3787 memset(iads.buffer->data + 4, 0, 8);
3797 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3807 log_error(
"Illegal IPv6 address length (%d), "
3808 "ignoring. (%s:%d)",
3814 log_error(
"Unable to allocate memory for "
3816 rval = ISC_R_NOMEMORY;
3820 addrds.data = addrds.buffer->data;
3833 putULong(addrds.buffer->data + 16, t1);
3834 putULong(addrds.buffer->data + 20, t2);
3839 "lifetime +%u", (
unsigned)t1);
3840 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3850 memset(addrds.buffer->data + 16, 0, 8);
3851 log_debug(
"XMT: | X-- Confirm Address %s",
3857 memset(addrds.buffer->data + 16, 0, 8);
3858 log_debug(
"XMT: | X-- Release Address %s",
3864 memset(addrds.buffer->data + 16, 0, 8);
3865 log_debug(
"XMT: | X-- Decline Address %s",
3870 log_fatal(
"Impossible condition at %s:%d.",
3883 if (ia->
addrs == NULL) {
3884 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
3885 rval = ISC_R_FAILURE;
3929 int wanted,
int *added)
3940 memset(&iads, 0,
sizeof(iads));
3941 memset(&addrds, 0,
sizeof(addrds));
3943 ia != NULL && rval ==
ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3952 log_error(
"Unable to allocate memory for IA_TA.");
3953 rval = ISC_R_NOMEMORY;
3958 memcpy(iads.buffer->data, ia->
iaid, 4);
3959 iads.data = iads.buffer->data;
3965 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3975 log_error(
"Illegal IPv6 address length (%d), "
3976 "ignoring. (%s:%d)",
3982 log_error(
"Unable to allocate memory for "
3984 rval = ISC_R_NOMEMORY;
3988 addrds.data = addrds.buffer->data;
4001 putULong(addrds.buffer->data + 16, t1);
4002 putULong(addrds.buffer->data + 20, t2);
4007 "lifetime +%u", (
unsigned)t1);
4008 log_debug(
"XMT: | | | X-- Max lifetime +%u",
4018 memset(addrds.buffer->data + 16, 0, 8);
4019 log_debug(
"XMT: | X-- Confirm Address %s",
4025 memset(addrds.buffer->data + 16, 0, 8);
4026 log_debug(
"XMT: | X-- Release Address %s",
4031 log_fatal(
"Impossible condition at %s:%d.",
4044 if (ia->
addrs == NULL) {
4045 log_debug(
"!!!: V IA_TA has no IAADDRs - removed.");
4046 rval = ISC_R_FAILURE;
4090 int wanted,
int *added)
4101 memset(&iads, 0,
sizeof(iads));
4102 memset(&prefds, 0,
sizeof(prefds));
4104 ia != NULL && rval ==
ISC_R_SUCCESS && (wanted == 0 || i < wanted);
4113 log_error(
"Unable to allocate memory for IA_PD.");
4114 rval = ISC_R_NOMEMORY;
4119 memcpy(iads.buffer->data, ia->
iaid, 4);
4120 iads.data = iads.buffer->data;
4130 #if MAX_TIME > 0xffffffff
4131 if (t1 > 0xffffffff)
4133 if (t2 > 0xffffffff)
4136 putULong(iads.buffer->data + 4, t1);
4137 putULong(iads.buffer->data + 8, t2);
4141 log_debug(
"XMT: | X-- Requested renew +%u",
4143 log_debug(
"XMT: | X-- Requested rebind +%u",
4149 memset(iads.buffer->data + 4, 0, 8);
4159 for (pref = ia->
addrs ; pref != NULL ; pref = pref->
next) {
4170 "ignoring. (%s:%d)",
4175 if (pref->
plen == 0) {
4177 "ignoring. (%s:%d)",
4182 log_error(
"Unable to allocate memory for "
4184 rval = ISC_R_NOMEMORY;
4188 prefds.data = prefds.buffer->data;
4193 memcpy(prefds.buffer->data + 9,
4205 putULong(prefds.buffer->data + 4, t2);
4207 log_debug(
"XMT: | | X-- IAPREFIX %s/%u",
4209 (
unsigned) pref->
plen);
4211 "lifetime +%u", (
unsigned)t1);
4212 log_debug(
"XMT: | | | X-- Max lifetime +%u",
4219 memset(prefds.buffer->data, 0, 8);
4220 log_debug(
"XMT: | X-- Release Prefix %s/%u",
4222 (
unsigned) pref->
plen);
4226 log_fatal(
"Impossible condition at %s:%d.",
4231 iaprefix_option, &prefds);
4239 if (ia->
addrs == NULL) {
4240 log_debug(
"!!!: V IA_PD has no IAPREFIXs - removed.");
4241 rval = ISC_R_FAILURE;
4245 ia_pd_option, &iads);
4259 static isc_boolean_t
4260 stopping_finished(
void)
4266 for (client = ip -> client; client; client = client ->
next) {
4280 reply_handler(
struct packet *packet,
struct client_state *client)
4283 isc_result_t check_status;
4291 if (!valid_reply(packet, client)) {
4292 log_error(
"Invalid Reply - rejecting.");
4296 lease = dhc6_leaseify(packet, client);
4304 check_status = dhc6_check_reply(client, lease);
4311 if (check_status != ISC_R_CANCELED)
4328 if (stopping_finished()) {
4339 int live_cnt = drop_declined_addrs(client->
active_lease);
4340 if (live_cnt == 0) {
4355 if (check_status == ISC_R_CANCELED)
4371 start_bound(client);
4399 start_bound(client);
4416 dhc6_marshall_values(
const char *prefix,
struct client_state *client,
4423 if ((lease != NULL) && (lease->
options != NULL))
4424 script_write_params6(client, prefix, lease->
options);
4425 if ((ia != NULL) && (ia->
options != NULL))
4426 script_write_params6(client, prefix, ia->
options);
4427 if ((addr != NULL) && (addr->
options != NULL))
4428 script_write_params6(client, prefix, addr->
options);
4434 "ip6_prefix",
"%s/%u",
4436 (
unsigned) addr->
plen);
4445 "ip6_type",
"temporary");
4476 lo_expire=
MAX_TIME, hi_expire=0, max_ia_starts = 0, tmp;
4477 int has_addrs = ISC_FALSE;
4478 int has_preferred_addrs = ISC_FALSE;
4491 for(ia = lease->bindings ; ia != NULL ; ia = ia->
next) {
4492 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
4495 this_ia_hi_expire = 0;
4497 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4509 has_preferred_addrs = ISC_TRUE;
4523 if (tmp > this_ia_hi_expire)
4524 this_ia_hi_expire = tmp;
4525 if (tmp < this_ia_lo_expire)
4526 this_ia_lo_expire = tmp;
4528 has_addrs = ISC_TRUE;
4533 if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
4534 use_expire = this_ia_hi_expire;
4536 use_expire = this_ia_lo_expire;
4542 if ((use_expire ==
MAX_TIME) || (use_expire <= 1))
4559 if (ia->
starts > max_ia_starts)
4560 max_ia_starts = ia->
starts;
4562 if (ia->
renew == 0) {
4564 }
else if (ia->
renew == 0xffffffff)
4574 tmp = use_expire + (use_expire / 2);
4575 }
else if (ia->
rebind == 0xffffffff)
4588 this_ia_hi_expire += ia->
starts;
4589 this_ia_lo_expire += ia->
starts;
4591 if (this_ia_hi_expire > hi_expire)
4592 hi_expire = this_ia_hi_expire;
4593 if (this_ia_lo_expire < lo_expire)
4594 lo_expire = this_ia_lo_expire;
4606 if (has_addrs == ISC_FALSE) {
4620 renew += max_ia_starts;
4622 rebind += max_ia_starts;
4624 switch(client->
state) {
4629 if ((rebind >
cur_time) && (renew < rebind)) {
4630 log_debug(
"PRC: Renewal event scheduled in %d seconds, "
4631 "to run for %u seconds.",
4633 (
unsigned)(rebind - renew));
4637 add_timeout(&tv, start_renew6, client, NULL, NULL);
4649 log_debug(
"PRC: Rebind event scheduled in %d seconds, "
4650 "to run for %d seconds.",
4651 (
int)(rebind - cur_time),
4652 (
int)(hi_expire - rebind));
4656 add_timeout(&tv, start_rebind6, client, NULL, NULL);
4669 if (has_preferred_addrs) {
4670 log_fatal(
"Impossible condition, state %d at %s:%d.",
4680 log_debug(
"PRC: Depreference scheduled in %d seconds.",
4681 (
int)(depref - cur_time));
4687 log_debug(
"PRC: Expiration scheduled in %d seconds.",
4688 (
int)(lo_expire - cur_time));
4689 tv.tv_sec = lo_expire;
4697 find_ia(
struct dhc6_ia *head, u_int16_t type,
const char *
id)
4701 for (ia = head ; ia != NULL ; ia = ia->
next) {
4704 if (memcmp(ia->
iaid,
id, 4) == 0)
4717 for (addr = head ; addr != NULL ; addr = addr->
next) {
4720 address->
len) == 0))
4733 for (pref = head ; pref != NULL ; pref = pref->
next) {
4735 (pref->
plen == plen) &&
4766 struct dhc6_ia *sia, *dia, *tia, **eia;
4767 struct dhc6_addr *saddr, *daddr, *taddr;
4770 if ((dst == NULL) || (src == NULL))
4773 for (sia = src->
bindings ; sia != NULL ; sia = sia->
next) {
4777 tia = dhc6_dup_ia(sia,
MDL);
4780 log_fatal(
"Out of memory merging lease - "
4781 "Unable to continue without losing "
4782 "state! (%s:%d)",
MDL);
4794 eia = &(*eia)->
next) {
4800 for (saddr = sia->
addrs ; saddr != NULL ;
4801 saddr = saddr->
next) {
4803 daddr = find_addr(dia->
addrs,
4806 daddr = find_pref(dia->
addrs,
4810 if (daddr == NULL) {
4811 taddr = dhc6_dup_addr(saddr,
MDL);
4816 "Unable to continue "
4847 int decline_cnt = 0;
4848 #if defined (NSUPDATE)
4849 TIME dns_update_offset = 1;
4853 if (lease == NULL) {
4854 log_error(
"Cannot enter bound state unless an active lease "
4863 switch (client->
state) {
4891 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
4899 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4904 if (oldia != NULL) {
4906 oldaddr = find_addr(oldia->
addrs,
4909 oldaddr = find_pref(oldia->
addrs,
4915 #if defined (NSUPDATE)
4919 dns_update_offset++);
4926 dhc6_marshall_values(
"old_", client, old,
4928 dhc6_marshall_values(
"new_", client, lease, ia, addr);
4929 script_write_requested6(client);
4945 start_decline6(client);
4950 if (ia->
addrs == NULL) {
4954 dhc6_marshall_values(
"old_", client, old,
4957 oldia->
addrs : NULL);
4959 dhc6_marshall_values(
"new_", client, lease, ia,
4961 script_write_requested6(client);
4972 dhc6_marshall_values(
"old_", client, old,
4977 dhc6_marshall_values(
"new_", client, lease, NULL, NULL);
4978 script_write_requested6(client);
4996 dhc6_check_times(client);
5003 bound_handler(
struct packet *packet,
struct client_state *client)
5005 log_debug(
"RCV: Input packets are ignored once bound.");
5032 dhc6_retrans_init(client);
5036 do_decline6(client);
5046 do_decline6(
void *input)
5051 struct timeval elapsed, tv;
5054 if (client == NULL || client->active_lease == NULL) {
5058 if ((client->MRC != 0) && (client->txcount > client->MRC)) {
5059 log_info(
"Max retransmission count exceeded.");
5066 if (client->txcount == 0) {
5067 client->start_time.tv_sec =
cur_tv.tv_sec;
5068 client->start_time.tv_usec =
cur_tv.tv_usec;
5072 elapsed.tv_sec =
cur_tv.tv_sec - client->start_time.tv_sec;
5073 elapsed.tv_usec =
cur_tv.tv_usec - client->start_time.tv_usec;
5074 if (elapsed.tv_usec < 0) {
5075 elapsed.tv_sec -= 1;
5076 elapsed.tv_usec += 1000000;
5079 memset(&ds, 0,
sizeof(ds));
5081 log_error(
"Unable to allocate memory for Decline.");
5088 memcpy(ds.
buffer->
data + 1, client->dhcpv6_transaction_id, 3);
5092 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
5093 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
5094 client->elapsed = 0xffff;
5096 client->elapsed = elapsed.tv_sec * 100;
5097 client->elapsed += elapsed.tv_usec / 10000;
5100 client->elapsed = htons(client->elapsed);
5103 make_client6_options(client, &client->sent_options,
5110 if (dhc6_add_ia_na_decline(client, &ds, client->active_lease)
5117 log_info(
"XMT: Decline on %s, interval %ld0ms.",
5118 client->name ? client->name : client->interface->name,
5119 (
long int)client->RT);
5123 if (send_ret != ds.
len) {
5124 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
5131 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
5132 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
5133 if (tv.tv_usec >= 1000000) {
5135 tv.tv_usec -= 1000000;
5137 add_timeout(&tv, do_decline6, client, NULL, NULL);
5138 dhc6_retrans_advance(client);
5146 client->active_lease = NULL;
5157 start_renew6(
void *input)
5163 log_info(
"PRC: Renewing lease on %s.",
5178 dhc6_retrans_init(client);
5181 do_refresh6(client);
5189 do_refresh6(
void *input)
5192 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
5196 struct timeval elapsed, tv;
5197 int send_ret, added;
5200 memset(&ds, 0,
sizeof(ds));
5203 if (lease == NULL) {
5204 log_error(
"Cannot renew without an active binding.");
5215 log_fatal(
"Internal inconsistency (%d) at %s:%d.",
5234 if (((client->
MRC != 0) && (client->
txcount > client->
MRC)) ||
5237 dhc6_check_times(client);
5250 log_error(
"Invalid unicast option length %d.", ds.
len);
5252 memset(&unicast, 0,
sizeof(DHCPv6DestAddr));
5253 unicast.sin6_family = AF_INET6;
5255 memcpy(&unicast.sin6_addr, ds.
data, 16);
5257 dest_addr = &unicast;
5265 memset(&ds, 0,
sizeof(ds));
5267 log_error(
"Unable to allocate memory for packet.");
5287 log_debug(
"XMT: Forming %s, 0 ms elapsed.",
5290 log_debug(
"XMT: Forming %s, %u0 ms elapsed.",
5296 make_client6_options(client, &client->
sent_options, lease,
5310 ((dhc6_add_ia_na(client, &ds, lease, client->
refresh_type,
5312 (dhc6_bare_ia_xx(client, &ds, wanted_ia_na - added,
5318 ((dhc6_add_ia_pd(client, &ds, lease, client->
refresh_type,
5320 (dhc6_bare_ia_xx(client, &ds, wanted_ia_pd - added,
5326 log_info(
"XMT: %s on %s, interval %ld0ms.",
5329 (
long int)client->
RT);
5333 if (send_ret != ds.
len) {
5334 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
5341 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5342 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5343 if (tv.tv_usec >= 1000000) {
5345 tv.tv_usec -= 1000000;
5347 add_timeout(&tv, do_refresh6, client, NULL, NULL);
5349 dhc6_retrans_advance(client);
5358 start_rebind6(
void *input)
5364 log_info(
"PRC: Rebinding lease on %s.",
5379 dhc6_retrans_init(client);
5382 do_refresh6(client);
5392 do_depref(
void *input)
5405 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
5406 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5412 dhc6_marshall_values(
"cur_", client, lease,
5414 script_write_requested6(client);
5420 log_info(
"PRC: Address %s depreferred.",
5423 log_info(
"PRC: Prefix %s/%u depreferred.",
5425 (
unsigned) addr->
plen);
5427 #if defined (NSUPDATE)
5438 dhc6_check_times(client);
5445 do_expire(
void *input)
5451 int has_addrs = ISC_FALSE;
5452 int ia_has_addrs = ISC_FALSE;
5461 ia_has_addrs = ISC_FALSE;
5462 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5468 dhc6_marshall_values(
"old_", client, lease,
5470 script_write_requested6(client);
5476 log_info(
"PRC: Address %s expired.",
5479 log_info(
"PRC: Prefix %s/%u expired.",
5481 (
unsigned) addr->
plen);
5483 #if defined (NSUPDATE)
5498 ia_has_addrs = ISC_TRUE;
5499 has_addrs = ISC_TRUE;
5505 if (ia_has_addrs == ISC_TRUE) {
5507 tia = &(*tia)->
next;
5513 dhc6_ia_destroy(&ia,
MDL);
5520 if (has_addrs == ISC_FALSE) {
5521 log_info(
"PRC: Bound lease is devoid of active addresses."
5522 " Re-initializing.");
5532 dhc6_check_times(client);
5550 script_write_params6(client,
"old_",
5552 script_write_requested6(client);
5564 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5566 dhc6_marshall_values(
"old_", client,
5568 script_write_requested6(client);
5571 #if defined (NSUPDATE)
5581 refresh_info_request6(
void *input)
5599 isc_boolean_t found = ISC_FALSE;
5604 for (i = 0; req[i] != NULL; i++) {
5605 if (req[i] == irt_option) {
5623 memset(&irt, 0,
sizeof(irt));
5633 if (expire == 0xffffffff)
5641 log_debug(
"PRC: Refresh event scheduled in %u seconds.",
5643 tv.tv_sec = cur_time + expire;
5645 add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5663 script_write_params6(client,
"old_",
5666 script_write_requested6(client);
5682 dhc6_check_irt(client);
5688 informed_handler(
struct packet *packet,
struct client_state *client)
5690 log_debug(
"RCV: Input packets are ignored once bound.");
5704 int buflen, i, oro_len;
5706 if ((op == NULL) || (client == NULL))
5718 const unsigned char *cdata;
5720 cdata = (
unsigned char *)&client->
elapsed;
5733 lease ? lease->
options : NULL,
5750 log_fatal(
"Failure assembling a DUID.");
5762 if (lease == NULL) {
5779 log_error(
"'send dhcp6.oro' syntax is deprecated, please "
5780 "use the 'request' syntax (\"man dhclient.conf\").");
5820 log_fatal(
"Out of memory constructing DHCPv6 ORO.");
5823 for (i = 0 ; req[i] != NULL ; i++) {
5824 if (buflen == oro_len) {
5825 struct buffer *tmpbuf = NULL;
5835 "DHCPv6 ORO buffer.");
5837 memcpy(buffer->
data, tmpbuf->
data, oro_len);
5856 log_fatal(
"Unable to create ORO option cache.");
5880 script_write_params6(
struct client_state *client,
const char *prefix,
5886 if (options == NULL)
5906 static void script_write_requested6(client)
5912 req = client->config->requested_options;
5917 for (i = 0 ; req[i] != NULL ; i++) {
5928 static isc_boolean_t
5939 memset(zeros, 0, 16);
5940 for (ia = lease->
bindings; ia != NULL; ia = ia->
next) {
5943 for (pref = ia->
addrs; pref != NULL; pref = pref->
next) {
5944 if (pref->
plen == 0)
5972 memset(&iads, 0,
sizeof(iads));
5973 memset(&addrds, 0,
sizeof(addrds));
5979 int start_new_ia = 1;
5980 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5994 rval = ISC_R_NOMEMORY;
5999 memcpy(iads.buffer->data, ia->
iaid, 4);
6000 iads.data = iads.buffer->data;
6004 memset(iads.buffer->data + 4, 0, 8);
6011 log_error(
"Illegal IPv6 address length (%d), "
6012 "ignoring. (%s:%d)",
6018 log_error(
"Unable to allocate memory for "
6020 rval = ISC_R_NOMEMORY;
6024 addrds.data = addrds.buffer->data;
6031 memset(addrds.buffer->data + 16, 0, 8);
6032 log_debug(
"XMT: | X-- Decline Address %s",
6044 if (ia->
addrs == NULL) {
6045 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
6046 rval = ISC_R_FAILURE;
6066 int drop_declined_addrs(
struct dhc6_lease *lease) {
6070 for (ia = lease->
bindings; ia != NULL; ia = ia->
next) {
6083 for (addr = ia->
addrs ; addr != NULL ; ) {
6092 if (ia->
addrs == addr) {
6094 prev_addr = addr->
next;
6115 static isc_boolean_t
6116 unexpired_address_in_lease(
struct dhc6_lease *lease)
6121 if (lease == NULL) {
6125 for (ia = lease->
bindings ; ia != NULL ; ia = ia->
next) {
6126 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
6134 log_debug(
"PRC: Previous lease is devoid of active addresses.");
struct timeval start_time
void start_selecting6(struct client_state *client)
int(* encapsulate)(struct data_string *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *)
struct binding_scope * global_scope
unsigned char dhcpv6_transaction_id[3]
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)
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 STATUS_NoAddrsAvail
struct group * on_transmission
int script_go(struct client_state *client)
Calls external script.
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
log_fatal("no memory for uname information.")
struct expression * expression
struct data_string default_duid
struct option_state * options
unsigned char dhcpv6_msg_type
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)
#define DHC6_ADDR_DECLINED
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)
Initializes basic variables for a script.
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)
if(parse_ip_addr(cfile,&match->addr))
struct dhc6_lease * advertised_leases
u_int32_t getUShort(const unsigned char *)
void start_confirm6(struct client_state *client)
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__
void * dmalloc(size_t, const char *, int)
struct interface_info * interfaces
u_int32_t getULong(const unsigned char *)
struct option ** required_options
void putUChar(unsigned char *, u_int32_t)
#define _PATH_DHCLIENT6_PID
struct universe ** universes
u_int32_t getUChar(const unsigned char *)
int option_state_dereference(struct option_state **ptr, const char *file, int line)
void start_init6(struct client_state *client)
void option_space_foreach(struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff, void(*func)(struct option_cache *, struct packet *, struct lease *, struct client_state *, struct option_state *, struct option_state *, struct binding_scope **, struct universe *, void *))
void(* v6_handler)(struct packet *, struct client_state *)
void unconfigure6(struct client_state *client, const char *reason)
void client_dns_remove(struct client_state *client, struct iaddr *addr)
struct universe dhcpv6_universe
int make_const_data(struct expression **expr, const unsigned char *data, unsigned len, int terminated, int allocate, const char *file, int line)
void dhcpv6_client_assignments(void)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
struct client_config * config
void dhclient_schedule_updates(struct client_state *client, struct iaddr *addr, int offset)
int dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
option_code_hash_t * code_hash
void putUShort(unsigned char *, u_int32_t)
const unsigned char * data
struct interface_info * interface
#define DHC6_ADDR_EXPIRED
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
#define DHCPV6_INFORMATION_REQUEST
struct dhc6_lease * old_lease
u_int32_t requested_lease
#define DHC6_ADDR_DEPREFFED
struct dhc6_lease * active_lease
int buffer_dereference(struct buffer **ptr, const char *file, int line)
#define STATUS_UseMulticast
#define IASUBOPT_PD_PREFLEN_OFFSET
isc_result_t write_client6_lease(struct client_state *client, struct dhc6_lease *lease, int rewrite, int sync)