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,
168 ent = getservbyname(
"dhcpv6-client",
"udp");
176 ent = getservbyname(
"dhcpv6-server",
"udp");
183 memset(&DHCPv6DestAddr, 0,
sizeof(DHCPv6DestAddr));
184 DHCPv6DestAddr.sin6_family = AF_INET6;
187 &DHCPv6DestAddr.sin6_addr) <= 0) {
192 if (!option_code_hash_lookup(&clientid_option,
194 log_fatal(
"Unable to find the CLIENTID option definition.");
197 if (!option_code_hash_lookup(&elapsed_option,
199 log_fatal(
"Unable to find the ELAPSED_TIME option definition.");
204 log_fatal(
"Unable to find the IA_NA option definition.");
209 log_fatal(
"Unable to find the IA_TA option definition.");
214 log_fatal(
"Unable to find the IA_PD option definition.");
219 log_fatal(
"Unable to find the IAADDR option definition.");
222 if (!option_code_hash_lookup(&iaprefix_option,
225 log_fatal(
"Unable to find the IAPREFIX option definition.");
230 log_fatal(
"Unable to find the ORO option definition.");
235 log_fatal(
"Unable to find the IRT option definition.");
280 split = (base - 1) / 10;
291 range = (split * 2) + 1;
311 client->
RT = client->
IRT + dhc6_rand(client->
IRT);
315 #if (RAND_MAX >= 0x00ffffff) 317 #elif (RAND_MAX >= 0x0000ffff) 318 xid = (random() << 16) ^ random();
319 #elif (RAND_MAX >= 0x000000ff) 320 xid = (random() << 16) ^ (random() << 8) ^ random();
322 # error "Random number generator of less than 8 bits not supported." 334 struct timeval elapsed, elapsed_plus_rt;
339 if (elapsed.tv_usec < 0) {
341 elapsed.tv_usec += 1000000;
345 elapsed.tv_sec += client->
RT / 100;
346 elapsed.tv_usec += (client->
RT % 100) * 10000;
347 if (elapsed.tv_usec >= 1000000) {
349 elapsed.tv_usec -= 1000000;
355 elapsed_plus_rt.tv_sec = elapsed.tv_sec;
356 elapsed_plus_rt.tv_usec = elapsed.tv_usec;
364 client->
RT += client->
RT + dhc6_rand(client->
RT);
374 if ((client->
MRT != 0) && (client->
RT > client->
MRT))
375 client->
RT = client->
MRT + dhc6_rand(client->
MRT);
381 if (client->
MRD == 0) {
387 elapsed.tv_sec += client->
RT / 100;
388 elapsed.tv_usec += (client->
RT % 100) * 10000;
389 if (elapsed.tv_usec >= 1000000) {
391 elapsed.tv_usec -= 1000000;
393 if (elapsed.tv_sec >= client->
MRD) {
400 client->
RT = client->
MRD - elapsed_plus_rt.tv_sec;
401 client->
RT = (client->
RT * 100) -
402 (elapsed_plus_rt.tv_usec / 10000);
417 memset(&sid, 0,
sizeof(sid));
418 memset(&cid, 0,
sizeof(cid));
421 log_error(
"Response without a server identifier received.");
430 log_error(
"Response without a client identifier.");
440 log_error(
"Local client identifier is missing!");
445 sid.len != cid.len ||
446 memcmp(sid.data, cid.data, sid.len)) {
447 log_error(
"Advertise with matching transaction ID, but " 448 "mismatching client id.");
453 if (sid.data != NULL)
455 if (cid.data != NULL)
468 struct dhc6_ia **insert_ia, *ia;
472 log_error(
"Out of memory for v6 lease structure.");
485 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
486 *insert_ia = dhc6_dup_ia(ia,
file,
line);
488 if (*insert_ia == NULL) {
493 insert_ia = &(*insert_ia)->
next;
510 log_error(
"Out of memory for v6 duplicate IA structure.");
521 insert_addr = ©->
addrs;
522 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
523 *insert_addr = dhc6_dup_addr(addr,
file,
line);
525 if (*insert_addr == NULL) {
530 insert_addr = &(*insert_addr)->
next;
589 log_error(
"Out of memory for v6 lease structure.");
596 memset(&ds, 0,
sizeof(ds));
604 log_error(
"Invalid length of DHCPv6 Preference option " 605 "(%d != 1)", ds.len);
610 lease->pref = ds.data[0];
612 (
unsigned)
lease->pref);
628 if ((dhc6_get_status_code(
lease->options, &code, NULL) == ISC_R_SUCCESS)
640 lease->options, code) != ISC_R_SUCCESS) {
650 lease->options, code) != ISC_R_SUCCESS) {
660 lease->options, code) != ISC_R_SUCCESS) {
677 lease->server_id.len == 0) {
680 log_error(
"Invalid SERVERID option cache.");
686 lease->server_id.data, 52));
707 memset(&ds, 0,
sizeof(ds));
710 for ( ; oc != NULL ; oc = oc->
next) {
713 log_error(
"Out of memory allocating IA_NA structure.");
714 return ISC_R_NOMEMORY;
719 memcpy(ia->
iaid, ds.data, 4);
745 log_debug(
"RCV: | !-- INVALID renew/rebind " 746 "times, IA_NA discarded.");
758 "IA_NA option state.");
761 return ISC_R_NOMEMORY;
781 if (result != ISC_R_SUCCESS) {
794 if ((ia->
addrs == NULL) ||
797 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
801 "no addrs, IA_NA discarded.");
802 dhc6_ia_destroy(&ia,
MDL);
811 log_error(
"Invalid IA_NA option cache.");
815 return ISC_R_UNEXPECTED;
820 return ISC_R_SUCCESS;
833 memset(&ds, 0,
sizeof(ds));
836 for ( ; oc != NULL ; oc = oc->
next) {
839 log_error(
"Out of memory allocating IA_TA structure.");
840 return ISC_R_NOMEMORY;
845 memcpy(ia->
iaid, ds.data, 4);
861 "IA_TA option state.");
864 return ISC_R_NOMEMORY;
884 if (result != ISC_R_SUCCESS) {
897 if ((ia->
addrs == NULL) ||
900 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
904 "no addrs, IA_TA discarded.");
905 dhc6_ia_destroy(&ia,
MDL);
914 log_error(
"Invalid IA_TA option cache.");
918 return ISC_R_UNEXPECTED;
923 return ISC_R_SUCCESS;
936 memset(&ds, 0,
sizeof(ds));
939 for ( ; oc != NULL ; oc = oc->
next) {
942 log_error(
"Out of memory allocating IA_PD structure.");
943 return ISC_R_NOMEMORY;
948 memcpy(ia->
iaid, ds.data, 4);
970 log_debug(
"RCV: | !-- INVALID renew/rebind " 971 "times, IA_PD discarded.");
983 "IA_PD option state.");
986 return ISC_R_NOMEMORY;
1004 result = dhc6_parse_prefixes(&ia->
addrs,
1007 if (result != ISC_R_SUCCESS) {
1020 if ((ia->
addrs == NULL) ||
1023 (dhc6_get_status_code(ia->
options, &ia_code, NULL)
1024 == ISC_R_SUCCESS) &&
1027 "no prefix, IA_PD discarded.");
1028 dhc6_ia_destroy(&ia,
MDL);
1032 while (*pia != NULL)
1033 pia = &(*pia)->
next;
1037 log_error(
"Invalid IA_PD option cache.");
1041 return ISC_R_UNEXPECTED;
1046 return ISC_R_SUCCESS;
1057 isc_result_t rval = ISC_R_SUCCESS;
1060 memset(&ds, 0,
sizeof(ds));
1063 for ( ; oc != NULL ; oc = oc->
next) {
1067 "address structure.");
1068 return ISC_R_NOMEMORY;
1082 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1084 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1092 log_debug(
"RCV: | | | !-- INVALID lifetimes, " 1093 "IAADDR discarded. Check your " 1094 "server configuration.");
1108 "IAADDR option state.");
1111 return ISC_R_NOMEMORY;
1137 rval = dhc6_check_status(ISC_R_SUCCESS,
1140 if (rval != ISC_R_SUCCESS) {
1142 " issue, IAADDR discarded.");
1151 paddr = &addr->
next;
1153 log_error(
"Invalid IAADDR option cache.");
1157 return ISC_R_UNEXPECTED;
1162 return ISC_R_SUCCESS;
1172 isc_result_t rval = ISC_R_SUCCESS;
1175 memset(&ds, 0,
sizeof(ds));
1178 for ( ; oc != NULL ; oc = oc->
next) {
1182 "prefix structure.");
1183 return ISC_R_NOMEMORY;
1196 log_debug(
"RCV: | | X-- IAPREFIX %s/%d",
1198 log_debug(
"RCV: | | | X-- Preferred lifetime %u.",
1200 log_debug(
"RCV: | | | X-- Max lifetime %u.",
1204 if ((pfx->
plen < 4) || (pfx->
plen > 128)) {
1205 log_debug(
"RCV: | | | !-- INVALID prefix " 1206 "length, IAPREFIX discarded. " 1207 "Check your server configuration.");
1217 log_debug(
"RCV: | | | !-- INVALID lifetimes, " 1218 "IAPREFIX discarded. Check your " 1219 "server configuration.");
1233 "IAPREFIX option state.");
1236 return ISC_R_NOMEMORY;
1262 rval = dhc6_check_status(ISC_R_SUCCESS,
1265 if (rval != ISC_R_SUCCESS) {
1267 " issue IAPREFIX discarded.");
1278 log_error(
"Invalid IAPREFIX option cache.");
1282 return ISC_R_UNEXPECTED;
1287 return ISC_R_SUCCESS;
1297 if (src == NULL || *src == NULL) {
1298 log_error(
"Attempt to destroy null lease.");
1303 if (
lease->server_id.len != 0)
1306 for (ia =
lease->bindings ; ia != NULL ; ia = nia) {
1312 if (
lease->options != NULL)
1329 if (src == NULL || *src == NULL) {
1330 log_error(
"Attempt to destroy null IA.");
1335 for (addr = ia->
addrs ; addr != NULL ; addr = naddr) {
1358 while (*head != NULL) {
1359 if ((*head)->server_id.len == new->server_id.len &&
1360 memcmp((*head)->server_id.data, new->server_id.data,
1361 new->server_id.len) == 0) {
1367 head= &(*head)->
next;
1396 #ifdef USE_ORIGINAL_CLIENT_LEASE_WEIGHTS 1397 #define SCORE_BINDING 50 1398 #define SCORE_ADDRESS 100 1400 #define SCORE_BINDING 10000 1401 #define SCORE_ADDRESS 100 1404 #define SCORE_OPTION 1 1406 #define SCORE_MIN (SCORE_BINDING + SCORE_ADDRESS) 1417 return lease->score;
1419 lease->score = SCORE_OPTION;
1425 for (i = 0 ; req[i] != NULL ; i++) {
1427 req[i]->code) == NULL) {
1429 return lease->score;
1437 for (i = 0 ; req[i] != NULL ; i++) {
1439 req[i]->code) != NULL)
1440 lease->score += SCORE_OPTION;
1444 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
1445 lease->score += SCORE_BINDING;
1447 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1448 lease->score += SCORE_ADDRESS;
1452 return lease->score;
1464 log_debug(
"PRC: Soliciting for leases (INIT).");
1477 dhc6_retrans_init(client);
1485 if (client->
RT <= client->
IRT)
1486 client->
RT = client->
IRT + (client->
IRT - client->
RT);
1488 if (client->
RT <= client->
IRT)
1489 client->
RT = client->
IRT + 1;
1498 tv.tv_sec =
cur_tv.tv_sec;
1499 tv.tv_usec =
cur_tv.tv_usec;
1501 if (tv.tv_usec >= 1000000) {
1503 tv.tv_usec -= 1000000;
1520 log_debug(
"PRC: Requesting information (INIT).");
1533 dhc6_retrans_init(client);
1542 tv.tv_sec =
cur_tv.tv_sec;
1543 tv.tv_usec =
cur_tv.tv_usec;
1545 if (tv.tv_usec >= 1000000) {
1547 tv.tv_usec -= 1000000;
1549 add_timeout(&tv, do_info_request6, client, NULL, NULL);
1564 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
1565 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
1575 log_info(
"PRC: Previous lease is devoid of active addresses." 1576 " Re-initializing.");
1593 !active_prefix(client) ||
1601 log_debug(
"PRC: Confirming active lease (INIT-REBOOT).");
1610 dhc6_retrans_init(client);
1619 tv.tv_sec =
cur_tv.tv_sec;
1620 tv.tv_usec =
cur_tv.tv_usec;
1622 if (tv.tv_usec >= 1000000) {
1624 tv.tv_usec -= 1000000;
1640 add_timeout(&tv, do_refresh6, client, NULL, NULL);
1642 add_timeout(&tv, do_confirm6, client, NULL, NULL);
1649 #define CHK_TIM_SUCCESS 0 1650 #define CHK_TIM_MRC_EXCEEDED 1 1651 #define CHK_TIM_MRD_EXCEEDED 2 1652 #define CHK_TIM_ALLOC_FAILURE 3 1655 check_timing6 (
struct client_state *client, u_int8_t msg_type,
1659 struct timeval elapsed;
1667 }
else if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
1668 log_info(
"Max retransmission count exceeded.");
1669 return(CHK_TIM_MRC_EXCEEDED);
1675 if (elapsed.tv_usec < 0) {
1676 elapsed.tv_sec -= 1;
1677 elapsed.tv_usec += 1000000;
1681 if ((client->
MRD != 0) && (elapsed.tv_sec >= client->
MRD)) {
1682 log_info(
"Max retransmission duration exceeded.");
1683 return(CHK_TIM_MRD_EXCEEDED);
1686 memset(ds, 0,
sizeof(*ds));
1688 log_error(
"Unable to allocate memory for %s.", msg_str);
1689 return(CHK_TIM_ALLOC_FAILURE);
1699 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
1700 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
1703 client->
elapsed = elapsed.tv_sec * 100;
1704 client->
elapsed += elapsed.tv_usec / 10000;
1708 log_debug(
"XMT: Forming %s, 0 ms elapsed.", msg_str);
1710 log_debug(
"XMT: Forming %s, %u0 ms elapsed.", msg_str,
1717 return(CHK_TIM_SUCCESS);
1739 int start_idx, copy_len;
1741 memset(ia, 0,
sizeof(*ia));
1743 return (ISC_R_NOMEMORY);
1765 return (ISC_R_SUCCESS);
1798 struct option *type_option;
1803 type_string =
"IA_NA";
1804 type_option = ia_na_option;
1808 type_string =
"IA_TA";
1809 type_option = ia_ta_option;
1813 type_string =
"IA_PD";
1814 type_option = ia_pd_option;
1818 return (ISC_R_FAILURE);
1821 for (i = 0; wanted != 0; i++) {
1822 rval = dhc6_create_iaid(client, &ia, i, len);
1823 if (rval != ISC_R_SUCCESS) {
1824 log_error(
"Unable to allocate memory for %s.",
1851 log_debug(
"XMT: | X-- Request renew in +%u",
1853 log_debug(
"XMT: | X-- Request rebind in +%u",
1865 return (ISC_R_SUCCESS);
1872 do_init6(
void *input)
1895 switch(check_timing6(client,
DHCPV6_SOLICIT,
"Solicit", NULL, &ds)) {
1896 case CHK_TIM_MRC_EXCEEDED:
1897 case CHK_TIM_ALLOC_FAILURE:
1899 case CHK_TIM_MRD_EXCEEDED:
1906 if (stopping_finished())
1931 if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
1932 log_error(
"Unable to allocate memory for IA_NA.");
1944 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
1945 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
1955 memset(&addr, 0,
sizeof(addr));
1956 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
1957 old_addr = old_addr->
next) {
1961 "Ignoring. (%s:%d)",
1974 addr.data = addr.buffer->data;
1977 memcpy(addr.buffer->data,
1983 putULong(addr.buffer->data + 16, t1);
1984 putULong(addr.buffer->data + 20, t2);
1986 log_debug(
"XMT: | X-- Request address %s.",
2014 if (dhc6_create_iaid(client, &ia, i, 4) != ISC_R_SUCCESS) {
2015 log_error(
"Unable to allocate memory for IA_TA.");
2031 memset(&addr, 0,
sizeof(addr));
2032 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2033 old_addr = old_addr->
next) {
2037 "Ignoring. (%s:%d)",
2050 addr.data = addr.buffer->data;
2053 memcpy(addr.buffer->data,
2059 putULong(addr.buffer->data + 16, t1);
2060 putULong(addr.buffer->data + 20, t2);
2062 log_debug(
"XMT: | X-- Request address %s.",
2090 memset(&ia, 0,
sizeof(ia));
2091 if (dhc6_create_iaid(client, &ia, i, 12) != ISC_R_SUCCESS) {
2092 log_error(
"Unable to allocate memory for IA_PD.");
2104 log_debug(
"XMT: | X-- Request renew in +%u", (
unsigned)t1);
2105 log_debug(
"XMT: | X-- Request rebind in +%u", (
unsigned)t2);
2115 memset(&addr, 0,
sizeof(addr));
2116 for (old_addr = old_ia->
addrs ; old_addr != NULL ;
2117 old_addr = old_addr->
next) {
2120 "Ignoring. (%s:%d)",
2132 addr.data = addr.buffer->data;
2138 putULong(addr.buffer->data + 4, t2);
2142 memcpy(addr.buffer->data + 9,
2146 log_debug(
"XMT: | X-- Request prefix %s/%u.",
2148 (
unsigned) old_addr->
plen);
2170 log_info(
"XMT: Solicit on %s, interval %ld0ms.",
2172 (
long int)client->
RT);
2175 ds.
data, ds.
len, &DHCPv6DestAddr);
2176 if (send_ret != ds.
len) {
2177 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2184 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2185 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2186 if (tv.tv_usec >= 1000000) {
2188 tv.tv_usec -= 1000000;
2192 dhc6_retrans_advance(client);
2197 do_info_request6(
void *input)
2207 "Info-Request", NULL, &ds)) {
2208 case CHK_TIM_MRC_EXCEEDED:
2209 case CHK_TIM_ALLOC_FAILURE:
2211 case CHK_TIM_MRD_EXCEEDED:
2213 case CHK_TIM_SUCCESS:
2225 log_info(
"XMT: Info-Request on %s, interval %ld0ms.",
2227 (
long int)client->
RT);
2230 ds.
data, ds.
len, &DHCPv6DestAddr);
2231 if (send_ret != ds.
len) {
2232 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
2239 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
2240 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
2241 if (tv.tv_usec >= 1000000) {
2243 tv.tv_usec -= 1000000;
2245 add_timeout(&tv, do_info_request6, client, NULL, NULL);
2247 dhc6_retrans_advance(client);
2254 do_confirm6(
void *input)
2258 int send_ret, added;
2263 if (client->active_lease == NULL)
2281 client->active_lease, &ds)) {
2282 case CHK_TIM_MRC_EXCEEDED:
2283 case CHK_TIM_MRD_EXCEEDED:
2284 start_bound(client);
2286 case CHK_TIM_ALLOC_FAILURE:
2288 case CHK_TIM_SUCCESS:
2300 dhc6_add_ia_na(client, &ds, client->active_lease,
2306 dhc6_add_ia_ta(client, &ds, client->active_lease,
2314 log_info(
"XMT: Confirm on %s, interval %ld0ms.",
2315 client->name ? client->name : client->interface->name,
2316 (
long int)client->RT);
2320 if (send_ret != ds.
len) {
2321 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2328 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2329 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2330 if (tv.tv_usec >= 1000000) {
2332 tv.tv_usec -= 1000000;
2334 add_timeout(&tv, do_confirm6, client, NULL, NULL);
2336 dhc6_retrans_advance(client);
2372 dhc6_retrans_init(client);
2375 do_release6(client);
2381 do_release6(
void *input)
2385 int send_ret, added;
2390 if ((client->active_lease == NULL) || !active_prefix(client))
2394 client->active_lease, &ds)) {
2395 case CHK_TIM_MRC_EXCEEDED:
2396 case CHK_TIM_ALLOC_FAILURE:
2397 case CHK_TIM_MRD_EXCEEDED:
2399 case CHK_TIM_SUCCESS:
2414 dhc6_add_ia_na(client, &ds, client->active_lease,
2420 dhc6_add_ia_pd(client, &ds, client->active_lease,
2427 log_info(
"XMT: Release on %s, interval %ld0ms.",
2428 client->name ? client->name : client->interface->name,
2429 (
long int)client->RT);
2433 if (send_ret != ds.
len) {
2434 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
2441 tv.tv_sec =
cur_tv.tv_sec + client->RT / 100;
2442 tv.tv_usec =
cur_tv.tv_usec + (client->RT % 100) * 10000;
2443 if (tv.tv_usec >= 1000000) {
2445 tv.tv_usec -= 1000000;
2447 add_timeout(&tv, do_release6, client, NULL, NULL);
2448 dhc6_retrans_advance(client);
2453 client->active_lease = NULL;
2454 if (stopping_finished())
2462 status_log(
int code,
const char *scope,
const char *additional,
int len)
2464 const char *msg = NULL;
2476 msg =
"NoAddrsAvail";
2488 msg =
"UseMulticast";
2492 msg =
"NoPrefixAvail";
2501 log_info(
"%s status code %s: %s", scope, msg,
2503 (
const unsigned char *)additional, 50));
2505 log_info(
"%s status code %s.", scope, msg);
2511 dhc6_get_status_code(
struct option_state *options,
unsigned *code,
2516 isc_result_t rval = ISC_R_SUCCESS;
2518 if ((options == NULL) || (code == NULL))
2521 if ((msg != NULL) && (msg->
len != 0))
2524 memset(&ds, 0,
sizeof(ds));
2539 if ((msg != NULL) && (ds.
len > 2)) {
2549 return ISC_R_NOTFOUND;
2555 dhc6_check_status(isc_result_t rval,
struct option_state *options,
2556 const char *scope,
unsigned *code)
2559 isc_result_t status;
2561 if ((scope == NULL) || (code == NULL))
2568 if (options != NULL) {
2569 memset(&msg, 0,
sizeof(msg));
2570 status = dhc6_get_status_code(options, code, &msg);
2572 if (status == ISC_R_SUCCESS) {
2573 status_log(*code, scope, (
char *)msg.
data, msg.
len);
2577 rval = ISC_R_FAILURE;
2579 }
else if (status != ISC_R_NOTFOUND)
2599 isc_result_t rval = ISC_R_SUCCESS;
2600 int have_addrs = ISC_FALSE;
2603 int got_na = 0, got_ta = 0, got_pd = 0;
2605 rval = dhc6_check_status(rval,
lease->options,
"message", &code);
2607 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
2622 log_error(
"dhc6_check_advertise: no type.");
2623 return ISC_R_FAILURE;
2628 rval = dhc6_check_status(rval, ia->
options, scope, &code);
2629 if (rval != ISC_R_SUCCESS)
2637 if (ia->
addrs != NULL) {
2638 have_addrs = ISC_TRUE;
2645 if ((have_addrs != ISC_TRUE) ||
2650 rval = ISC_R_ADDRNOTAVAIL;
2658 static isc_boolean_t
2659 dhc6_init_action(
struct client_state *client, isc_result_t *rvalp,
2665 if (client == NULL) {
2670 if (*rvalp == ISC_R_SUCCESS)
2681 static isc_boolean_t
2682 dhc6_select_action(
struct client_state *client, isc_result_t *rvalp,
2691 if (client == NULL) {
2697 if (rval == ISC_R_SUCCESS)
2791 if ((client == NULL) || (client->
active_lease == NULL))
2796 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
2809 static isc_boolean_t
2810 dhc6_reply_action(
struct client_state *client, isc_result_t *rvalp,
2818 if (client == NULL) {
2824 if (rval == ISC_R_SUCCESS)
2874 dhc6_withdraw_lease(client);
2910 static isc_boolean_t
2911 dhc6_stop_action(
struct client_state *client, isc_result_t *rvalp,
2919 if (client == NULL) {
2925 if (rval == ISC_R_SUCCESS)
2940 if (rval == ISC_R_FAILURE)
2941 *rvalp = ISC_R_SUCCESS;
2977 isc_result_t *, unsigned);
2979 isc_result_t rval = ISC_R_SUCCESS;
2983 int have_addrs = ISC_FALSE;
2984 int got_na = 0, got_ta = 0, got_pd = 0;
2986 if ((client == NULL) || (
new == NULL))
2989 switch (client->
state) {
2991 action = dhc6_init_action;
2996 action = dhc6_select_action;
3001 action = dhc6_reply_action;
3006 action = dhc6_stop_action;
3011 return ISC_R_CANCELED;
3018 rval = dhc6_check_status(rval, new->options,
"message", &code);
3019 if (action(client, &rval, code))
3020 return ISC_R_CANCELED;
3022 for (ia = new->bindings ; ia != NULL ; ia = ia->
next) {
3037 log_error(
"dhc6_check_reply: no type.");
3040 rval = dhc6_check_status(rval, ia->
options, scope, &code);
3042 if (action(client, &rval, code))
3043 return ISC_R_CANCELED;
3045 if (ia->
addrs != NULL) {
3046 have_addrs = ISC_TRUE;
3063 if ((have_addrs != ISC_TRUE) ||
3068 rval = ISC_R_FAILURE;
3070 return ISC_R_CANCELED;
3078 switch (client->
state) {
3083 nscore = dhc6_score_lease(client,
new);
3086 (nscore < (sscore / 2))) {
3092 log_error(
"PRC: BAIT AND SWITCH detected. Score of " 3093 "supplied lease (%d) is substantially " 3094 "smaller than the advertised score (%d). " 3095 "Trying other servers.",
3103 return ISC_R_CANCELED;
3127 log_fatal(
"REALLY impossible condition at %s:%d.",
MDL);
3128 return ISC_R_CANCELED;
3153 if (!valid_reply(
packet, client)) {
3154 log_error(
"Invalid Advertise - rejecting.");
3166 if (dhc6_check_advertise(
lease) != ISC_R_SUCCESS) {
3167 log_debug(
"PRC: Lease failed to satisfy.");
3172 int lease_score = dhc6_score_lease(client,
lease);
3173 #ifdef ENFORCE_DHCPV6_CLIENT_REQUIRE 3174 if (lease_score == 0) {
3175 log_debug(
"RCV:Advertised lease scored 0, toss it.");
3194 ((
lease->pref == 255) && (lease_score > SCORE_MIN))) {
3195 log_debug(
"RCV: Advertisement immediately selected.");
3199 log_debug(
"RCV: Advertisement recorded.");
3207 isc_result_t check_status;
3216 if (!valid_reply(
packet, client)) {
3217 log_error(
"Invalid Reply - rejecting.");
3221 check_status = dhc6_check_status(ISC_R_SUCCESS,
packet->
options,
3224 if (check_status != ISC_R_SUCCESS) {
3228 if (check_status != ISC_R_CANCELED)
3238 if (check_status == ISC_R_CANCELED)
3252 log_fatal(
"Out of memory for v6 lease structure.");
3262 start_informed(client);
3271 isc_result_t check_status;
3276 init_handler(
packet, client);
3284 if (!valid_reply(
packet, client)) {
3285 log_error(
"Invalid Reply - rejecting.");
3292 log_error(
"Reply without Rapid-Commit - rejecting.");
3304 check_status = dhc6_check_reply(client,
lease);
3305 if (check_status != ISC_R_SUCCESS) {
3338 start_bound(client);
3373 struct dhc6_lease **rpos, *rval, **candp, *cand;
3376 if (head == NULL || *head == NULL)
3381 rscore = dhc6_score_lease(client, rval);
3382 candp = &rval->
next;
3385 log_debug(
"PRC: Considering best lease.");
3386 log_debug(
"PRC: X-- Initial candidate %s (s: %d, p: %u).",
3389 rscore, (
unsigned)rval->
pref);
3391 for (; cand != NULL ; candp = &cand->
next, cand = *candp) {
3392 cscore = dhc6_score_lease(client, cand);
3394 log_debug(
"PRC: X-- Candidate %s (s: %d, p: %u).",
3397 cscore, (
unsigned)cand->
pref);
3421 if ((rscore < SCORE_MIN) && (cscore >= SCORE_MIN)) {
3422 log_debug(
"PRC: | X-- Selected, has bindings.");
3423 }
else if (cand->
pref < rval->
pref) {
3424 log_debug(
"PRC: | X-- Rejected, lower preference.");
3426 }
else if (cand->
pref > rval->
pref) {
3427 log_debug(
"PRC: | X-- Selected, higher preference.");
3428 }
else if (cscore > rscore) {
3429 log_debug(
"PRC: | X-- Selected, equal preference, " 3431 }
else if (cscore < rscore) {
3432 log_debug(
"PRC: | X-- Rejected, equal preference, " 3440 log_debug(
"PRC: | X-- Selected, equal preference, " 3441 "equal score, binary lesser server ID.");
3443 log_debug(
"PRC: | X-- Rejected, equal preference, " 3444 "equal score, binary greater server ID.");
3468 log_error(
"Can not enter DHCPv6 SELECTING state with no " 3469 "leases to select from!");
3473 log_debug(
"PRC: Selecting best advertised lease.");
3489 dhc6_retrans_init(client);
3502 do_select6(
void *input)
3508 int send_ret, added;
3514 if (
lease == NULL ||
lease->bindings == NULL) {
3515 log_error(
"Illegal to attempt selection without selecting " 3521 case CHK_TIM_MRC_EXCEEDED:
3522 case CHK_TIM_MRD_EXCEEDED:
3525 lease->server_id.data, 56));
3537 case CHK_TIM_ALLOC_FAILURE:
3539 case CHK_TIM_SUCCESS:
3590 log_info(
"XMT: Request on %s, interval %ld0ms.",
3592 (
long int)client->
RT);
3595 ds.
data, ds.
len, &DHCPv6DestAddr);
3596 if (send_ret != ds.
len) {
3597 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
3604 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
3605 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
3606 if (tv.tv_usec >= 1000000) {
3608 tv.tv_usec -= 1000000;
3612 dhc6_retrans_advance(client);
3630 for (ia =
lease->bindings; ia != NULL; ia = ia->
next) {
3667 int wanted,
int *added)
3673 isc_result_t rval = ISC_R_SUCCESS;
3678 memset(&iads, 0,
sizeof(iads));
3679 memset(&addrds, 0,
sizeof(addrds));
3680 for (ia =
lease->bindings, i = 0;
3681 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3690 log_error(
"Unable to allocate memory for IA_NA.");
3691 rval = ISC_R_NOMEMORY;
3696 memcpy(iads.buffer->data, ia->
iaid, 4);
3697 iads.data = iads.buffer->data;
3707 #if MAX_TIME > 0xffffffff 3708 if (t1 > 0xffffffff)
3710 if (t2 > 0xffffffff)
3713 putULong(iads.buffer->data + 4, t1);
3714 putULong(iads.buffer->data + 8, t2);
3718 log_debug(
"XMT: | X-- Requested renew +%u",
3720 log_debug(
"XMT: | X-- Requested rebind +%u",
3728 memset(iads.buffer->data + 4, 0, 8);
3738 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3748 log_error(
"Illegal IPv6 address length (%d), " 3749 "ignoring. (%s:%d)",
3755 log_error(
"Unable to allocate memory for " 3757 rval = ISC_R_NOMEMORY;
3761 addrds.data = addrds.buffer->data;
3774 putULong(addrds.buffer->data + 16, t1);
3775 putULong(addrds.buffer->data + 20, t2);
3780 "lifetime +%u", (
unsigned)t1);
3781 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3791 memset(addrds.buffer->data + 16, 0, 8);
3792 log_debug(
"XMT: | X-- Confirm Address %s",
3798 memset(addrds.buffer->data + 16, 0, 8);
3799 log_debug(
"XMT: | X-- Release Address %s",
3805 memset(addrds.buffer->data + 16, 0, 8);
3806 log_debug(
"XMT: | X-- Decline Address %s",
3811 log_fatal(
"Impossible condition at %s:%d.",
3824 if (ia->
addrs == NULL) {
3825 log_debug(
"!!!: V IA_NA has no IAADDRs - removed.");
3826 rval = ISC_R_FAILURE;
3827 }
else if (rval == ISC_R_SUCCESS) {
3836 if (rval == ISC_R_SUCCESS)
3870 int wanted,
int *added)
3876 isc_result_t rval = ISC_R_SUCCESS;
3881 memset(&iads, 0,
sizeof(iads));
3882 memset(&addrds, 0,
sizeof(addrds));
3883 for (ia =
lease->bindings, i = 0;
3884 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
3893 log_error(
"Unable to allocate memory for IA_TA.");
3894 rval = ISC_R_NOMEMORY;
3899 memcpy(iads.buffer->data, ia->
iaid, 4);
3900 iads.data = iads.buffer->data;
3906 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
3916 log_error(
"Illegal IPv6 address length (%d), " 3917 "ignoring. (%s:%d)",
3923 log_error(
"Unable to allocate memory for " 3925 rval = ISC_R_NOMEMORY;
3929 addrds.data = addrds.buffer->data;
3942 putULong(addrds.buffer->data + 16, t1);
3943 putULong(addrds.buffer->data + 20, t2);
3948 "lifetime +%u", (
unsigned)t1);
3949 log_debug(
"XMT: | | | X-- Max lifetime +%u",
3959 memset(addrds.buffer->data + 16, 0, 8);
3960 log_debug(
"XMT: | X-- Confirm Address %s",
3966 memset(addrds.buffer->data + 16, 0, 8);
3967 log_debug(
"XMT: | X-- Release Address %s",
3972 log_fatal(
"Impossible condition at %s:%d.",
3985 if (ia->
addrs == NULL) {
3986 log_debug(
"!!!: V IA_TA has no IAADDRs - removed.");
3987 rval = ISC_R_FAILURE;
3988 }
else if (rval == ISC_R_SUCCESS) {
3997 if (rval == ISC_R_SUCCESS)
4031 int wanted,
int *added)
4037 isc_result_t rval = ISC_R_SUCCESS;
4042 memset(&iads, 0,
sizeof(iads));
4043 memset(&prefds, 0,
sizeof(prefds));
4044 for (ia =
lease->bindings, i = 0;
4045 ia != NULL && rval == ISC_R_SUCCESS && (wanted == 0 || i < wanted);
4054 log_error(
"Unable to allocate memory for IA_PD.");
4055 rval = ISC_R_NOMEMORY;
4060 memcpy(iads.buffer->data, ia->
iaid, 4);
4061 iads.data = iads.buffer->data;
4071 #if MAX_TIME > 0xffffffff 4072 if (t1 > 0xffffffff)
4074 if (t2 > 0xffffffff)
4077 putULong(iads.buffer->data + 4, t1);
4078 putULong(iads.buffer->data + 8, t2);
4082 log_debug(
"XMT: | X-- Requested renew +%u",
4084 log_debug(
"XMT: | X-- Requested rebind +%u",
4090 memset(iads.buffer->data + 4, 0, 8);
4100 for (pref = ia->
addrs ; pref != NULL ; pref = pref->
next) {
4111 "ignoring. (%s:%d)",
4116 if (pref->
plen == 0) {
4118 "ignoring. (%s:%d)",
4123 log_error(
"Unable to allocate memory for " 4125 rval = ISC_R_NOMEMORY;
4129 prefds.data = prefds.buffer->data;
4134 memcpy(prefds.buffer->data + 9,
4146 putULong(prefds.buffer->data + 4, t2);
4148 log_debug(
"XMT: | | X-- IAPREFIX %s/%u",
4150 (
unsigned) pref->
plen);
4152 "lifetime +%u", (
unsigned)t1);
4153 log_debug(
"XMT: | | | X-- Max lifetime +%u",
4160 memset(prefds.buffer->data, 0, 8);
4161 log_debug(
"XMT: | X-- Release Prefix %s/%u",
4163 (
unsigned) pref->
plen);
4167 log_fatal(
"Impossible condition at %s:%d.",
4172 iaprefix_option, &prefds);
4180 if (ia->
addrs == NULL) {
4181 log_debug(
"!!!: V IA_PD has no IAPREFIXs - removed.");
4182 rval = ISC_R_FAILURE;
4183 }
else if (rval == ISC_R_SUCCESS) {
4186 ia_pd_option, &iads);
4192 if (rval == ISC_R_SUCCESS)
4200 static isc_boolean_t
4201 stopping_finished(
void)
4207 for (client =
ip -> client; client; client = client ->
next) {
4224 isc_result_t check_status;
4232 if (!valid_reply(
packet, client)) {
4233 log_error(
"Invalid Reply - rejecting.");
4245 check_status = dhc6_check_reply(client,
lease);
4246 if (check_status != ISC_R_SUCCESS) {
4252 if (check_status != ISC_R_CANCELED)
4271 if (stopping_finished())
4284 if (check_status == ISC_R_CANCELED)
4300 start_bound(client);
4328 start_bound(client);
4345 dhc6_marshall_values(
const char *prefix,
struct client_state *client,
4352 if ((
lease != NULL) && (
lease->options != NULL))
4353 script_write_params6(client, prefix,
lease->options);
4354 if ((ia != NULL) && (ia->
options != NULL))
4355 script_write_params6(client, prefix, ia->
options);
4356 if ((addr != NULL) && (addr->
options != NULL))
4357 script_write_params6(client, prefix, addr->
options);
4363 "ip6_prefix",
"%s/%u",
4365 (
unsigned) addr->
plen);
4374 "ip6_type",
"temporary");
4405 lo_expire=
MAX_TIME, hi_expire=0, max_ia_starts = 0, tmp;
4406 int has_addrs = ISC_FALSE;
4407 int has_preferred_addrs = ISC_FALSE;
4420 for(ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4421 TIME this_ia_lo_expire, this_ia_hi_expire, use_expire;
4424 this_ia_hi_expire = 0;
4426 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4438 has_preferred_addrs = ISC_TRUE;
4452 if (tmp > this_ia_hi_expire)
4453 this_ia_hi_expire = tmp;
4454 if (tmp < this_ia_lo_expire)
4455 this_ia_lo_expire = tmp;
4457 has_addrs = ISC_TRUE;
4462 if (this_ia_lo_expire <= (this_ia_hi_expire / 2))
4463 use_expire = this_ia_hi_expire;
4465 use_expire = this_ia_lo_expire;
4471 if ((use_expire ==
MAX_TIME) || (use_expire <= 1))
4488 if (ia->
starts > max_ia_starts)
4489 max_ia_starts = ia->
starts;
4491 if (ia->
renew == 0) {
4493 }
else if (ia->
renew == 0xffffffff)
4503 tmp = use_expire + (use_expire / 2);
4504 }
else if (ia->
rebind == 0xffffffff)
4517 this_ia_hi_expire += ia->
starts;
4518 this_ia_lo_expire += ia->
starts;
4520 if (this_ia_hi_expire > hi_expire)
4521 hi_expire = this_ia_hi_expire;
4522 if (this_ia_lo_expire < lo_expire)
4523 lo_expire = this_ia_lo_expire;
4535 if (has_addrs == ISC_FALSE) {
4549 renew += max_ia_starts;
4551 rebind += max_ia_starts;
4553 switch(client->
state) {
4558 if ((rebind >
cur_time) && (renew < rebind)) {
4559 log_debug(
"PRC: Renewal event scheduled in %d seconds, " 4560 "to run for %u seconds.",
4562 (
unsigned)(rebind - renew));
4566 add_timeout(&tv, start_renew6, client, NULL, NULL);
4578 log_debug(
"PRC: Rebind event scheduled in %d seconds, " 4579 "to run for %d seconds.",
4581 (
int)(hi_expire - rebind));
4585 add_timeout(&tv, start_rebind6, client, NULL, NULL);
4598 if (has_preferred_addrs) {
4599 log_fatal(
"Impossible condition, state %d at %s:%d.",
4609 log_debug(
"PRC: Depreference scheduled in %d seconds.",
4616 log_debug(
"PRC: Expiration scheduled in %d seconds.",
4618 tv.tv_sec = lo_expire;
4626 find_ia(
struct dhc6_ia *head, u_int16_t type,
const char *
id)
4630 for (ia = head ; ia != NULL ; ia = ia->
next) {
4633 if (memcmp(ia->
iaid,
id, 4) == 0)
4646 for (addr = head ; addr != NULL ; addr = addr->
next) {
4662 for (pref = head ; pref != NULL ; pref = pref->
next) {
4695 struct dhc6_ia *sia, *dia, *tia, **eia;
4696 struct dhc6_addr *saddr, *daddr, *taddr;
4699 if ((dst == NULL) || (src == NULL))
4702 for (sia = src->
bindings ; sia != NULL ; sia = sia->
next) {
4706 tia = dhc6_dup_ia(sia,
MDL);
4709 log_fatal(
"Out of memory merging lease - " 4710 "Unable to continue without losing " 4711 "state! (%s:%d)",
MDL);
4723 eia = &(*eia)->
next) {
4729 for (saddr = sia->
addrs ; saddr != NULL ;
4730 saddr = saddr->
next) {
4732 daddr = find_addr(dia->
addrs,
4735 daddr = find_pref(dia->
addrs,
4739 if (daddr == NULL) {
4740 taddr = dhc6_dup_addr(saddr,
MDL);
4745 "Unable to continue " 4776 #if defined (NSUPDATE) 4777 TIME dns_update_offset = 1;
4781 if (
lease == NULL) {
4782 log_error(
"Cannot enter bound state unless an active lease " 4786 lease->released = ISC_FALSE;
4791 switch (client->
state) {
4819 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
4827 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
4832 if (oldia != NULL) {
4834 oldaddr = find_addr(oldia->
addrs,
4837 oldaddr = find_pref(oldia->
addrs,
4843 #if defined (NSUPDATE) 4847 dns_update_offset++);
4854 dhc6_marshall_values(
"old_", client, old,
4856 dhc6_marshall_values(
"new_", client,
lease, ia, addr);
4857 script_write_requested6(client);
4861 start_decline6(client);
4867 if (ia->
addrs == NULL) {
4871 dhc6_marshall_values(
"old_", client, old,
4874 oldia->
addrs : NULL);
4876 dhc6_marshall_values(
"new_", client,
lease, ia,
4878 script_write_requested6(client);
4885 if (
lease->bindings == NULL) {
4889 dhc6_marshall_values(
"old_", client, old,
4894 dhc6_marshall_values(
"new_", client,
lease, NULL, NULL);
4895 script_write_requested6(client);
4913 dhc6_check_times(client);
4939 dhc6_retrans_init(client);
4943 do_decline6(client);
4950 do_decline6(
void *input)
4954 struct timeval elapsed, tv;
4955 int send_ret, added;
4959 if ((client->
active_lease == NULL) || !active_prefix(client))
4962 if ((client->
MRC != 0) && (client->
txcount > client->
MRC)) {
4963 log_info(
"Max retransmission count exceeded.");
4978 if (elapsed.tv_usec < 0) {
4979 elapsed.tv_sec -= 1;
4980 elapsed.tv_usec += 1000000;
4983 memset(&ds, 0,
sizeof(ds));
4985 log_error(
"Unable to allocate memory for Decline.");
4996 if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
4997 ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
5000 client->
elapsed = elapsed.tv_sec * 100;
5001 client->
elapsed += elapsed.tv_usec / 10000;
5028 log_info(
"XMT: Decline on %s, interval %ld0ms.",
5030 (
long int)client->
RT);
5034 if (send_ret != ds.
len) {
5035 log_error(
"dhc6: sendpacket6() sent %d of %d bytes",
5042 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5043 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5044 if (tv.tv_usec >= 1000000) {
5046 tv.tv_usec -= 1000000;
5048 add_timeout(&tv, do_decline6, client, NULL, NULL);
5049 dhc6_retrans_advance(client);
5065 log_debug(
"RCV: Input packets are ignored once bound.");
5073 start_renew6(
void *input)
5079 log_info(
"PRC: Renewing lease on %s.",
5094 dhc6_retrans_init(client);
5097 do_refresh6(client);
5105 do_refresh6(
void *input)
5108 struct sockaddr_in6 unicast, *dest_addr = &DHCPv6DestAddr;
5112 struct timeval elapsed, tv;
5113 int send_ret, added;
5116 memset(&ds, 0,
sizeof(ds));
5119 if (
lease == NULL) {
5120 log_error(
"Cannot renew without an active binding.");
5131 log_fatal(
"Internal inconsistency (%d) at %s:%d.",
5150 if (((client->
MRC != 0) && (client->
txcount > client->
MRC)) ||
5153 dhc6_check_times(client);
5166 log_error(
"Invalid unicast option length %d.", ds.
len);
5168 memset(&unicast, 0,
sizeof(DHCPv6DestAddr));
5169 unicast.sin6_family = AF_INET6;
5171 memcpy(&unicast.sin6_addr, ds.
data, 16);
5173 dest_addr = &unicast;
5181 memset(&ds, 0,
sizeof(ds));
5183 log_error(
"Unable to allocate memory for packet.");
5203 log_debug(
"XMT: Forming %s, 0 ms elapsed.",
5206 log_debug(
"XMT: Forming %s, %u0 ms elapsed.",
5242 log_info(
"XMT: %s on %s, interval %ld0ms.",
5245 (
long int)client->
RT);
5249 if (send_ret != ds.
len) {
5250 log_error(
"dhc6: send_packet6() sent %d of %d bytes",
5257 tv.tv_sec =
cur_tv.tv_sec + client->
RT / 100;
5258 tv.tv_usec =
cur_tv.tv_usec + (client->
RT % 100) * 10000;
5259 if (tv.tv_usec >= 1000000) {
5261 tv.tv_usec -= 1000000;
5263 add_timeout(&tv, do_refresh6, client, NULL, NULL);
5265 dhc6_retrans_advance(client);
5274 start_rebind6(
void *input)
5280 log_info(
"PRC: Rebinding lease on %s.",
5295 dhc6_retrans_init(client);
5298 do_refresh6(client);
5308 do_depref(
void *input)
5321 for (ia =
lease->bindings ; ia != NULL ; ia = ia->
next) {
5322 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5328 dhc6_marshall_values(
"cur_", client,
lease,
5330 script_write_requested6(client);
5336 log_info(
"PRC: Address %s depreferred.",
5339 log_info(
"PRC: Prefix %s/%u depreferred.",
5341 (
unsigned) addr->
plen);
5343 #if defined (NSUPDATE) 5354 dhc6_check_times(client);
5361 do_expire(
void *input)
5367 int has_addrs = ISC_FALSE;
5368 int ia_has_addrs = ISC_FALSE;
5376 for (ia =
lease->bindings, tia = &
lease->bindings; ia != NULL ; ) {
5377 ia_has_addrs = ISC_FALSE;
5378 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5384 dhc6_marshall_values(
"old_", client,
lease,
5386 script_write_requested6(client);
5392 log_info(
"PRC: Address %s expired.",
5395 log_info(
"PRC: Prefix %s/%u expired.",
5397 (
unsigned) addr->
plen);
5399 #if defined (NSUPDATE) 5414 ia_has_addrs = ISC_TRUE;
5415 has_addrs = ISC_TRUE;
5421 if (ia_has_addrs == ISC_TRUE) {
5423 tia = &(*tia)->
next;
5429 dhc6_ia_destroy(&ia,
MDL);
5436 if (has_addrs == ISC_FALSE) {
5437 log_info(
"PRC: Bound lease is devoid of active addresses." 5438 " Re-initializing.");
5448 dhc6_check_times(client);
5466 script_write_params6(client,
"old_",
5468 script_write_requested6(client);
5480 for (addr = ia->
addrs ; addr != NULL ; addr = addr->
next) {
5482 dhc6_marshall_values(
"old_", client,
5484 script_write_requested6(client);
5487 #if defined (NSUPDATE) 5497 refresh_info_request6(
void *input)
5515 isc_boolean_t found = ISC_FALSE;
5520 for (i = 0; req[i] != NULL; i++) {
5521 if (req[i] == irt_option) {
5539 memset(&irt, 0,
sizeof(irt));
5549 if (expire == 0xffffffff)
5557 log_debug(
"PRC: Refresh event scheduled in %u seconds.",
5561 add_timeout(&tv, refresh_info_request6, client, NULL, NULL);
5579 script_write_params6(client,
"old_",
5582 script_write_requested6(client);
5598 dhc6_check_irt(client);
5606 log_debug(
"RCV: Input packets are ignored once bound.");
5620 int buflen, i, oro_len;
5622 if ((op == NULL) || (client == NULL))
5634 const unsigned char *cdata;
5636 cdata = (
unsigned char *)&client->
elapsed;
5666 log_fatal(
"Failure assembling a DUID.");
5678 if (
lease == NULL) {
5695 log_error(
"'send dhcp6.oro' syntax is deprecated, please " 5696 "use the 'request' syntax (\"man dhclient.conf\").");
5736 log_fatal(
"Out of memory constructing DHCPv6 ORO.");
5739 for (i = 0 ; req[i] != NULL ; i++) {
5740 if (buflen == oro_len) {
5741 struct buffer *tmpbuf = NULL;
5751 "DHCPv6 ORO buffer.");
5772 log_fatal(
"Unable to create ORO option cache.");
5796 script_write_params6(
struct client_state *client,
const char *prefix,
5802 if (options == NULL)
5822 static void script_write_requested6(
client)
5833 for (i = 0 ; req[i] != NULL ; i++) {
5844 static isc_boolean_t
5855 memset(zeros, 0, 16);
5856 for (ia =
lease->bindings; ia != NULL; ia = ia->
next) {
5859 for (pref = ia->
addrs; pref != NULL; pref = pref->
next) {
5860 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
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)