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,
167 ent = getservbyname(
"dhcpv6-client",
"udp");
175 ent = getservbyname(
"dhcpv6-server",
"udp");
182 memset(&DHCPv6DestAddr, 0,
sizeof(DHCPv6DestAddr));
183 DHCPv6DestAddr.sin6_family = AF_INET6;
186 &DHCPv6DestAddr.sin6_addr) <= 0) {
191 if (!option_code_hash_lookup(&clientid_option,
193 log_fatal(
"Unable to find the CLIENTID option definition.");
196 if (!option_code_hash_lookup(&elapsed_option,
198 log_fatal(
"Unable to find the ELAPSED_TIME option definition.");
203 log_fatal(
"Unable to find the IA_NA option definition.");
208 log_fatal(
"Unable to find the IA_TA option definition.");
213 log_fatal(
"Unable to find the IA_PD option definition.");
218 log_fatal(
"Unable to find the IAADDR option definition.");
221 if (!option_code_hash_lookup(&iaprefix_option,
224 log_fatal(
"Unable to find the IAPREFIX option definition.");
229 log_fatal(
"Unable to find the ORO option definition.");
234 log_fatal(
"Unable to find the IRT option definition.");
279 split = (base - 1) / 10;
290 range = (split * 2) + 1;
310 client->
RT = client->
IRT + dhc6_rand(client->
IRT);
314 #if (RAND_MAX >= 0x00ffffff) 316 #elif (RAND_MAX >= 0x0000ffff) 317 xid = (random() << 16) ^ random();
318 #elif (RAND_MAX >= 0x000000ff) 319 xid = (random() << 16) ^ (random() << 8) ^ random();
321 # error "Random number generator of less than 8 bits not supported." 333 struct timeval elapsed, elapsed_plus_rt;
338 if (elapsed.tv_usec < 0) {
340 elapsed.tv_usec += 1000000;
344 elapsed.tv_sec += client->
RT / 100;
345 elapsed.tv_usec += (client->
RT % 100) * 10000;
346 if (elapsed.tv_usec >= 1000000) {
348 elapsed.tv_usec -= 1000000;
354 elapsed_plus_rt.tv_sec = elapsed.tv_sec;
355 elapsed_plus_rt.tv_usec = elapsed.tv_usec;
363 client->
RT += client->
RT + dhc6_rand(client->
RT);
373 if ((client->
MRT != 0) && (client->
RT > client->
MRT))
374 client->
RT = client->
MRT + dhc6_rand(client->
MRT);
380 if (client->
MRD == 0) {
386 elapsed.tv_sec += client->
RT / 100;
387 elapsed.tv_usec += (client->
RT % 100) * 10000;
388 if (elapsed.tv_usec >= 1000000) {
390 elapsed.tv_usec -= 1000000;
392 if (elapsed.tv_sec >= client->
MRD) {
399 client->
RT = client->
MRD - elapsed_plus_rt.tv_sec;
400 client->
RT = (client->
RT * 100) -
401 (elapsed_plus_rt.tv_usec / 10000);
416 memset(&sid, 0,
sizeof(sid));
417 memset(&cid, 0,
sizeof(cid));
420 log_error(
"Response without a server identifier received.");
429 log_error(
"Response without a client identifier.");
439 log_error(
"Local client identifier is missing!");
444 sid.len != cid.len ||
445 memcmp(sid.data, cid.data, sid.len)) {
446 log_error(
"Advertise with matching transaction ID, but " 447 "mismatching client id.");
452 if (sid.data != NULL)
454 if (cid.data != NULL)
467 struct dhc6_ia **insert_ia, *ia;
471 log_error(
"Out of memory for v6 lease structure.");
484 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
485 *insert_ia = dhc6_dup_ia(ia,
file,
line);
487 if (*insert_ia == NULL) {
492 insert_ia = &(*insert_ia)->
next;
509 log_error(
"Out of memory for v6 duplicate IA structure.");
520 insert_addr = ©->
addrs;
521 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
522 *insert_addr = dhc6_dup_addr(addr,
file,
line);
524 if (*insert_addr == NULL) {
529 insert_addr = &(*insert_addr)->
next;
588 log_error(
"Out of memory for v6 lease structure.");
595 memset(&ds, 0,
sizeof(ds));
603 log_error(
"Invalid length of DHCPv6 Preference option " 604 "(%d != 1)", ds.len);
609 lease->pref = ds.data[0];
611 (
unsigned)
lease->pref);
627 if ((dhc6_get_status_code(
lease->options, &code, NULL) == ISC_R_SUCCESS)
639 lease->options, code) != ISC_R_SUCCESS) {
649 lease->options, code) != ISC_R_SUCCESS) {
659 lease->options, code) != ISC_R_SUCCESS) {
676 lease->server_id.len == 0) {
679 log_error(
"Invalid SERVERID option cache.");
685 lease->server_id.data, 52));
706 memset(&ds, 0,
sizeof(ds));
709 for ( ; oc != NULL ; oc = oc->
next) {
712 log_error(
"Out of memory allocating IA_NA structure.");
713 return ISC_R_NOMEMORY;
718 memcpy(ia->
iaid, ds.data, 4);
744 log_debug(
"RCV: | !-- INVALID renew/rebind " 745 "times, IA_NA discarded.");
757 "IA_NA option state.");
760 return ISC_R_NOMEMORY;
780 if (result != ISC_R_SUCCESS) {
793 if ((ia->
addrs == NULL) ||
796 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
800 "no addrs, IA_NA discarded.");
801 dhc6_ia_destroy(&ia,
MDL);
810 log_error(
"Invalid IA_NA option cache.");
814 return ISC_R_UNEXPECTED;
819 return ISC_R_SUCCESS;
832 memset(&ds, 0,
sizeof(ds));
835 for ( ; oc != NULL ; oc = oc->
next) {
838 log_error(
"Out of memory allocating IA_TA structure.");
839 return ISC_R_NOMEMORY;
844 memcpy(ia->
iaid, ds.data, 4);
860 "IA_TA option state.");
863 return ISC_R_NOMEMORY;
883 if (result != ISC_R_SUCCESS) {
896 if ((ia->
addrs == NULL) ||
899 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
903 "no addrs, IA_TA discarded.");
904 dhc6_ia_destroy(&ia,
MDL);
913 log_error(
"Invalid IA_TA option cache.");
917 return ISC_R_UNEXPECTED;
922 return ISC_R_SUCCESS;
935 memset(&ds, 0,
sizeof(ds));
938 for ( ; oc != NULL ; oc = oc->
next) {
941 log_error(
"Out of memory allocating IA_PD structure.");
942 return ISC_R_NOMEMORY;
947 memcpy(ia->
iaid, ds.data, 4);
969 log_debug(
"RCV: | !-- INVALID renew/rebind " 970 "times, IA_PD discarded.");
982 "IA_PD option state.");
985 return ISC_R_NOMEMORY;
1003 result = dhc6_parse_prefixes(&ia->
addrs,
1006 if (result != ISC_R_SUCCESS) {
1019 if ((ia->
addrs == NULL) ||
1022 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
1023 == ISC_R_SUCCESS) &&
1026 "no prefix, IA_PD discarded.");
1027 dhc6_ia_destroy(&ia,
MDL);
1031 while (*pia != NULL)
1032 pia = &(*pia)->
next;
1036 log_error(
"Invalid IA_PD option cache.");
1040 return ISC_R_UNEXPECTED;
1045 return ISC_R_SUCCESS;
1056 isc_result_t rval = ISC_R_SUCCESS;
1059 memset(&ds, 0,
sizeof(ds));
1062 for ( ; oc != NULL ; oc = oc->
next) {
1066 "address structure.");
1067 return ISC_R_NOMEMORY;
1081 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1083 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1091 log_debug(
"RCV: | | | !-- INVALID lifetimes, " 1092 "IAADDR discarded. Check your " 1093 "server configuration.");
1107 "IAADDR option state.");
1110 return ISC_R_NOMEMORY;
1136 rval = dhc6_check_status(ISC_R_SUCCESS,
1139 if (rval != ISC_R_SUCCESS) {
1141 " issue, IAADDR discarded.");
1150 paddr = &addr->
next;
1152 log_error(
"Invalid IAADDR option cache.");
1156 return ISC_R_UNEXPECTED;
1161 return ISC_R_SUCCESS;
1171 isc_result_t rval = ISC_R_SUCCESS;
1174 memset(&ds, 0,
sizeof(ds));
1177 for ( ; oc != NULL ; oc = oc->
next) {
1181 "prefix structure.");
1182 return ISC_R_NOMEMORY;
1195 log_debug(
"RCV: | | X-- IAPREFIX %s/%d",
1197 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1199 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1203 if ((pfx->
plen < 4) || (pfx->
plen > 128)) {
1204 log_debug(
"RCV: | | | !-- INVALID prefix " 1205 "length, IAPREFIX discarded. " 1206 "Check your server configuration.");
1216 log_debug(
"RCV: | | | !-- INVALID lifetimes, " 1217 "IAPREFIX discarded. Check your " 1218 "server configuration.");
1232 "IAPREFIX option state.");
1235 return ISC_R_NOMEMORY;
1261 rval = dhc6_check_status(ISC_R_SUCCESS,
1264 if (rval != ISC_R_SUCCESS) {
1266 " issue IAPREFIX discarded.");
1277 log_error(
"Invalid IAPREFIX option cache.");
1281 return ISC_R_UNEXPECTED;
1286 return ISC_R_SUCCESS;
1296 if (src == NULL || *src == NULL) {
1297 log_error(
"Attempt to destroy null lease.");
1302 if (
lease->server_id.len != 0)
1305 for (ia =
lease->bindings ; ia != NULL ; ia = nia) {
1311 if (
lease->options != NULL)
1328 if (src == NULL || *src == NULL) {
1329 log_error(
"Attempt to destroy null IA.");
1334 for (addr = ia->
addrs ; addr != NULL ; addr = naddr) {
1357 while (*head != NULL) {
1358 if ((*head)->server_id.len == new->server_id.len &&
1359 memcmp((*head)->server_id.data, new->server_id.data,
1360 new->server_id.len) == 0) {
1366 head= &(*head)->
next;
1395 #ifdef USE_ORIGINAL_CLIENT_LEASE_WEIGHTS 1396 #define SCORE_BINDING 50 1397 #define SCORE_ADDRESS 100 1399 #define SCORE_BINDING 10000 1400 #define SCORE_ADDRESS 100 1403 #define SCORE_OPTION 1 1405 #define SCORE_MIN (SCORE_BINDING + SCORE_ADDRESS) 1416 return lease->score;
1418 lease->score = SCORE_OPTION;
1424 for (i = 0 ; req[i] != NULL ; i++) {
1426 req[i]->code) == NULL) {
1428 return lease->score;
1436 for (i = 0 ; req[i] != NULL ; i++) {
1438 req[i]->code) != NULL)
1439 lease->score += SCORE_OPTION;
1443 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
1444 lease->score += SCORE_BINDING;
1446 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1447 lease->score += SCORE_ADDRESS;
1451 return lease->score;
1463 log_debug(
"PRC: Soliciting for leases (INIT).");
1476 dhc6_retrans_init(client);
1484 if (client->
RT <= client->
IRT)
1485 client->
RT = client->
IRT + (client->
IRT - client->
RT);
1487 if (client->
RT <= client->
IRT)
1488 client->
RT = client->
IRT + 1;
1497 tv.tv_sec =
cur_tv.tv_sec;
1498 tv.tv_usec =
cur_tv.tv_usec;
1500 if (tv.tv_usec >= 1000000) {
1502 tv.tv_usec -= 1000000;
1519 log_debug(
"PRC: Requesting information (INIT).");
1532 dhc6_retrans_init(client);
1541 tv.tv_sec =
cur_tv.tv_sec;
1542 tv.tv_usec =
cur_tv.tv_usec;
1544 if (tv.tv_usec >= 1000000) {
1546 tv.tv_usec -= 1000000;
1548 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1563 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
1564 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1574 log_info(
"PRC: Previous lease is devoid of active addresses." 1575 " Re-initializing.");
1592 !active_prefix(client) ||
1600 log_debug(
"PRC: Confirming active lease (INIT-REBOOT).");
1609 dhc6_retrans_init(client);
1618 tv.tv_sec =
cur_tv.tv_sec;
1619 tv.tv_usec =
cur_tv.tv_usec;
1621 if (tv.tv_usec >= 1000000) {
1623 tv.tv_usec -= 1000000;
1639 add_timeout(&tv, do_refresh6, client, NULL, NULL);
1641 add_timeout(&tv, do_confirm6, client, NULL, NULL);
1648 #define CHK_TIM_SUCCESS 0 1649 #define CHK_TIM_MRC_EXCEEDED 1 1650 #define CHK_TIM_MRD_EXCEEDED 2 1651 #define CHK_TIM_ALLOC_FAILURE 3 1654 check_timing6 (
struct client_state *client, u_int8_t msg_type,
1658 struct timeval elapsed;
1666 }
else if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
1667 log_info(
"Max retransmission count exceeded.");
1668 return(CHK_TIM_MRC_EXCEEDED);
1674 if (elapsed.tv_usec < 0) {
1675 elapsed.tv_sec -= 1;
1676 elapsed.tv_usec += 1000000;
1680 if ((client->
MRD != 0) && (elapsed.tv_sec >= client->
MRD)) {
1681 log_info(
"Max retransmission duration exceeded.");
1682 return(CHK_TIM_MRD_EXCEEDED);
1685 memset(ds, 0,
sizeof(*ds));
1687 log_error(
"Unable to allocate memory for %s.", msg_str);
1688 return(CHK_TIM_ALLOC_FAILURE);
1698 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1699 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1702 client->
elapsed = elapsed.tv_sec * 100;
1703 client->
elapsed += elapsed.tv_usec / 10000;
1707 log_debug(
"XMT: Forming %s, 0 ms elapsed.", msg_str);
1709 log_debug(
"XMT: Forming %s, %u0 ms elapsed.", msg_str,
1716 return(CHK_TIM_SUCCESS);
1738 int start_idx, copy_len;
1740 memset(ia, 0,
sizeof(*ia));
1742 return (ISC_R_NOMEMORY);
1764 return (ISC_R_SUCCESS);
1797 struct option *type_option;
1802 type_string =
"IA_NA";
1803 type_option = ia_na_option;
1807 type_string =
"IA_TA";
1808 type_option = ia_ta_option;
1812 type_string =
"IA_PD";
1813 type_option = ia_pd_option;
1817 return (ISC_R_FAILURE);
1820 for (i = 0; wanted != 0; i++) {
1821 rval = dhc6_create_iaid(client, &ia, i, len);
1822 if (rval != ISC_R_SUCCESS) {
1823 log_error(
"Unable to allocate memory for %s.",
1850 log_debug(
"XMT: | X-- Request renew in +%u",
1852 log_debug(
"XMT: | X-- Request rebind in +%u",
1864 return (ISC_R_SUCCESS);
1871 do_init6(
void *input)
1894 switch(check_timing6(client,
DHCPV6_SOLICIT,
"Solicit", NULL, &ds)) {
1895 case CHK_TIM_MRC_EXCEEDED:
1896 case CHK_TIM_ALLOC_FAILURE:
1898 case CHK_TIM_MRD_EXCEEDED:
1905 if (stopping_finished())
1930 if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
1931 log_error(
"Unable to allocate memory for IA_NA.");
1943 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1944 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1954 memset(&addr, 0,
sizeof(addr));
1955 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1956 old_addr = old_addr->
next) {
1960 "Ignoring. (%s:%d)",
1973 addr.data = addr.buffer->data;
1976 memcpy(addr.buffer->data,
1982 putULong(addr.buffer->data + 16, t1);
1983 putULong(addr.buffer->data + 20, t2);
1985 log_debug(
"XMT: | X-- Request address %s.",
2013 if (dhc6_create_iaid(client, &ia, i, 4) != ISC_R_SUCCESS) {
2014 log_error(
"Unable to allocate memory for IA_TA.");
2030 memset(&addr, 0,
sizeof(addr));
2031 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2032 old_addr = old_addr->
next) {
2036 "Ignoring. (%s:%d)",
2049 addr.data = addr.buffer->data;
2052 memcpy(addr.buffer->data,
2058 putULong(addr.buffer->data + 16, t1);
2059 putULong(addr.buffer->data + 20, t2);
2061 log_debug(
"XMT: | X-- Request address %s.",
2089 memset(&ia, 0,
sizeof(ia));
2090 if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
2091 log_error(
"Unable to allocate memory for IA_PD.");
2103 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
2104 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
2114 memset(&addr, 0,
sizeof(addr));
2115 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2116 old_addr = old_addr->
next) {
2119 "Ignoring. (%s:%d)",
2131 addr.data = addr.buffer->data;
2137 putULong(addr.buffer->data + 4, t2);
2141 memcpy(addr.buffer->data + 9,
2145 log_debug(
"XMT: | X-- Request prefix %s/%u.",
2147 (
unsigned) old_addr->
plen);
2169 log_info(
"XMT: Solicit on %s, interval %ld0ms.",
2171 (
long int)client->
RT);
2174 ds.
data, ds.
len, &DHCPv6DestAddr);
2175 if (send_ret != ds.
len) {
2176 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2183 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2184 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2185 if (tv.tv_usec >= 1000000) {
2187 tv.tv_usec -= 1000000;
2191 dhc6_retrans_advance(client);
2196 do_info_request6(
void *input)
2206 "Info-Request", NULL, &ds)) {
2207 case CHK_TIM_MRC_EXCEEDED:
2208 case CHK_TIM_ALLOC_FAILURE:
2210 case CHK_TIM_MRD_EXCEEDED:
2212 case CHK_TIM_SUCCESS:
2224 log_info(
"XMT: Info-Request on %s, interval %ld0ms.",
2226 (
long int)client->
RT);
2229 ds.
data, ds.
len, &DHCPv6DestAddr);
2230 if (send_ret != ds.
len) {
2231 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2238 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2239 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2240 if (tv.tv_usec >= 1000000) {
2242 tv.tv_usec -= 1000000;
2244 add_timeout(&tv, do_info_request6, client, NULL, NULL);
2246 dhc6_retrans_advance(client);
2253 do_confirm6(
void *input)
2257 int send_ret, added;
2262 if (client->active_lease == NULL)
2280 client->active_lease, &ds)) {
2281 case CHK_TIM_MRC_EXCEEDED:
2282 case CHK_TIM_MRD_EXCEEDED:
2283 start_bound(client);
2285 case CHK_TIM_ALLOC_FAILURE:
2287 case CHK_TIM_SUCCESS:
2299 dhc6_add_ia_na(client, &ds, client->active_lease,
2305 dhc6_add_ia_ta(client, &ds, client->active_lease,
2313 log_info(
"XMT: Confirm on %s, interval %ld0ms.",
2314 client->name ? client->name : client->interface->name,
2315 (
long int)client->RT);
2319 if (send_ret != ds.
len) {
2320 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2327 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2328 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2329 if (tv.tv_usec >= 1000000) {
2331 tv.tv_usec -= 1000000;
2333 add_timeout(&tv, do_confirm6, client, NULL, NULL);
2335 dhc6_retrans_advance(client);
2371 dhc6_retrans_init(client);
2374 do_release6(client);
2380 do_release6(
void *input)
2384 int send_ret, added;
2389 if ((client->active_lease == NULL) || !active_prefix(client))
2393 client->active_lease, &ds)) {
2394 case CHK_TIM_MRC_EXCEEDED:
2395 case CHK_TIM_ALLOC_FAILURE:
2396 case CHK_TIM_MRD_EXCEEDED:
2398 case CHK_TIM_SUCCESS:
2413 dhc6_add_ia_na(client, &ds, client->active_lease,
2419 dhc6_add_ia_pd(client, &ds, client->active_lease,
2426 log_info(
"XMT: Release on %s, interval %ld0ms.",
2427 client->name ? client->name : client->interface->name,
2428 (
long int)client->RT);
2432 if (send_ret != ds.
len) {
2433 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2440 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2441 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2442 if (tv.tv_usec >= 1000000) {
2444 tv.tv_usec -= 1000000;
2446 add_timeout(&tv, do_release6, client, NULL, NULL);
2447 dhc6_retrans_advance(client);
2452 client->active_lease = NULL;
2453 if (stopping_finished())
2461 status_log(
int code,
const char *scope,
const char *additional,
int len)
2463 const char *msg = NULL;
2475 msg =
"NoAddrsAvail";
2487 msg =
"UseMulticast";
2491 msg =
"NoPrefixAvail";
2500 log_info(
"%s status code %s: %s", scope, msg,
2502 (
const unsigned char *)additional, 50));
2504 log_info(
"%s status code %s.", scope, msg);
2510 dhc6_get_status_code(
struct option_state *options,
unsigned *code,
2515 isc_result_t rval = ISC_R_SUCCESS;
2517 if ((options == NULL) || (code == NULL))
2520 if ((msg != NULL) && (msg->
len != 0))
2523 memset(&ds, 0,
sizeof(ds));
2538 if ((msg != NULL) && (ds.
len > 2)) {
2548 return ISC_R_NOTFOUND;
2554 dhc6_check_status(isc_result_t rval,
struct option_state *options,
2555 const char *scope,
unsigned *code)
2558 isc_result_t status;
2560 if ((scope == NULL) || (code == NULL))
2567 if (options != NULL) {
2568 memset(&msg, 0,
sizeof(msg));
2569 status = dhc6_get_status_code(options, code, &msg);
2571 if (status == ISC_R_SUCCESS) {
2572 status_log(*code, scope, (
char *)msg.
data, msg.
len);
2576 rval = ISC_R_FAILURE;
2578 }
else if (status != ISC_R_NOTFOUND)
2598 isc_result_t rval = ISC_R_SUCCESS;
2599 int have_addrs = ISC_FALSE;
2602 int got_na = 0, got_ta = 0, got_pd = 0;
2604 rval = dhc6_check_status(rval,
lease->options,
"message", &code);
2606 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
2621 log_error(
"dhc6_check_advertise: no type.");
2622 return ISC_R_FAILURE;
2627 rval = dhc6_check_status(rval, ia->
options, scope, &code);
2628 if (rval != ISC_R_SUCCESS)
2636 if (ia->
addrs != NULL) {
2637 have_addrs = ISC_TRUE;
2644 if ((have_addrs != ISC_TRUE) ||
2649 rval = ISC_R_ADDRNOTAVAIL;
2657 static isc_boolean_t
2658 dhc6_init_action(
struct client_state *client, isc_result_t *rvalp,
2664 if (client == NULL) {
2669 if (*rvalp == ISC_R_SUCCESS)
2680 static isc_boolean_t
2681 dhc6_select_action(
struct client_state *client, isc_result_t *rvalp,
2690 if (client == NULL) {
2696 if (rval == ISC_R_SUCCESS)
2790 if ((client == NULL) || (client->
active_lease == NULL))
2795 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2808 static isc_boolean_t
2809 dhc6_reply_action(
struct client_state *client, isc_result_t *rvalp,
2817 if (client == NULL) {
2823 if (rval == ISC_R_SUCCESS)
2873 dhc6_withdraw_lease(client);
2909 static isc_boolean_t
2910 dhc6_stop_action(
struct client_state *client, isc_result_t *rvalp,
2918 if (client == NULL) {
2924 if (rval == ISC_R_SUCCESS)
2939 if (rval == ISC_R_FAILURE)
2940 *rvalp = ISC_R_SUCCESS;
2976 isc_result_t *, unsigned);
2978 isc_result_t rval = ISC_R_SUCCESS;
2982 int have_addrs = ISC_FALSE;
2983 int got_na = 0, got_ta = 0, got_pd = 0;
2985 if ((client == NULL) || (
new == NULL))
2988 switch (client->
state) {
2990 action = dhc6_init_action;
2995 action = dhc6_select_action;
3000 action = dhc6_reply_action;
3005 action = dhc6_stop_action;
3010 return ISC_R_CANCELED;
3017 rval = dhc6_check_status(rval, new->options,
"message", &code);
3018 if (action(client, &rval, code))
3019 return ISC_R_CANCELED;
3021 for (ia = new->bindings ; ia != NULL ; ia = ia->
next) {
3036 log_error(
"dhc6_check_reply: no type.");
3039 rval = dhc6_check_status(rval, ia->
options, scope, &code);
3041 if (action(client, &rval, code))
3042 return ISC_R_CANCELED;
3044 if (ia->
addrs != NULL) {
3045 have_addrs = ISC_TRUE;
3062 if ((have_addrs != ISC_TRUE) ||
3067 rval = ISC_R_FAILURE;
3069 return ISC_R_CANCELED;
3077 switch (client->
state) {
3082 nscore = dhc6_score_lease(client,
new);
3085 (nscore < (sscore / 2))) {
3091 log_error(
"PRC: BAIT AND SWITCH detected. Score of " 3092 "supplied lease (%d) is substantially " 3093 "smaller than the advertised score (%d). " 3094 "Trying other servers.",
3102 return ISC_R_CANCELED;
3126 log_fatal(
"REALLY impossible condition at %s:%d.",
MDL);
3127 return ISC_R_CANCELED;
3152 if (!valid_reply(
packet, client)) {
3153 log_error(
"Invalid Advertise - rejecting.");
3165 if (dhc6_check_advertise(
lease) != ISC_R_SUCCESS) {
3166 log_debug(
"PRC: Lease failed to satisfy.");
3171 int lease_score = dhc6_score_lease(client,
lease);
3172 #ifdef ENFORCE_DHCPV6_CLIENT_REQUIRE 3173 if (lease_score == 0) {
3174 log_debug(
"RCV:Advertised lease scored 0, toss it.");
3193 ((
lease->pref == 255) && (lease_score > SCORE_MIN))) {
3194 log_debug(
"RCV: Advertisement immediately selected.");
3198 log_debug(
"RCV: Advertisement recorded.");
3206 isc_result_t check_status;
3215 if (!valid_reply(
packet, client)) {
3216 log_error(
"Invalid Reply - rejecting.");
3220 check_status = dhc6_check_status(ISC_R_SUCCESS,
packet->
options,
3223 if (check_status != ISC_R_SUCCESS) {
3227 if (check_status != ISC_R_CANCELED)
3237 if (check_status == ISC_R_CANCELED)
3251 log_fatal(
"Out of memory for v6 lease structure.");
3261 start_informed(client);
3270 isc_result_t check_status;
3275 init_handler(
packet, client);
3283 if (!valid_reply(
packet, client)) {
3284 log_error(
"Invalid Reply - rejecting.");
3291 log_error(
"Reply without Rapid-Commit - rejecting.");
3303 check_status = dhc6_check_reply(client,
lease);
3304 if (check_status != ISC_R_SUCCESS) {
3337 start_bound(client);
3372 struct dhc6_lease **rpos, *rval, **candp, *cand;
3375 if (head == NULL || *head == NULL)
3380 rscore = dhc6_score_lease(client, rval);
3381 candp = &rval->
next;
3384 log_debug(
"PRC: Considering best lease.");
3385 log_debug(
"PRC: X-- Initial candidate %s (s: %d, p: %u).",
3388 rscore, (
unsigned)rval->
pref);
3390 for (; cand != NULL ; candp = &cand->
next, cand = *candp) {
3391 cscore = dhc6_score_lease(client, cand);
3393 log_debug(
"PRC: X-- Candidate %s (s: %d, p: %u).",
3396 cscore, (
unsigned)cand->
pref);
3420 if ((rscore < SCORE_MIN) && (cscore >= SCORE_MIN)) {
3421 log_debug(
"PRC: | X-- Selected, has bindings.");
3422 }
else if (cand->
pref < rval->
pref) {
3423 log_debug(
"PRC: | X-- Rejected, lower preference.");
3425 }
else if (cand->
pref > rval->
pref) {
3426 log_debug(
"PRC: | X-- Selected, higher preference.");
3427 }
else if (cscore > rscore) {
3428 log_debug(
"PRC: | X-- Selected, equal preference, " 3430 }
else if (cscore < rscore) {
3431 log_debug(
"PRC: | X-- Rejected, equal preference, " 3439 log_debug(
"PRC: | X-- Selected, equal preference, " 3440 "equal score, binary lesser server ID.");
3442 log_debug(
"PRC: | X-- Rejected, equal preference, " 3443 "equal score, binary greater server ID.");
3467 log_error(
"Can not enter DHCPv6 SELECTING state with no " 3468 "leases to select from!");
3472 log_debug(
"PRC: Selecting best advertised lease.");
3488 dhc6_retrans_init(client);
3501 do_select6(
void *input)
3507 int send_ret, added;
3513 if (
lease == NULL ||
lease->bindings == NULL) {
3514 log_error(
"Illegal to attempt selection without selecting " 3520 case CHK_TIM_MRC_EXCEEDED:
3521 case CHK_TIM_MRD_EXCEEDED:
3524 lease->server_id.data, 56));
3536 case CHK_TIM_ALLOC_FAILURE:
3538 case CHK_TIM_SUCCESS:
3589 log_info(
"XMT: Request on %s, interval %ld0ms.",
3591 (
long int)client->
RT);
3594 ds.
data, ds.
len, &DHCPv6DestAddr);
3595 if (send_ret != ds.
len) {
3596 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
3603 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
3604 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
3605 if (tv.tv_usec >= 1000000) {
3607 tv.tv_usec -= 1000000;
3611 dhc6_retrans_advance(client);
3629 for (ia =
lease->bindings; ia != NULL; ia = ia->
next) {
3666 int wanted,
int *added)
3672 isc_result_t rval = ISC_R_SUCCESS;
3677 memset(&iads, 0,
sizeof(iads));
3678 memset(&addrds, 0,
sizeof(addrds));
3679 for (ia =
lease->bindings, i = 0;
3680 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3689 log_error(
"Unable to allocate memory for IA_NA.");
3690 rval = ISC_R_NOMEMORY;
3695 memcpy(iads.buffer->data, ia->
iaid, 4);
3696 iads.data = iads.buffer->data;
3706 #if MAX_TIME > 0xffffffff 3707 if (t1 > 0xffffffff)
3709 if (t2 > 0xffffffff)
3712 putULong(iads.buffer->data + 4, t1);
3713 putULong(iads.buffer->data + 8, t2);
3717 log_debug(
"XMT: | X-- Requested renew +%u",
3719 log_debug(
"XMT: | X-- Requested rebind +%u",
3727 memset(iads.buffer->data + 4, 0, 8);
3737 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3747 log_error(
"Illegal IPv6 address length (%d), " 3748 "ignoring. (%s:%d)",
3754 log_error(
"Unable to allocate memory for " 3756 rval = ISC_R_NOMEMORY;
3760 addrds.data = addrds.buffer->data;
3773 putULong(addrds.buffer->data + 16, t1);
3774 putULong(addrds.buffer->data + 20, t2);
3779 "lifetime +%u", (
unsigned)t1);
3780 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3790 memset(addrds.buffer->data + 16, 0, 8);
3791 log_debug(
"XMT: | X-- Confirm Address %s",
3797 memset(addrds.buffer->data + 16, 0, 8);
3798 log_debug(
"XMT: | X-- Release Address %s",
3804 memset(addrds.buffer->data + 16, 0, 8);
3805 log_debug(
"XMT: | X-- Decline Address %s",
3810 log_fatal(
"Impossible condition at %s:%d.",
3823 if (ia->
addrs == NULL) {
3824 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
3825 rval = ISC_R_FAILURE;
3826 }
else if (rval == ISC_R_SUCCESS) {
3835 if (rval == ISC_R_SUCCESS)
3869 int wanted,
int *added)
3875 isc_result_t rval = ISC_R_SUCCESS;
3880 memset(&iads, 0,
sizeof(iads));
3881 memset(&addrds, 0,
sizeof(addrds));
3882 for (ia =
lease->bindings, i = 0;
3883 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3892 log_error(
"Unable to allocate memory for IA_TA.");
3893 rval = ISC_R_NOMEMORY;
3898 memcpy(iads.buffer->data, ia->
iaid, 4);
3899 iads.data = iads.buffer->data;
3905 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3915 log_error(
"Illegal IPv6 address length (%d), " 3916 "ignoring. (%s:%d)",
3922 log_error(
"Unable to allocate memory for " 3924 rval = ISC_R_NOMEMORY;
3928 addrds.data = addrds.buffer->data;
3941 putULong(addrds.buffer->data + 16, t1);
3942 putULong(addrds.buffer->data + 20, t2);
3947 "lifetime +%u", (
unsigned)t1);
3948 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3958 memset(addrds.buffer->data + 16, 0, 8);
3959 log_debug(
"XMT: | X-- Confirm Address %s",
3965 memset(addrds.buffer->data + 16, 0, 8);
3966 log_debug(
"XMT: | X-- Release Address %s",
3971 log_fatal(
"Impossible condition at %s:%d.",
3984 if (ia->
addrs == NULL) {
3985 log_debug(
"!!!: V IA_TA has no IAADDRs - removed.");
3986 rval = ISC_R_FAILURE;
3987 }
else if (rval == ISC_R_SUCCESS) {
3996 if (rval == ISC_R_SUCCESS)
4030 int wanted,
int *added)
4036 isc_result_t rval = ISC_R_SUCCESS;
4041 memset(&iads, 0,
sizeof(iads));
4042 memset(&prefds, 0,
sizeof(prefds));
4043 for (ia =
lease->bindings, i = 0;
4044 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
4053 log_error(
"Unable to allocate memory for IA_PD.");
4054 rval = ISC_R_NOMEMORY;
4059 memcpy(iads.buffer->data, ia->
iaid, 4);
4060 iads.data = iads.buffer->data;
4070 #if MAX_TIME > 0xffffffff 4071 if (t1 > 0xffffffff)
4073 if (t2 > 0xffffffff)
4076 putULong(iads.buffer->data + 4, t1);
4077 putULong(iads.buffer->data + 8, t2);
4081 log_debug(
"XMT: | X-- Requested renew +%u",
4083 log_debug(
"XMT: | X-- Requested rebind +%u",
4089 memset(iads.buffer->data + 4, 0, 8);
4099 for (pref = ia->
addrs ; pref != NULL ; pref = pref->
next) {
4110 "ignoring. (%s:%d)",
4115 if (pref->
plen == 0) {
4117 "ignoring. (%s:%d)",
4122 log_error(
"Unable to allocate memory for " 4124 rval = ISC_R_NOMEMORY;
4128 prefds.data = prefds.buffer->data;
4133 memcpy(prefds.buffer->data + 9,
4145 putULong(prefds.buffer->data + 4, t2);
4147 log_debug(
"XMT: | | X-- IAPREFIX %s/%u",
4149 (
unsigned) pref->
plen);
4151 "lifetime +%u", (
unsigned)t1);
4152 log_debug(
"XMT: | | | X-- Max lifetime +%u",
4159 memset(prefds.buffer->data, 0, 8);
4160 log_debug(
"XMT: | X-- Release Prefix %s/%u",
4162 (
unsigned) pref->
plen);
4166 log_fatal(
"Impossible condition at %s:%d.",
4171 iaprefix_option, &prefds);
4179 if (ia->
addrs == NULL) {
4180 log_debug(
"!!!: V IA_PD has no IAPREFIXs - removed.");
4181 rval = ISC_R_FAILURE;
4182 }
else if (rval == ISC_R_SUCCESS) {
4185 ia_pd_option, &iads);
4191 if (rval == ISC_R_SUCCESS)
4199 static isc_boolean_t
4200 stopping_finished(
void)
4206 for (client =
ip -> client; client; client = client ->
next) {
4223 isc_result_t check_status;
4231 if (!valid_reply(
packet, client)) {
4232 log_error(
"Invalid Reply - rejecting.");
4244 check_status = dhc6_check_reply(client,
lease);
4245 if (check_status != ISC_R_SUCCESS) {
4251 if (check_status != ISC_R_CANCELED)
4270 if (stopping_finished())
4283 if (check_status == ISC_R_CANCELED)
4299 start_bound(client);
4327 start_bound(client);
4344 dhc6_marshall_values(
const char *prefix,
struct client_state *client,
4351 if ((
lease != NULL) && (
lease->options != NULL))
4352 script_write_params6(client, prefix,
lease->options);
4353 if ((ia != NULL) && (ia->
options != NULL))
4354 script_write_params6(client, prefix, ia->
options);
4355 if ((addr != NULL) && (addr->
options != NULL))
4356 script_write_params6(client, prefix, addr->
options);
4362 "ip6_prefix",
"%s/%u",
4364 (
unsigned) addr->
plen);
4373 "ip6_type",
"temporary");
4404 lo_expire=
MAX_TIME, hi_expire=0, max_ia_starts = 0, tmp;
4405 int has_addrs = ISC_FALSE;
4406 int has_preferred_addrs = ISC_FALSE;
4419 for(ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4420 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
4423 this_ia_hi_expire = 0;
4425 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4437 has_preferred_addrs = ISC_TRUE;
4451 if (tmp > this_ia_hi_expire)
4452 this_ia_hi_expire = tmp;
4453 if (tmp < this_ia_lo_expire)
4454 this_ia_lo_expire = tmp;
4456 has_addrs = ISC_TRUE;
4461 if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
4462 use_expire = this_ia_hi_expire;
4464 use_expire = this_ia_lo_expire;
4470 if ((use_expire ==
MAX_TIME) || (use_expire <= 1))
4487 if (ia->
starts > max_ia_starts)
4488 max_ia_starts = ia->
starts;
4490 if (ia->
renew == 0) {
4492 }
else if (ia->
renew == 0xffffffff)
4502 tmp = use_expire + (use_expire / 2);
4503 }
else if (ia->
rebind == 0xffffffff)
4516 this_ia_hi_expire += ia->
starts;
4517 this_ia_lo_expire += ia->
starts;
4519 if (this_ia_hi_expire > hi_expire)
4520 hi_expire = this_ia_hi_expire;
4521 if (this_ia_lo_expire < lo_expire)
4522 lo_expire = this_ia_lo_expire;
4534 if (has_addrs == ISC_FALSE) {
4548 renew += max_ia_starts;
4550 rebind += max_ia_starts;
4552 switch(client->
state) {
4557 if ((rebind >
cur_time) && (renew < rebind)) {
4558 log_debug(
"PRC: Renewal event scheduled in %d seconds, " 4559 "to run for %u seconds.",
4561 (
unsigned)(rebind - renew));
4565 add_timeout(&tv, start_renew6, client, NULL, NULL);
4577 log_debug(
"PRC: Rebind event scheduled in %d seconds, " 4578 "to run for %d seconds.",
4580 (
int)(hi_expire - rebind));
4584 add_timeout(&tv, start_rebind6, client, NULL, NULL);
4597 if (has_preferred_addrs) {
4598 log_fatal(
"Impossible condition, state %d at %s:%d.",
4608 log_debug(
"PRC: Depreference scheduled in %d seconds.",
4615 log_debug(
"PRC: Expiration scheduled in %d seconds.",
4617 tv.tv_sec = lo_expire;
4625 find_ia(
struct dhc6_ia *head, u_int16_t type,
const char *
id)
4629 for (ia = head ; ia != NULL ; ia = ia->
next) {
4632 if (memcmp(ia->
iaid,
id, 4) == 0)
4645 for (addr = head ; addr != NULL ; addr = addr->
next) {
4661 for (pref = head ; pref != NULL ; pref = pref->
next) {
4694 struct dhc6_ia *sia, *dia, *tia, **eia;
4695 struct dhc6_addr *saddr, *daddr, *taddr;
4698 if ((dst == NULL) || (src == NULL))
4701 for (sia = src->
bindings ; sia != NULL ; sia = sia->
next) {
4705 tia = dhc6_dup_ia(sia,
MDL);
4708 log_fatal(
"Out of memory merging lease - " 4709 "Unable to continue without losing " 4710 "state! (%s:%d)",
MDL);
4722 eia = &(*eia)->
next) {
4728 for (saddr = sia->
addrs ; saddr != NULL ;
4729 saddr = saddr->
next) {
4731 daddr = find_addr(dia->
addrs,
4734 daddr = find_pref(dia->
addrs,
4738 if (daddr == NULL) {
4739 taddr = dhc6_dup_addr(saddr,
MDL);
4744 "Unable to continue " 4775 #if defined (NSUPDATE) 4776 TIME dns_update_offset = 1;
4780 if (
lease == NULL) {
4781 log_error(
"Cannot enter bound state unless an active lease " 4785 lease->released = ISC_FALSE;
4790 switch (client->
state) {
4818 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4826 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4831 if (oldia != NULL) {
4833 oldaddr = find_addr(oldia->
addrs,
4836 oldaddr = find_pref(oldia->
addrs,
4842 #if defined (NSUPDATE) 4846 dns_update_offset++);
4853 dhc6_marshall_values(
"old_", client, old,
4855 dhc6_marshall_values(
"new_", client,
lease, ia, addr);
4856 script_write_requested6(client);
4860 start_decline6(client);
4866 if (ia->
addrs == NULL) {
4870 dhc6_marshall_values(
"old_", client, old,
4873 oldia->
addrs : NULL);
4875 dhc6_marshall_values(
"new_", client,
lease, ia,
4877 script_write_requested6(client);
4884 if (
lease->bindings == NULL) {
4888 dhc6_marshall_values(
"old_", client, old,
4893 dhc6_marshall_values(
"new_", client,
lease, NULL, NULL);
4894 script_write_requested6(client);
4912 dhc6_check_times(client);
4938 dhc6_retrans_init(client);
4942 do_decline6(client);
4949 do_decline6(
void *input)
4953 struct timeval elapsed, tv;
4954 int send_ret, added;
4958 if ((client->
active_lease == NULL) || !active_prefix(client))
4961 if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
4962 log_info(
"Max retransmission count exceeded.");
4977 if (elapsed.tv_usec < 0) {
4978 elapsed.tv_sec -= 1;
4979 elapsed.tv_usec += 1000000;
4982 memset(&ds, 0,
sizeof(ds));
4984 log_error(
"Unable to allocate memory for Decline.");
4995 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
4996 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
4999 client->
elapsed = elapsed.tv_sec * 100;
5000 client->
elapsed += elapsed.tv_usec / 10000;
5027 log_info(
"XMT: Decline on %s, interval %ld0ms.",
5029 (
long int)client->
RT);
5033 if (send_ret != ds.
len) {
5034 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
5041 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5042 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5043 if (tv.tv_usec >= 1000000) {
5045 tv.tv_usec -= 1000000;
5047 add_timeout(&tv, do_decline6, client, NULL, NULL);
5048 dhc6_retrans_advance(client);
5064 log_debug(
"RCV: Input packets are ignored once bound.");
5072 start_renew6(
void *input)
5078 log_info(
"PRC: Renewing lease on %s.",
5093 dhc6_retrans_init(client);
5096 do_refresh6(client);
5104 do_refresh6(
void *input)
5107 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
5111 struct timeval elapsed, tv;
5112 int send_ret, added;
5115 memset(&ds, 0,
sizeof(ds));
5118 if (
lease == NULL) {
5119 log_error(
"Cannot renew without an active binding.");
5130 log_fatal(
"Internal inconsistency (%d) at %s:%d.",
5149 if (((client->
MRC != 0) && (client->
txcount > client->
MRC)) ||
5152 dhc6_check_times(client);
5165 log_error(
"Invalid unicast option length %d.", ds.
len);
5167 memset(&unicast, 0,
sizeof(DHCPv6DestAddr));
5168 unicast.sin6_family = AF_INET6;
5170 memcpy(&unicast.sin6_addr, ds.
data, 16);
5172 dest_addr = &unicast;
5180 memset(&ds, 0,
sizeof(ds));
5182 log_error(
"Unable to allocate memory for packet.");
5202 log_debug(
"XMT: Forming %s, 0 ms elapsed.",
5205 log_debug(
"XMT: Forming %s, %u0 ms elapsed.",
5241 log_info(
"XMT: %s on %s, interval %ld0ms.",
5244 (
long int)client->
RT);
5248 if (send_ret != ds.
len) {
5249 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
5256 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5257 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5258 if (tv.tv_usec >= 1000000) {
5260 tv.tv_usec -= 1000000;
5262 add_timeout(&tv, do_refresh6, client, NULL, NULL);
5264 dhc6_retrans_advance(client);
5273 start_rebind6(
void *input)
5279 log_info(
"PRC: Rebinding lease on %s.",
5294 dhc6_retrans_init(client);
5297 do_refresh6(client);
5307 do_depref(
void *input)
5320 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
5321 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5327 dhc6_marshall_values(
"cur_", client,
lease,
5329 script_write_requested6(client);
5335 log_info(
"PRC: Address %s depreferred.",
5338 log_info(
"PRC: Prefix %s/%u depreferred.",
5340 (
unsigned) addr->
plen);
5342 #if defined (NSUPDATE) 5353 dhc6_check_times(client);
5360 do_expire(
void *input)
5366 int has_addrs = ISC_FALSE;
5367 int ia_has_addrs = ISC_FALSE;
5375 for (ia =
lease->bindings, tia = &
lease->bindings; ia != NULL ; ) {
5376 ia_has_addrs = ISC_FALSE;
5377 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5383 dhc6_marshall_values(
"old_", client,
lease,
5385 script_write_requested6(client);
5391 log_info(
"PRC: Address %s expired.",
5394 log_info(
"PRC: Prefix %s/%u expired.",
5396 (
unsigned) addr->
plen);
5398 #if defined (NSUPDATE) 5413 ia_has_addrs = ISC_TRUE;
5414 has_addrs = ISC_TRUE;
5420 if (ia_has_addrs == ISC_TRUE) {
5422 tia = &(*tia)->
next;
5428 dhc6_ia_destroy(&ia,
MDL);
5435 if (has_addrs == ISC_FALSE) {
5436 log_info(
"PRC: Bound lease is devoid of active addresses." 5437 " Re-initializing.");
5447 dhc6_check_times(client);
5465 script_write_params6(client,
"old_",
5467 script_write_requested6(client);
5479 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5481 dhc6_marshall_values(
"old_", client,
5483 script_write_requested6(client);
5486 #if defined (NSUPDATE) 5496 refresh_info_request6(
void *input)
5514 isc_boolean_t found = ISC_FALSE;
5519 for (i = 0; req[i] != NULL; i++) {
5520 if (req[i] == irt_option) {
5538 memset(&irt, 0,
sizeof(irt));
5548 if (expire == 0xffffffff)
5556 log_debug(
"PRC: Refresh event scheduled in %u seconds.",
5560 add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5578 script_write_params6(client,
"old_",
5581 script_write_requested6(client);
5597 dhc6_check_irt(client);
5605 log_debug(
"RCV: Input packets are ignored once bound.");
5619 int buflen, i, oro_len;
5621 if ((op == NULL) || (client == NULL))
5633 const unsigned char *cdata;
5635 cdata = (
unsigned char *)&client->
elapsed;
5665 log_fatal(
"Failure assembling a DUID.");
5677 if (
lease == NULL) {
5694 log_error(
"'send dhcp6.oro' syntax is deprecated, please " 5695 "use the 'request' syntax (\"man dhclient.conf\").");
5735 log_fatal(
"Out of memory constructing DHCPv6 ORO.");
5738 for (i = 0 ; req[i] != NULL ; i++) {
5739 if (buflen == oro_len) {
5740 struct buffer *tmpbuf = NULL;
5750 "DHCPv6 ORO buffer.");
5771 log_fatal(
"Unable to create ORO option cache.");
5795 script_write_params6(
struct client_state *client,
const char *prefix,
5801 if (options == NULL)
5821 static void script_write_requested6(
client)
5832 for (i = 0 ; req[i] != NULL ; i++) {
5843 static isc_boolean_t
5854 memset(zeros, 0, 16);
5855 for (ia =
lease->bindings; ia != NULL; ia = ia->
next) {
5858 for (pref = ia->
addrs; pref != NULL; pref = pref->
next) {
5859 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)
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)
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
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)
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)
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__
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 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)