60#if LWIP_IPV6 && LWIP_IPV6_DHCP6
70#ifdef LWIP_HOOK_FILENAME
71#include LWIP_HOOK_FILENAME
73#ifndef LWIP_HOOK_DHCP6_APPEND_OPTIONS
74#define LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len)
76#ifndef LWIP_HOOK_DHCP6_PARSE_OPTION
77#define LWIP_HOOK_DHCP6_PARSE_OPTION(netif, dhcp6, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0)
80#if LWIP_DNS && LWIP_DHCP6_MAX_DNS_SERVERS
81#if DNS_MAX_SERVERS > LWIP_DHCP6_MAX_DNS_SERVERS
82#define LWIP_DHCP6_PROVIDE_DNS_SERVERS LWIP_DHCP6_MAX_DNS_SERVERS
84#define LWIP_DHCP6_PROVIDE_DNS_SERVERS DNS_MAX_SERVERS
87#define LWIP_DHCP6_PROVIDE_DNS_SERVERS 0
96enum dhcp6_option_idx {
97 DHCP6_OPTION_IDX_CLI_ID = 0,
98 DHCP6_OPTION_IDX_SERVER_ID,
99#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
100 DHCP6_OPTION_IDX_DNS_SERVER,
101 DHCP6_OPTION_IDX_DOMAIN_LIST,
103#if LWIP_DHCP6_GET_NTP_SRV
104 DHCP6_OPTION_IDX_NTP_SERVER,
109struct dhcp6_option_info {
116struct dhcp6_option_info dhcp6_rx_options[DHCP6_OPTION_IDX_MAX];
118#define dhcp6_option_given(dhcp6, idx) (dhcp6_rx_options[idx].option_given != 0)
119#define dhcp6_got_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 1)
120#define dhcp6_clear_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 0)
121#define dhcp6_clear_all_options(dhcp6) (memset(dhcp6_rx_options, 0, sizeof(dhcp6_rx_options)))
122#define dhcp6_get_option_start(dhcp6, idx) (dhcp6_rx_options[idx].val_start)
123#define dhcp6_get_option_length(dhcp6, idx) (dhcp6_rx_options[idx].val_length)
124#define dhcp6_set_option(dhcp6, idx, start, len) do { dhcp6_rx_options[idx].val_start = (start); dhcp6_rx_options[idx].val_length = (len); }while(0)
130static struct udp_pcb *dhcp6_pcb;
131static u8_t dhcp6_pcb_refcount;
139dhcp6_inc_pcb_refcount(
void)
141 if (dhcp6_pcb_refcount == 0) {
142 LWIP_ASSERT(
"dhcp6_inc_pcb_refcount(): memory leak", dhcp6_pcb ==
NULL);
145 dhcp6_pcb = udp_new_ip6();
147 if (dhcp6_pcb ==
NULL) {
155 udp_recv(dhcp6_pcb, dhcp6_recv,
NULL);
158 dhcp6_pcb_refcount++;
165dhcp6_dec_pcb_refcount(
void)
167 LWIP_ASSERT(
"dhcp6_pcb_refcount(): refcount error", (dhcp6_pcb_refcount > 0));
168 dhcp6_pcb_refcount--;
170 if (dhcp6_pcb_refcount == 0) {
171 udp_remove(dhcp6_pcb);
185dhcp6_set_struct(
struct netif *
netif,
struct dhcp6 *dhcp6)
192 memset(dhcp6, 0,
sizeof(
struct dhcp6));
194 netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, dhcp6);
212 netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6,
NULL);
217dhcp6_get_struct(
struct netif *
netif,
const char *dbg_requester)
219 struct dhcp6 *dhcp6 = netif_dhcp6_data(
netif);
222 dhcp6 = (
struct dhcp6 *)
mem_malloc(
sizeof(
struct dhcp6));
229 memset(dhcp6, 0,
sizeof(
struct dhcp6));
231 netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, dhcp6);
237 if (!dhcp6->pcb_allocated) {
238 if (dhcp6_inc_pcb_refcount() !=
ERR_OK) {
240 netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6,
NULL);
244 dhcp6->pcb_allocated = 1;
254dhcp6_set_state(
struct dhcp6 *dhcp6,
u8_t new_state,
const char *dbg_caller)
257 dhcp6->state, new_state, dbg_caller));
258 if (new_state != dhcp6->state) {
259 dhcp6->state = new_state;
261 dhcp6->request_timeout = 0;
266dhcp6_stateless_enabled(
struct dhcp6 *dhcp6)
322 dhcp6 = dhcp6_get_struct(
netif,
"dhcp6_enable_stateless()");
326 if (dhcp6_stateless_enabled(dhcp6)) {
352 dhcp6 = netif_dhcp6_data(
netif);
356 (dhcp6_stateless_enabled(dhcp6) ?
"stateless" :
"stateful")));
358 if (dhcp6->pcb_allocated != 0) {
359 dhcp6_dec_pcb_refcount();
360 dhcp6->pcb_allocated = 0;
377dhcp6_create_msg(
struct netif *
netif,
struct dhcp6 *dhcp6,
u8_t message_type,
388 (
"dhcp6_create_msg(): could not allocate pbuf\n"));
391 LWIP_ASSERT(
"dhcp6_create_msg: check that first pbuf can hold struct dhcp6_msg",
392 (p_out->len >=
sizeof(
struct dhcp6_msg) + opt_len_alloc));
396 if (dhcp6->tries == 0) {
397 dhcp6->xid = LWIP_RAND() & 0xFFFFFF;
401 (
"transaction id xid(%"X32_F")\n", dhcp6->xid));
403 msg_out = (
struct dhcp6_msg *)p_out->payload;
406 msg_out->msgtype = message_type;
407 msg_out->transaction_id[0] = (
u8_t)(dhcp6->xid >> 16);
408 msg_out->transaction_id[1] = (
u8_t)(dhcp6->xid >> 8);
409 msg_out->transaction_id[2] = (
u8_t)dhcp6->xid;
410 *options_out_len = 0;
419 return options_out_len;
429 LWIP_ASSERT(
"dhcp6_option_optionrequest: options_out_len + sizeof(struct dhcp6_msg) + addlen <= max_len",
430 sizeof(
struct dhcp6_msg) + options_out_len + 4U + (2U * num_req_options) <= max_len);
435 for (
i = 0;
i < num_req_options;
i++) {
443dhcp6_msg_finalize(
u16_t options_out_len,
struct pbuf *p_out)
450#if LWIP_IPV6_DHCP6_STATELESS
452dhcp6_information_request(
struct netif *
netif,
struct dhcp6 *dhcp6)
454 const u16_t requested_options[] = {
455#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
459#if LWIP_DHCP6_GET_NTP_SRV
466 u16_t options_out_len;
469 p_out = dhcp6_create_msg(
netif, dhcp6,
DHCP6_INFOREQUEST, 4 +
sizeof(requested_options), &options_out_len);
476 options_out_len = dhcp6_option_optionrequest(options_out_len,
options, requested_options,
480 dhcp6_msg_finalize(options_out_len, p_out);
490 if (dhcp6->tries < 255) {
493 msecs = (
u16_t)((dhcp6->tries < 6 ? 1 << dhcp6->tries : 60) * 1000);
494 dhcp6->request_timeout = (
u16_t)((msecs + DHCP6_TIMER_MSECS - 1) / DHCP6_TIMER_MSECS);
499dhcp6_request_config(
struct netif *
netif,
struct dhcp6 *dhcp6)
504 dhcp6_information_request(
netif, dhcp6);
511dhcp6_abort_config_request(
struct dhcp6 *dhcp6)
523dhcp6_handle_config_reply(
struct netif *
netif,
struct pbuf *p_msg_in)
525 struct dhcp6 *dhcp6 = netif_dhcp6_data(
netif);
530#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
531 if (dhcp6_option_given(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER)) {
533 ip6_addr_t *dns_addr6;
534 u16_t op_start = dhcp6_get_option_start(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER);
535 u16_t op_len = dhcp6_get_option_length(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER);
541 for (
n = 0,
idx = op_start; (
idx < op_start + op_len) && (
n < LWIP_DHCP6_PROVIDE_DNS_SERVERS);
548 ip6_addr_assign_zone(dns_addr6, IP6_UNKNOWN,
netif);
550 dns_setserver(
n, &dns_addr);
556#if LWIP_DHCP6_GET_NTP_SRV
557 if (dhcp6_option_given(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER)) {
559 u16_t op_start = dhcp6_get_option_start(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER);
560 u16_t op_len = dhcp6_get_option_length(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER);
567 ip6_addr_t *ntp_addr6 =
ip_2_ip6(&ntp_server_addrs[
n]);
574 ip6_addr_assign_zone(ntp_addr6, IP6_UNKNOWN,
netif);
576 dhcp6_set_ntp_servers(
n, ntp_server_addrs);
591 dhcp6 = netif_dhcp6_data(
netif);
597#if LWIP_IPV6_DHCP6_STATELESS
599 if (dhcp6_stateless_enabled(dhcp6)) {
601 dhcp6_request_config(
netif, dhcp6);
603 dhcp6_abort_config_request(dhcp6);
617dhcp6_parse_reply(
struct pbuf *
p,
struct dhcp6 *dhcp6)
627 dhcp6_clear_all_options(dhcp6);
634 offset_max =
p->tot_len;
638 while ((
offset + 4 <= offset_max)) {
644 if (val_offset <
offset) {
650 if (op_len ==
NULL) {
654 op = (op_len[0] << 8) | op_len[1];
655 len = (op_len[2] << 8) | op_len[3];
657 if (
offset < val_offset) {
664 dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_CLI_ID);
665 dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_CLI_ID, val_offset,
len);
668 dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_SERVER_ID);
669 dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_SERVER_ID, val_offset,
len);
671#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
673 dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER);
674 dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_DNS_SERVER, val_offset,
len);
677 dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_DOMAIN_LIST);
678 dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_DOMAIN_LIST, val_offset,
len);
681#if LWIP_DHCP6_GET_NTP_SRV
683 dhcp6_got_option(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER);
684 dhcp6_set_option(dhcp6, DHCP6_OPTION_IDX_NTP_SERVER, val_offset,
len);
689 LWIP_HOOK_DHCP6_PARSE_OPTION(
ip_current_netif(), dhcp6, dhcp6->state, msg_in,
690 msg_in->msgtype,
op,
len,
q, val_offset);
701 struct dhcp6 *dhcp6 = netif_dhcp6_data(
netif);
709 if ((dhcp6 ==
NULL) || (dhcp6->pcb_allocated == 0)) {
710 goto free_pbuf_and_return;
726 goto free_pbuf_and_return;
730 xid = reply_msg->transaction_id[0] << 16;
731 xid |= reply_msg->transaction_id[1] << 8;
732 xid |= reply_msg->transaction_id[2];
733 if (
xid != dhcp6->xid) {
735 (
"transaction id mismatch reply_msg->xid(%"X32_F")!= dhcp6->xid(%"X32_F")\n",
xid, dhcp6->xid));
736 goto free_pbuf_and_return;
739 if (dhcp6_parse_reply(
p, dhcp6) !=
ERR_OK) {
741 (
"problem unfolding DHCPv6 message - too short on memory?\n"));
742 goto free_pbuf_and_return;
750#if LWIP_IPV6_DHCP6_STATELESS
754 dhcp6_handle_config_reply(
netif,
p);
775dhcp6_timeout(
struct netif *
netif,
struct dhcp6 *dhcp6)
782#if LWIP_IPV6_DHCP6_STATELESS
786 dhcp6_information_request(
netif, dhcp6);
804 struct dhcp6 *dhcp6 = netif_dhcp6_data(
netif);
808 if (dhcp6->request_timeout > 1) {
809 dhcp6->request_timeout--;
810 }
else if (dhcp6->request_timeout == 1) {
811 dhcp6->request_timeout--;
815 dhcp6_timeout(
netif, dhcp6);
#define LWIP_ARRAYSIZE(x)
#define mem_free(ptr, bsize)
void * mem_malloc(mem_size_t size_in)
#define LWIP_DEBUGF(debug, message)
#define LWIP_ERROR(message, expression, handler)
#define LWIP_ASSERT(message, assertion)
#define ip_set_option(pcb, opt)
#define ip_current_netif()
#define ip_current_input_netif()
GLdouble GLdouble GLdouble GLdouble q
GLenum const GLvoid * addr
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define LWIP_UNUSED_ARG(x)
#define LWIP_DBG_LEVEL_SERIOUS
#define LWIP_DBG_LEVEL_WARNING
#define LWIP_DHCP6_MAX_NTP_SERVERS
void pbuf_realloc(struct pbuf *p, u16_t new_len)
void * pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
#define ipaddr_ntoa(ipaddr)
#define IPADDR6_INIT_HOST(a, b, c, d)
#define ip_addr_set_zero_ip6(ipaddr)
#define NETIF_FOREACH(netif)
#define DHCP6_OPTION_SERVERID
#define DHCP6_OPTION_DNS_SERVERS
#define DHCP6_INFOREQUEST
#define DHCP6_OPTION_CLIENTID
#define DHCP6_OPTION_SNTP_SERVERS
#define DHCP6_OPTION_DOMAIN_LIST
@ DHCP6_STATE_REQUESTING_CONFIG
@ DHCP6_STATE_STATELESS_IDLE
#define DHCP6_SERVER_PORT
#define DHCP6_CLIENT_PORT