summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKinsey Moore <kinsey.moore@oarcorp.com>2022-08-24 15:53:12 -0500
committerJoel Sherrill <joel@rtems.org>2022-08-26 08:50:51 -0500
commit444dc8a2b564c2c8d26806bd87514f60ccff3114 (patch)
tree06a0adbc5110a5a4d59d56b3b84464e23893f7db
parentUpdate lwip submodule to 2.1.3 (diff)
downloadrtems-lwip-444dc8a2b564c2c8d26806bd87514f60ccff3114.tar.bz2
lwip: Update to 2.1.3
This updates lwIP to the STABLE-2_1_3_RELEASE tag.
-rw-r--r--lwip/src/api/api_lib.c12
-rw-r--r--lwip/src/api/api_msg.c3
-rw-r--r--lwip/src/api/netdb.c9
-rw-r--r--lwip/src/api/sockets.c14
-rw-r--r--lwip/src/api/tcpip.c2
-rw-r--r--lwip/src/core/altcp.c36
-rw-r--r--lwip/src/core/altcp_tcp.c52
-rw-r--r--lwip/src/core/init.c5
-rw-r--r--lwip/src/core/ipv4/dhcp.c57
-rw-r--r--lwip/src/core/ipv4/etharp.c8
-rw-r--r--lwip/src/core/ipv4/icmp.c18
-rw-r--r--lwip/src/core/ipv4/ip4_addr.c2
-rw-r--r--lwip/src/core/ipv6/dhcp6.c13
-rw-r--r--lwip/src/core/ipv6/icmp6.c27
-rw-r--r--lwip/src/core/ipv6/ip6.c2
-rw-r--r--lwip/src/core/ipv6/ip6_frag.c2
-rw-r--r--lwip/src/core/ipv6/mld6.c4
-rw-r--r--lwip/src/core/ipv6/nd6.c30
-rw-r--r--lwip/src/core/netif.c44
-rw-r--r--lwip/src/core/pbuf.c58
-rw-r--r--lwip/src/core/tcp.c6
-rw-r--r--lwip/src/core/tcp_in.c5
-rw-r--r--lwip/src/core/tcp_out.c7
-rw-r--r--lwip/src/core/udp.c12
-rw-r--r--lwip/src/include/lwip/altcp.h5
-rw-r--r--lwip/src/include/lwip/altcp_tls.h28
-rw-r--r--lwip/src/include/lwip/apps/altcp_tls_mbedtls_opts.h42
-rw-r--r--lwip/src/include/lwip/apps/sntp.h6
-rw-r--r--lwip/src/include/lwip/apps/sntp_opts.h6
-rw-r--r--lwip/src/include/lwip/debug.h4
-rw-r--r--lwip/src/include/lwip/if_api.h2
-rw-r--r--lwip/src/include/lwip/init.h2
-rw-r--r--lwip/src/include/lwip/netif.h6
-rw-r--r--lwip/src/include/lwip/opt.h25
-rw-r--r--lwip/src/include/lwip/pbuf.h4
-rw-r--r--lwip/src/include/lwip/priv/altcp_priv.h13
-rw-r--r--lwip/src/include/lwip/prot/icmp6.h2
-rw-r--r--lwip/src/include/lwip/prot/ip6.h2
-rw-r--r--lwip/src/include/netif/ppp/ppp_opts.h7
-rw-r--r--lwip/src/include/netif/ppp/pppoe.h8
-rw-r--r--lwip/src/netif/lowpan6.c2
-rw-r--r--lwip/src/netif/lowpan6_ble.c2
-rw-r--r--lwip/src/netif/lowpan6_common.c8
-rw-r--r--lwip/src/netif/ppp/ppp.c5
-rw-r--r--lwip/src/netif/ppp/pppoe.c43
-rw-r--r--lwip/src/netif/zepif.c2
46 files changed, 483 insertions, 169 deletions
diff --git a/lwip/src/api/api_lib.c b/lwip/src/api/api_lib.c
index e03b8b7..ffa14d6 100644
--- a/lwip/src/api/api_lib.c
+++ b/lwip/src/api/api_lib.c
@@ -201,16 +201,16 @@ netconn_prepare_delete(struct netconn *conn)
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).conn = conn;
+#if LWIP_TCP
#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
/* get the time we started, which is later compared to
sys_now() + conn->send_timeout */
API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
-#if LWIP_TCP
API_MSG_VAR_REF(msg).msg.sd.polls_left =
((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
-#endif /* LWIP_TCP */
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
+#endif /* LWIP_TCP */
err = netconn_apimsg(lwip_netconn_do_delconn, &API_MSG_VAR_REF(msg));
API_MSG_VAR_FREE(msg);
@@ -500,7 +500,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
NETCONN_MBOX_WAITING_INC(conn);
if (netconn_is_nonblocking(conn)) {
- if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_ARCH_TIMEOUT) {
+ if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_MBOX_EMPTY) {
API_MSG_VAR_FREE_ACCEPT(msg);
NETCONN_MBOX_WAITING_DEC(conn);
return ERR_WOULDBLOCK;
@@ -597,7 +597,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
NETCONN_MBOX_WAITING_INC(conn);
if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) ||
(conn->flags & NETCONN_FLAG_MBOXCLOSED) || (conn->pending_err != ERR_OK)) {
- if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_ARCH_TIMEOUT) {
+ if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_MBOX_EMPTY) {
err_t err;
NETCONN_MBOX_WAITING_DEC(conn);
err = netconn_err(conn);
@@ -1346,7 +1346,7 @@ void
netconn_thread_init(void)
{
sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
- if ((sem == NULL) || !sys_sem_valid(sem)) {
+ if (!sys_sem_valid(sem)) {
/* call alloc only once */
LWIP_NETCONN_THREAD_SEM_ALLOC();
LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET()));
@@ -1357,7 +1357,7 @@ void
netconn_thread_cleanup(void)
{
sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
- if ((sem != NULL) && sys_sem_valid(sem)) {
+ if (sys_sem_valid(sem)) {
/* call free only once */
LWIP_NETCONN_THREAD_SEM_FREE();
}
diff --git a/lwip/src/api/api_msg.c b/lwip/src/api/api_msg.c
index 3953102..3f08e03 100644
--- a/lwip/src/api/api_msg.c
+++ b/lwip/src/api/api_msg.c
@@ -716,6 +716,9 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
conn->pending_err = ERR_OK;
conn->type = t;
conn->pcb.tcp = NULL;
+#if LWIP_NETCONN_FULLDUPLEX
+ conn->mbox_threads_waiting = 0;
+#endif
/* If all sizes are the same, every compiler should optimize this switch to nothing */
switch (NETCONNTYPE_GROUP(t)) {
diff --git a/lwip/src/api/netdb.c b/lwip/src/api/netdb.c
index 8771425..ee78297 100644
--- a/lwip/src/api/netdb.c
+++ b/lwip/src/api/netdb.c
@@ -128,8 +128,7 @@ lwip_gethostbyname(const char *name)
if (s_hostent.h_addr_list != NULL) {
u8_t idx;
for (idx = 0; s_hostent.h_addr_list[idx]; idx++) {
- LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
- LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
+ LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa(s_phostent_addr[idx])));
}
}
#endif /* DNS_DEBUG */
@@ -306,7 +305,11 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
/* service name specified: convert to port number
* @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */
port_nr = atoi(servname);
- if ((port_nr <= 0) || (port_nr > 0xffff)) {
+ if (port_nr == 0 && (servname[0] != '0')) {
+ /* atoi failed - service was not numeric */
+ return EAI_SERVICE;
+ }
+ if ((port_nr < 0) || (port_nr > 0xffff)) {
return EAI_SERVICE;
}
}
diff --git a/lwip/src/api/sockets.c b/lwip/src/api/sockets.c
index cb7df91..7852635 100644
--- a/lwip/src/api/sockets.c
+++ b/lwip/src/api/sockets.c
@@ -688,7 +688,6 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
err = netconn_peer(newconn, &naddr, &port);
if (err != ERR_OK) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err));
- netconn_delete(newconn);
free_socket(nsock, 1);
sock_set_errno(sock, err_to_errno(err));
done_socket(sock);
@@ -2073,7 +2072,9 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
/* Call lwip_selscan again: there could have been events between
the last scan (without us on the list) and putting us on the list! */
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
- if (!nready) {
+ if (nready < 0) {
+ set_errno(EBADF);
+ } else if (!nready) {
/* Still none ready, just wait to be woken */
if (timeout == 0) {
/* Wait forever */
@@ -2102,7 +2103,8 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
(exceptset && FD_ISSET(i, exceptset))) {
struct lwip_sock *sock;
SYS_ARCH_PROTECT(lev);
- sock = tryget_socket_unconn_locked(i);
+ sock = tryget_socket_unconn_nouse(i);
+ LWIP_ASSERT("socket gone at the end of select", sock != NULL);
if (sock != NULL) {
/* for now, handle select_waiting==0... */
LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
@@ -2110,7 +2112,6 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
sock->select_waiting--;
}
SYS_ARCH_UNPROTECT(lev);
- done_socket(sock);
} else {
SYS_ARCH_UNPROTECT(lev);
/* Not a valid socket */
@@ -2147,6 +2148,11 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
/* See what's set now after waiting */
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
+ if (nready < 0) {
+ set_errno(EBADF);
+ lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
+ return -1;
+ }
}
}
}
diff --git a/lwip/src/api/tcpip.c b/lwip/src/api/tcpip.c
index 743553a..a7e312a 100644
--- a/lwip/src/api/tcpip.c
+++ b/lwip/src/api/tcpip.c
@@ -217,7 +217,7 @@ tcpip_thread_poll_one(void)
int ret = 0;
struct tcpip_msg *msg;
- if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_ARCH_TIMEOUT) {
+ if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_MBOX_EMPTY) {
LOCK_TCPIP_CORE();
if (msg != NULL) {
tcpip_thread_handle_msg(msg);
diff --git a/lwip/src/core/altcp.c b/lwip/src/core/altcp.c
index d46d6cd..4abef7c 100644
--- a/lwip/src/core/altcp.c
+++ b/lwip/src/core/altcp.c
@@ -501,6 +501,24 @@ altcp_get_port(struct altcp_pcb *conn, int local)
return 0;
}
+#if LWIP_TCP_KEEPALIVE
+void
+altcp_keepalive_disable(struct altcp_pcb *conn)
+{
+ if (conn && conn->fns && conn->fns->keepalive_disable) {
+ conn->fns->keepalive_disable(conn);
+ }
+}
+
+void
+altcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count)
+{
+ if (conn && conn->fns && conn->fns->keepalive_enable) {
+ conn->fns->keepalive_enable(conn, idle, intvl, count);
+ }
+}
+#endif
+
#ifdef LWIP_DEBUG
enum tcp_state
altcp_dbg_get_tcp_state(struct altcp_pcb *conn)
@@ -666,6 +684,24 @@ altcp_default_get_port(struct altcp_pcb *conn, int local)
return 0;
}
+#if LWIP_TCP_KEEPALIVE
+void
+altcp_default_keepalive_disable(struct altcp_pcb *conn)
+{
+ if (conn && conn->inner_conn) {
+ altcp_keepalive_disable(conn->inner_conn);
+ }
+}
+
+void
+altcp_default_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count)
+{
+ if (conn && conn->inner_conn) {
+ altcp_keepalive_enable(conn->inner_conn, idle, intvl, count);
+ }
+}
+#endif
+
#ifdef LWIP_DEBUG
enum tcp_state
altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn)
diff --git a/lwip/src/core/altcp_tcp.c b/lwip/src/core/altcp_tcp.c
index b715f04..1869e2a 100644
--- a/lwip/src/core/altcp_tcp.c
+++ b/lwip/src/core/altcp_tcp.c
@@ -49,6 +49,7 @@
#include "lwip/altcp_tcp.h"
#include "lwip/priv/altcp_priv.h"
#include "lwip/tcp.h"
+#include "lwip/priv/tcp_priv.h"
#include "lwip/mem.h"
#include <string.h>
@@ -160,21 +161,25 @@ static void
altcp_tcp_remove_callbacks(struct tcp_pcb *tpcb)
{
tcp_arg(tpcb, NULL);
- tcp_recv(tpcb, NULL);
- tcp_sent(tpcb, NULL);
- tcp_err(tpcb, NULL);
- tcp_poll(tpcb, NULL, tpcb->pollinterval);
+ if (tpcb->state != LISTEN) {
+ tcp_recv(tpcb, NULL);
+ tcp_sent(tpcb, NULL);
+ tcp_err(tpcb, NULL);
+ tcp_poll(tpcb, NULL, tpcb->pollinterval);
+ }
}
static void
altcp_tcp_setup_callbacks(struct altcp_pcb *conn, struct tcp_pcb *tpcb)
{
tcp_arg(tpcb, conn);
- tcp_recv(tpcb, altcp_tcp_recv);
- tcp_sent(tpcb, altcp_tcp_sent);
- tcp_err(tpcb, altcp_tcp_err);
- /* tcp_poll is set when interval is set by application */
- /* listen is set totally different :-) */
+ /* this might be called for LISTN when close fails... */
+ if (tpcb->state != LISTEN) {
+ tcp_recv(tpcb, altcp_tcp_recv);
+ tcp_sent(tpcb, altcp_tcp_sent);
+ tcp_err(tpcb, altcp_tcp_err);
+ /* tcp_poll is set when interval is set by application */
+ }
}
static void
@@ -446,6 +451,31 @@ altcp_tcp_setprio(struct altcp_pcb *conn, u8_t prio)
}
}
+#if LWIP_TCP_KEEPALIVE
+static void
+altcp_tcp_keepalive_disable(struct altcp_pcb *conn)
+{
+ if (conn && conn->state) {
+ struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+ ALTCP_TCP_ASSERT_CONN(conn);
+ ip_reset_option(pcb, SOF_KEEPALIVE);
+ }
+}
+
+static void
+altcp_tcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t cnt)
+{
+ if (conn && conn->state) {
+ struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
+ ALTCP_TCP_ASSERT_CONN(conn);
+ ip_set_option(pcb, SOF_KEEPALIVE);
+ pcb->keep_idle = idle ? idle : TCP_KEEPIDLE_DEFAULT;
+ pcb->keep_intvl = intvl ? intvl : TCP_KEEPINTVL_DEFAULT;
+ pcb->keep_cnt = cnt ? cnt : TCP_KEEPCNT_DEFAULT;
+ }
+}
+#endif
+
static void
altcp_tcp_dealloc(struct altcp_pcb *conn)
{
@@ -535,6 +565,10 @@ const struct altcp_functions altcp_tcp_functions = {
altcp_tcp_get_tcp_addrinfo,
altcp_tcp_get_ip,
altcp_tcp_get_port
+#if LWIP_TCP_KEEPALIVE
+ , altcp_tcp_keepalive_disable
+ , altcp_tcp_keepalive_enable
+#endif
#ifdef LWIP_DEBUG
, altcp_tcp_dbg_get_tcp_state
#endif
diff --git a/lwip/src/core/init.c b/lwip/src/core/init.c
index b3737a3..3620e1d 100644
--- a/lwip/src/core/init.c
+++ b/lwip/src/core/init.c
@@ -237,8 +237,9 @@ PACK_STRUCT_END
#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
#endif
#endif /* LWIP_NETCONN && LWIP_TCP */
-#if LWIP_SOCKET
-#endif /* LWIP_SOCKET */
+#if LWIP_NETCONN_FULLDUPLEX && !LWIP_NETCONN_SEM_PER_THREAD
+#error "For LWIP_NETCONN_FULLDUPLEX to work, LWIP_NETCONN_SEM_PER_THREAD is required"
+#endif
/* Compile-time checks for deprecated options.
diff --git a/lwip/src/core/ipv4/dhcp.c b/lwip/src/core/ipv4/dhcp.c
index 534574f..76b9f68 100644
--- a/lwip/src/core/ipv4/dhcp.c
+++ b/lwip/src/core/ipv4/dhcp.c
@@ -127,6 +127,11 @@
#define LWIP_DHCP_PROVIDE_DNS_SERVERS 0
#endif
+#ifndef LWIP_DHCP_INPUT_ERROR
+#define LWIP_DHCP_INPUT_ERROR(message, expression, handler) do { if (!(expression)) { \
+ handler;} } while(0)
+#endif
+
/** Option handling: options are parsed in dhcp_parse_reply
* and saved in an array where other functions can load them from.
* This might be moved into the struct dhcp (not necessarily since
@@ -1115,13 +1120,6 @@ dhcp_bind(struct netif *netif)
}
ip4_addr_copy(gw_addr, dhcp->offered_gw_addr);
- /* gateway address not given? */
- if (ip4_addr_isany_val(gw_addr)) {
- /* copy network address */
- ip4_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
- /* use first host address on network as gateway */
- ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL));
- }
#if LWIP_DHCP_AUTOIP_COOP
if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
@@ -1349,6 +1347,7 @@ dhcp_release_and_stop(struct netif *netif)
/* create and initialize the DHCP message header */
struct pbuf *p_out;
u16_t options_out_len;
+ dhcp_set_state(dhcp, DHCP_STATE_OFF);
p_out = dhcp_create_msg(netif, dhcp, DHCP_RELEASE, &options_out_len);
if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
@@ -1365,10 +1364,12 @@ dhcp_release_and_stop(struct netif *netif)
/* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
}
- }
- /* remove IP address from interface (prevents routing from selecting this interface) */
- netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
+ /* remove IP address from interface (prevents routing from selecting this interface) */
+ netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
+ } else {
+ dhcp_set_state(dhcp, DHCP_STATE_OFF);
+ }
#if LWIP_DHCP_AUTOIP_COOP
if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
@@ -1377,8 +1378,6 @@ dhcp_release_and_stop(struct netif *netif)
}
#endif /* LWIP_DHCP_AUTOIP_COOP */
- dhcp_set_state(dhcp, DHCP_STATE_OFF);
-
if (dhcp->pcb_allocated != 0) {
dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
dhcp->pcb_allocated = 0;
@@ -1509,6 +1508,7 @@ dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp)
u8_t *options;
u16_t offset;
u16_t offset_max;
+ u16_t options_offset;
u16_t options_idx;
u16_t options_idx_max;
struct pbuf *q;
@@ -1541,6 +1541,7 @@ dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp)
options_idx_max = p->tot_len;
again:
q = p;
+ options_offset = options_idx;
while ((q != NULL) && (options_idx >= q->len)) {
options_idx = (u16_t)(options_idx - q->len);
options_idx_max = (u16_t)(options_idx_max - q->len);
@@ -1579,58 +1580,58 @@ again:
/* will be increased below */
break;
case (DHCP_OPTION_SUBNET_MASK):
- LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
break;
case (DHCP_OPTION_ROUTER):
decode_len = 4; /* only copy the first given router */
- LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_ROUTER;
break;
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
case (DHCP_OPTION_DNS_SERVER):
/* special case: there might be more than one server */
- LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
/* limit number of DNS servers */
decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS);
- LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
break;
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
case (DHCP_OPTION_LEASE_TIME):
- LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
break;
#if LWIP_DHCP_GET_NTP_SRV
case (DHCP_OPTION_NTP):
/* special case: there might be more than one server */
- LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
/* limit number of NTP servers */
decode_len = LWIP_MIN(len, 4 * LWIP_DHCP_MAX_NTP_SERVERS);
- LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_NTP_SERVER;
break;
#endif /* LWIP_DHCP_GET_NTP_SRV*/
case (DHCP_OPTION_OVERLOAD):
- LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len == 1", len == 1, return ERR_VAL;);
/* decode overload only in options, not in file/sname: invalid packet */
- LWIP_ERROR("overload in file/sname", options_idx == DHCP_OPTIONS_OFS, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("overload in file/sname", options_offset == DHCP_OPTIONS_OFS, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_OVERLOAD;
break;
case (DHCP_OPTION_MESSAGE_TYPE):
- LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len == 1", len == 1, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
break;
case (DHCP_OPTION_SERVER_ID):
- LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_SERVER_ID;
break;
case (DHCP_OPTION_T1):
- LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_T1;
break;
case (DHCP_OPTION_T2):
- LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_T2;
break;
default:
@@ -1662,7 +1663,7 @@ decode_next:
if (decode_len > 4) {
/* decode more than one u32_t */
u16_t next_val_offset;
- LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
dhcp_got_option(dhcp, decode_idx);
dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value));
decode_len = (u8_t)(decode_len - 4);
@@ -1677,7 +1678,7 @@ decode_next:
} else if (decode_len == 4) {
value = lwip_ntohl(value);
} else {
- LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
value = ((u8_t *)&value)[0];
}
dhcp_got_option(dhcp, decode_idx);
@@ -1690,7 +1691,7 @@ decode_next:
offset_max = (u16_t)(offset_max - q->len);
if (offset < offset_max) {
q = q->next;
- LWIP_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
+ LWIP_DHCP_INPUT_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
options = (u8_t *)q->payload;
} else {
/* We've run out of bytes, probably no end marker. Don't proceed. */
diff --git a/lwip/src/core/ipv4/etharp.c b/lwip/src/core/ipv4/etharp.c
index 442aac0..c3a5a10 100644
--- a/lwip/src/core/ipv4/etharp.c
+++ b/lwip/src/core/ipv4/etharp.c
@@ -983,6 +983,14 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
/* We don't re-send arp request in etharp_tmr, but we still queue packets,
since this failure could be temporary, and the next packet calling
etharp_query again could lead to sending the queued packets. */
+ } else {
+ /* ARP request successfully sent */
+ if ((arp_table[i].state == ETHARP_STATE_PENDING) && !is_new_entry) {
+ /* A new ARP request has been sent for a pending entry. Reset the ctime to
+ not let it expire too fast. */
+ LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: reset ctime for entry %"S16_F"\n", (s16_t)i));
+ arp_table[i].ctime = 0;
+ }
}
if (q == NULL) {
return result;
diff --git a/lwip/src/core/ipv4/icmp.c b/lwip/src/core/ipv4/icmp.c
index a462ccd..59b493a 100644
--- a/lwip/src/core/ipv4/icmp.c
+++ b/lwip/src/core/ipv4/icmp.c
@@ -62,7 +62,7 @@
#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
-/* The amount of data from the original packet to return in a dest-unreachable */
+/* The maximum amount of data from the original packet to return in a dest-unreachable */
#define ICMP_DEST_UNREACH_DATASIZE 8
static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
@@ -345,20 +345,26 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
struct icmp_echo_hdr *icmphdr;
ip4_addr_t iphdr_src;
struct netif *netif;
+ u16_t response_pkt_len;
/* increase number of messages attempted to send */
MIB2_STATS_INC(mib2.icmpoutmsgs);
- /* ICMP header + IP header + 8 bytes of data */
- q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
- PBUF_RAM);
+ /* Keep IP header + up to 8 bytes */
+ response_pkt_len = IP_HLEN + ICMP_DEST_UNREACH_DATASIZE;
+ if (p->tot_len < response_pkt_len) {
+ response_pkt_len = p->tot_len;
+ }
+
+ /* ICMP header + part of original packet */
+ q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + response_pkt_len, PBUF_RAM);
if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
MIB2_STATS_INC(mib2.icmpouterrors);
return;
}
LWIP_ASSERT("check that first pbuf can hold icmp message",
- (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE)));
+ (q->len >= (sizeof(struct icmp_echo_hdr) + response_pkt_len)));
iphdr = (struct ip_hdr *)p->payload;
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
@@ -375,7 +381,7 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
/* copy fields from original packet */
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
- IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
+ response_pkt_len);
ip4_addr_copy(iphdr_src, iphdr->src);
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
diff --git a/lwip/src/core/ipv4/ip4_addr.c b/lwip/src/core/ipv4/ip4_addr.c
index 33204d1..f99d8dd 100644
--- a/lwip/src/core/ipv4/ip4_addr.c
+++ b/lwip/src/core/ipv4/ip4_addr.c
@@ -173,6 +173,8 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
}
for (;;) {
if (lwip_isdigit(c)) {
+ if((base == 8) && ((u32_t)(c - '0') >= 8))
+ break;
val = (val * base) + (u32_t)(c - '0');
c = *++cp;
} else if (base == 16 && lwip_isxdigit(c)) {
diff --git a/lwip/src/core/ipv6/dhcp6.c b/lwip/src/core/ipv6/dhcp6.c
index 7cf98a5..bcf5d20 100644
--- a/lwip/src/core/ipv6/dhcp6.c
+++ b/lwip/src/core/ipv6/dhcp6.c
@@ -451,7 +451,16 @@ dhcp6_msg_finalize(u16_t options_out_len, struct pbuf *p_out)
static void
dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)
{
- const u16_t requested_options[] = {DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_SNTP_SERVERS};
+ const u16_t requested_options[] = {
+#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
+ DHCP6_OPTION_DNS_SERVERS,
+ DHCP6_OPTION_DOMAIN_LIST
+#endif
+#if LWIP_DHCP6_GET_NTP_SRV
+ , DHCP6_OPTION_SNTP_SERVERS
+#endif
+ };
+
u16_t msecs;
struct pbuf *p_out;
u16_t options_out_len;
@@ -527,7 +536,7 @@ dhcp6_handle_config_reply(struct netif *netif, struct pbuf *p_msg_in)
u16_t idx;
u8_t n;
- memset(&dns_addr, 0, sizeof(dns_addr));
+ ip_addr_set_zero_ip6(&dns_addr);
dns_addr6 = ip_2_ip6(&dns_addr);
for (n = 0, idx = op_start; (idx < op_start + op_len) && (n < LWIP_DHCP6_PROVIDE_DNS_SERVERS);
n++, idx += sizeof(struct ip6_addr_packed)) {
diff --git a/lwip/src/core/ipv6/icmp6.c b/lwip/src/core/ipv6/icmp6.c
index 167738a..4fd1021 100644
--- a/lwip/src/core/ipv6/icmp6.c
+++ b/lwip/src/core/ipv6/icmp6.c
@@ -57,9 +57,9 @@
#include <string.h>
-#if LWIP_ICMP6_DATASIZE == 0
+#if !LWIP_ICMP6_DATASIZE || (LWIP_ICMP6_DATASIZE > (IP6_MIN_MTU_LENGTH - IP6_HLEN - ICMP6_HLEN))
#undef LWIP_ICMP6_DATASIZE
-#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_DATASIZE (IP6_MIN_MTU_LENGTH - IP6_HLEN - ICMP6_HLEN)
#endif
/* Forward declarations */
@@ -387,26 +387,35 @@ icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data,
{
struct pbuf *q;
struct icmp6_hdr *icmp6hdr;
+ u16_t datalen = LWIP_MIN(p->tot_len, LWIP_ICMP6_DATASIZE);
+ u16_t offset;
- /* ICMPv6 header + IPv6 header + data */
- q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE,
+ /* ICMPv6 header + datalen (as much of the offending packet as possible) */
+ q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + datalen,
PBUF_RAM);
if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n"));
ICMP6_STATS_INC(icmp6.memerr);
return;
}
- LWIP_ASSERT("check that first pbuf can hold icmp 6message",
- (q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));
+ LWIP_ASSERT("check that first pbuf can hold icmp6 header",
+ (q->len >= (sizeof(struct icmp6_hdr))));
icmp6hdr = (struct icmp6_hdr *)q->payload;
icmp6hdr->type = type;
icmp6hdr->code = code;
icmp6hdr->data = lwip_htonl(data);
- /* copy fields from original packet */
- SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload,
- IP6_HLEN + LWIP_ICMP6_DATASIZE);
+ /* copy fields from original packet (which may be a chain of pbufs) */
+ offset = sizeof(struct icmp6_hdr);
+ while (p && datalen) {
+ u16_t len = LWIP_MIN(datalen, p->len);
+ err_t res = pbuf_take_at(q, p->payload, len, offset);
+ if (res != ERR_OK) break;
+ datalen -= len;
+ offset += len;
+ p = p->next;
+ }
/* calculate checksum */
icmp6hdr->chksum = 0;
diff --git a/lwip/src/core/ipv6/ip6.c b/lwip/src/core/ipv6/ip6.c
index eda11dc..060d5f3 100644
--- a/lwip/src/core/ipv6/ip6.c
+++ b/lwip/src/core/ipv6/ip6.c
@@ -1305,6 +1305,7 @@ ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
netif = ip6_route(&src_addr, &dest_addr);
+ dest = &dest_addr;
}
if (netif == NULL) {
@@ -1364,6 +1365,7 @@ ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
netif = ip6_route(&src_addr, &dest_addr);
+ dest = &dest_addr;
}
if (netif == NULL) {
diff --git a/lwip/src/core/ipv6/ip6_frag.c b/lwip/src/core/ipv6/ip6_frag.c
index d6c5d22..8b352f5 100644
--- a/lwip/src/core/ipv6/ip6_frag.c
+++ b/lwip/src/core/ipv6/ip6_frag.c
@@ -781,7 +781,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
return ERR_MEM;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
- (p->len >= (IP6_HLEN)));
+ (rambuf->len >= (IP6_HLEN)));
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
ip6hdr = (struct ip6_hdr *)rambuf->payload;
frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
diff --git a/lwip/src/core/ipv6/mld6.c b/lwip/src/core/ipv6/mld6.c
index 6387d46..a9c917d 100644
--- a/lwip/src/core/ipv6/mld6.c
+++ b/lwip/src/core/ipv6/mld6.c
@@ -253,7 +253,7 @@ mld6_input(struct pbuf *p, struct netif *inp)
while (group != NULL) {
if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
(!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
- mld6_delayed_report(group, mld_hdr->max_resp_delay);
+ mld6_delayed_report(group, lwip_ntohs(mld_hdr->max_resp_delay));
}
group = group->next;
}
@@ -265,7 +265,7 @@ mld6_input(struct pbuf *p, struct netif *inp)
group = mld6_lookfor_group(inp, ip6_current_dest_addr());
if (group != NULL) {
/* Schedule a report. */
- mld6_delayed_report(group, mld_hdr->max_resp_delay);
+ mld6_delayed_report(group, lwip_ntohs(mld_hdr->max_resp_delay));
}
}
break; /* ICMP6_TYPE_MLQ */
diff --git a/lwip/src/core/ipv6/nd6.c b/lwip/src/core/ipv6/nd6.c
index db0c132..81992fa 100644
--- a/lwip/src/core/ipv6/nd6.c
+++ b/lwip/src/core/ipv6/nd6.c
@@ -693,11 +693,11 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
mtu_opt = (struct mtu_option *)buffer;
mtu32 = lwip_htonl(mtu_opt->mtu);
- if ((mtu32 >= 1280) && (mtu32 <= 0xffff)) {
+ if ((mtu32 >= IP6_MIN_MTU_LENGTH) && (mtu32 <= 0xffff)) {
#if LWIP_ND6_ALLOW_RA_UPDATES
if (inp->mtu) {
/* don't set the mtu for IPv6 higher than the netif driver supports */
- inp->mtu6 = LWIP_MIN(inp->mtu, (u16_t)mtu32);
+ inp->mtu6 = LWIP_MIN(LWIP_MIN(inp->mtu, inp->mtu6), (u16_t)mtu32);
} else {
inp->mtu6 = (u16_t)mtu32;
}
@@ -766,7 +766,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
rdnss_opt = (struct rdnss_option *)buffer;
num = (rdnss_opt->length - 1) / 2;
- for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) {
+ for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++, copy_offset += sizeof(ip6_addr_p_t)) {
ip_addr_t rdnss_address;
/* Copy directly from pbuf to get an aligned, zoned copy of the prefix. */
@@ -1182,15 +1182,27 @@ nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags)
{
struct ns_header *ns_hdr;
struct pbuf *p;
- const ip6_addr_t *src_addr;
+ const ip6_addr_t *src_addr = NULL;
u16_t lladdr_opt_len;
LWIP_ASSERT("target address is required", target_addr != NULL);
- if (!(flags & ND6_SEND_FLAG_ANY_SRC) &&
- ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) {
- /* Use link-local address as source address. */
- src_addr = netif_ip6_addr(netif, 0);
+ if (!(flags & ND6_SEND_FLAG_ANY_SRC)) {
+ int i;
+ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
+ if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
+ ip6_addr_netcmp(target_addr, netif_ip6_addr(netif, i))) {
+ src_addr = netif_ip6_addr(netif, i);
+ break;
+ }
+ }
+
+ if (i == LWIP_IPV6_NUM_ADDRESSES) {
+ LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("ICMPv6 NS: no available src address\n"));
+ ND6_STATS_INC(nd6.err);
+ return;
+ }
+
/* calculate option length (in 8-byte-blocks) */
lladdr_opt_len = ((netif->hwaddr_len + 2) + 7) >> 3;
} else {
@@ -2300,7 +2312,7 @@ nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif)
return netif_mtu6(netif);
}
- return 1280; /* Minimum MTU */
+ return IP6_MIN_MTU_LENGTH; /* Minimum MTU */
}
diff --git a/lwip/src/core/netif.c b/lwip/src/core/netif.c
index 15200a2..699daf4 100644
--- a/lwip/src/core/netif.c
+++ b/lwip/src/core/netif.c
@@ -348,10 +348,6 @@ netif_add(struct netif *netif,
#if LWIP_IPV6 && LWIP_IPV6_MLD
netif->mld_mac_filter = NULL;
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
-#if ENABLE_LOOPBACK
- netif->loop_first = NULL;
- netif->loop_last = NULL;
-#endif /* ENABLE_LOOPBACK */
/* remember netif specific state information data */
netif->state = state;
@@ -359,9 +355,16 @@ netif_add(struct netif *netif,
netif->input = input;
NETIF_RESET_HINTS(netif);
-#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
+#if ENABLE_LOOPBACK
+ netif->loop_first = NULL;
+ netif->loop_last = NULL;
+#if LWIP_LOOPBACK_MAX_PBUFS
netif->loop_cnt_current = 0;
-#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
+#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+ netif->reschedule_poll = 0;
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
+#endif /* ENABLE_LOOPBACK */
#if LWIP_IPV4
netif_set_addr(netif, ipaddr, netmask, gw);
@@ -1031,6 +1034,10 @@ netif_set_link_down(struct netif *netif)
if (netif->flags & NETIF_FLAG_LINK_UP) {
netif_clear_flags(netif, NETIF_FLAG_LINK_UP);
+#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
+ netif->mtu6 = netif->mtu;
+#endif
+
NETIF_LINK_CALLBACK(netif);
#if LWIP_NETIF_EXT_STATUS_CALLBACK
{
@@ -1062,11 +1069,12 @@ netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callb
/**
* @ingroup netif
* Send an IP packet to be received on the same netif (loopif-like).
- * The pbuf is simply copied and handed back to netif->input.
- * In multithreaded mode, this is done directly since netif->input must put
- * the packet on a queue.
- * In callback mode, the packet is put on an internal queue and is fed to
+ * The pbuf is copied and added to an internal queue which is fed to
* netif->input by netif_poll().
+ * In multithreaded mode, the call to netif_poll() is queued to be done on the
+ * TCP/IP thread.
+ * In callback mode, the user has the responsibility to call netif_poll() in
+ * the main loop of their application.
*
* @param netif the lwip network interface structure
* @param p the (IP) packet to 'send'
@@ -1143,6 +1151,12 @@ netif_loop_output(struct netif *netif, struct pbuf *p)
LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
netif->loop_last->next = r;
netif->loop_last = last;
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+ if (netif->reschedule_poll) {
+ schedule_poll = 1;
+ netif->reschedule_poll = 0;
+ }
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
} else {
netif->loop_first = r;
netif->loop_last = last;
@@ -1160,7 +1174,11 @@ netif_loop_output(struct netif *netif, struct pbuf *p)
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
/* For multithreading environment, schedule a call to netif_poll */
if (schedule_poll) {
- tcpip_try_callback((tcpip_callback_fn)netif_poll, netif);
+ if (tcpip_try_callback((tcpip_callback_fn)netif_poll, netif) != ERR_OK) {
+ SYS_ARCH_PROTECT(lev);
+ netif->reschedule_poll = 1;
+ SYS_ARCH_UNPROTECT(lev);
+ }
}
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
@@ -1710,6 +1728,10 @@ netif_find(const char *name)
}
num = (u8_t)atoi(&name[2]);
+ if (!num && (name[2] != '0')) {
+ /* this means atoi has failed */
+ return NULL;
+ }
NETIF_FOREACH(netif) {
if (num == netif->num &&
diff --git a/lwip/src/core/pbuf.c b/lwip/src/core/pbuf.c
index a209e0c..7638dfd 100644
--- a/lwip/src/core/pbuf.c
+++ b/lwip/src/core/pbuf.c
@@ -271,7 +271,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
break;
}
case PBUF_RAM: {
- u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
+ mem_size_t payload_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len);
/* bug #50040: Check for integer overflow when calculating alloc_len */
@@ -960,54 +960,88 @@ pbuf_dechain(struct pbuf *p)
err_t
pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
{
- size_t offset_to = 0, offset_from = 0, len;
-
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
(const void *)p_to, (const void *)p_from));
+ LWIP_ERROR("pbuf_copy: invalid source", p_from != NULL, return ERR_ARG;);
+ return pbuf_copy_partial_pbuf(p_to, p_from, p_from->tot_len, 0);
+}
+
+/**
+ * @ingroup pbuf
+ * Copy part or all of one packet buffer into another, to a specified offset.
+ *
+ * @note Only data in one packet is copied, no packet queue!
+ * @note Argument order is shared with pbuf_copy, but different than pbuf_copy_partial.
+ *
+ * @param p_to pbuf destination of the copy
+ * @param p_from pbuf source of the copy
+ * @param copy_len number of bytes to copy
+ * @param offset offset in destination pbuf where to copy to
+ *
+ * @return ERR_OK if copy_len bytes were copied
+ * ERR_ARG if one of the pbufs is NULL or p_from is shorter than copy_len
+ * or p_to is not big enough to hold copy_len at offset
+ * ERR_VAL if any of the pbufs are part of a queue
+ */
+err_t
+pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset)
+{
+ size_t offset_to = offset, offset_from = 0, len_calc;
+ u16_t len;
+
+ LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy_partial_pbuf(%p, %p, %"U16_F", %"U16_F")\n",
+ (const void *)p_to, (const void *)p_from, copy_len, offset));
+
+ /* is the copy_len in range? */
+ LWIP_ERROR("pbuf_copy_partial_pbuf: copy_len bigger than source", ((p_from != NULL) &&
+ (p_from->tot_len >= copy_len)), return ERR_ARG;);
/* is the target big enough to hold the source? */
- LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) &&
- (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;);
+ LWIP_ERROR("pbuf_copy_partial_pbuf: target not big enough", ((p_to != NULL) &&
+ (p_to->tot_len >= (offset + copy_len))), return ERR_ARG;);
/* iterate through pbuf chain */
do {
/* copy one part of the original chain */
if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
/* complete current p_from fits into current p_to */
- len = p_from->len - offset_from;
+ len_calc = p_from->len - offset_from;
} else {
/* current p_from does not fit into current p_to */
- len = p_to->len - offset_to;
+ len_calc = p_to->len - offset_to;
}
+ len = (u16_t)LWIP_MIN(copy_len, len_calc);
MEMCPY((u8_t *)p_to->payload + offset_to, (u8_t *)p_from->payload + offset_from, len);
offset_to += len;
offset_from += len;
+ copy_len -= len;
LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len);
if (offset_from >= p_from->len) {
/* on to next p_from (if any) */
offset_from = 0;
p_from = p_from->next;
+ LWIP_ERROR("p_from != NULL", (p_from != NULL) || (copy_len == 0), return ERR_ARG;);
}
if (offset_to == p_to->len) {
/* on to next p_to (if any) */
offset_to = 0;
p_to = p_to->next;
- LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL), return ERR_ARG;);
+ LWIP_ERROR("p_to != NULL", (p_to != NULL) || (copy_len == 0), return ERR_ARG;);
}
if ((p_from != NULL) && (p_from->len == p_from->tot_len)) {
/* don't copy more than one packet! */
- LWIP_ERROR("pbuf_copy() does not allow packet queues!",
+ LWIP_ERROR("pbuf_copy_partial_pbuf() does not allow packet queues!",
(p_from->next == NULL), return ERR_VAL;);
}
if ((p_to != NULL) && (p_to->len == p_to->tot_len)) {
/* don't copy more than one packet! */
- LWIP_ERROR("pbuf_copy() does not allow packet queues!",
+ LWIP_ERROR("pbuf_copy_partial_pbuf() does not allow packet queues!",
(p_to->next == NULL), return ERR_VAL;);
}
- } while (p_from);
- LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n"));
+ } while (copy_len);
+ LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy_partial_pbuf: copy complete.\n"));
return ERR_OK;
}
diff --git a/lwip/src/core/tcp.c b/lwip/src/core/tcp.c
index bd7d64e..371db2b 100644
--- a/lwip/src/core/tcp.c
+++ b/lwip/src/core/tcp.c
@@ -647,6 +647,7 @@ tcp_abort(struct tcp_pcb *pcb)
* bound to all local IP addresses.
* If another connection is bound to the same port, the function will
* return ERR_USE, otherwise ERR_OK is returned.
+ * @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
*
* @param pcb the tcp_pcb to bind (no check is done whether this pcb is
* already bound!)
@@ -889,7 +890,7 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err)
lpcb->state = LISTEN;
lpcb->prio = pcb->prio;
lpcb->so_options = pcb->so_options;
- lpcb->netif_idx = NETIF_NO_INDEX;
+ lpcb->netif_idx = pcb->netif_idx;
lpcb->ttl = pcb->ttl;
lpcb->tos = pcb->tos;
#if LWIP_IPV4 && LWIP_IPV6
@@ -1933,6 +1934,7 @@ tcp_alloc(u8_t prio)
* any of the TCP PCB lists.
* The pcb is not put on any list until binding using tcp_bind().
* If memory is not available for creating the new pcb, NULL is returned.
+ * @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
*
* @internal: Maybe there should be a idle TCP PCB list where these
* PCBs are put on. Port reservation using tcp_bind() is implemented but
@@ -1952,6 +1954,7 @@ tcp_new(void)
* Creates a new TCP protocol control block but doesn't
* place it on any of the TCP PCB lists.
* The pcb is not put on any list until binding using tcp_bind().
+ * @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
*
* @param type IP address type, see @ref lwip_ip_addr_type definitions.
* If you want to listen to IPv4 and IPv6 (dual-stack) connections,
@@ -2067,6 +2070,7 @@ tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
* @ingroup tcp_raw
* Used for specifying the function that should be called when a
* LISTENing connection has been connected to another host.
+ * @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
*
* @param pcb tcp_pcb to set the accept callback
* @param accept callback function to call for this pcb when LISTENing
diff --git a/lwip/src/core/tcp_in.c b/lwip/src/core/tcp_in.c
index 428a6f4..2202e38 100644
--- a/lwip/src/core/tcp_in.c
+++ b/lwip/src/core/tcp_in.c
@@ -852,8 +852,9 @@ tcp_process(struct tcp_pcb *pcb)
/* Do different things depending on the TCP state. */
switch (pcb->state) {
case SYN_SENT:
- LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
- pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno)));
+ LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %s %"U32_F"\n",
+ ackno, pcb->snd_nxt, pcb->unacked ? "" : " empty:",
+ pcb->unacked ? lwip_ntohl(pcb->unacked->tcphdr->seqno) : 0));
/* received SYN ACK with expected sequence number? */
if ((flags & TCP_ACK) && (flags & TCP_SYN)
&& (ackno == pcb->lastack + 1)) {
diff --git a/lwip/src/core/tcp_out.c b/lwip/src/core/tcp_out.c
index 724df10..8149d39 100644
--- a/lwip/src/core/tcp_out.c
+++ b/lwip/src/core/tcp_out.c
@@ -913,6 +913,7 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split)
seg = tcp_create_segment(pcb, p, remainder_flags, lwip_ntohl(useg->tcphdr->seqno) + split, optflags);
if (seg == NULL) {
+ p = NULL; /* Freed by tcp_create_segment */
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("tcp_split_unsent_seg: could not create new TCP segment\n"));
goto memerr;
@@ -2002,7 +2003,7 @@ tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno,
LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
return;
}
- tcp_output_fill_options(pcb, p, 0, optlen);
+ tcp_output_fill_options(pcb, p, 0, 0);
MIB2_STATS_INC(mib2.tcpoutrsts);
@@ -2096,7 +2097,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
("tcp_keepalive: could not allocate memory for pbuf\n"));
return ERR_MEM;
}
- tcp_output_fill_options(pcb, p, 0, optlen);
+ tcp_output_fill_options(pcb, p, 0, 0);
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n",
@@ -2178,7 +2179,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
pcb->snd_nxt = snd_nxt;
}
- tcp_output_fill_options(pcb, p, 0, optlen);
+ tcp_output_fill_options(pcb, p, 0, 0);
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
diff --git a/lwip/src/core/udp.c b/lwip/src/core/udp.c
index 9d2cb4a..0b609d3 100644
--- a/lwip/src/core/udp.c
+++ b/lwip/src/core/udp.c
@@ -997,9 +997,13 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
{
/* port matches that of PCB in list and REUSEADDR not set -> reject */
if ((ipcb->local_port == port) &&
+ (((IP_GET_TYPE(&ipcb->local_ip) == IP_GET_TYPE(ipaddr)) &&
/* IP address matches or any IP used? */
- (ip_addr_cmp(&ipcb->local_ip, ipaddr) || ip_addr_isany(ipaddr) ||
- ip_addr_isany(&ipcb->local_ip))) {
+ (ip_addr_cmp(&ipcb->local_ip, ipaddr) ||
+ ip_addr_isany(ipaddr) ||
+ ip_addr_isany(&ipcb->local_ip))) ||
+ (IP_GET_TYPE(&ipcb->local_ip) == IPADDR_TYPE_ANY) ||
+ (IP_GET_TYPE(ipaddr) == IPADDR_TYPE_ANY))) {
/* other PCB already binds to this local IP and port */
LWIP_DEBUGF(UDP_DEBUG,
("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
@@ -1208,6 +1212,7 @@ udp_remove(struct udp_pcb *pcb)
* Creates a new UDP pcb which can be used for UDP communication. The
* pcb is not active until it has either been bound to a local address
* or connected to a remote address.
+ * @see MEMP_NUM_UDP_PCB
*
* @return The UDP PCB which was created. NULL if the PCB data structure
* could not be allocated.
@@ -1242,7 +1247,8 @@ udp_new(void)
* Create a UDP PCB for specific IP type.
* The pcb is not active until it has either been bound to a local address
* or connected to a remote address.
- *
+ * @see MEMP_NUM_UDP_PCB
+ *
* @param type IP address type, see @ref lwip_ip_addr_type definitions.
* If you want to listen to IPv4 and IPv6 (dual-stack) packets,
* supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE.
diff --git a/lwip/src/include/lwip/altcp.h b/lwip/src/include/lwip/altcp.h
index 97abc54..1b24544 100644
--- a/lwip/src/include/lwip/altcp.h
+++ b/lwip/src/include/lwip/altcp.h
@@ -129,6 +129,11 @@ err_t altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr,
ip_addr_t *altcp_get_ip(struct altcp_pcb *conn, int local);
u16_t altcp_get_port(struct altcp_pcb *conn, int local);
+#if LWIP_TCP_KEEPALIVE
+void altcp_keepalive_disable(struct altcp_pcb *conn);
+void altcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
+#endif
+
#ifdef LWIP_DEBUG
enum tcp_state altcp_dbg_get_tcp_state(struct altcp_pcb *conn);
#endif
diff --git a/lwip/src/include/lwip/altcp_tls.h b/lwip/src/include/lwip/altcp_tls.h
index 7b17c60..ff797f2 100644
--- a/lwip/src/include/lwip/altcp_tls.h
+++ b/lwip/src/include/lwip/altcp_tls.h
@@ -61,7 +61,22 @@ extern "C" {
struct altcp_tls_config;
/** @ingroup altcp_tls
- * Create an ALTCP_TLS server configuration handle
+ * Create an ALTCP_TLS server configuration handle prepared for multiple certificates
+ */
+struct altcp_tls_config *altcp_tls_create_config_server(uint8_t cert_count);
+
+/** @ingroup altcp_tls
+ * Add a certificate to an ALTCP_TLS server configuration handle
+ */
+err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config,
+ const u8_t *privkey, size_t privkey_len,
+ const u8_t *privkey_pass, size_t privkey_pass_len,
+ const u8_t *cert, size_t cert_len);
+
+/** @ingroup altcp_tls
+ * Create an ALTCP_TLS server configuration handle with one certificate
+ * (short version of calling @ref altcp_tls_create_config_server and
+ * @ref altcp_tls_config_server_add_privkey_cert)
*/
struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
@@ -85,6 +100,17 @@ struct altcp_tls_config *altcp_tls_create_config_client_2wayauth(const u8_t *ca,
void altcp_tls_free_config(struct altcp_tls_config *conf);
/** @ingroup altcp_tls
+ * Free an ALTCP_TLS global entropy instance.
+ * All ALTCP_TLS configuration are linked to one altcp_tls_entropy_rng structure
+ * that handle an unique system entropy & ctr_drbg instance.
+ * This function allow application to free this altcp_tls_entropy_rng structure
+ * when all configuration referencing it were destroyed.
+ * This function does nothing if some ALTCP_TLS configuration handle are still
+ * active.
+ */
+void altcp_tls_free_entropy(void);
+
+/** @ingroup altcp_tls
* Create new ALTCP_TLS layer wrapping an existing pcb as inner connection (e.g. TLS over TCP)
*/
struct altcp_pcb *altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb);
diff --git a/lwip/src/include/lwip/apps/altcp_tls_mbedtls_opts.h b/lwip/src/include/lwip/apps/altcp_tls_mbedtls_opts.h
index 36cddd9..71aa599 100644
--- a/lwip/src/include/lwip/apps/altcp_tls_mbedtls_opts.h
+++ b/lwip/src/include/lwip/apps/altcp_tls_mbedtls_opts.h
@@ -55,11 +55,49 @@
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_OFF
#endif
-/** Set a session timeout in seconds for the basic session cache
+/** Configure lwIP debug level of the mbedTLS library */
+#ifndef ALTCP_MBEDTLS_LIB_DEBUG
+#define ALTCP_MBEDTLS_LIB_DEBUG LWIP_DBG_OFF
+#endif
+
+/** Configure minimum internal debug level of the mbedTLS library */
+#ifndef ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN
+#define ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN 0
+#endif
+
+/** Enable the basic session cache
* ATTENTION: Using a session cache can lower security by reusing keys!
*/
+#ifndef ALTCP_MBEDTLS_USE_SESSION_CACHE
+#define ALTCP_MBEDTLS_USE_SESSION_CACHE 0
+#endif
+
+/** Maximum cache size of the basic session cache */
+#ifndef ALTCP_MBEDTLS_SESSION_CACHE_SIZE
+#define ALTCP_MBEDTLS_SESSION_CACHE_SIZE 30
+#endif
+
+/** Set a session timeout in seconds for the basic session cache */
#ifndef ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
-#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS 0
+#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS (60 * 60)
+#endif
+
+/** Use session tickets to speed up connection setup (needs
+ * MBEDTLS_SSL_SESSION_TICKETS enabled in mbedTLS config).
+ * ATTENTION: Using session tickets can lower security by reusing keys!
+ */
+#ifndef ALTCP_MBEDTLS_USE_SESSION_TICKETS
+#define ALTCP_MBEDTLS_USE_SESSION_TICKETS 0
+#endif
+
+/** Session ticket cipher */
+#ifndef ALTCP_MBEDTLS_SESSION_TICKET_CIPHER
+#define ALTCP_MBEDTLS_SESSION_TICKET_CIPHER MBEDTLS_CIPHER_AES_256_GCM
+#endif
+
+/** Maximum timeout for session tickets */
+#ifndef ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS
+#define ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS (60 * 60 * 24)
#endif
#endif /* LWIP_ALTCP */
diff --git a/lwip/src/include/lwip/apps/sntp.h b/lwip/src/include/lwip/apps/sntp.h
index 3c0f95f..c415253 100644
--- a/lwip/src/include/lwip/apps/sntp.h
+++ b/lwip/src/include/lwip/apps/sntp.h
@@ -67,11 +67,11 @@ void sntp_setservername(u8_t idx, const char *server);
const char *sntp_getservername(u8_t idx);
#endif /* SNTP_SERVER_DNS */
-#if SNTP_GET_SERVERS_FROM_DHCP
+#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
void sntp_servermode_dhcp(int set_servers_from_dhcp);
-#else /* SNTP_GET_SERVERS_FROM_DHCP */
+#else /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
#define sntp_servermode_dhcp(x)
-#endif /* SNTP_GET_SERVERS_FROM_DHCP */
+#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
#ifdef __cplusplus
}
diff --git a/lwip/src/include/lwip/apps/sntp_opts.h b/lwip/src/include/lwip/apps/sntp_opts.h
index ed98040..cb62771 100644
--- a/lwip/src/include/lwip/apps/sntp_opts.h
+++ b/lwip/src/include/lwip/apps/sntp_opts.h
@@ -67,6 +67,12 @@
#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV
#endif
+/** Set this to 1 to implement the callback function called by dhcpv6 when
+ * NTP servers are received. */
+#if !defined SNTP_GET_SERVERS_FROM_DHCPV6 || defined __DOXYGEN__
+#define SNTP_GET_SERVERS_FROM_DHCPV6 LWIP_DHCP6_GET_NTP_SRV
+#endif
+
/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers
* One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
* \#define SNTP_SERVER_ADDRESS "pool.ntp.org"
diff --git a/lwip/src/include/lwip/debug.h b/lwip/src/include/lwip/debug.h
index baa6a40..579fd24 100644
--- a/lwip/src/include/lwip/debug.h
+++ b/lwip/src/include/lwip/debug.h
@@ -120,9 +120,7 @@
#endif /* LWIP_NOASSERT */
#ifndef LWIP_ERROR
-#ifndef LWIP_NOASSERT
-#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message)
-#elif defined LWIP_DEBUG
+#ifdef LWIP_DEBUG
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message))
#else
#define LWIP_PLATFORM_ERROR(message)
diff --git a/lwip/src/include/lwip/if_api.h b/lwip/src/include/lwip/if_api.h
index 39017ab..b7269e2 100644
--- a/lwip/src/include/lwip/if_api.h
+++ b/lwip/src/include/lwip/if_api.h
@@ -49,7 +49,9 @@
extern "C" {
#endif
+#ifndef IF_NAMESIZE
#define IF_NAMESIZE NETIF_NAMESIZE
+#endif
char * lwip_if_indextoname(unsigned int ifindex, char *ifname);
unsigned int lwip_if_nametoindex(const char *ifname);
diff --git a/lwip/src/include/lwip/init.h b/lwip/src/include/lwip/init.h
index a149be1..6cabfc8 100644
--- a/lwip/src/include/lwip/init.h
+++ b/lwip/src/include/lwip/init.h
@@ -54,7 +54,7 @@ extern "C" {
/** x.X.x: Minor version of the stack */
#define LWIP_VERSION_MINOR 1
/** x.x.X: Revision of the stack */
-#define LWIP_VERSION_REVISION 2
+#define LWIP_VERSION_REVISION 3
/** For release candidates, this is set to 1..254
* For official releases, this is set to 255 (LWIP_RC_RELEASE)
* For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */
diff --git a/lwip/src/include/lwip/netif.h b/lwip/src/include/lwip/netif.h
index 911196a..9a16ded 100644
--- a/lwip/src/include/lwip/netif.h
+++ b/lwip/src/include/lwip/netif.h
@@ -386,6 +386,10 @@ struct netif {
#if LWIP_LOOPBACK_MAX_PBUFS
u16_t loop_cnt_current;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
+#if LWIP_NETIF_LOOPBACK_MULTITHREADING
+ /* Used if the original scheduling failed. */
+ u8_t reschedule_poll;
+#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
#endif /* ENABLE_LOOPBACK */
};
@@ -451,7 +455,7 @@ void netif_set_gw(struct netif *netif, const ip4_addr_t *gw);
#define netif_set_flags(netif, set_flags) do { (netif)->flags = (u8_t)((netif)->flags | (set_flags)); } while(0)
#define netif_clear_flags(netif, clr_flags) do { (netif)->flags = (u8_t)((netif)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
-#define netif_is_flag_set(nefif, flag) (((netif)->flags & (flag)) != 0)
+#define netif_is_flag_set(netif, flag) (((netif)->flags & (flag)) != 0)
void netif_set_up(struct netif *netif);
void netif_set_down(struct netif *netif);
diff --git a/lwip/src/include/lwip/opt.h b/lwip/src/include/lwip/opt.h
index 38edf41..34e4fd0 100644
--- a/lwip/src/include/lwip/opt.h
+++ b/lwip/src/include/lwip/opt.h
@@ -1551,7 +1551,7 @@
* TCP_MSS, IP header, and link header.
*/
#if !defined PBUF_POOL_BUFSIZE || defined __DOXYGEN__
-#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
+#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+PBUF_IP_HLEN+PBUF_TRANSPORT_HLEN+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif
/**
@@ -1561,6 +1561,14 @@
#if !defined LWIP_PBUF_REF_T || defined __DOXYGEN__
#define LWIP_PBUF_REF_T u8_t
#endif
+
+/**
+ * LWIP_PBUF_CUSTOM_DATA: Store private data on pbufs (e.g. timestamps)
+ * This extends struct pbuf so user can store custom data on every pbuf.
+ */
+#if !defined LWIP_PBUF_CUSTOM_DATA || defined __DOXYGEN__
+#define LWIP_PBUF_CUSTOM_DATA
+#endif
/**
* @}
*/
@@ -1918,11 +1926,8 @@
/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread,
* writing from a 2nd thread and closing from a 3rd thread at the same time.
- * ATTENTION: This is currently really alpha! Some requirements:
- * - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from
- * multiple threads at once
- * - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox
- * and prevent a task pending on this during/after deletion
+ * LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from
+ * multiple threads at once!
*/
#if !defined LWIP_NETCONN_FULLDUPLEX || defined __DOXYGEN__
#define LWIP_NETCONN_FULLDUPLEX 0
@@ -2452,7 +2457,7 @@
* network startup.
*/
#if !defined LWIP_IPV6_SEND_ROUTER_SOLICIT || defined __DOXYGEN__
-#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
+#define LWIP_IPV6_SEND_ROUTER_SOLICIT LWIP_IPV6
#endif
/**
@@ -2497,10 +2502,12 @@
/**
* LWIP_ICMP6_DATASIZE: bytes from original packet to send back in
- * ICMPv6 error messages.
+ * ICMPv6 error messages (0 = default of IP6_MIN_MTU_LENGTH)
+ * ATTENTION: RFC4443 section 2.4 says IP6_MIN_MTU_LENGTH is a MUST,
+ * so override this only if you absolutely have to!
*/
#if !defined LWIP_ICMP6_DATASIZE || defined __DOXYGEN__
-#define LWIP_ICMP6_DATASIZE 8
+#define LWIP_ICMP6_DATASIZE 0
#endif
/**
diff --git a/lwip/src/include/lwip/pbuf.h b/lwip/src/include/lwip/pbuf.h
index 82902a4..e5daf96 100644
--- a/lwip/src/include/lwip/pbuf.h
+++ b/lwip/src/include/lwip/pbuf.h
@@ -219,6 +219,9 @@ struct pbuf {
/** For incoming packets, this contains the input netif's index */
u8_t if_idx;
+
+ /** In case the user needs to store data custom data on a pbuf */
+ LWIP_PBUF_CUSTOM_DATA
};
@@ -293,6 +296,7 @@ void pbuf_cat(struct pbuf *head, struct pbuf *tail);
void pbuf_chain(struct pbuf *head, struct pbuf *tail);
struct pbuf *pbuf_dechain(struct pbuf *p);
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from);
+err_t pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset);
u16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
void *pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset);
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len);
diff --git a/lwip/src/include/lwip/priv/altcp_priv.h b/lwip/src/include/lwip/priv/altcp_priv.h
index 2d3b2fd..d1de9b1 100644
--- a/lwip/src/include/lwip/priv/altcp_priv.h
+++ b/lwip/src/include/lwip/priv/altcp_priv.h
@@ -85,6 +85,11 @@ typedef err_t (*altcp_get_tcp_addrinfo_fn)(struct altcp_pcb *conn, int local, ip
typedef ip_addr_t *(*altcp_get_ip_fn)(struct altcp_pcb *conn, int local);
typedef u16_t (*altcp_get_port_fn)(struct altcp_pcb *conn, int local);
+#if LWIP_TCP_KEEPALIVE
+typedef void (*altcp_keepalive_disable_fn)(struct altcp_pcb *conn);
+typedef void (*altcp_keepalive_enable_fn)(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
+#endif
+
#ifdef LWIP_DEBUG
typedef enum tcp_state (*altcp_dbg_get_tcp_state_fn)(struct altcp_pcb *conn);
#endif
@@ -111,6 +116,10 @@ struct altcp_functions {
altcp_get_tcp_addrinfo_fn addrinfo;
altcp_get_ip_fn getip;
altcp_get_port_fn getport;
+#if LWIP_TCP_KEEPALIVE
+ altcp_keepalive_disable_fn keepalive_disable;
+ altcp_keepalive_enable_fn keepalive_enable;
+#endif
#ifdef LWIP_DEBUG
altcp_dbg_get_tcp_state_fn dbg_get_tcp_state;
#endif
@@ -133,6 +142,10 @@ void altcp_default_dealloc(struct altcp_pcb *conn);
err_t altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
ip_addr_t *altcp_default_get_ip(struct altcp_pcb *conn, int local);
u16_t altcp_default_get_port(struct altcp_pcb *conn, int local);
+#if LWIP_TCP_KEEPALIVE
+void altcp_default_keepalive_disable(struct altcp_pcb *conn);
+void altcp_default_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
+#endif
#ifdef LWIP_DEBUG
enum tcp_state altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn);
#endif
diff --git a/lwip/src/include/lwip/prot/icmp6.h b/lwip/src/include/lwip/prot/icmp6.h
index 3461120..36989f6 100644
--- a/lwip/src/include/lwip/prot/icmp6.h
+++ b/lwip/src/include/lwip/prot/icmp6.h
@@ -146,6 +146,8 @@ PACK_STRUCT_END
# include "arch/epstruct.h"
#endif
+#define ICMP6_HLEN 8
+
/** This is the ICMP6 header adapted for echo req/resp. */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
diff --git a/lwip/src/include/lwip/prot/ip6.h b/lwip/src/include/lwip/prot/ip6.h
index 0f6de45..7df81ed 100644
--- a/lwip/src/include/lwip/prot/ip6.h
+++ b/lwip/src/include/lwip/prot/ip6.h
@@ -44,6 +44,8 @@
extern "C" {
#endif
+#define IP6_MIN_MTU_LENGTH 1280
+
/** This is the packed version of ip6_addr_t,
used in network headers that are itself packed */
#ifdef PACK_STRUCT_USE_INCLUDES
diff --git a/lwip/src/include/netif/ppp/ppp_opts.h b/lwip/src/include/netif/ppp/ppp_opts.h
index 6702bec..479a006 100644
--- a/lwip/src/include/netif/ppp/ppp_opts.h
+++ b/lwip/src/include/netif/ppp/ppp_opts.h
@@ -45,6 +45,13 @@
#endif
/**
+ * PPPOE_SCNAME_SUPPORT==1: Enable PPP Over Ethernet Service Name and Concentrator Name support
+ */
+#ifndef PPPOE_SCNAME_SUPPORT
+#define PPPOE_SCNAME_SUPPORT 0
+#endif
+
+/**
* PPPOL2TP_SUPPORT==1: Enable PPP Over L2TP
*/
#ifndef PPPOL2TP_SUPPORT
diff --git a/lwip/src/include/netif/ppp/pppoe.h b/lwip/src/include/netif/ppp/pppoe.h
index 08ab7ab..8994d38 100644
--- a/lwip/src/include/netif/ppp/pppoe.h
+++ b/lwip/src/include/netif/ppp/pppoe.h
@@ -149,10 +149,10 @@ struct pppoe_softc {
u16_t sc_session; /* PPPoE session id */
u8_t sc_state; /* discovery phase or session connected */
-#ifdef PPPOE_TODO
- u8_t *sc_service_name; /* if != NULL: requested name of service */
- u8_t *sc_concentrator_name; /* if != NULL: requested concentrator id */
-#endif /* PPPOE_TODO */
+#if PPPOE_SCNAME_SUPPORT
+ const char *sc_service_name; /* if != NULL: requested name of service */
+ const char *sc_concentrator_name; /* if != NULL: requested concentrator id */
+#endif /* PPPOE_SCNAME_SUPPORT */
u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */
u8_t sc_ac_cookie_len; /* length of cookie data */
#ifdef PPPOE_SERVER
diff --git a/lwip/src/netif/lowpan6.c b/lwip/src/netif/lowpan6.c
index 7f0d276..5e6f009 100644
--- a/lwip/src/netif/lowpan6.c
+++ b/lwip/src/netif/lowpan6.c
@@ -881,7 +881,7 @@ lowpan6_if_init(struct netif *netif)
MIB2_INIT_NETIF(netif, snmp_ifType_other, 0);
/* maximum transfer unit */
- netif->mtu = 1280;
+ netif->mtu = IP6_MIN_MTU_LENGTH;
/* broadcast capability */
netif->flags = NETIF_FLAG_BROADCAST /* | NETIF_FLAG_LOWPAN6 */;
diff --git a/lwip/src/netif/lowpan6_ble.c b/lwip/src/netif/lowpan6_ble.c
index d89816d..6de0ae3 100644
--- a/lwip/src/netif/lowpan6_ble.c
+++ b/lwip/src/netif/lowpan6_ble.c
@@ -417,7 +417,7 @@ rfc7668_if_init(struct netif *netif)
MIB2_INIT_NETIF(netif, snmp_ifType_other, 0);
/* maximum transfer unit, set according to RFC7668 ch2.4 */
- netif->mtu = 1280;
+ netif->mtu = IP6_MIN_MTU_LENGTH;
/* no flags set (no broadcast, ethernet,...)*/
netif->flags = 0;
diff --git a/lwip/src/netif/lowpan6_common.c b/lwip/src/netif/lowpan6_common.c
index baea206..4db1ebb 100644
--- a/lwip/src/netif/lowpan6_common.c
+++ b/lwip/src/netif/lowpan6_common.c
@@ -440,7 +440,7 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
if ((lowpan6_buffer[0] & 0x18) == 0x00) {
header_temp = ((lowpan6_buffer[lowpan6_offset+1] & 0x0f) << 16) | \
(lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset+3];
- LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 00, ECN: 0x%2x, Flowlabel+DSCP: 0x%8X\n", \
+ LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 00, ECN: 0x%"X8_F", Flowlabel+DSCP: 0x%8"X32_F"\n", \
lowpan6_buffer[lowpan6_offset],header_temp));
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], header_temp);
/* increase offset, processed 4 bytes here:
@@ -448,14 +448,14 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
lowpan6_offset += 4;
} else if ((lowpan6_buffer[0] & 0x18) == 0x08) {
header_temp = ((lowpan6_buffer[lowpan6_offset] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset+2];
- LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 01, ECN: 0x%2x, Flowlabel: 0x%2X, DSCP ignored\n", \
+ LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 01, ECN: 0x%"X8_F", Flowlabel: 0x%2"X32_F", DSCP ignored\n", \
lowpan6_buffer[lowpan6_offset] & 0xc0,header_temp));
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset] & 0xc0, header_temp);
/* increase offset, processed 3 bytes here:
* TF=01: ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided.*/
lowpan6_offset += 3;
} else if ((lowpan6_buffer[0] & 0x18) == 0x10) {
- LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 10, DCSP+ECN: 0x%2x, Flowlabel ignored\n", lowpan6_buffer[lowpan6_offset]));
+ LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("TF: 10, DCSP+ECN: 0x%"X8_F", Flowlabel ignored\n", lowpan6_buffer[lowpan6_offset]));
IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset],0);
/* increase offset, processed 1 byte here:
* ECN + DSCP (1 byte), Flow Label is elided.*/
@@ -564,7 +564,7 @@ lowpan6_decompress_hdr(u8_t *lowpan6_buffer, size_t lowpan6_bufsize,
#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
ip6hdr->src.addr[0] = lowpan6_contexts[i].addr[0];
ip6hdr->src.addr[1] = lowpan6_contexts[i].addr[1];
- LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == xx, context compression found @%d: %8X, %8X\n", (int)i, ip6hdr->src.addr[0], ip6hdr->src.addr[1]));
+ LWIP_DEBUGF(LWIP_LOWPAN6_DECOMPRESSION_DEBUG, ("SAM == xx, context compression found @%d: %8"X32_F", %8"X32_F"\n", (int)i, ip6hdr->src.addr[0], ip6hdr->src.addr[1]));
#else
LWIP_UNUSED_ARG(lowpan6_contexts);
#endif
diff --git a/lwip/src/netif/ppp/ppp.c b/lwip/src/netif/ppp/ppp.c
index a9c18e3..be58553 100644
--- a/lwip/src/netif/ppp/ppp.c
+++ b/lwip/src/netif/ppp/ppp.c
@@ -216,7 +216,8 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protoc
/***********************************/
#if PPP_AUTH_SUPPORT
void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) {
- LWIP_ASSERT_CORE_LOCKED();
+ LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD", pcb->phase == PPP_PHASE_DEAD);
+
#if PAP_SUPPORT
pcb->settings.refuse_pap = !(authtype & PPPAUTHTYPE_PAP);
#endif /* PAP_SUPPORT */
@@ -238,6 +239,8 @@ void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *pas
#if MPPE_SUPPORT
/* Set MPPE configuration */
void ppp_set_mppe(ppp_pcb *pcb, u8_t flags) {
+ LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD", pcb->phase == PPP_PHASE_DEAD);
+
if (flags == PPP_MPPE_DISABLE) {
pcb->settings.require_mppe = 0;
return;
diff --git a/lwip/src/netif/ppp/pppoe.c b/lwip/src/netif/ppp/pppoe.c
index 8ed2d63..971b36b 100644
--- a/lwip/src/netif/ppp/pppoe.c
+++ b/lwip/src/netif/ppp/pppoe.c
@@ -175,8 +175,10 @@ ppp_pcb *pppoe_create(struct netif *pppif,
{
ppp_pcb *ppp;
struct pppoe_softc *sc;
+#if !PPPOE_SCNAME_SUPPORT
LWIP_UNUSED_ARG(service_name);
LWIP_UNUSED_ARG(concentrator_name);
+#endif /* !PPPOE_SCNAME_SUPPORT */
LWIP_ASSERT_CORE_LOCKED();
sc = (struct pppoe_softc *)LWIP_MEMPOOL_ALLOC(PPPOE_IF);
@@ -193,6 +195,10 @@ ppp_pcb *pppoe_create(struct netif *pppif,
memset(sc, 0, sizeof(struct pppoe_softc));
sc->pcb = ppp;
sc->sc_ethif = ethif;
+#if PPPOE_SCNAME_SUPPORT
+ sc->sc_service_name = service_name;
+ sc->sc_concentrator_name = concentrator_name;
+#endif /* PPPOE_SCNAME_SUPPORT */
/* put the new interface at the head of the list */
sc->next = pppoe_softc_list;
pppoe_softc_list = sc;
@@ -300,15 +306,6 @@ pppoe_destroy(ppp_pcb *ppp, void *ctx)
break;
}
}
-
-#ifdef PPPOE_TODO
- if (sc->sc_concentrator_name) {
- mem_free(sc->sc_concentrator_name);
- }
- if (sc->sc_service_name) {
- mem_free(sc->sc_service_name);
- }
-#endif /* PPPOE_TODO */
LWIP_MEMPOOL_FREE(PPPOE_IF, sc);
return ERR_OK;
@@ -757,13 +754,13 @@ pppoe_send_padi(struct pppoe_softc *sc)
struct pbuf *pb;
u8_t *p;
int len;
-#ifdef PPPOE_TODO
+#if PPPOE_SCNAME_SUPPORT
int l1 = 0, l2 = 0; /* XXX: gcc */
-#endif /* PPPOE_TODO */
+#endif /* PPPOE_SCNAME_SUPPORT */
/* calculate length of frame (excluding ethernet header + pppoe header) */
len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */
-#ifdef PPPOE_TODO
+#if PPPOE_SCNAME_SUPPORT
if (sc->sc_service_name != NULL) {
l1 = (int)strlen(sc->sc_service_name);
len += l1;
@@ -772,7 +769,7 @@ pppoe_send_padi(struct pppoe_softc *sc)
l2 = (int)strlen(sc->sc_concentrator_name);
len += 2 + 2 + l2;
}
-#endif /* PPPOE_TODO */
+#endif /* PPPOE_SCNAME_SUPPORT */
LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
@@ -787,24 +784,24 @@ pppoe_send_padi(struct pppoe_softc *sc)
/* fill in pkt */
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len);
PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
-#ifdef PPPOE_TODO
+#if PPPOE_SCNAME_SUPPORT
if (sc->sc_service_name != NULL) {
PPPOE_ADD_16(p, l1);
MEMCPY(p, sc->sc_service_name, l1);
p += l1;
} else
-#endif /* PPPOE_TODO */
+#endif /* PPPOE_SCNAME_SUPPORT */
{
PPPOE_ADD_16(p, 0);
}
-#ifdef PPPOE_TODO
+#if PPPOE_SCNAME_SUPPORT
if (sc->sc_concentrator_name != NULL) {
PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
PPPOE_ADD_16(p, l2);
MEMCPY(p, sc->sc_concentrator_name, l2);
p += l2;
}
-#endif /* PPPOE_TODO */
+#endif /* PPPOE_SCNAME_SUPPORT */
PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
PPPOE_ADD_16(p, sizeof(sc));
MEMCPY(p, &sc, sizeof sc);
@@ -982,17 +979,17 @@ pppoe_send_padr(struct pppoe_softc *sc)
struct pbuf *pb;
u8_t *p;
size_t len;
-#ifdef PPPOE_TODO
+#if PPPOE_SCNAME_SUPPORT
size_t l1 = 0; /* XXX: gcc */
-#endif /* PPPOE_TODO */
+#endif /* PPPOE_SCNAME_SUPPORT */
len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */
-#ifdef PPPOE_TODO
+#if PPPOE_SCNAME_SUPPORT
if (sc->sc_service_name != NULL) { /* service name tag maybe empty */
l1 = strlen(sc->sc_service_name);
len += l1;
}
-#endif /* PPPOE_TODO */
+#endif /* PPPOE_SCNAME_SUPPORT */
if (sc->sc_ac_cookie_len > 0) {
len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */
}
@@ -1006,13 +1003,13 @@ pppoe_send_padr(struct pppoe_softc *sc)
p = (u8_t*)pb->payload;
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
-#ifdef PPPOE_TODO
+#if PPPOE_SCNAME_SUPPORT
if (sc->sc_service_name != NULL) {
PPPOE_ADD_16(p, l1);
MEMCPY(p, sc->sc_service_name, l1);
p += l1;
} else
-#endif /* PPPOE_TODO */
+#endif /* PPPOE_SCNAME_SUPPORT */
{
PPPOE_ADD_16(p, 0);
}
diff --git a/lwip/src/netif/zepif.c b/lwip/src/netif/zepif.c
index b403303..de43b99 100644
--- a/lwip/src/netif/zepif.c
+++ b/lwip/src/netif/zepif.c
@@ -201,7 +201,7 @@ zepif_linkoutput(struct netif *netif, struct pbuf *p)
state->seqno++;
zep->len = (u8_t)p->tot_len;
- err = pbuf_take_at(q, p->payload, p->tot_len, sizeof(struct zep_hdr));
+ err = pbuf_copy_partial_pbuf(q, p, p->tot_len, sizeof(struct zep_hdr));
if (err == ERR_OK) {
#if ZEPIF_LOOPBACK
zepif_udp_recv(netif, state->pcb, pbuf_clone(PBUF_RAW, PBUF_RAM, q), NULL, 0);