Revert "Test / RFC: Reformat a few files using clang-format"

This reverts commit 8b4a8159a8.

We do not want to do this shortly before a release. Reformatting (buggy reformatting) may introduce new bugs.
This commit is contained in:
Dirk Ziegelmeier 2018-07-18 08:34:01 +02:00
parent 0985e925a1
commit eeb2218b3d
25 changed files with 2761 additions and 3061 deletions

View File

@ -63,11 +63,11 @@
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/ip.h" #include "lwip/ip.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/priv/api_msg.h" #include "lwip/priv/api_msg.h"
#include "lwip/priv/tcp_priv.h" #include "lwip/priv/tcp_priv.h"
#include "lwip/priv/tcpip_priv.h" #include "lwip/priv/tcpip_priv.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#ifdef LWIP_HOOK_FILENAME #ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME #include LWIP_HOOK_FILENAME
@ -75,11 +75,11 @@
#include <string.h> #include <string.h>
#define API_MSG_VAR_REF(name) API_VAR_REF(name) #define API_MSG_VAR_REF(name) API_VAR_REF(name)
#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name) #define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name)
#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM) #define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM)
#define API_MSG_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, NULL) #define API_MSG_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, NULL)
#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name) #define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name)
#if TCP_LISTEN_BACKLOG #if TCP_LISTEN_BACKLOG
/* need to allocate API message for accept so empty message pool does not result in event loss /* need to allocate API message for accept so empty message pool does not result in event loss
@ -92,22 +92,18 @@
#endif /* TCP_LISTEN_BACKLOG */ #endif /* TCP_LISTEN_BACKLOG */
#if LWIP_NETCONN_FULLDUPLEX #if LWIP_NETCONN_FULLDUPLEX
#define NETCONN_RECVMBOX_WAITABLE(conn) \ #define NETCONN_RECVMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->recvmbox) && (((conn)->flags & NETCONN_FLAG_MBOXINVALID) == 0))
(sys_mbox_valid(&(conn)->recvmbox) && (((conn)->flags & NETCONN_FLAG_MBOXINVALID) == 0)) #define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & (NETCONN_FLAG_MBOXCLOSED|NETCONN_FLAG_MBOXINVALID)) == 0))
#define NETCONN_ACCEPTMBOX_WAITABLE(conn) \
(sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & (NETCONN_FLAG_MBOXCLOSED | NETCONN_FLAG_MBOXINVALID)) == 0))
#define NETCONN_MBOX_WAITING_INC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1) #define NETCONN_MBOX_WAITING_INC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1)
#define NETCONN_MBOX_WAITING_DEC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1) #define NETCONN_MBOX_WAITING_DEC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1)
#else /* LWIP_NETCONN_FULLDUPLEX */ #else /* LWIP_NETCONN_FULLDUPLEX */
#define NETCONN_RECVMBOX_WAITABLE(conn) sys_mbox_valid(&(conn)->recvmbox) #define NETCONN_RECVMBOX_WAITABLE(conn) sys_mbox_valid(&(conn)->recvmbox)
#define NETCONN_ACCEPTMBOX_WAITABLE(conn) \ #define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & NETCONN_FLAG_MBOXCLOSED) == 0))
(sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & NETCONN_FLAG_MBOXCLOSED) == 0))
#define NETCONN_MBOX_WAITING_INC(conn) #define NETCONN_MBOX_WAITING_INC(conn)
#define NETCONN_MBOX_WAITING_DEC(conn) #define NETCONN_MBOX_WAITING_DEC(conn)
#endif /* LWIP_NETCONN_FULLDUPLEX */ #endif /* LWIP_NETCONN_FULLDUPLEX */
static err_t static err_t netconn_close_shutdown(struct netconn *conn, u8_t how);
netconn_close_shutdown(struct netconn *conn, u8_t how);
/** /**
* Call the lower part of a netconn_* function * Call the lower part of a netconn_* function
@ -286,7 +282,7 @@ netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
err = netconn_apimsg(lwip_netconn_do_getaddr, &API_MSG_VAR_REF(msg)); err = netconn_apimsg(lwip_netconn_do_getaddr, &API_MSG_VAR_REF(msg));
*addr = msg->msg.ad.ipaddr; *addr = msg->msg.ad.ipaddr;
*port = msg->msg.ad.port; *port = msg->msg.ad.port;
#else /* LWIP_MPU_COMPATIBLE */ #else /* LWIP_MPU_COMPATIBLE */
msg.msg.ad.ipaddr = addr; msg.msg.ad.ipaddr = addr;
msg.msg.ad.port = port; msg.msg.ad.port = port;
err = netconn_apimsg(lwip_netconn_do_getaddr, &msg); err = netconn_apimsg(lwip_netconn_do_getaddr, &msg);
@ -326,7 +322,8 @@ netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port)
/* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY, /* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY,
* and NETCONN_FLAG_IPV6_V6ONLY is 0, use IP_ANY_TYPE to bind * and NETCONN_FLAG_IPV6_V6ONLY is 0, use IP_ANY_TYPE to bind
*/ */
if ((netconn_get_ipv6only(conn) == 0) && ip_addr_cmp(addr, IP6_ADDR_ANY)) { if ((netconn_get_ipv6only(conn) == 0) &&
ip_addr_cmp(addr, IP6_ADDR_ANY)) {
addr = IP_ANY_TYPE; addr = IP_ANY_TYPE;
} }
#endif /* LWIP_IPV4 && LWIP_IPV6 */ #endif /* LWIP_IPV4 && LWIP_IPV6 */
@ -454,7 +451,7 @@ netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
API_MSG_VAR_FREE(msg); API_MSG_VAR_FREE(msg);
return err; return err;
#else /* LWIP_TCP */ #else /* LWIP_TCP */
LWIP_UNUSED_ARG(conn); LWIP_UNUSED_ARG(conn);
LWIP_UNUSED_ARG(backlog); LWIP_UNUSED_ARG(backlog);
return ERR_ARG; return ERR_ARG;
@ -481,9 +478,9 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
API_MSG_VAR_DECLARE(msg); API_MSG_VAR_DECLARE(msg);
#endif /* TCP_LISTEN_BACKLOG */ #endif /* TCP_LISTEN_BACKLOG */
LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
*new_conn = NULL; *new_conn = NULL;
LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
/* NOTE: Although the opengroup spec says a pending error shall be returned to /* NOTE: Although the opengroup spec says a pending error shall be returned to
send/recv/getsockopt(SO_ERROR) only, we return it for listening send/recv/getsockopt(SO_ERROR) only, we return it for listening
@ -555,7 +552,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
*new_conn = newconn; *new_conn = newconn;
/* don't set conn->last_err: it's only ERR_OK, anyway */ /* don't set conn->last_err: it's only ERR_OK, anyway */
return ERR_OK; return ERR_OK;
#else /* LWIP_TCP */ #else /* LWIP_TCP */
LWIP_UNUSED_ARG(conn); LWIP_UNUSED_ARG(conn);
LWIP_UNUSED_ARG(new_conn); LWIP_UNUSED_ARG(new_conn);
return ERR_ARG; return ERR_ARG;
@ -586,7 +583,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
*new_buf = NULL; *new_buf = NULL;
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
if (!NETCONN_RECVMBOX_WAITABLE(conn)) { if (!NETCONN_RECVMBOX_WAITABLE(conn)) {
err_t err = netconn_err(conn); err_t err = netconn_err(conn);
@ -598,8 +595,8 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
} }
NETCONN_MBOX_WAITING_INC(conn); NETCONN_MBOX_WAITING_INC(conn);
if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) || (conn->flags & NETCONN_FLAG_MBOXCLOSED) || if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) ||
(conn->pending_err != ERR_OK)) { (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_ARCH_TIMEOUT) {
err_t err; err_t err;
NETCONN_MBOX_WAITING_DEC(conn); NETCONN_MBOX_WAITING_DEC(conn);
@ -668,7 +665,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
/* Register event with callback */ /* Register event with callback */
API_EVENT(conn, NETCONN_EVT_RCVMINUS, len); API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%" U16_F "\n", buf, len)); LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
*new_buf = buf; *new_buf = buf;
/* don't set conn->last_err: it's only ERR_OK, anyway */ /* don't set conn->last_err: it's only ERR_OK, anyway */
@ -679,9 +676,8 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
static err_t static err_t
netconn_tcp_recvd_msg(struct netconn *conn, size_t len, struct api_msg *msg) netconn_tcp_recvd_msg(struct netconn *conn, size_t len, struct api_msg *msg)
{ {
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
return ERR_ARG;);
msg->conn = conn; msg->conn = conn;
msg->msg.r.len = len; msg->msg.r.len = len;
@ -694,9 +690,8 @@ netconn_tcp_recvd(struct netconn *conn, size_t len)
{ {
err_t err; err_t err;
API_MSG_VAR_DECLARE(msg); API_MSG_VAR_DECLARE(msg);
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
return ERR_ARG;);
API_MSG_VAR_ALLOC(msg); API_MSG_VAR_ALLOC(msg);
err = netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg)); err = netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg));
@ -725,7 +720,7 @@ netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags
if (!(apiflags & NETCONN_NOAUTORCVD)) { if (!(apiflags & NETCONN_NOAUTORCVD)) {
/* need to allocate API message here so empty message pool does not result in event loss /* need to allocate API message here so empty message pool does not result in event loss
* see bug #47512: MPU_COMPATIBLE may fail on empty pool */ * see bug #47512: MPU_COMPATIBLE may fail on empty pool */
API_MSG_VAR_ALLOC(msg); API_MSG_VAR_ALLOC(msg);
} }
@ -742,7 +737,7 @@ netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags
u16_t len = buf ? buf->tot_len : 1; u16_t len = buf ? buf->tot_len : 1;
/* don't care for the return value of lwip_netconn_do_recv */ /* don't care for the return value of lwip_netconn_do_recv */
/* @todo: this should really be fixed, e.g. by retrying in poll on error */ /* @todo: this should really be fixed, e.g. by retrying in poll on error */
netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg)); netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg));
API_MSG_VAR_FREE(msg); API_MSG_VAR_FREE(msg);
} }
@ -754,7 +749,7 @@ netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags
netconn_set_flags(conn, NETCONN_FIN_RX_PENDING); netconn_set_flags(conn, NETCONN_FIN_RX_PENDING);
return ERR_WOULDBLOCK; return ERR_WOULDBLOCK;
} else { } else {
handle_fin: handle_fin:
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
if (conn->pcb.ip == NULL) { if (conn->pcb.ip == NULL) {
/* race condition: RST during recv */ /* race condition: RST during recv */
@ -786,9 +781,8 @@ netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags
err_t err_t
netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf) netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
{ {
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
return ERR_ARG;);
return netconn_recv_data_tcp(conn, new_buf, 0); return netconn_recv_data_tcp(conn, new_buf, 0);
} }
@ -808,9 +802,8 @@ netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
err_t err_t
netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags) netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags)
{ {
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
return ERR_ARG;);
return netconn_recv_data_tcp(conn, new_buf, apiflags); return netconn_recv_data_tcp(conn, new_buf, apiflags);
} }
@ -828,9 +821,8 @@ netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t ap
err_t err_t
netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf) netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf)
{ {
LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
return ERR_ARG;);
return netconn_recv_data(conn, (void **)new_buf, 0); return netconn_recv_data(conn, (void **)new_buf, 0);
} }
@ -849,9 +841,8 @@ netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf)
err_t err_t
netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags) netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags)
{ {
LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
return ERR_ARG;);
return netconn_recv_data(conn, (void **)new_buf, apiflags); return netconn_recv_data(conn, (void **)new_buf, apiflags);
} }
@ -875,7 +866,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
*new_buf = NULL; *new_buf = NULL;
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
#if LWIP_TCP #if LWIP_TCP
#if (LWIP_UDP || LWIP_RAW) #if (LWIP_UDP || LWIP_RAW)
@ -952,9 +943,9 @@ netconn_send(struct netconn *conn, struct netbuf *buf)
API_MSG_VAR_DECLARE(msg); API_MSG_VAR_DECLARE(msg);
err_t err; err_t err;
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %" U16_F " bytes\n", buf->p->tot_len)); LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
API_MSG_VAR_ALLOC(msg); API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).conn = conn; API_MSG_VAR_REF(msg).conn = conn;
@ -980,7 +971,8 @@ netconn_send(struct netconn *conn, struct netbuf *buf)
* @return ERR_OK if data was sent, any other err_t on error * @return ERR_OK if data was sent, any other err_t on error
*/ */
err_t err_t
netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags, size_t *bytes_written) netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
u8_t apiflags, size_t *bytes_written)
{ {
struct netvector vector; struct netvector vector;
vector.ptr = dataptr; vector.ptr = dataptr;
@ -1002,11 +994,8 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, u8_
* @return ERR_OK if data was sent, any other err_t on error * @return ERR_OK if data was sent, any other err_t on error
*/ */
err_t err_t
netconn_write_vectors_partly(struct netconn *conn, netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt,
struct netvector *vectors, u8_t apiflags, size_t *bytes_written)
u16_t vectorcnt,
u8_t apiflags,
size_t *bytes_written)
{ {
API_MSG_VAR_DECLARE(msg); API_MSG_VAR_DECLARE(msg);
err_t err; err_t err;
@ -1014,8 +1003,8 @@ netconn_write_vectors_partly(struct netconn *conn,
size_t size; size_t size;
int i; int i;
LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP), return ERR_VAL;); LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP), return ERR_VAL;);
dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
#if LWIP_SO_SNDTIMEO #if LWIP_SO_SNDTIMEO
if (conn->send_timeout != 0) { if (conn->send_timeout != 0) {
@ -1103,7 +1092,7 @@ netconn_close_shutdown(struct netconn *conn, u8_t how)
err_t err; err_t err;
LWIP_UNUSED_ARG(how); LWIP_UNUSED_ARG(how);
LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
API_MSG_VAR_ALLOC(msg); API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).conn = conn; API_MSG_VAR_REF(msg).conn = conn;
@ -1114,7 +1103,7 @@ netconn_close_shutdown(struct netconn *conn, u8_t how)
/* get the time we started, which is later compared to /* get the time we started, which is later compared to
sys_now() + conn->send_timeout */ sys_now() + conn->send_timeout */
API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now(); API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ #else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
API_MSG_VAR_REF(msg).msg.sd.polls_left = API_MSG_VAR_REF(msg).msg.sd.polls_left =
((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1; ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ #endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
@ -1197,7 +1186,7 @@ netconn_join_leave_group(struct netconn *conn,
API_MSG_VAR_DECLARE(msg); API_MSG_VAR_DECLARE(msg);
err_t err; err_t err;
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
API_MSG_VAR_ALLOC(msg); API_MSG_VAR_ALLOC(msg);
@ -1239,7 +1228,7 @@ netconn_join_leave_group_netif(struct netconn *conn,
API_MSG_VAR_DECLARE(msg); API_MSG_VAR_DECLARE(msg);
err_t err; err_t err;
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
API_MSG_VAR_ALLOC(msg); API_MSG_VAR_ALLOC(msg);
@ -1314,7 +1303,7 @@ netconn_gethostbyname(const char *name, ip_addr_t *addr)
#if LWIP_MPU_COMPATIBLE #if LWIP_MPU_COMPATIBLE
strncpy(API_VAR_REF(msg).name, name, DNS_MAX_NAME_LENGTH - 1); strncpy(API_VAR_REF(msg).name, name, DNS_MAX_NAME_LENGTH - 1);
API_VAR_REF(msg).name[DNS_MAX_NAME_LENGTH - 1] = 0; API_VAR_REF(msg).name[DNS_MAX_NAME_LENGTH - 1] = 0;
#else /* LWIP_MPU_COMPATIBLE */ #else /* LWIP_MPU_COMPATIBLE */
msg.err = &err; msg.err = &err;
msg.sem = &sem; msg.sem = &sem;
API_VAR_REF(msg).addr = API_VAR_REF(addr); API_VAR_REF(msg).addr = API_VAR_REF(addr);
@ -1325,7 +1314,7 @@ netconn_gethostbyname(const char *name, ip_addr_t *addr)
#endif /* LWIP_IPV4 && LWIP_IPV6 */ #endif /* LWIP_IPV4 && LWIP_IPV6 */
#if LWIP_NETCONN_SEM_PER_THREAD #if LWIP_NETCONN_SEM_PER_THREAD
API_VAR_REF(msg).sem = LWIP_NETCONN_THREAD_SEM_GET(); API_VAR_REF(msg).sem = LWIP_NETCONN_THREAD_SEM_GET();
#else /* LWIP_NETCONN_SEM_PER_THREAD*/ #else /* LWIP_NETCONN_SEM_PER_THREAD*/
err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0); err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0);
if (err != ERR_OK) { if (err != ERR_OK) {
API_VAR_FREE(MEMP_DNS_API_MSG, msg); API_VAR_FREE(MEMP_DNS_API_MSG, msg);

View File

@ -44,13 +44,13 @@
#include "lwip/ip.h" #include "lwip/ip.h"
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
#include "lwip/raw.h"
#include "lwip/tcp.h"
#include "lwip/udp.h" #include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/raw.h"
#include "lwip/dns.h"
#include "lwip/igmp.h"
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/igmp.h"
#include "lwip/dns.h"
#include "lwip/mld6.h" #include "lwip/mld6.h"
#include "lwip/priv/tcpip_priv.h" #include "lwip/priv/tcpip_priv.h"
@ -59,14 +59,10 @@
/* netconns are polled once per second (e.g. continue write on memory error) */ /* netconns are polled once per second (e.g. continue write on memory error) */
#define NETCONN_TCP_POLL_INTERVAL 2 #define NETCONN_TCP_POLL_INTERVAL 2
#define SET_NONBLOCKING_CONNECT(conn, val) \ #define SET_NONBLOCKING_CONNECT(conn, val) do { if (val) { \
do { \ netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \
if (val) { \ } else { \
netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \ netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); }} while(0)
} else { \
netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \
} \
} while (0)
#define IN_NONBLOCKING_CONNECT(conn) netconn_is_flag_set(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT) #define IN_NONBLOCKING_CONNECT(conn) netconn_is_flag_set(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT)
#if LWIP_NETCONN_FULLDUPLEX #if LWIP_NETCONN_FULLDUPLEX
@ -78,28 +74,22 @@
/* forward declarations */ /* forward declarations */
#if LWIP_TCP #if LWIP_TCP
#if LWIP_TCPIP_CORE_LOCKING #if LWIP_TCPIP_CORE_LOCKING
#define WRITE_DELAYED , 1 #define WRITE_DELAYED , 1
#define WRITE_DELAYED_PARAM , u8_t delayed #define WRITE_DELAYED_PARAM , u8_t delayed
#else /* LWIP_TCPIP_CORE_LOCKING */ #else /* LWIP_TCPIP_CORE_LOCKING */
#define WRITE_DELAYED #define WRITE_DELAYED
#define WRITE_DELAYED_PARAM #define WRITE_DELAYED_PARAM
#endif /* LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_TCPIP_CORE_LOCKING */
static err_t static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM);
lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM); static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM);
static err_t
lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM);
#endif #endif
static void static void netconn_drain(struct netconn *conn);
netconn_drain(struct netconn *conn);
#if LWIP_TCPIP_CORE_LOCKING #if LWIP_TCPIP_CORE_LOCKING
#define TCPIP_APIMSG_ACK(m) #define TCPIP_APIMSG_ACK(m)
#else /* LWIP_TCPIP_CORE_LOCKING */ #else /* LWIP_TCPIP_CORE_LOCKING */
#define TCPIP_APIMSG_ACK(m) \ #define TCPIP_APIMSG_ACK(m) do { sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0)
do { \
sys_sem_signal(LWIP_API_MSG_SEM(m)); \
} while (0)
#endif /* LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_TCPIP_CORE_LOCKING */
#if LWIP_NETCONN_FULLDUPLEX #if LWIP_NETCONN_FULLDUPLEX
@ -156,6 +146,7 @@ lwip_netconn_is_err_msg(void *msg, err_t *err)
} }
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
#if LWIP_RAW #if LWIP_RAW
/** /**
* Receive callback function for RAW netconns. * Receive callback function for RAW netconns.
@ -165,7 +156,8 @@ lwip_netconn_is_err_msg(void *msg, err_t *err)
* @see raw.h (struct raw_pcb.recv) for parameters and return value * @see raw.h (struct raw_pcb.recv) for parameters and return value
*/ */
static u8_t static u8_t
recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
const ip_addr_t *addr)
{ {
struct pbuf *q; struct pbuf *q;
struct netbuf *buf; struct netbuf *buf;
@ -223,7 +215,8 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
* @see udp.h (struct udp_pcb.recv) for parameters * @see udp.h (struct udp_pcb.recv) for parameters
*/ */
static void static void
recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port)
{ {
struct netbuf *buf; struct netbuf *buf;
struct netconn *conn; struct netconn *conn;
@ -246,7 +239,8 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
#if LWIP_SO_RCVBUF #if LWIP_SO_RCVBUF
SYS_ARCH_GET(conn->recv_avail, recv_avail); SYS_ARCH_GET(conn->recv_avail, recv_avail);
if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) || ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) ||
((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
#else /* LWIP_SO_RCVBUF */ #else /* LWIP_SO_RCVBUF */
if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) { if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
#endif /* LWIP_SO_RCVBUF */ #endif /* LWIP_SO_RCVBUF */
@ -368,14 +362,14 @@ poll_tcp(void *arg, struct tcp_pcb *pcb)
LWIP_ASSERT("conn != NULL", (conn != NULL)); LWIP_ASSERT("conn != NULL", (conn != NULL));
if (conn->state == NETCONN_WRITE) { if (conn->state == NETCONN_WRITE) {
lwip_netconn_do_writemore(conn WRITE_DELAYED); lwip_netconn_do_writemore(conn WRITE_DELAYED);
} else if (conn->state == NETCONN_CLOSE) { } else if (conn->state == NETCONN_CLOSE) {
#if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER #if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER
if (conn->current_msg && conn->current_msg->msg.sd.polls_left) { if (conn->current_msg && conn->current_msg->msg.sd.polls_left) {
conn->current_msg->msg.sd.polls_left--; conn->current_msg->msg.sd.polls_left--;
} }
#endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */ #endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */
lwip_netconn_do_close_internal(conn WRITE_DELAYED); lwip_netconn_do_close_internal(conn WRITE_DELAYED);
} }
/* @todo: implement connect timeout here? */ /* @todo: implement connect timeout here? */
@ -410,9 +404,9 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
if (conn) { if (conn) {
if (conn->state == NETCONN_WRITE) { if (conn->state == NETCONN_WRITE) {
lwip_netconn_do_writemore(conn WRITE_DELAYED); lwip_netconn_do_writemore(conn WRITE_DELAYED);
} else if (conn->state == NETCONN_CLOSE) { } else if (conn->state == NETCONN_CLOSE) {
lwip_netconn_do_close_internal(conn WRITE_DELAYED); lwip_netconn_do_close_internal(conn WRITE_DELAYED);
} }
/* If the queued byte- or pbuf-count drops below the configured low-water limit, /* If the queued byte- or pbuf-count drops below the configured low-water limit,
@ -479,7 +473,8 @@ err_tcp(void *arg, err_t err)
sys_mbox_trypost(&conn->acceptmbox, mbox_msg); sys_mbox_trypost(&conn->acceptmbox, mbox_msg);
} }
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || (old_state == NETCONN_CONNECT)) { if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
(old_state == NETCONN_CONNECT)) {
/* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary /* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary
since the pcb has already been deleted! */ since the pcb has already been deleted! */
int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn);
@ -760,14 +755,14 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
#if LWIP_TCP #if LWIP_TCP
sys_mbox_set_invalid(&conn->acceptmbox); sys_mbox_set_invalid(&conn->acceptmbox);
#endif #endif
conn->state = NETCONN_NONE; conn->state = NETCONN_NONE;
#if LWIP_SOCKET #if LWIP_SOCKET
/* initialize socket to -1 since 0 is a valid socket */ /* initialize socket to -1 since 0 is a valid socket */
conn->socket = -1; conn->socket = -1;
#endif /* LWIP_SOCKET */ #endif /* LWIP_SOCKET */
conn->callback = callback; conn->callback = callback;
#if LWIP_TCP #if LWIP_TCP
conn->current_msg = NULL; conn->current_msg = NULL;
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
#if LWIP_SO_SNDTIMEO #if LWIP_SO_SNDTIMEO
conn->send_timeout = 0; conn->send_timeout = 0;
@ -777,7 +772,7 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
#endif /* LWIP_SO_RCVTIMEO */ #endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVBUF #if LWIP_SO_RCVBUF
conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
conn->recv_avail = 0; conn->recv_avail = 0;
#endif /* LWIP_SO_RCVBUF */ #endif /* LWIP_SO_RCVBUF */
#if LWIP_SO_LINGER #if LWIP_SO_LINGER
conn->linger = -1; conn->linger = -1;
@ -805,9 +800,11 @@ netconn_free(struct netconn *conn)
netconn_drain(conn); netconn_drain(conn);
#endif /* LWIP_NETCONN_FULLDUPLEX */ #endif /* LWIP_NETCONN_FULLDUPLEX */
LWIP_ASSERT("recvmbox must be deallocated before calling this function", !sys_mbox_valid(&conn->recvmbox)); LWIP_ASSERT("recvmbox must be deallocated before calling this function",
!sys_mbox_valid(&conn->recvmbox));
#if LWIP_TCP #if LWIP_TCP
LWIP_ASSERT("acceptmbox must be deallocated before calling this function", !sys_mbox_valid(&conn->acceptmbox)); LWIP_ASSERT("acceptmbox must be deallocated before calling this function",
!sys_mbox_valid(&conn->acceptmbox));
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
#if !LWIP_NETCONN_SEM_PER_THREAD #if !LWIP_NETCONN_SEM_PER_THREAD
@ -920,7 +917,7 @@ netconn_mark_mbox_invalid(struct netconn *conn)
* @param conn the TCP netconn to close * @param conn the TCP netconn to close
*/ */
static err_t static err_t
lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM) lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
{ {
err_t err; err_t err;
u8_t shut, shut_rx, shut_tx, shut_close; u8_t shut, shut_rx, shut_tx, shut_close;
@ -944,7 +941,10 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
(also if RD or WR side was shut down before already) */ (also if RD or WR side was shut down before already) */
if (shut == NETCONN_SHUT_RDWR) { if (shut == NETCONN_SHUT_RDWR) {
shut_close = 1; shut_close = 1;
} else if (shut_rx && ((tpcb->state == FIN_WAIT_1) || (tpcb->state == FIN_WAIT_2) || (tpcb->state == CLOSING))) { } else if (shut_rx &&
((tpcb->state == FIN_WAIT_1) ||
(tpcb->state == FIN_WAIT_2) ||
(tpcb->state == CLOSING))) {
shut_close = 1; shut_close = 1;
} else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) { } else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) {
shut_close = 1; shut_close = 1;
@ -988,7 +988,8 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
if (netconn_is_nonblocking(conn)) { if (netconn_is_nonblocking(conn)) {
/* data left on a nonblocking netconn -> cannot linger */ /* data left on a nonblocking netconn -> cannot linger */
err = ERR_WOULDBLOCK; err = ERR_WOULDBLOCK;
} else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= (conn->linger * 1000)) { } else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >=
(conn->linger * 1000)) {
/* data left but linger timeout has expired (this happens on further /* data left but linger timeout has expired (this happens on further
calls to this function through poll_tcp */ calls to this function through poll_tcp */
tcp_abort(tpcb); tcp_abort(tpcb);
@ -1037,7 +1038,7 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
} }
#endif #endif
if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) { if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) {
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ #else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
if (conn->current_msg->msg.sd.polls_left == 0) { if (conn->current_msg->msg.sd.polls_left == 0) {
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ #endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
close_finished = 1; close_finished = 1;
@ -1119,7 +1120,8 @@ lwip_netconn_do_delconn(void *m)
#if LWIP_NETCONN_FULLDUPLEX #if LWIP_NETCONN_FULLDUPLEX
/* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */ /* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */
if (state != NETCONN_NONE) { if (state != NETCONN_NONE) {
if ((state == NETCONN_WRITE) || ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) { if ((state == NETCONN_WRITE) ||
((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
/* close requested, abort running write/connect */ /* close requested, abort running write/connect */
sys_sem_t *op_completed_sem; sys_sem_t *op_completed_sem;
LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
@ -1130,8 +1132,10 @@ lwip_netconn_do_delconn(void *m)
sys_sem_signal(op_completed_sem); sys_sem_signal(op_completed_sem);
} }
} }
#else /* LWIP_NETCONN_FULLDUPLEX */ #else /* LWIP_NETCONN_FULLDUPLEX */
if (((state != NETCONN_NONE) && (state != NETCONN_LISTEN) && (state != NETCONN_CONNECT)) || if (((state != NETCONN_NONE) &&
(state != NETCONN_LISTEN) &&
(state != NETCONN_CONNECT)) ||
((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) { ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
/* This means either a blocking write or blocking connect is running /* This means either a blocking write or blocking connect is running
(nonblocking write returns and sets state to NONE) */ (nonblocking write returns and sets state to NONE) */
@ -1139,12 +1143,13 @@ lwip_netconn_do_delconn(void *m)
} else } else
#endif /* LWIP_NETCONN_FULLDUPLEX */ #endif /* LWIP_NETCONN_FULLDUPLEX */
{ {
LWIP_ASSERT("blocking connect in progress", (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); LWIP_ASSERT("blocking connect in progress",
(state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
msg->err = ERR_OK; msg->err = ERR_OK;
#if LWIP_NETCONN_FULLDUPLEX #if LWIP_NETCONN_FULLDUPLEX
/* Mark mboxes invalid */ /* Mark mboxes invalid */
netconn_mark_mbox_invalid(msg->conn); netconn_mark_mbox_invalid(msg->conn);
#else /* LWIP_NETCONN_FULLDUPLEX */ #else /* LWIP_NETCONN_FULLDUPLEX */
netconn_drain(msg->conn); netconn_drain(msg->conn);
#endif /* LWIP_NETCONN_FULLDUPLEX */ #endif /* LWIP_NETCONN_FULLDUPLEX */
@ -1176,7 +1181,7 @@ lwip_netconn_do_delconn(void *m)
LOCK_TCPIP_CORE(); LOCK_TCPIP_CORE();
LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
} }
#else /* LWIP_TCPIP_CORE_LOCKING */ #else /* LWIP_TCPIP_CORE_LOCKING */
lwip_netconn_do_close_internal(msg->conn); lwip_netconn_do_close_internal(msg->conn);
#endif /* LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_TCPIP_CORE_LOCKING */
/* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing
@ -1321,7 +1326,8 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
was_blocking = !IN_NONBLOCKING_CONNECT(conn); was_blocking = !IN_NONBLOCKING_CONNECT(conn);
SET_NONBLOCKING_CONNECT(conn, 0); SET_NONBLOCKING_CONNECT(conn, 0);
LWIP_ASSERT("blocking connect state error", LWIP_ASSERT("blocking connect state error",
(was_blocking && op_completed_sem != NULL) || (!was_blocking && op_completed_sem == NULL)); (was_blocking && op_completed_sem != NULL) ||
(!was_blocking && op_completed_sem == NULL));
conn->current_msg = NULL; conn->current_msg = NULL;
conn->state = NETCONN_NONE; conn->state = NETCONN_NONE;
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
@ -1370,8 +1376,8 @@ lwip_netconn_do_connect(void *m)
err = ERR_ISCONN; err = ERR_ISCONN;
} else { } else {
setup_tcp(msg->conn); setup_tcp(msg->conn);
err = tcp_connect( err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr),
msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port, lwip_netconn_do_connected); msg->msg.bc.port, lwip_netconn_do_connected);
if (err == ERR_OK) { if (err == ERR_OK) {
u8_t non_blocking = netconn_is_nonblocking(msg->conn); u8_t non_blocking = netconn_is_nonblocking(msg->conn);
msg->conn->state = NETCONN_CONNECT; msg->conn->state = NETCONN_CONNECT;
@ -1396,7 +1402,9 @@ lwip_netconn_do_connect(void *m)
break; break;
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
default: default:
LWIP_ERROR("Invalid netconn type", 0, do { err = ERR_VAL; } while (0)); LWIP_ERROR("Invalid netconn type", 0, do {
err = ERR_VAL;
} while (0));
break; break;
} }
} }
@ -1459,11 +1467,12 @@ lwip_netconn_do_listen(void *m)
#endif /* TCP_LISTEN_BACKLOG */ #endif /* TCP_LISTEN_BACKLOG */
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
/* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY, /* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY,
* and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen
*/ */
if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) && (netconn_get_ipv6only(msg->conn) == 0)) { if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) &&
(netconn_get_ipv6only(msg->conn) == 0)) {
/* change PCB type to IPADDR_TYPE_ANY */ /* change PCB type to IPADDR_TYPE_ANY */
IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip, IPADDR_TYPE_ANY); IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip, IPADDR_TYPE_ANY);
IP_SET_TYPE_VAL(msg->conn->pcb.tcp->remote_ip, IPADDR_TYPE_ANY); IP_SET_TYPE_VAL(msg->conn->pcb.tcp->remote_ip, IPADDR_TYPE_ANY);
} }
#endif /* LWIP_IPV4 && LWIP_IPV6 */ #endif /* LWIP_IPV4 && LWIP_IPV6 */
@ -1541,17 +1550,14 @@ lwip_netconn_do_send(void *m)
case NETCONN_UDP: case NETCONN_UDP:
#if LWIP_CHECKSUM_ON_COPY #if LWIP_CHECKSUM_ON_COPY
if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) {
err = udp_send_chksum( err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p,
msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
} else { } else {
err = udp_sendto_chksum(msg->conn->pcb.udp, err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p,
msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port,
&msg->msg.b->addr, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
msg->msg.b->port,
msg->msg.b->flags & NETBUF_FLAG_CHKSUM,
msg->msg.b->toport_chksum);
} }
#else /* LWIP_CHECKSUM_ON_COPY */ #else /* LWIP_CHECKSUM_ON_COPY */
if (ip_addr_isany_val(msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { if (ip_addr_isany_val(msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) {
err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
} else { } else {
@ -1631,7 +1637,7 @@ lwip_netconn_do_accepted(void *m)
* ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
*/ */
static err_t static err_t
lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
{ {
err_t err; err_t err;
const void *dataptr; const void *dataptr;
@ -1654,7 +1660,8 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
#if LWIP_SO_SNDTIMEO #if LWIP_SO_SNDTIMEO
if ((conn->send_timeout != 0) && ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { if ((conn->send_timeout != 0) &&
((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
write_finished = 1; write_finished = 1;
if (conn->current_msg->msg.w.offset == 0) { if (conn->current_msg->msg.w.offset == 0) {
/* nothing has been written */ /* nothing has been written */
@ -1695,7 +1702,8 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
1) We couldn't finish the current vector because of 16-bit size limitations. 1) We couldn't finish the current vector because of 16-bit size limitations.
tcp_write() and tcp_sndbuf() both are limited to 16-bit sizes tcp_write() and tcp_sndbuf() both are limited to 16-bit sizes
2) We are sending the remainder of the current vector and have more */ 2) We are sending the remainder of the current vector and have more */
if ((len == 0xffff && diff > 0xffffUL) || (len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) { if ((len == 0xffff && diff > 0xffffUL) ||
(len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) {
write_more = 1; write_more = 1;
apiflags |= TCP_WRITE_FLAG_MORE; apiflags |= TCP_WRITE_FLAG_MORE;
} else { } else {
@ -1718,13 +1726,14 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
} while (write_more && err == ERR_OK); } while (write_more && err == ERR_OK);
/* if OK or memory error, check available space */ /* if OK or memory error, check available space */
if ((err == ERR_OK) || (err == ERR_MEM)) { if ((err == ERR_OK) || (err == ERR_MEM)) {
err_mem: err_mem:
if (dontblock && (conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len)) { if (dontblock && (conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len)) {
/* non-blocking write did not write everything: mark the pcb non-writable /* non-blocking write did not write everything: mark the pcb non-writable
and let poll_tcp check writable space to mark the pcb writable again */ and let poll_tcp check writable space to mark the pcb writable again */
API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0); API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0);
conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
} else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
(tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
/* The queued byte- or pbuf-count exceeds the configured low-water limit, /* The queued byte- or pbuf-count exceeds the configured low-water limit,
let select mark this pcb as non-writable. */ let select mark this pcb as non-writable. */
API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0); API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0);
@ -1826,7 +1835,7 @@ lwip_netconn_do_write(void *m)
LOCK_TCPIP_CORE(); LOCK_TCPIP_CORE();
LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE); LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE);
} }
#else /* LWIP_TCPIP_CORE_LOCKING */ #else /* LWIP_TCPIP_CORE_LOCKING */
lwip_netconn_do_writemore(msg->conn); lwip_netconn_do_writemore(msg->conn);
#endif /* LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_TCPIP_CORE_LOCKING */
/* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG /* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG
@ -1835,7 +1844,7 @@ lwip_netconn_do_write(void *m)
} else { } else {
err = ERR_CONN; err = ERR_CONN;
} }
#else /* LWIP_TCP */ #else /* LWIP_TCP */
err = ERR_VAL; err = ERR_VAL;
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
#if (LWIP_UDP || LWIP_RAW) #if (LWIP_UDP || LWIP_RAW)
@ -1861,9 +1870,11 @@ lwip_netconn_do_getaddr(void *m)
if (msg->conn->pcb.ip != NULL) { if (msg->conn->pcb.ip != NULL) {
if (msg->msg.ad.local) { if (msg->msg.ad.local) {
ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->local_ip); ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr),
msg->conn->pcb.ip->local_ip);
} else { } else {
ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->remote_ip); ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr),
msg->conn->pcb.ip->remote_ip);
} }
msg->err = ERR_OK; msg->err = ERR_OK;
@ -1898,8 +1909,7 @@ lwip_netconn_do_getaddr(void *m)
/* pcb is not connected and remote name is requested */ /* pcb is not connected and remote name is requested */
msg->err = ERR_CONN; msg->err = ERR_CONN;
} else { } else {
API_EXPR_DEREF(msg->msg.ad.port) = API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port);
(msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port);
} }
break; break;
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
@ -1929,7 +1939,8 @@ lwip_netconn_do_close(void *m)
enum netconn_state state = msg->conn->state; enum netconn_state state = msg->conn->state;
/* First check if this is a TCP netconn and if it is in a correct state /* First check if this is a TCP netconn and if it is in a correct state
(LISTEN doesn't support half shutdown) */ (LISTEN doesn't support half shutdown) */
if ((msg->conn->pcb.tcp != NULL) && (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) && if ((msg->conn->pcb.tcp != NULL) &&
(NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) &&
((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) { ((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) {
/* Check if we are in a connected state */ /* Check if we are in a connected state */
if (state == NETCONN_CONNECT) { if (state == NETCONN_CONNECT) {
@ -1955,7 +1966,7 @@ lwip_netconn_do_close(void *m)
} }
} }
if (state == NETCONN_NONE) { if (state == NETCONN_NONE) {
#else /* LWIP_NETCONN_FULLDUPLEX */ #else /* LWIP_NETCONN_FULLDUPLEX */
msg->err = ERR_INPROGRESS; msg->err = ERR_INPROGRESS;
} else { } else {
#endif /* LWIP_NETCONN_FULLDUPLEX */ #endif /* LWIP_NETCONN_FULLDUPLEX */
@ -1963,7 +1974,7 @@ lwip_netconn_do_close(void *m)
#if LWIP_NETCONN_FULLDUPLEX #if LWIP_NETCONN_FULLDUPLEX
/* Mark mboxes invalid */ /* Mark mboxes invalid */
netconn_mark_mbox_invalid(msg->conn); netconn_mark_mbox_invalid(msg->conn);
#else /* LWIP_NETCONN_FULLDUPLEX */ #else /* LWIP_NETCONN_FULLDUPLEX */
netconn_drain(msg->conn); netconn_drain(msg->conn);
#endif /* LWIP_NETCONN_FULLDUPLEX */ #endif /* LWIP_NETCONN_FULLDUPLEX */
} }
@ -1978,7 +1989,7 @@ lwip_netconn_do_close(void *m)
LOCK_TCPIP_CORE(); LOCK_TCPIP_CORE();
LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
} }
#else /* LWIP_TCPIP_CORE_LOCKING */ #else /* LWIP_TCPIP_CORE_LOCKING */
lwip_netconn_do_close_internal(msg->conn); lwip_netconn_do_close_internal(msg->conn);
#endif /* LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_TCPIP_CORE_LOCKING */
/* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */ /* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */
@ -2064,18 +2075,22 @@ lwip_netconn_do_join_leave_group_netif(void *m)
#if LWIP_IPV6 && LWIP_IPV6_MLD #if LWIP_IPV6 && LWIP_IPV6_MLD
if (NETCONNTYPE_ISIPV6(msg->conn->type)) { if (NETCONNTYPE_ISIPV6(msg->conn->type)) {
if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
msg->err = mld6_joingroup_netif(netif, ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); msg->err = mld6_joingroup_netif(netif,
ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
} else { } else {
msg->err = mld6_leavegroup_netif(netif, ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); msg->err = mld6_leavegroup_netif(netif,
ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
} }
} else } else
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
{ {
#if LWIP_IGMP #if LWIP_IGMP
if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
msg->err = igmp_joingroup_netif(netif, ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); msg->err = igmp_joingroup_netif(netif,
ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
} else { } else {
msg->err = igmp_leavegroup_netif(netif, ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); msg->err = igmp_leavegroup_netif(netif,
ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
} }
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
} }
@ -2135,8 +2150,8 @@ lwip_netconn_do_gethostbyname(void *arg)
LWIP_DNS_ADDRTYPE_DEFAULT; LWIP_DNS_ADDRTYPE_DEFAULT;
#endif #endif
API_EXPR_DEREF(msg->err) = API_EXPR_DEREF(msg->err) = dns_gethostbyname_addrtype(msg->name,
dns_gethostbyname_addrtype(msg->name, API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype); API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype);
#if LWIP_TCPIP_CORE_LOCKING #if LWIP_TCPIP_CORE_LOCKING
/* For core locking, only block if we need to wait for answer/timeout */ /* For core locking, only block if we need to wait for answer/timeout */
if (API_EXPR_DEREF(msg->err) == ERR_INPROGRESS) { if (API_EXPR_DEREF(msg->err) == ERR_INPROGRESS) {
@ -2145,7 +2160,7 @@ lwip_netconn_do_gethostbyname(void *arg)
LOCK_TCPIP_CORE(); LOCK_TCPIP_CORE();
LWIP_ASSERT("do_gethostbyname still in progress!!", API_EXPR_DEREF(msg->err) != ERR_INPROGRESS); LWIP_ASSERT("do_gethostbyname still in progress!!", API_EXPR_DEREF(msg->err) != ERR_INPROGRESS);
} }
#else /* LWIP_TCPIP_CORE_LOCKING */ #else /* LWIP_TCPIP_CORE_LOCKING */
if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) { if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) {
/* on error or immediate success, wake up the application /* on error or immediate success, wake up the application
* task waiting in netconn_gethostbyname */ * task waiting in netconn_gethostbyname */

View File

@ -44,25 +44,25 @@
#if !NO_SYS #if !NO_SYS
/** Table to quickly map an lwIP error (err_t) to a socket error /** Table to quickly map an lwIP error (err_t) to a socket error
* by using -err as an index */ * by using -err as an index */
static const int err_to_errno_table[] = { static const int err_to_errno_table[] = {
0, /* ERR_OK 0 No error, everything OK. */ 0, /* ERR_OK 0 No error, everything OK. */
ENOMEM, /* ERR_MEM -1 Out of memory error. */ ENOMEM, /* ERR_MEM -1 Out of memory error. */
ENOBUFS, /* ERR_BUF -2 Buffer error. */ ENOBUFS, /* ERR_BUF -2 Buffer error. */
EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
EINVAL, /* ERR_VAL -6 Illegal value. */ EINVAL, /* ERR_VAL -6 Illegal value. */
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
EADDRINUSE, /* ERR_USE -8 Address in use. */ EADDRINUSE, /* ERR_USE -8 Address in use. */
EALREADY, /* ERR_ALREADY -9 Already connecting. */ EALREADY, /* ERR_ALREADY -9 Already connecting. */
EISCONN, /* ERR_ISCONN -10 Conn already established.*/ EISCONN, /* ERR_ISCONN -10 Conn already established.*/
ENOTCONN, /* ERR_CONN -11 Not connected. */ ENOTCONN, /* ERR_CONN -11 Not connected. */
-1, /* ERR_IF -12 Low-level netif error */ -1, /* ERR_IF -12 Low-level netif error */
ECONNABORTED, /* ERR_ABRT -13 Connection aborted. */ ECONNABORTED, /* ERR_ABRT -13 Connection aborted. */
ECONNRESET, /* ERR_RST -14 Connection reset. */ ECONNRESET, /* ERR_RST -14 Connection reset. */
ENOTCONN, /* ERR_CLSD -15 Connection closed. */ ENOTCONN, /* ERR_CLSD -15 Connection closed. */
EIO /* ERR_ARG -16 Illegal argument. */ EIO /* ERR_ARG -16 Illegal argument. */
}; };
int int

View File

@ -67,7 +67,7 @@ lwip_if_indextoname(unsigned int ifindex, char *ifname)
return ifname; return ifname;
} }
} }
#else /* LWIP_NETIF_API */ #else /* LWIP_NETIF_API */
LWIP_UNUSED_ARG(ifindex); LWIP_UNUSED_ARG(ifindex);
LWIP_UNUSED_ARG(ifname); LWIP_UNUSED_ARG(ifname);
#endif /* LWIP_NETIF_API */ #endif /* LWIP_NETIF_API */
@ -93,9 +93,9 @@ lwip_if_nametoindex(const char *ifname)
if (!err) { if (!err) {
return idx; return idx;
} }
#else /* LWIP_NETIF_API */ #else /* LWIP_NETIF_API */
LWIP_UNUSED_ARG(ifname); LWIP_UNUSED_ARG(ifname);
#endif /* LWIP_NETIF_API */ #endif /* LWIP_NETIF_API */
return 0; /* invalid index */ return 0; /* invalid index */
} }

View File

@ -46,8 +46,8 @@
#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ #if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
#include "lwip/memp.h"
#include "lwip/netbuf.h" #include "lwip/netbuf.h"
#include "lwip/memp.h"
#include <string.h> #include <string.h>
@ -59,8 +59,8 @@
* @return a pointer to a new netbuf * @return a pointer to a new netbuf
* NULL on lack of memory * NULL on lack of memory
*/ */
struct netbuf * struct
netbuf_new(void) netbuf *netbuf_new(void)
{ {
struct netbuf *buf; struct netbuf *buf;
@ -111,7 +111,8 @@ netbuf_alloc(struct netbuf *buf, u16_t size)
if (buf->p == NULL) { if (buf->p == NULL) {
return NULL; return NULL;
} }
LWIP_ASSERT("check that first pbuf can hold size", (buf->p->len >= size)); LWIP_ASSERT("check that first pbuf can hold size",
(buf->p->len >= size));
buf->ptr = buf->p; buf->ptr = buf->p;
return buf->p->payload; return buf->p->payload;
} }

View File

@ -39,19 +39,18 @@
#if LWIP_DNS && LWIP_SOCKET #if LWIP_DNS && LWIP_SOCKET
#include "lwip/api.h"
#include "lwip/dns.h"
#include "lwip/err.h" #include "lwip/err.h"
#include "lwip/ip_addr.h"
#include "lwip/mem.h" #include "lwip/mem.h"
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/ip_addr.h"
#include "lwip/api.h"
#include "lwip/dns.h"
#include <stdlib.h> /* atoi */
#include <string.h> /* memset */ #include <string.h> /* memset */
#include <stdlib.h> /* atoi */
/** helper struct for gethostbyname_r to access the char* buffer */ /** helper struct for gethostbyname_r to access the char* buffer */
struct gethostbyname_r_helper struct gethostbyname_r_helper {
{
ip_addr_t *addr_list[2]; ip_addr_t *addr_list[2];
ip_addr_t addr; ip_addr_t addr;
char *aliases; char *aliases;
@ -130,8 +129,7 @@ lwip_gethostbyname(const char *name)
u8_t idx; u8_t idx;
for (idx = 0; s_hostent.h_addr_list[idx]; 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] == %p\n", idx, s_hostent.h_addr_list[idx]));
LWIP_DEBUGF(DNS_DEBUG, LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
} }
} }
#endif /* DNS_DEBUG */ #endif /* DNS_DEBUG */
@ -161,12 +159,8 @@ lwip_gethostbyname(const char *name)
* is stored in *h_errnop instead of h_errno to be thread-safe * is stored in *h_errnop instead of h_errno to be thread-safe
*/ */
int int
lwip_gethostbyname_r(const char *name, lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
struct hostent *ret, size_t buflen, struct hostent **result, int *h_errnop)
char *buf,
size_t buflen,
struct hostent **result,
int *h_errnop)
{ {
err_t err; err_t err;
struct gethostbyname_r_helper *h; struct gethostbyname_r_helper *h;
@ -272,7 +266,8 @@ lwip_freeaddrinfo(struct addrinfo *ai)
* @todo: implement AI_V4MAPPED, AI_ADDRCONFIG * @todo: implement AI_V4MAPPED, AI_ADDRCONFIG
*/ */
int int
lwip_getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) lwip_getaddrinfo(const char *nodename, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{ {
err_t err; err_t err;
ip_addr_t addr; ip_addr_t addr;
@ -300,7 +295,7 @@ lwip_getaddrinfo(const char *nodename, const char *servname, const struct addrin
#if LWIP_IPV6 #if LWIP_IPV6
&& (ai_family != AF_INET6) && (ai_family != AF_INET6)
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
) { ) {
return EAI_FAMILY; return EAI_FAMILY;
} }
} else { } else {
@ -324,7 +319,8 @@ lwip_getaddrinfo(const char *nodename, const char *servname, const struct addrin
return EAI_NONAME; return EAI_NONAME;
} }
#if LWIP_IPV4 && LWIP_IPV6 #if LWIP_IPV4 && LWIP_IPV6
if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) || (IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) { if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) ||
(IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) {
return EAI_NONAME; return EAI_NONAME;
} }
#endif /* LWIP_IPV4 && LWIP_IPV6 */ #endif /* LWIP_IPV4 && LWIP_IPV6 */
@ -363,7 +359,8 @@ lwip_getaddrinfo(const char *nodename, const char *servname, const struct addrin
total_size += namelen + 1; total_size += namelen + 1;
} }
/* If this fails, please report to lwip-devel! :-) */ /* If this fails, please report to lwip-devel! :-) */
LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", total_size <= NETDB_ELEM_SIZE); LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
total_size <= NETDB_ELEM_SIZE);
ai = (struct addrinfo *)memp_malloc(MEMP_NETDB); ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
if (ai == NULL) { if (ai == NULL) {
return EAI_MEMORY; return EAI_MEMORY;

View File

@ -43,16 +43,16 @@
#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ #if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
#include "lwip/etharp.h" #include "lwip/etharp.h"
#include "lwip/memp.h"
#include "lwip/netifapi.h" #include "lwip/netifapi.h"
#include "lwip/memp.h"
#include "lwip/priv/tcpip_priv.h" #include "lwip/priv/tcpip_priv.h"
#include <string.h> /* strncpy */ #include <string.h> /* strncpy */
#define NETIFAPI_VAR_REF(name) API_VAR_REF(name) #define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name) #define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM) #define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name) #define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
/** /**
* Call netif_add() inside the tcpip_thread context. * Call netif_add() inside the tcpip_thread context.
@ -64,15 +64,15 @@ netifapi_do_netif_add(struct tcpip_api_call_data *m)
* We know it works because the structs have been instantiated as struct netifapi_msg */ * We know it works because the structs have been instantiated as struct netifapi_msg */
struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
if (!netif_add(msg->netif, if (!netif_add( msg->netif,
#if LWIP_IPV4 #if LWIP_IPV4
API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.ipaddr),
API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.netmask),
API_EXPR_REF(msg->msg.add.gw), API_EXPR_REF(msg->msg.add.gw),
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
msg->msg.add.state, msg->msg.add.state,
msg->msg.add.init, msg->msg.add.init,
msg->msg.add.input)) { msg->msg.add.input)) {
return ERR_IF; return ERR_IF;
} else { } else {
return ERR_OK; return ERR_OK;
@ -90,15 +90,17 @@ netifapi_do_netif_set_addr(struct tcpip_api_call_data *m)
* We know it works because the structs have been instantiated as struct netifapi_msg */ * We know it works because the structs have been instantiated as struct netifapi_msg */
struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m; struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
netif_set_addr( netif_set_addr( msg->netif,
msg->netif, API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.gw)); API_EXPR_REF(msg->msg.add.ipaddr),
API_EXPR_REF(msg->msg.add.netmask),
API_EXPR_REF(msg->msg.add.gw));
return ERR_OK; return ERR_OK;
} }
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
/** /**
* Call netif_name_to_index() inside the tcpip_thread context. * Call netif_name_to_index() inside the tcpip_thread context.
*/ */
static err_t static err_t
netifapi_do_name_to_index(struct tcpip_api_call_data *m) netifapi_do_name_to_index(struct tcpip_api_call_data *m)
{ {
@ -111,8 +113,8 @@ netifapi_do_name_to_index(struct tcpip_api_call_data *m)
} }
/** /**
* Call netif_index_to_name() inside the tcpip_thread context. * Call netif_index_to_name() inside the tcpip_thread context.
*/ */
static err_t static err_t
netifapi_do_index_to_name(struct tcpip_api_call_data *m) netifapi_do_index_to_name(struct tcpip_api_call_data *m)
{ {
@ -219,13 +221,9 @@ netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type)
err_t err_t
netifapi_netif_add(struct netif *netif, netifapi_netif_add(struct netif *netif,
#if LWIP_IPV4 #if LWIP_IPV4
const ip4_addr_t *ipaddr, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
const ip4_addr_t *netmask,
const ip4_addr_t *gw,
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
void *state, void *state, netif_init_fn init, netif_input_fn input)
netif_init_fn init,
netif_input_fn input)
{ {
err_t err; err_t err;
NETIFAPI_VAR_DECLARE(msg); NETIFAPI_VAR_DECLARE(msg);
@ -245,13 +243,13 @@ netifapi_netif_add(struct netif *netif,
NETIFAPI_VAR_REF(msg).netif = netif; NETIFAPI_VAR_REF(msg).netif = netif;
#if LWIP_IPV4 #if LWIP_IPV4
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask); NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw); NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
NETIFAPI_VAR_REF(msg).msg.add.state = state; NETIFAPI_VAR_REF(msg).msg.add.state = state;
NETIFAPI_VAR_REF(msg).msg.add.init = init; NETIFAPI_VAR_REF(msg).msg.add.init = init;
NETIFAPI_VAR_REF(msg).msg.add.input = input; NETIFAPI_VAR_REF(msg).msg.add.input = input;
err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call); err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
NETIFAPI_VAR_FREE(msg); NETIFAPI_VAR_FREE(msg);
return err; return err;
@ -266,7 +264,10 @@ netifapi_netif_add(struct netif *netif,
* @note for params @see netif_set_addr() * @note for params @see netif_set_addr()
*/ */
err_t err_t
netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw) netifapi_netif_set_addr(struct netif *netif,
const ip4_addr_t *ipaddr,
const ip4_addr_t *netmask,
const ip4_addr_t *gw)
{ {
err_t err; err_t err;
NETIFAPI_VAR_DECLARE(msg); NETIFAPI_VAR_DECLARE(msg);
@ -283,9 +284,9 @@ netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4
} }
NETIFAPI_VAR_REF(msg).netif = netif; NETIFAPI_VAR_REF(msg).netif = netif;
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask); NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw); NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call); err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
NETIFAPI_VAR_FREE(msg); NETIFAPI_VAR_FREE(msg);
return err; return err;
@ -299,7 +300,8 @@ netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4
* @note use only for functions where there is only "netif" parameter. * @note use only for functions where there is only "netif" parameter.
*/ */
err_t err_t
netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, netifapi_errt_fn errtfunc) netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
netifapi_errt_fn errtfunc)
{ {
err_t err; err_t err;
NETIFAPI_VAR_DECLARE(msg); NETIFAPI_VAR_DECLARE(msg);
@ -314,13 +316,13 @@ netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, netifapi_e
} }
/** /**
* @ingroup netifapi_netif * @ingroup netifapi_netif
* Call netif_name_to_index() in a thread-safe way by running that function inside the * Call netif_name_to_index() in a thread-safe way by running that function inside the
* tcpip_thread context. * tcpip_thread context.
* *
* @param name the interface name of the netif * @param name the interface name of the netif
* @param idx output index of the found netif * @param idx output index of the found netif
*/ */
err_t err_t
netifapi_netif_name_to_index(const char *name, u8_t *idx) netifapi_netif_name_to_index(const char *name, u8_t *idx)
{ {
@ -345,14 +347,14 @@ netifapi_netif_name_to_index(const char *name, u8_t *idx)
} }
/** /**
* @ingroup netifapi_netif * @ingroup netifapi_netif
* Call netif_index_to_name() in a thread-safe way by running that function inside the * Call netif_index_to_name() in a thread-safe way by running that function inside the
* tcpip_thread context. * tcpip_thread context.
* *
* @param idx the interface index of the netif * @param idx the interface index of the netif
* @param name output name of the found netif, empty '\0' string if netif not found. * @param name output name of the found netif, empty '\0' string if netif not found.
* name should be of at least NETIF_NAMESIZE bytes * name should be of at least NETIF_NAMESIZE bytes
*/ */
err_t err_t
netifapi_netif_index_to_name(u8_t idx, char *name) netifapi_netif_index_to_name(u8_t idx, char *name)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -40,20 +40,20 @@
#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ #if !NO_SYS /* don't build if not configured for use in lwipopts.h */
#include "lwip/etharp.h"
#include "lwip/init.h"
#include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/priv/tcpip_priv.h" #include "lwip/priv/tcpip_priv.h"
#include "lwip/sys.h" #include "lwip/sys.h"
#include "lwip/memp.h"
#include "lwip/mem.h"
#include "lwip/init.h"
#include "lwip/ip.h"
#include "lwip/pbuf.h"
#include "lwip/etharp.h"
#include "netif/ethernet.h" #include "netif/ethernet.h"
#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name) #define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name)
#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name) #define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name)
#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM) #define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM)
#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name) #define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
/* global variables */ /* global variables */
static tcpip_init_done_fn tcpip_init_done; static tcpip_init_done_fn tcpip_init_done;
@ -65,8 +65,7 @@ static sys_mbox_t tcpip_mbox;
sys_mutex_t lock_tcpip_core; sys_mutex_t lock_tcpip_core;
#endif /* LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_TCPIP_CORE_LOCKING */
static void static void tcpip_thread_handle_msg(struct tcpip_msg *msg);
tcpip_thread_handle_msg(struct tcpip_msg *msg);
#if !LWIP_TIMERS #if !LWIP_TIMERS
/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */ /* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */
@ -137,7 +136,7 @@ tcpip_thread(void *arg)
tcpip_init_done(tcpip_init_done_arg); tcpip_init_done(tcpip_init_done_arg);
} }
while (1) { /* MAIN Loop */ while (1) { /* MAIN Loop */
LWIP_TCPIP_THREAD_ALIVE(); LWIP_TCPIP_THREAD_ALIVE();
/* wait for a message, timeouts are processed while waiting */ /* wait for a message, timeouts are processed while waiting */
TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg); TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg);
@ -247,7 +246,7 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
ret = input_fn(p, inp); ret = input_fn(p, inp);
UNLOCK_TCPIP_CORE(); UNLOCK_TCPIP_CORE();
return ret; return ret;
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ #else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
struct tcpip_msg *msg; struct tcpip_msg *msg;
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
@ -421,6 +420,7 @@ tcpip_untimeout(sys_timeout_handler h, void *arg)
} }
#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ #endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
/** /**
* Sends a message to TCPIP thread to call a function. Caller thread blocks on * Sends a message to TCPIP thread to call a function. Caller thread blocks on
* on a provided semaphore, which ist NOT automatically signalled by TCPIP thread, * on a provided semaphore, which ist NOT automatically signalled by TCPIP thread,
@ -442,7 +442,7 @@ tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
fn(apimsg); fn(apimsg);
UNLOCK_TCPIP_CORE(); UNLOCK_TCPIP_CORE();
return ERR_OK; return ERR_OK;
#else /* LWIP_TCPIP_CORE_LOCKING */ #else /* LWIP_TCPIP_CORE_LOCKING */
TCPIP_MSG_VAR_DECLARE(msg); TCPIP_MSG_VAR_DECLARE(msg);
LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem)); LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
@ -496,7 +496,7 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn; TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn;
#if LWIP_NETCONN_SEM_PER_THREAD #if LWIP_NETCONN_SEM_PER_THREAD
TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET(); TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET();
#else /* LWIP_NETCONN_SEM_PER_THREAD */ #else /* LWIP_NETCONN_SEM_PER_THREAD */
TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem; TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem;
#endif /* LWIP_NETCONN_SEM_PER_THREAD */ #endif /* LWIP_NETCONN_SEM_PER_THREAD */
sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg)); sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg));
@ -519,7 +519,7 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
* e.g. the message is allocated once and posted several times from an IRQ * e.g. the message is allocated once and posted several times from an IRQ
* using tcpip_callbackmsg_trycallback(). * using tcpip_callbackmsg_trycallback().
* Example usage: Trigger execution of an ethernet IRQ DPC routine in lwIP thread context. * Example usage: Trigger execution of an ethernet IRQ DPC routine in lwIP thread context.
* *
* @param function the function to call * @param function the function to call
* @param ctx parameter passed to function * @param ctx parameter passed to function
* @return a struct pointer to pass to tcpip_callbackmsg_trycallback(). * @return a struct pointer to pass to tcpip_callbackmsg_trycallback().

View File

@ -62,10 +62,10 @@
#include "lwip/mem.h" #include "lwip/mem.h"
/* #include "lwip/udp.h" */ /* #include "lwip/udp.h" */
#include "lwip/autoip.h"
#include "lwip/etharp.h"
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/autoip.h"
#include "lwip/etharp.h"
#include "lwip/prot/autoip.h" #include "lwip/prot/autoip.h"
#include <string.h> #include <string.h>
@ -73,10 +73,11 @@
/** Pseudo random macro based on netif informations. /** Pseudo random macro based on netif informations.
* You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */ * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
#ifndef LWIP_AUTOIP_RAND #ifndef LWIP_AUTOIP_RAND
#define LWIP_AUTOIP_RAND(netif) \ #define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
((((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
(netif_autoip_data(netif) ? netif_autoip_data(netif)->tried_llipaddr : 0)) ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
(netif_autoip_data(netif)? netif_autoip_data(netif)->tried_llipaddr : 0))
#endif /* LWIP_AUTOIP_RAND */ #endif /* LWIP_AUTOIP_RAND */
/** /**
@ -84,15 +85,14 @@
* If you want to override this, define it to something else in lwipopts.h. * If you want to override this, define it to something else in lwipopts.h.
*/ */
#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR #ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ #define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */ #endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
/* static functions */ /* static functions */
static err_t static err_t autoip_arp_announce(struct netif *netif);
autoip_arp_announce(struct netif *netif); static void autoip_start_probing(struct netif *netif);
static void
autoip_start_probing(struct netif *netif);
/** /**
* @ingroup autoip * @ingroup autoip
@ -108,7 +108,8 @@ autoip_set_struct(struct netif *netif, struct autoip *autoip)
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
LWIP_ASSERT("netif != NULL", netif != NULL); LWIP_ASSERT("netif != NULL", netif != NULL);
LWIP_ASSERT("autoip != NULL", autoip != NULL); LWIP_ASSERT("autoip != NULL", autoip != NULL);
LWIP_ASSERT("netif already has a struct autoip set", netif_autoip_data(netif) == NULL); LWIP_ASSERT("netif already has a struct autoip set",
netif_autoip_data(netif) == NULL);
/* clear data structure */ /* clear data structure */
memset(autoip, 0, sizeof(struct autoip)); memset(autoip, 0, sizeof(struct autoip));
@ -184,16 +185,14 @@ autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr)
if (addr > AUTOIP_RANGE_END) { if (addr > AUTOIP_RANGE_END) {
addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
} }
LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && (addr <= AUTOIP_RANGE_END)); LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
(addr <= AUTOIP_RANGE_END));
ip4_addr_set_u32(ipaddr, lwip_htonl(addr)); ip4_addr_set_u32(ipaddr, lwip_htonl(addr));
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_create_addr(): tried_llipaddr=%" U16_F ", %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
(u16_t)(autoip->tried_llipaddr), (u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
ip4_addr1_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
ip4_addr2_16(ipaddr),
ip4_addr3_16(ipaddr),
ip4_addr4_16(ipaddr)));
} }
/** /**
@ -232,15 +231,10 @@ autoip_bind(struct netif *netif)
ip4_addr_t sn_mask, gw_addr; ip4_addr_t sn_mask, gw_addr;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_bind(netif=%p) %c%c%" U16_F " %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
(void *)netif, (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
netif->name[0], ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
netif->name[1], ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
(u16_t)netif->num,
ip4_addr1_16(&autoip->llipaddr),
ip4_addr2_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr),
ip4_addr4_16(&autoip->llipaddr)));
IP4_ADDR(&sn_mask, 255, 255, 0, 0); IP4_ADDR(&sn_mask, 255, 255, 0, 0);
IP4_ADDR(&gw_addr, 0, 0, 0, 0); IP4_ADDR(&gw_addr, 0, 0, 0, 0);
@ -271,15 +265,17 @@ autoip_start(struct netif *netif)
*/ */
netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
LWIP_DEBUGF( LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0],
("autoip_start(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); netif->name[1], (u16_t)netif->num));
if (autoip == NULL) { if (autoip == NULL) {
/* no AutoIP client attached yet? */ /* no AutoIP client attached yet? */
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): starting new AUTOIP client\n")); LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_start(): starting new AUTOIP client\n"));
autoip = (struct autoip *)mem_calloc(1, sizeof(struct autoip)); autoip = (struct autoip *)mem_calloc(1, sizeof(struct autoip));
if (autoip == NULL) { if (autoip == NULL) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): could not allocate autoip\n")); LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_start(): could not allocate autoip\n"));
return ERR_MEM; return ERR_MEM;
} }
/* store this AutoIP client in the netif */ /* store this AutoIP client in the netif */
@ -307,11 +303,9 @@ autoip_start_probing(struct netif *netif)
autoip->state = AUTOIP_STATE_PROBING; autoip->state = AUTOIP_STATE_PROBING;
autoip->sent_num = 0; autoip->sent_num = 0;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_start_probing(): changing state to PROBING: %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&autoip->llipaddr), ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
ip4_addr2_16(&autoip->llipaddr), ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
ip4_addr3_16(&autoip->llipaddr),
ip4_addr4_16(&autoip->llipaddr)));
/* time to wait to first probe, this is randomly /* time to wait to first probe, this is randomly
* chosen out of 0 to PROBE_WAIT seconds. * chosen out of 0 to PROBE_WAIT seconds.
@ -374,8 +368,7 @@ autoip_tmr(void)
{ {
struct netif *netif; struct netif *netif;
/* loop through netif's */ /* loop through netif's */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
struct autoip *autoip = netif_autoip_data(netif); struct autoip *autoip = netif_autoip_data(netif);
/* only act on AutoIP configured interfaces */ /* only act on AutoIP configured interfaces */
if (autoip != NULL) { if (autoip != NULL) {
@ -384,7 +377,8 @@ autoip_tmr(void)
} }
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() AutoIP-State: %" U16_F ", ttw=%" U16_F "\n", (u16_t)(autoip->state), autoip->ttw)); ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
(u16_t)(autoip->state), autoip->ttw));
if (autoip->ttw > 0) { if (autoip->ttw > 0) {
autoip->ttw--; autoip->ttw--;
@ -402,11 +396,9 @@ autoip_tmr(void)
autoip->sent_num = 1; autoip->sent_num = 1;
autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_tmr(): changing state to ANNOUNCING: %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&autoip->llipaddr), ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
ip4_addr2_16(&autoip->llipaddr), ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
ip4_addr3_16(&autoip->llipaddr),
ip4_addr4_16(&autoip->llipaddr)));
} else { } else {
autoip_arp_probe(netif); autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n")); LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n"));
@ -416,7 +408,8 @@ autoip_tmr(void)
autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
} else { } else {
/* calculate time to wait to next probe */ /* calculate time to wait to next probe */
autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND)) + autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
PROBE_MIN * AUTOIP_TICKS_PER_SECOND); PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
} }
} }
@ -435,11 +428,9 @@ autoip_tmr(void)
autoip->sent_num = 0; autoip->sent_num = 0;
autoip->ttw = 0; autoip->ttw = 0;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_tmr(): changing state to BOUND: %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&autoip->llipaddr), ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
ip4_addr2_16(&autoip->llipaddr), ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
ip4_addr3_16(&autoip->llipaddr),
ip4_addr4_16(&autoip->llipaddr)));
} }
} }
break; break;
@ -488,7 +479,8 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
* ip.dst == llipaddr && hw.src != own hwaddr * ip.dst == llipaddr && hw.src != own hwaddr
*/ */
if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) || if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) ||
(ip4_addr_isany_val(sipaddr) && ip4_addr_cmp(&dipaddr, &autoip->llipaddr) && (ip4_addr_isany_val(sipaddr) &&
ip4_addr_cmp(&dipaddr, &autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr))) { !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Probe Conflict detected\n")); ("autoip_arp_reply(): Probe Conflict detected\n"));
@ -499,7 +491,8 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
* in any state we have a conflict if * in any state we have a conflict if
* ip.src == llipaddr && hw.src != own hwaddr * ip.src == llipaddr && hw.src != own hwaddr
*/ */
if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) && !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) { if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Conflicting ARP-Packet detected\n")); ("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
autoip_handle_arp_conflict(netif); autoip_handle_arp_conflict(netif);

View File

@ -67,18 +67,18 @@
#if LWIP_IPV4 && LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ #if LWIP_IPV4 && LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/autoip.h" #include "lwip/stats.h"
#include "lwip/mem.h"
#include "lwip/udp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/def.h" #include "lwip/def.h"
#include "lwip/dhcp.h" #include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "lwip/etharp.h" #include "lwip/etharp.h"
#include "lwip/ip_addr.h"
#include "lwip/mem.h"
#include "lwip/netif.h"
#include "lwip/prot/dhcp.h" #include "lwip/prot/dhcp.h"
#include "lwip/prot/iana.h" #include "lwip/prot/iana.h"
#include "lwip/stats.h"
#include "lwip/udp.h"
#include <string.h> #include <string.h>
@ -89,17 +89,14 @@
#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr) #define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr)
#endif #endif
#ifndef LWIP_HOOK_DHCP_PARSE_OPTION #ifndef LWIP_HOOK_DHCP_PARSE_OPTION
#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \ #define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0)
do { \
LWIP_UNUSED_ARG(msg); \
} while (0)
#endif #endif
/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using /** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using
* LWIP_RAND() (this overrides DHCP_GLOBAL_XID) * LWIP_RAND() (this overrides DHCP_GLOBAL_XID)
*/ */
#ifndef DHCP_CREATE_RAND_XID #ifndef DHCP_CREATE_RAND_XID
#define DHCP_CREATE_RAND_XID 1 #define DHCP_CREATE_RAND_XID 1
#endif #endif
/** Default for DHCP_GLOBAL_XID is 0xABCD0000 /** Default for DHCP_GLOBAL_XID is 0xABCD0000
@ -113,12 +110,12 @@
/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU /** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU
* MTU is checked to be big enough in dhcp_start */ * MTU is checked to be big enough in dhcp_start */
#define DHCP_MAX_MSG_LEN(netif) (netif->mtu) #define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576 #define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
/** Minimum length for reply before packet is parsed */ /** Minimum length for reply before packet is parsed */
#define DHCP_MIN_REPLY_LEN 44 #define DHCP_MIN_REPLY_LEN 44
#define REBOOT_TRIES 2 #define REBOOT_TRIES 2
#if LWIP_DNS && LWIP_DHCP_MAX_DNS_SERVERS #if LWIP_DNS && LWIP_DHCP_MAX_DNS_SERVERS
#if DNS_MAX_SERVERS > LWIP_DHCP_MAX_DNS_SERVERS #if DNS_MAX_SERVERS > LWIP_DHCP_MAX_DNS_SERVERS
@ -135,8 +132,7 @@
* This might be moved into the struct dhcp (not necessarily since * This might be moved into the struct dhcp (not necessarily since
* lwIP is single-threaded and the array is only used while in recv * lwIP is single-threaded and the array is only used while in recv
* callback). */ * callback). */
enum dhcp_option_idx enum dhcp_option_idx {
{
DHCP_OPTION_IDX_OVERLOAD = 0, DHCP_OPTION_IDX_OVERLOAD = 0,
DHCP_OPTION_IDX_MSG_TYPE, DHCP_OPTION_IDX_MSG_TYPE,
DHCP_OPTION_IDX_SERVER_ID, DHCP_OPTION_IDX_SERVER_ID,
@ -162,18 +158,17 @@ u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
/** Holds a flag which option was received and is contained in dhcp_rx_options_val, /** Holds a flag which option was received and is contained in dhcp_rx_options_val,
only valid while in dhcp_recv. only valid while in dhcp_recv.
@todo: move this into struct dhcp? */ @todo: move this into struct dhcp? */
u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
static u8_t dhcp_discover_request_options[] = { DHCP_OPTION_SUBNET_MASK, static u8_t dhcp_discover_request_options[] = {
DHCP_OPTION_ROUTER, DHCP_OPTION_SUBNET_MASK,
DHCP_OPTION_BROADCAST DHCP_OPTION_ROUTER,
DHCP_OPTION_BROADCAST
#if LWIP_DHCP_PROVIDE_DNS_SERVERS #if LWIP_DHCP_PROVIDE_DNS_SERVERS
, , DHCP_OPTION_DNS_SERVER
DHCP_OPTION_DNS_SERVER
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
#if LWIP_DHCP_GET_NTP_SRV #if LWIP_DHCP_GET_NTP_SRV
, , DHCP_OPTION_NTP
DHCP_OPTION_NTP
#endif /* LWIP_DHCP_GET_NTP_SRV */ #endif /* LWIP_DHCP_GET_NTP_SRV */
}; };
@ -182,67 +177,49 @@ static u32_t xid;
static u8_t xid_initialised; static u8_t xid_initialised;
#endif /* DHCP_GLOBAL_XID */ #endif /* DHCP_GLOBAL_XID */
#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0) #define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0)
#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1) #define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1)
#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0) #define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0)
#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given))) #define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx]) #define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx])
#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val)) #define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val))
static struct udp_pcb *dhcp_pcb; static struct udp_pcb *dhcp_pcb;
static u8_t dhcp_pcb_refcount; static u8_t dhcp_pcb_refcount;
/* DHCP client state machine functions */ /* DHCP client state machine functions */
static err_t static err_t dhcp_discover(struct netif *netif);
dhcp_discover(struct netif *netif); static err_t dhcp_select(struct netif *netif);
static err_t static void dhcp_bind(struct netif *netif);
dhcp_select(struct netif *netif);
static void
dhcp_bind(struct netif *netif);
#if DHCP_DOES_ARP_CHECK #if DHCP_DOES_ARP_CHECK
static err_t static err_t dhcp_decline(struct netif *netif);
dhcp_decline(struct netif *netif);
#endif /* DHCP_DOES_ARP_CHECK */ #endif /* DHCP_DOES_ARP_CHECK */
static err_t static err_t dhcp_rebind(struct netif *netif);
dhcp_rebind(struct netif *netif); static err_t dhcp_reboot(struct netif *netif);
static err_t static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
dhcp_reboot(struct netif *netif);
static void
dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
/* receive, unfold, parse and free incoming messages */ /* receive, unfold, parse and free incoming messages */
static void static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
/* set the DHCP timers */ /* set the DHCP timers */
static void static void dhcp_timeout(struct netif *netif);
dhcp_timeout(struct netif *netif); static void dhcp_t1_timeout(struct netif *netif);
static void static void dhcp_t2_timeout(struct netif *netif);
dhcp_t1_timeout(struct netif *netif);
static void
dhcp_t2_timeout(struct netif *netif);
/* build outgoing messages */ /* build outgoing messages */
/* create a DHCP message, fill in common headers */ /* create a DHCP message, fill in common headers */
static struct pbuf * static struct pbuf *dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len);
dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len);
/* add a DHCP option (type, then length in bytes) */ /* add a DHCP option (type, then length in bytes) */
static u16_t static u16_t dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len);
dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len);
/* add option values */ /* add option values */
static u16_t static u16_t dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value);
dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value); static u16_t dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value);
static u16_t static u16_t dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value);
dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value);
static u16_t
dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value);
#if LWIP_NETIF_HOSTNAME #if LWIP_NETIF_HOSTNAME
static u16_t static u16_t dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif);
dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif);
#endif /* LWIP_NETIF_HOSTNAME */ #endif /* LWIP_NETIF_HOSTNAME */
/* always add the DHCP options trailer to end and pad */ /* always add the DHCP options trailer to end and pad */
static void static void dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out);
dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out);
/** Ensure DHCP PCB is allocated and bound */ /** Ensure DHCP PCB is allocated and bound */
static err_t static err_t
@ -301,9 +278,8 @@ dhcp_handle_nak(struct netif *netif)
{ {
struct dhcp *dhcp = netif_dhcp_data(netif); struct dhcp *dhcp = netif_dhcp_data(netif);
LWIP_DEBUGF( LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n",
DHCP_DEBUG | LWIP_DBG_TRACE, (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
("dhcp_handle_nak(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
/* Change to a defined state - set this before assigning the address /* Change to a defined state - set this before assigning the address
to ensure the callback can use dhcp_supplied_address() */ to ensure the callback can use dhcp_supplied_address() */
dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF); dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
@ -329,8 +305,8 @@ dhcp_check(struct netif *netif)
struct dhcp *dhcp = netif_dhcp_data(netif); struct dhcp *dhcp = netif_dhcp_data(netif);
err_t result; err_t result;
u16_t msecs; u16_t msecs;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], (s16_t)netif->name[1])); (s16_t)netif->name[1]));
dhcp_set_state(dhcp, DHCP_STATE_CHECKING); dhcp_set_state(dhcp, DHCP_STATE_CHECKING);
/* create an ARP query for the offered IP address, expecting that no host /* create an ARP query for the offered IP address, expecting that no host
responds, as the IP address should not be in use. */ responds, as the IP address should not be in use. */
@ -343,8 +319,7 @@ dhcp_check(struct netif *netif)
} }
msecs = 500; msecs = 500;
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
("dhcp_check(): set request timeout %" U16_F " msecs\n", msecs));
} }
#endif /* DHCP_DOES_ARP_CHECK */ #endif /* DHCP_DOES_ARP_CHECK */
@ -358,20 +333,19 @@ dhcp_handle_offer(struct netif *netif, struct dhcp_msg *msg_in)
{ {
struct dhcp *dhcp = netif_dhcp_data(netif); struct dhcp *dhcp = netif_dhcp_data(netif);
LWIP_DEBUGF( LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n",
DHCP_DEBUG | LWIP_DBG_TRACE, (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
("dhcp_handle_offer(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
/* obtain the server address */ /* obtain the server address */
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) { if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
dhcp->request_timeout = 0; /* stop timer */ dhcp->request_timeout = 0; /* stop timer */
ip_addr_set_ip4_u32(&dhcp->server_ip_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID))); ip_addr_set_ip4_u32(&dhcp->server_ip_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID)));
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n",
("dhcp_handle_offer(): server 0x%08" X32_F "\n", ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr)))); ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
/* remember offered address */ /* remember offered address */
ip4_addr_copy(dhcp->offered_ip_addr, msg_in->yiaddr); ip4_addr_copy(dhcp->offered_ip_addr, msg_in->yiaddr);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n",
("dhcp_handle_offer(): offer for 0x%08" X32_F "\n", ip4_addr_get_u32(&dhcp->offered_ip_addr))); ip4_addr_get_u32(&dhcp->offered_ip_addr)));
dhcp_select(netif); dhcp_select(netif);
} else { } else {
@ -402,32 +376,24 @@ dhcp_select(struct netif *netif)
dhcp = netif_dhcp_data(netif); dhcp = netif_dhcp_data(netif);
LWIP_ERROR("dhcp_select: dhcp != NULL", (dhcp != NULL), return ERR_VAL;); LWIP_ERROR("dhcp_select: dhcp != NULL", (dhcp != NULL), return ERR_VAL;);
LWIP_DEBUGF( LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
DHCP_DEBUG | LWIP_DBG_TRACE,
("dhcp_select(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
dhcp_set_state(dhcp, DHCP_STATE_REQUESTING); dhcp_set_state(dhcp, DHCP_STATE_REQUESTING);
/* create and initialize the DHCP message header */ /* create and initialize the DHCP message header */
p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len); p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
if (p_out != NULL) { if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
options_out_len = options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
/* MUST request the offered IP address */ /* MUST request the offered IP address */
options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4); options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
options_out_len = options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4); options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4);
options_out_len = dhcp_option_long( options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
options_out_len = dhcp_option(options_out_len, options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
msg_out->options,
DHCP_OPTION_PARAMETER_REQUEST_LIST,
LWIP_ARRAYSIZE(dhcp_discover_request_options));
for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
} }
@ -444,8 +410,7 @@ dhcp_select(struct netif *netif)
pbuf_free(p_out); pbuf_free(p_out);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
} else { } else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n"));
("dhcp_select: could not allocate DHCP request\n"));
result = ERR_MEM; result = ERR_MEM;
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
@ -453,7 +418,7 @@ dhcp_select(struct netif *netif)
} }
msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000); msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %" U16_F " msecs\n", msecs)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
return result; return result;
} }
@ -467,8 +432,7 @@ dhcp_coarse_tmr(void)
struct netif *netif; struct netif *netif;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n"));
/* iterate through all network interfaces */ /* iterate through all network interfaces */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
/* only act on DHCP configured interfaces */ /* only act on DHCP configured interfaces */
struct dhcp *dhcp = netif_dhcp_data(netif); struct dhcp *dhcp = netif_dhcp_data(netif);
if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) { if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) {
@ -505,8 +469,7 @@ dhcp_fine_tmr(void)
{ {
struct netif *netif; struct netif *netif;
/* loop through netif's */ /* loop through netif's */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
struct dhcp *dhcp = netif_dhcp_data(netif); struct dhcp *dhcp = netif_dhcp_data(netif);
/* only act on DHCP configured interfaces */ /* only act on DHCP configured interfaces */
if (dhcp != NULL) { if (dhcp != NULL) {
@ -548,8 +511,7 @@ dhcp_timeout(struct netif *netif)
if (dhcp->tries <= 5) { if (dhcp->tries <= 5) {
dhcp_select(netif); dhcp_select(netif);
} else { } else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
dhcp_release_and_stop(netif); dhcp_release_and_stop(netif);
dhcp_start(netif); dhcp_start(netif);
} }
@ -590,7 +552,8 @@ dhcp_t1_timeout(struct netif *netif)
(dhcp->state == DHCP_STATE_RENEWING)) { (dhcp->state == DHCP_STATE_RENEWING)) {
/* just retry to renew - note that the rebind timer (t2) will /* just retry to renew - note that the rebind timer (t2) will
* eventually time-out if renew tries fail. */ * eventually time-out if renew tries fail. */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t1_timeout(): must renew\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_t1_timeout(): must renew\n"));
/* This slightly different to RFC2131: DHCPREQUEST will be sent from state /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */ DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */
dhcp_renew(netif); dhcp_renew(netif);
@ -615,7 +578,8 @@ dhcp_t2_timeout(struct netif *netif)
if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) || if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
(dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) { (dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) {
/* just retry to rebind */ /* just retry to rebind */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout(): must rebind\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_t2_timeout(): must rebind\n"));
/* This slightly different to RFC2131: DHCPREQUEST will be sent from state /* This slightly different to RFC2131: DHCPREQUEST will be sent from state
DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */ DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */
dhcp_rebind(netif); dhcp_rebind(netif);
@ -745,8 +709,7 @@ dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
* *
* @param netif the netif from which to remove the struct dhcp * @param netif the netif from which to remove the struct dhcp
*/ */
void void dhcp_cleanup(struct netif *netif)
dhcp_cleanup(struct netif *netif)
{ {
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
LWIP_ASSERT("netif != NULL", netif != NULL); LWIP_ASSERT("netif != NULL", netif != NULL);
@ -780,9 +743,7 @@ dhcp_start(struct netif *netif)
LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;); LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
dhcp = netif_dhcp_data(netif); dhcp = netif_dhcp_data(netif);
LWIP_DEBUGF( LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_start(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
/* check MTU of the netif */ /* check MTU of the netif */
if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
@ -831,6 +792,7 @@ dhcp_start(struct netif *netif)
} }
#endif /* LWIP_DHCP_CHECK_LINK_UP */ #endif /* LWIP_DHCP_CHECK_LINK_UP */
/* (re)start the DHCP negotiation */ /* (re)start the DHCP negotiation */
result = dhcp_discover(netif); result = dhcp_discover(netif);
if (result != ERR_OK) { if (result != ERR_OK) {
@ -872,8 +834,7 @@ dhcp_inform(struct netif *netif)
p_out = dhcp_create_msg(netif, &dhcp, DHCP_INFORM, &options_out_len); p_out = dhcp_create_msg(netif, &dhcp, DHCP_INFORM, &options_out_len);
if (p_out != NULL) { if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
options_out_len = options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, &dhcp, DHCP_STATE_INFORMING, msg_out, DHCP_INFORM, &options_out_len); LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, &dhcp, DHCP_STATE_INFORMING, msg_out, DHCP_INFORM, &options_out_len);
@ -885,8 +846,7 @@ dhcp_inform(struct netif *netif)
pbuf_free(p_out); pbuf_free(p_out);
} else { } else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n"));
("dhcp_inform: could not allocate DHCP request\n"));
} }
dhcp_dec_pcb_refcount(); /* delete DHCP PCB if not needed any more */ dhcp_dec_pcb_refcount(); /* delete DHCP PCB if not needed any more */
@ -952,8 +912,8 @@ dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr)
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n"));
/* is a DHCP client doing an ARP check? */ /* is a DHCP client doing an ARP check? */
if ((dhcp != NULL) && (dhcp->state == DHCP_STATE_CHECKING)) { if ((dhcp != NULL) && (dhcp->state == DHCP_STATE_CHECKING)) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n",
("dhcp_arp_reply(): CHECKING, arp reply for 0x%08" X32_F "\n", ip4_addr_get_u32(addr))); ip4_addr_get_u32(addr)));
/* did a host respond with the address we /* did a host respond with the address we
were offered by the DHCP server? */ were offered by the DHCP server? */
if (ip4_addr_cmp(addr, &dhcp->offered_ip_addr)) { if (ip4_addr_cmp(addr, &dhcp->offered_ip_addr)) {
@ -990,8 +950,7 @@ dhcp_decline(struct netif *netif)
if (p_out != NULL) { if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4); options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
options_out_len = options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_BACKING_OFF, msg_out, DHCP_DECLINE, &options_out_len); LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_BACKING_OFF, msg_out, DHCP_DECLINE, &options_out_len);
dhcp_option_trailer(options_out_len, msg_out->options, p_out); dhcp_option_trailer(options_out_len, msg_out->options, p_out);
@ -1010,11 +969,12 @@ dhcp_decline(struct netif *netif)
} }
msecs = 10 * 1000; msecs = 10 * 1000;
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %" U16_F " msecs\n", msecs)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
return result; return result;
} }
#endif /* DHCP_DOES_ARP_CHECK */ #endif /* DHCP_DOES_ARP_CHECK */
/** /**
* Start the DHCP process, discover a DHCP server. * Start the DHCP process, discover a DHCP server.
* *
@ -1040,29 +1000,23 @@ dhcp_discover(struct netif *netif)
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n"));
options_out_len = options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
options_out_len = dhcp_option(options_out_len, options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
msg_out->options,
DHCP_OPTION_PARAMETER_REQUEST_LIST,
LWIP_ARRAYSIZE(dhcp_discover_request_options));
for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
} }
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_SELECTING, msg_out, DHCP_DISCOVER, &options_out_len); LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_SELECTING, msg_out, DHCP_DISCOVER, &options_out_len);
dhcp_option_trailer(options_out_len, msg_out->options, p_out); dhcp_option_trailer(options_out_len, msg_out->options, p_out);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER)\n"));
("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER)\n"));
udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY); udp_sendto_if_src(dhcp_pcb, p_out, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER, netif, IP4_ADDR_ANY);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
pbuf_free(p_out); pbuf_free(p_out);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
} else { } else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n"));
("dhcp_discover: could not allocate DHCP request\n"));
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
dhcp->tries++; dhcp->tries++;
@ -1075,11 +1029,11 @@ dhcp_discover(struct netif *netif)
#endif /* LWIP_DHCP_AUTOIP_COOP */ #endif /* LWIP_DHCP_AUTOIP_COOP */
msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000); msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000);
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
("dhcp_discover(): set request timeout %" U16_F " msecs\n", msecs));
return result; return result;
} }
/** /**
* Bind the interface to the offered IP address. * Bind the interface to the offered IP address.
* *
@ -1094,17 +1048,14 @@ dhcp_bind(struct netif *netif)
LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;);
dhcp = netif_dhcp_data(netif); dhcp = netif_dhcp_data(netif);
LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;);
LWIP_DEBUGF( LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
DHCP_DEBUG | LWIP_DBG_TRACE,
("dhcp_bind(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
/* reset time used of lease */ /* reset time used of lease */
dhcp->lease_used = 0; dhcp->lease_used = 0;
if (dhcp->offered_t0_lease != 0xffffffffUL) { if (dhcp->offered_t0_lease != 0xffffffffUL) {
/* set renewal period timer */ /* set renewal period timer */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease));
("dhcp_bind(): t0 renewal timer %" U32_F " secs\n", dhcp->offered_t0_lease));
timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
if (timeout > 0xffff) { if (timeout > 0xffff) {
timeout = 0xffff; timeout = 0xffff;
@ -1113,15 +1064,13 @@ dhcp_bind(struct netif *netif)
if (dhcp->t0_timeout == 0) { if (dhcp->t0_timeout == 0) {
dhcp->t0_timeout = 1; dhcp->t0_timeout = 1;
} }
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease * 1000));
("dhcp_bind(): set request timeout %" U32_F " msecs\n", dhcp->offered_t0_lease * 1000));
} }
/* temporary DHCP lease? */ /* temporary DHCP lease? */
if (dhcp->offered_t1_renew != 0xffffffffUL) { if (dhcp->offered_t1_renew != 0xffffffffUL) {
/* set renewal period timer */ /* set renewal period timer */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
("dhcp_bind(): t1 renewal timer %" U32_F " secs\n", dhcp->offered_t1_renew));
timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
if (timeout > 0xffff) { if (timeout > 0xffff) {
timeout = 0xffff; timeout = 0xffff;
@ -1130,14 +1079,12 @@ dhcp_bind(struct netif *netif)
if (dhcp->t1_timeout == 0) { if (dhcp->t1_timeout == 0) {
dhcp->t1_timeout = 1; dhcp->t1_timeout = 1;
} }
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew * 1000));
("dhcp_bind(): set request timeout %" U32_F " msecs\n", dhcp->offered_t1_renew * 1000));
dhcp->t1_renew_time = dhcp->t1_timeout; dhcp->t1_renew_time = dhcp->t1_timeout;
} }
/* set renewal period timer */ /* set renewal period timer */
if (dhcp->offered_t2_rebind != 0xffffffffUL) { if (dhcp->offered_t2_rebind != 0xffffffffUL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
("dhcp_bind(): t2 rebind timer %" U32_F " secs\n", dhcp->offered_t2_rebind));
timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS;
if (timeout > 0xffff) { if (timeout > 0xffff) {
timeout = 0xffff; timeout = 0xffff;
@ -1146,8 +1093,7 @@ dhcp_bind(struct netif *netif)
if (dhcp->t2_timeout == 0) { if (dhcp->t2_timeout == 0) {
dhcp->t2_timeout = 1; dhcp->t2_timeout = 1;
} }
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind * 1000));
("dhcp_bind(): set request timeout %" U32_F " msecs\n", dhcp->offered_t2_rebind * 1000));
dhcp->t2_rebind_time = dhcp->t2_timeout; dhcp->t2_rebind_time = dhcp->t2_timeout;
} }
@ -1187,11 +1133,8 @@ dhcp_bind(struct netif *netif)
} }
#endif /* LWIP_DHCP_AUTOIP_COOP */ #endif /* LWIP_DHCP_AUTOIP_COOP */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F" SN: 0x%08"X32_F" GW: 0x%08"X32_F"\n",
("dhcp_bind(): IP: 0x%08" X32_F " SN: 0x%08" X32_F " GW: 0x%08" X32_F "\n", ip4_addr_get_u32(&dhcp->offered_ip_addr), ip4_addr_get_u32(&sn_mask), ip4_addr_get_u32(&gw_addr)));
ip4_addr_get_u32(&dhcp->offered_ip_addr),
ip4_addr_get_u32(&sn_mask),
ip4_addr_get_u32(&gw_addr)));
/* netif is now bound to DHCP leased address - set this before assigning the address /* netif is now bound to DHCP leased address - set this before assigning the address
to ensure the callback can use dhcp_supplied_address() */ to ensure the callback can use dhcp_supplied_address() */
dhcp_set_state(dhcp, DHCP_STATE_BOUND); dhcp_set_state(dhcp, DHCP_STATE_BOUND);
@ -1224,14 +1167,10 @@ dhcp_renew(struct netif *netif)
p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len); p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
if (p_out != NULL) { if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
options_out_len = options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
options_out_len = dhcp_option(options_out_len, options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
msg_out->options,
DHCP_OPTION_PARAMETER_REQUEST_LIST,
LWIP_ARRAYSIZE(dhcp_discover_request_options));
for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
} }
@ -1248,8 +1187,7 @@ dhcp_renew(struct netif *netif)
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n"));
} else { } else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n"));
("dhcp_renew: could not allocate DHCP request\n"));
result = ERR_MEM; result = ERR_MEM;
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
@ -1258,8 +1196,7 @@ dhcp_renew(struct netif *netif)
/* back-off on retries, but to a maximum of 20 seconds */ /* back-off on retries, but to a maximum of 20 seconds */
msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000); msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000);
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs));
("dhcp_renew(): set request timeout %" U16_F " msecs\n", msecs));
return result; return result;
} }
@ -1285,14 +1222,10 @@ dhcp_rebind(struct netif *netif)
p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len); p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
if (p_out != NULL) { if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
options_out_len = options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif)); options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN(netif));
options_out_len = dhcp_option(options_out_len, options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
msg_out->options,
DHCP_OPTION_PARAMETER_REQUEST_LIST,
LWIP_ARRAYSIZE(dhcp_discover_request_options));
for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
} }
@ -1309,8 +1242,7 @@ dhcp_rebind(struct netif *netif)
pbuf_free(p_out); pbuf_free(p_out);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
} else { } else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n"));
("dhcp_rebind: could not allocate DHCP request\n"));
result = ERR_MEM; result = ERR_MEM;
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
@ -1318,8 +1250,7 @@ dhcp_rebind(struct netif *netif)
} }
msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000); msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000);
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs));
("dhcp_rebind(): set request timeout %" U16_F " msecs\n", msecs));
return result; return result;
} }
@ -1345,18 +1276,13 @@ dhcp_reboot(struct netif *netif)
p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len); p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
if (p_out != NULL) { if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
options_out_len = options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN_MIN_REQUIRED); options_out_len = dhcp_option_short(options_out_len, msg_out->options, DHCP_MAX_MSG_LEN_MIN_REQUIRED);
options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4); options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4);
options_out_len = options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr)));
options_out_len = dhcp_option(options_out_len, options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options));
msg_out->options,
DHCP_OPTION_PARAMETER_REQUEST_LIST,
LWIP_ARRAYSIZE(dhcp_discover_request_options));
for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) {
options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]); options_out_len = dhcp_option_byte(options_out_len, msg_out->options, dhcp_discover_request_options[i]);
} }
@ -1373,8 +1299,7 @@ dhcp_reboot(struct netif *netif)
pbuf_free(p_out); pbuf_free(p_out);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
} else { } else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n"));
("dhcp_reboot: could not allocate DHCP request\n"));
result = ERR_MEM; result = ERR_MEM;
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
@ -1382,8 +1307,7 @@ dhcp_reboot(struct netif *netif)
} }
msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000); msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000);
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs));
("dhcp_reboot(): set request timeout %" U16_F " msecs\n", msecs));
return result; return result;
} }
@ -1432,8 +1356,7 @@ dhcp_release_and_stop(struct netif *netif)
if (p_out != NULL) { if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload; struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4); options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_SERVER_ID, 4);
options_out_len = options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr))));
dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr))));
LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, dhcp->state, msg_out, DHCP_RELEASE, &options_out_len); LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, dhcp->state, msg_out, DHCP_RELEASE, &options_out_len);
dhcp_option_trailer(options_out_len, msg_out->options, p_out); dhcp_option_trailer(options_out_len, msg_out->options, p_out);
@ -1442,10 +1365,8 @@ dhcp_release_and_stop(struct netif *netif)
pbuf_free(p_out); pbuf_free(p_out);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n"));
} else { } else {
/* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release /* 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"));
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("dhcp_release: could not allocate DHCP request\n"));
} }
} }
@ -1513,8 +1434,7 @@ dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
static u16_t static u16_t
dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len) dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len)
{ {
LWIP_ASSERT("dhcp_option: options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", LWIP_ASSERT("dhcp_option: options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN);
options[options_out_len++] = option_type; options[options_out_len++] = option_type;
options[options_out_len++] = option_len; options[options_out_len++] = option_len;
return options_out_len; return options_out_len;
@ -1536,7 +1456,7 @@ dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value)
{ {
LWIP_ASSERT("dhcp_option_short: options_out_len + 2 <= DHCP_OPTIONS_LEN", options_out_len + 2U <= DHCP_OPTIONS_LEN); LWIP_ASSERT("dhcp_option_short: options_out_len + 2 <= DHCP_OPTIONS_LEN", options_out_len + 2U <= DHCP_OPTIONS_LEN);
options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8); options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
options[options_out_len++] = (u8_t)(value & 0x00ffU); options[options_out_len++] = (u8_t) (value & 0x00ffU);
return options_out_len; return options_out_len;
} }
@ -1718,18 +1638,10 @@ again:
break; break;
default: default:
decode_len = 0; decode_len = 0;
LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %" U16_F " in options\n", (u16_t)op)); LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op));
LWIP_HOOK_DHCP_PARSE_OPTION(ip_current_netif(), LWIP_HOOK_DHCP_PARSE_OPTION(ip_current_netif(), dhcp, dhcp->state, msg_in,
dhcp, dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) ? (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) : 0,
dhcp->state, op, len, q, val_offset);
msg_in,
dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)
? (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE)
: 0,
op,
len,
q,
val_offset);
break; break;
} }
if (op == DHCP_OPTION_PAD) { if (op == DHCP_OPTION_PAD) {
@ -1743,7 +1655,7 @@ again:
if (decode_len > 0) { if (decode_len > 0) {
u32_t value = 0; u32_t value = 0;
u16_t copy_len; u16_t copy_len;
decode_next: decode_next:
LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX); LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX);
if (!dhcp_option_given(dhcp, decode_idx)) { if (!dhcp_option_given(dhcp, decode_idx)) {
copy_len = LWIP_MIN(decode_len, 4); copy_len = LWIP_MIN(decode_len, 4);
@ -1826,15 +1738,15 @@ again:
if (!file_overloaded) { if (!file_overloaded) {
/* only do this for ACK messages */ /* only do this for ACK messages */
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) && if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK)) (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
/* copy bootp file name, don't care for sname (server hostname) */ /* copy bootp file name, don't care for sname (server hostname) */
if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN - 1, DHCP_FILE_OFS) != (DHCP_FILE_LEN - 1)) { if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS) != (DHCP_FILE_LEN-1)) {
return ERR_BUF; return ERR_BUF;
} }
/* make sure the string is really NULL-terminated */ /* make sure the string is really NULL-terminated */
dhcp->boot_file_name[DHCP_FILE_LEN - 1] = 0; dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
} }
#endif /* LWIP_DHCP_BOOTP_FILE */ #endif /* LWIP_DHCP_BOOTP_FILE */
return ERR_OK; return ERR_OK;
} }
@ -1860,16 +1772,10 @@ dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
LWIP_ASSERT("invalid server address type", IP_IS_V4(addr)); LWIP_ASSERT("invalid server address type", IP_IS_V4(addr));
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void *)p,
("dhcp_recv(pbuf = %p) from DHCP server %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " port %" U16_F "\n", ip4_addr1_16(ip_2_ip4(addr)), ip4_addr2_16(ip_2_ip4(addr)), ip4_addr3_16(ip_2_ip4(addr)), ip4_addr4_16(ip_2_ip4(addr)), port));
(void *)p, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
ip4_addr1_16(ip_2_ip4(addr)), LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
ip4_addr2_16(ip_2_ip4(addr)),
ip4_addr3_16(ip_2_ip4(addr)),
ip4_addr4_16(ip_2_ip4(addr)),
port));
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %" U16_F "\n", p->len));
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %" U16_F "\n", p->tot_len));
/* prevent warnings about unused arguments */ /* prevent warnings about unused arguments */
LWIP_UNUSED_ARG(pcb); LWIP_UNUSED_ARG(pcb);
LWIP_UNUSED_ARG(addr); LWIP_UNUSED_ARG(addr);
@ -1881,28 +1787,22 @@ dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
} }
if (reply_msg->op != DHCP_BOOTREPLY) { if (reply_msg->op != DHCP_BOOTREPLY) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));
("not a DHCP reply message, but type %" U16_F "\n", (u16_t)reply_msg->op));
goto free_pbuf_and_return; goto free_pbuf_and_return;
} }
/* iterate through hardware address and match against DHCP message */ /* iterate through hardware address and match against DHCP message */
for (i = 0; i < netif->hwaddr_len && i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) { for (i = 0; i < netif->hwaddr_len && i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) {
if (netif->hwaddr[i] != reply_msg->chaddr[i]) { if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("netif->hwaddr[%" U16_F "]==%02" X16_F " != reply_msg->chaddr[%" U16_F "]==%02" X16_F "\n", ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n",
(u16_t)i, (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
(u16_t)netif->hwaddr[i],
(u16_t)i,
(u16_t)reply_msg->chaddr[i]));
goto free_pbuf_and_return; goto free_pbuf_and_return;
} }
} }
/* match transaction ID against what we expected */ /* match transaction ID against what we expected */
if (lwip_ntohl(reply_msg->xid) != dhcp->xid) { if (lwip_ntohl(reply_msg->xid) != dhcp->xid) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("transaction id mismatch reply_msg->xid(%" X32_F ")!=dhcp->xid(%" X32_F ")\n", ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n", lwip_ntohl(reply_msg->xid), dhcp->xid));
lwip_ntohl(reply_msg->xid),
dhcp->xid));
goto free_pbuf_and_return; goto free_pbuf_and_return;
} }
/* option fields could be unfold? */ /* option fields could be unfold? */
@ -1949,8 +1849,9 @@ dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
} }
} }
/* received a DHCP_NAK in appropriate state? */ /* received a DHCP_NAK in appropriate state? */
else if ((msg_type == DHCP_NAK) && ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) || else if ((msg_type == DHCP_NAK) &&
(dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING))) { ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) ||
(dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING ))) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));
dhcp_handle_nak(netif); dhcp_handle_nak(netif);
} }
@ -1987,7 +1888,7 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t
* at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */
#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) #if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
static u32_t xid; static u32_t xid;
#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ #else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
static u32_t xid = 0xABCD0000; static u32_t xid = 0xABCD0000;
#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ #endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
#else #else
@ -2000,7 +1901,8 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t
LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return NULL;); LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return NULL;);
p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
if (p_out == NULL) { if (p_out == NULL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_create_msg(): could not allocate pbuf\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("dhcp_create_msg(): could not allocate pbuf\n"));
return NULL; return NULL;
} }
LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg", LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
@ -2012,13 +1914,14 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t
if (dhcp->tries == 0) { if (dhcp->tries == 0) {
#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) #if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
xid = LWIP_RAND(); xid = LWIP_RAND();
#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ #else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
xid++; xid++;
#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ #endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
} }
dhcp->xid = xid; dhcp->xid = xid;
} }
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("transaction id xid(%" X32_F ")\n", xid)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
("transaction id xid(%"X32_F")\n", xid));
msg_out = (struct dhcp_msg *)p_out->payload; msg_out = (struct dhcp_msg *)p_out->payload;
memset(msg_out, 0, sizeof(struct dhcp_msg)); memset(msg_out, 0, sizeof(struct dhcp_msg));
@ -2061,7 +1964,8 @@ dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out)
{ {
options[options_out_len++] = DHCP_OPTION_END; options[options_out_len++] = DHCP_OPTION_END;
/* packet is too small, or not 4 byte aligned? */ /* packet is too small, or not 4 byte aligned? */
while (((options_out_len < DHCP_MIN_OPTIONS_LEN) || (options_out_len & 3)) && (options_out_len < DHCP_OPTIONS_LEN)) { while (((options_out_len < DHCP_MIN_OPTIONS_LEN) || (options_out_len & 3)) &&
(options_out_len < DHCP_OPTIONS_LEN)) {
/* add a fill/padding byte */ /* add a fill/padding byte */
options[options_out_len++] = 0; options[options_out_len++] = 0;
} }

View File

@ -47,12 +47,12 @@
#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */ #if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */
#include "lwip/autoip.h"
#include "lwip/dhcp.h"
#include "lwip/etharp.h" #include "lwip/etharp.h"
#include "lwip/prot/iana.h"
#include "lwip/snmp.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/prot/iana.h"
#include "netif/ethernet.h" #include "netif/ethernet.h"
#include <string.h> #include <string.h>
@ -63,7 +63,7 @@
/** Re-request a used ARP entry 1 minute before it would expire to prevent /** Re-request a used ARP entry 1 minute before it would expire to prevent
* breaking a steadily used connection because the ARP entry timed out. */ * breaking a steadily used connection because the ARP entry timed out. */
#define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30) #define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30)
#define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15) #define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15)
/** the time an ARP entry stays pending after first request, /** the time an ARP entry stays pending after first request,
@ -76,25 +76,22 @@
#define ARP_MAXPENDING 5 #define ARP_MAXPENDING 5
/** ARP states */ /** ARP states */
enum etharp_state enum etharp_state {
{
ETHARP_STATE_EMPTY = 0, ETHARP_STATE_EMPTY = 0,
ETHARP_STATE_PENDING, ETHARP_STATE_PENDING,
ETHARP_STATE_STABLE, ETHARP_STATE_STABLE,
ETHARP_STATE_STABLE_REREQUESTING_1, ETHARP_STATE_STABLE_REREQUESTING_1,
ETHARP_STATE_STABLE_REREQUESTING_2 ETHARP_STATE_STABLE_REREQUESTING_2
#if ETHARP_SUPPORT_STATIC_ENTRIES #if ETHARP_SUPPORT_STATIC_ENTRIES
, , ETHARP_STATE_STATIC
ETHARP_STATE_STATIC
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
}; };
struct etharp_entry struct etharp_entry {
{
#if ARP_QUEUEING #if ARP_QUEUEING
/** Pointer to queue of pending outgoing packets on this ARP entry. */ /** Pointer to queue of pending outgoing packets on this ARP entry. */
struct etharp_q_entry *q; struct etharp_q_entry *q;
#else /* ARP_QUEUEING */ #else /* ARP_QUEUEING */
/** Pointer to a single pending outgoing packet on this ARP entry. */ /** Pointer to a single pending outgoing packet on this ARP entry. */
struct pbuf *q; struct pbuf *q;
#endif /* ARP_QUEUEING */ #endif /* ARP_QUEUEING */
@ -113,39 +110,32 @@ static netif_addr_idx_t etharp_cached_entry;
/** Try hard to create a new entry - we want the IP address to appear in /** Try hard to create a new entry - we want the IP address to appear in
the cache (even if this means removing an active entry or so). */ the cache (even if this means removing an active entry or so). */
#define ETHARP_FLAG_TRY_HARD 1 #define ETHARP_FLAG_TRY_HARD 1
#define ETHARP_FLAG_FIND_ONLY 2 #define ETHARP_FLAG_FIND_ONLY 2
#if ETHARP_SUPPORT_STATIC_ENTRIES #if ETHARP_SUPPORT_STATIC_ENTRIES
#define ETHARP_FLAG_STATIC_ENTRY 4 #define ETHARP_FLAG_STATIC_ENTRY 4
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
#if LWIP_NETIF_HWADDRHINT #if LWIP_NETIF_HWADDRHINT
#define ETHARP_SET_ADDRHINT(netif, addrhint) \ #define ETHARP_SET_ADDRHINT(netif, addrhint) do { if (((netif) != NULL) && ((netif)->hints != NULL)) { \
do { \ (netif)->hints->addr_hint = (addrhint); }} while(0)
if (((netif) != NULL) && ((netif)->hints != NULL)) { \
(netif)->hints->addr_hint = (addrhint); \
} \
} while (0)
#else /* LWIP_NETIF_HWADDRHINT */ #else /* LWIP_NETIF_HWADDRHINT */
#define ETHARP_SET_ADDRHINT(netif, addrhint) (etharp_cached_entry = (addrhint)) #define ETHARP_SET_ADDRHINT(netif, addrhint) (etharp_cached_entry = (addrhint))
#endif /* LWIP_NETIF_HWADDRHINT */ #endif /* LWIP_NETIF_HWADDRHINT */
/* Check for maximum ARP_TABLE_SIZE */ /* Check for maximum ARP_TABLE_SIZE */
#if (ARP_TABLE_SIZE > NETIF_ADDR_IDX_MAX) #if (ARP_TABLE_SIZE > NETIF_ADDR_IDX_MAX)
#error "ARP_TABLE_SIZE must fit in an s16_t, you have to reduce it in your lwipopts.h" #error "ARP_TABLE_SIZE must fit in an s16_t, you have to reduce it in your lwipopts.h"
#endif #endif
static err_t
etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr); static err_t etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr);
static err_t static err_t etharp_raw(struct netif *netif,
etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, const struct eth_addr *ethdst_addr,
const struct eth_addr *ethsrc_addr, const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr,
const struct eth_addr *ethdst_addr, const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr,
const struct eth_addr *hwsrc_addr, const u16_t opcode);
const ip4_addr_t *ipsrc_addr,
const struct eth_addr *hwdst_addr,
const ip4_addr_t *ipdst_addr,
const u16_t opcode);
#if ARP_QUEUEING #if ARP_QUEUEING
/** /**
@ -182,9 +172,7 @@ etharp_free_entry(int i)
/* and empty packet queue */ /* and empty packet queue */
if (arp_table[i].q != NULL) { if (arp_table[i].q != NULL) {
/* remove all queued packets */ /* remove all queued packets */
LWIP_DEBUGF( LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q)));
ETHARP_DEBUG,
("etharp_free_entry: freeing entry %" U16_F ", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q)));
free_etharp_q(arp_table[i].q); free_etharp_q(arp_table[i].q);
arp_table[i].q = NULL; arp_table[i].q = NULL;
} }
@ -218,15 +206,14 @@ etharp_tmr(void)
#if ETHARP_SUPPORT_STATIC_ENTRIES #if ETHARP_SUPPORT_STATIC_ENTRIES
&& (state != ETHARP_STATE_STATIC) && (state != ETHARP_STATE_STATIC)
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
) { ) {
arp_table[i].ctime++; arp_table[i].ctime++;
if ((arp_table[i].ctime >= ARP_MAXAGE) || if ((arp_table[i].ctime >= ARP_MAXAGE) ||
((arp_table[i].state == ETHARP_STATE_PENDING) && (arp_table[i].ctime >= ARP_MAXPENDING))) { ((arp_table[i].state == ETHARP_STATE_PENDING) &&
(arp_table[i].ctime >= ARP_MAXPENDING))) {
/* pending or stable entry has become old! */ /* pending or stable entry has become old! */
LWIP_DEBUGF(ETHARP_DEBUG, LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %d.\n",
("etharp_timer: expired %s entry %d.\n", arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i));
arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending",
i));
/* clean up entries that have just been expired */ /* clean up entries that have just been expired */
etharp_free_entry(i); etharp_free_entry(i);
} else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) { } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
@ -308,7 +295,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
#if ETHARP_TABLE_MATCH_NETIF #if ETHARP_TABLE_MATCH_NETIF
&& ((netif == NULL) || (netif == arp_table[i].netif)) && ((netif == NULL) || (netif == arp_table[i].netif))
#endif /* ETHARP_TABLE_MATCH_NETIF */ #endif /* ETHARP_TABLE_MATCH_NETIF */
) { ) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %d\n", (int)i)); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %d\n", (int)i));
/* found exact IP address match, simply bail out */ /* found exact IP address match, simply bail out */
return i; return i;
@ -322,7 +309,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
age_queue = arp_table[i].ctime; age_queue = arp_table[i].ctime;
} }
} else } else
/* pending without queued packets? */ /* pending without queued packets? */
{ {
if (arp_table[i].ctime >= age_pending) { if (arp_table[i].ctime >= age_pending) {
old_pending = i; old_pending = i;
@ -351,8 +338,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||
/* or no empty entry found and not allowed to recycle? */ /* or no empty entry found and not allowed to recycle? */
((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
return (s16_t)ERR_MEM; return (s16_t)ERR_MEM;
} }
@ -381,16 +367,12 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
} else if (old_pending < ARP_TABLE_SIZE) { } else if (old_pending < ARP_TABLE_SIZE) {
/* recycle oldest pending */ /* recycle oldest pending */
i = old_pending; i = old_pending;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %d (without queue)\n", (int)i));
("etharp_find_entry: selecting oldest pending entry %d (without queue)\n", (int)i));
/* 4) found recyclable pending entry with queued packets? */ /* 4) found recyclable pending entry with queued packets? */
} else if (old_queue < ARP_TABLE_SIZE) { } else if (old_queue < ARP_TABLE_SIZE) {
/* recycle oldest pending (queued packets are free in etharp_free_entry) */ /* recycle oldest pending (queued packets are free in etharp_free_entry) */
i = old_queue; i = old_queue;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %d, freeing packet queue %p\n", (int)i, (void *)(arp_table[i].q)));
("etharp_find_entry: selecting oldest pending entry %d, freeing packet queue %p\n",
(int)i,
(void *)(arp_table[i].q)));
/* no empty or recyclable entries found */ /* no empty or recyclable entries found */
} else { } else {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n"));
@ -403,7 +385,8 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
} }
LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY); LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY",
arp_table[i].state == ETHARP_STATE_EMPTY);
/* IP address given? */ /* IP address given? */
if (ipaddr != NULL) { if (ipaddr != NULL) {
@ -440,23 +423,15 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et
{ {
s16_t i; s16_t i;
LWIP_ASSERT("netif->hwaddr_len == ETH_HWADDR_LEN", netif->hwaddr_len == ETH_HWADDR_LEN); LWIP_ASSERT("netif->hwaddr_len == ETH_HWADDR_LEN", netif->hwaddr_len == ETH_HWADDR_LEN);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
("etharp_update_arp_entry: %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " - %02" X16_F ":%02" X16_F ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
":%02" X16_F ":%02" X16_F ":%02" X16_F ":%02" X16_F "\n", (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2],
ip4_addr1_16(ipaddr), (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5]));
ip4_addr2_16(ipaddr),
ip4_addr3_16(ipaddr),
ip4_addr4_16(ipaddr),
(u16_t)ethaddr->addr[0],
(u16_t)ethaddr->addr[1],
(u16_t)ethaddr->addr[2],
(u16_t)ethaddr->addr[3],
(u16_t)ethaddr->addr[4],
(u16_t)ethaddr->addr[5]));
/* non-unicast address? */ /* non-unicast address? */
if (ip4_addr_isany(ipaddr) || ip4_addr_isbroadcast(ipaddr, netif) || ip4_addr_ismulticast(ipaddr)) { if (ip4_addr_isany(ipaddr) ||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ip4_addr_isbroadcast(ipaddr, netif) ||
("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); ip4_addr_ismulticast(ipaddr)) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
return ERR_ARG; return ERR_ARG;
} }
/* find or create ARP entry */ /* find or create ARP entry */
@ -485,7 +460,7 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et
/* insert in SNMP ARP index tree */ /* insert in SNMP ARP index tree */
mib2_add_arp_entry(netif, &arp_table[i].ipaddr); mib2_add_arp_entry(netif, &arp_table[i].ipaddr);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %" S16_F "\n", i)); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", i));
/* update address */ /* update address */
SMEMCPY(&arp_table[i].ethaddr, ethaddr, ETH_HWADDR_LEN); SMEMCPY(&arp_table[i].ethaddr, ethaddr, ETH_HWADDR_LEN);
/* reset time stamp */ /* reset time stamp */
@ -502,7 +477,7 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et
p = q->p; p = q->p;
/* now queue entry can be freed */ /* now queue entry can be freed */
memp_free(MEMP_ARP_QUEUE, q); memp_free(MEMP_ARP_QUEUE, q);
#else /* ARP_QUEUEING */ #else /* ARP_QUEUEING */
if (arp_table[i].q != NULL) { if (arp_table[i].q != NULL) {
struct pbuf *p = arp_table[i].q; struct pbuf *p = arp_table[i].q;
arp_table[i].q = NULL; arp_table[i].q = NULL;
@ -529,19 +504,10 @@ etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr)
{ {
struct netif *netif; struct netif *netif;
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
("etharp_add_static_entry: %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " - %02" X16_F ":%02" X16_F ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
":%02" X16_F ":%02" X16_F ":%02" X16_F ":%02" X16_F "\n", (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2],
ip4_addr1_16(ipaddr), (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5]));
ip4_addr2_16(ipaddr),
ip4_addr3_16(ipaddr),
ip4_addr4_16(ipaddr),
(u16_t)ethaddr->addr[0],
(u16_t)ethaddr->addr[1],
(u16_t)ethaddr->addr[2],
(u16_t)ethaddr->addr[3],
(u16_t)ethaddr->addr[4],
(u16_t)ethaddr->addr[5]));
netif = ip4_route(ipaddr); netif = ip4_route(ipaddr);
if (netif == NULL) { if (netif == NULL) {
@ -564,12 +530,8 @@ etharp_remove_static_entry(const ip4_addr_t *ipaddr)
{ {
s16_t i; s16_t i;
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
("etharp_remove_static_entry: %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
ip4_addr1_16(ipaddr),
ip4_addr2_16(ipaddr),
ip4_addr3_16(ipaddr),
ip4_addr4_16(ipaddr)));
/* find or create ARP entry */ /* find or create ARP entry */
i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL); i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL);
@ -618,11 +580,13 @@ etharp_cleanup_netif(struct netif *netif)
* @return table index if found, -1 otherwise * @return table index if found, -1 otherwise
*/ */
ssize_t ssize_t
etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr **eth_ret, const ip4_addr_t **ip_ret) etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr,
struct eth_addr **eth_ret, const ip4_addr_t **ip_ret)
{ {
s16_t i; s16_t i;
LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", eth_ret != NULL && ip_ret != NULL); LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
eth_ret != NULL && ip_ret != NULL);
LWIP_UNUSED_ARG(netif); LWIP_UNUSED_ARG(netif);
@ -652,8 +616,8 @@ etharp_get_entry(size_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth
LWIP_ASSERT("eth_ret != NULL", eth_ret != NULL); LWIP_ASSERT("eth_ret != NULL", eth_ret != NULL);
if ((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { if ((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
*ipaddr = &arp_table[i].ipaddr; *ipaddr = &arp_table[i].ipaddr;
*netif = arp_table[i].netif; *netif = arp_table[i].netif;
*eth_ret = &arp_table[i].ethaddr; *eth_ret = &arp_table[i].ethaddr;
return 1; return 1;
} else { } else {
@ -688,15 +652,13 @@ etharp_input(struct pbuf *p, struct netif *netif)
hdr = (struct etharp_hdr *)p->payload; hdr = (struct etharp_hdr *)p->payload;
/* RFC 826 "Packet Reception": */ /* RFC 826 "Packet Reception": */
if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) || (hdr->hwlen != ETH_HWADDR_LEN) || if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) ||
(hdr->protolen != sizeof(ip4_addr_t)) || (hdr->proto != PP_HTONS(ETHTYPE_IP))) { (hdr->hwlen != ETH_HWADDR_LEN) ||
(hdr->protolen != sizeof(ip4_addr_t)) ||
(hdr->proto != PP_HTONS(ETHTYPE_IP))) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%" U16_F ("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
"/%" U16_F "/%" U16_F "/%" U16_F ")\n", hdr->hwtype, (u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen));
hdr->hwtype,
(u16_t)hdr->hwlen,
hdr->proto,
(u16_t)hdr->protolen));
ETHARP_STATS_INC(etharp.proterr); ETHARP_STATS_INC(etharp.proterr);
ETHARP_STATS_INC(etharp.drop); ETHARP_STATS_INC(etharp.drop);
pbuf_free(p); pbuf_free(p);
@ -729,7 +691,8 @@ etharp_input(struct pbuf *p, struct netif *netif)
can result in directly sending the queued packets for this host. can result in directly sending the queued packets for this host.
ARP message not directed to us? ARP message not directed to us?
-> update the source IP address in the cache, if present */ -> update the source IP address in the cache, if present */
etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
/* now act on the message itself */ /* now act on the message itself */
switch (hdr->opcode) { switch (hdr->opcode) {
@ -739,17 +702,14 @@ etharp_input(struct pbuf *p, struct netif *netif)
* reply. In any case, we time-stamp any existing ARP entry, * reply. In any case, we time-stamp any existing ARP entry,
* and possibly send out an IP packet that was queued on it. */ * and possibly send out an IP packet that was queued on it. */
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n")); LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n"));
/* ARP request for our address? */ /* ARP request for our address? */
if (for_us) { if (for_us) {
/* send ARP response */ /* send ARP response */
etharp_raw(netif, etharp_raw(netif,
(struct eth_addr *)netif->hwaddr, (struct eth_addr *)netif->hwaddr, &hdr->shwaddr,
&hdr->shwaddr, (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif),
(struct eth_addr *)netif->hwaddr, &hdr->shwaddr, &sipaddr,
netif_ip4_addr(netif),
&hdr->shwaddr,
&sipaddr,
ARP_REPLY); ARP_REPLY);
/* we are not configured? */ /* we are not configured? */
} else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) { } else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) {
@ -773,8 +733,7 @@ etharp_input(struct pbuf *p, struct netif *netif)
#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ #endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */
break; break;
default: default:
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP unknown opcode type %"S16_F"\n", lwip_htons(hdr->opcode)));
("etharp_input: ARP unknown opcode type %" S16_F "\n", lwip_htons(hdr->opcode)));
ETHARP_STATS_INC(etharp.err); ETHARP_STATS_INC(etharp.err);
break; break;
} }
@ -788,7 +747,8 @@ etharp_input(struct pbuf *p, struct netif *netif)
static err_t static err_t
etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, netif_addr_idx_t arp_idx) etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, netif_addr_idx_t arp_idx)
{ {
LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", arp_table[arp_idx].state >= ETHARP_STATE_STABLE); LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
/* if arp table entry is about to expire: re-request it, /* if arp table entry is about to expire: re-request it,
but only if its state is ETHARP_STATE_STABLE to prevent flooding the but only if its state is ETHARP_STATE_STABLE to prevent flooding the
network with ARP requests if this address is used frequently. */ network with ARP requests if this address is used frequently. */
@ -862,7 +822,8 @@ etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
netif_addr_idx_t i; netif_addr_idx_t i;
/* outside local network? if so, this can neither be a global broadcast nor /* outside local network? if so, this can neither be a global broadcast nor
a subnet broadcast. */ a subnet broadcast. */
if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) && !ip4_addr_islinklocal(ipaddr)) { if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) &&
!ip4_addr_islinklocal(ipaddr)) {
#if LWIP_AUTOIP #if LWIP_AUTOIP
struct ip_hdr *iphdr = LWIP_ALIGNMENT_CAST(struct ip_hdr *, q->payload); struct ip_hdr *iphdr = LWIP_ALIGNMENT_CAST(struct ip_hdr *, q->payload);
/* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with
@ -978,7 +939,9 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
netif_addr_idx_t i; netif_addr_idx_t i;
/* non-unicast address? */ /* non-unicast address? */
if (ip4_addr_isbroadcast(ipaddr, netif) || ip4_addr_ismulticast(ipaddr) || ip4_addr_isany(ipaddr)) { if (ip4_addr_isbroadcast(ipaddr, netif) ||
ip4_addr_ismulticast(ipaddr) ||
ip4_addr_isany(ipaddr)) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
return ERR_ARG; return ERR_ARG;
} }
@ -1008,7 +971,8 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
/* { i is either a STABLE or (new or existing) PENDING entry } */ /* { i is either a STABLE or (new or existing) PENDING entry } */
LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
((arp_table[i].state == ETHARP_STATE_PENDING) || (arp_table[i].state >= ETHARP_STATE_STABLE))); ((arp_table[i].state == ETHARP_STATE_PENDING) ||
(arp_table[i].state >= ETHARP_STATE_STABLE)));
/* do we have a new entry? or an implicit query request? */ /* do we have a new entry? or an implicit query request? */
if (is_new_entry || (q == NULL)) { if (is_new_entry || (q == NULL)) {
@ -1091,33 +1055,27 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
memp_free(MEMP_ARP_QUEUE, old); memp_free(MEMP_ARP_QUEUE, old);
} }
#endif #endif
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, i));
("etharp_query: queued packet %p on ARP entry %" U16_F "\n", (void *)q, i));
result = ERR_OK; result = ERR_OK;
} else { } else {
/* the pool MEMP_ARP_QUEUE is empty */ /* the pool MEMP_ARP_QUEUE is empty */
pbuf_free(p); pbuf_free(p);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
result = ERR_MEM; result = ERR_MEM;
} }
#else /* ARP_QUEUEING */ #else /* ARP_QUEUEING */
/* always queue one packet per ARP request only, freeing a previously queued packet */ /* always queue one packet per ARP request only, freeing a previously queued packet */
if (arp_table[i].q != NULL) { if (arp_table[i].q != NULL) {
LWIP_DEBUGF( LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"U16_F"\n", (void *)q, (u16_t)i));
ETHARP_DEBUG | LWIP_DBG_TRACE,
("etharp_query: dropped previously queued packet %p for ARP entry %" U16_F "\n", (void *)q, (u16_t)i));
pbuf_free(arp_table[i].q); pbuf_free(arp_table[i].q);
} }
arp_table[i].q = p; arp_table[i].q = p;
result = ERR_OK; result = ERR_OK;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, (u16_t)i));
("etharp_query: queued packet %p on ARP entry %" U16_F "\n", (void *)q, (u16_t)i));
#endif /* ARP_QUEUEING */ #endif /* ARP_QUEUEING */
} else { } else {
ETHARP_STATS_INC(etharp.memerr); ETHARP_STATS_INC(etharp.memerr);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
result = ERR_MEM; result = ERR_MEM;
} }
} }
@ -1140,13 +1098,10 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
* any other err_t on failure * any other err_t on failure
*/ */
static err_t static err_t
etharp_raw(struct netif *netif, etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
const struct eth_addr *ethsrc_addr,
const struct eth_addr *ethdst_addr, const struct eth_addr *ethdst_addr,
const struct eth_addr *hwsrc_addr, const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr,
const ip4_addr_t *ipsrc_addr, const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr,
const struct eth_addr *hwdst_addr,
const ip4_addr_t *ipdst_addr,
const u16_t opcode) const u16_t opcode)
{ {
struct pbuf *p; struct pbuf *p;
@ -1164,7 +1119,8 @@ etharp_raw(struct netif *netif,
ETHARP_STATS_INC(etharp.memerr); ETHARP_STATS_INC(etharp.memerr);
return ERR_MEM; return ERR_MEM;
} }
LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", (p->len >= SIZEOF_ETHARP_HDR)); LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
(p->len >= SIZEOF_ETHARP_HDR));
hdr = (struct etharp_hdr *)p->payload; hdr = (struct etharp_hdr *)p->payload;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
@ -1224,14 +1180,9 @@ etharp_raw(struct netif *netif,
static err_t static err_t
etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr) etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr)
{ {
return etharp_raw(netif, return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, hw_dst_addr,
(struct eth_addr *)netif->hwaddr, (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), &ethzero,
hw_dst_addr, ipaddr, ARP_REQUEST);
(struct eth_addr *)netif->hwaddr,
netif_ip4_addr(netif),
&ethzero,
ipaddr,
ARP_REQUEST);
} }
/** /**

View File

@ -43,10 +43,10 @@
#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ #if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/icmp.h" #include "lwip/icmp.h"
#include "lwip/inet_chksum.h" #include "lwip/inet_chksum.h"
#include "lwip/ip.h" #include "lwip/ip.h"
#include "lwip/def.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include <string.h> #include <string.h>
@ -65,8 +65,7 @@
/* The amount of data from the original packet to return in a dest-unreachable */ /* The amount of data from the original packet to return in a dest-unreachable */
#define ICMP_DEST_UNREACH_DATASIZE 8 #define ICMP_DEST_UNREACH_DATASIZE 8
static void static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
/** /**
* Processes ICMP input packets, called from ip_input(). * Processes ICMP input packets, called from ip_input().
@ -95,11 +94,11 @@ icmp_input(struct pbuf *p, struct netif *inp)
iphdr_in = ip4_current_header(); iphdr_in = ip4_current_header();
hlen = IPH_HL_BYTES(iphdr_in); hlen = IPH_HL_BYTES(iphdr_in);
if (hlen < IP_HLEN) { if (hlen < IP_HLEN) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%" S16_F " bytes) received\n", hlen)); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%"S16_F" bytes) received\n", hlen));
goto lenerr; goto lenerr;
} }
if (p->len < sizeof(u16_t) * 2) { if (p->len < sizeof(u16_t) * 2) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%" U16_F " bytes) received\n", p->tot_len)); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
goto lenerr; goto lenerr;
} }
@ -123,7 +122,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
#if LWIP_MULTICAST_PING #if LWIP_MULTICAST_PING
/* For multicast, use address of receiving interface as source address */ /* For multicast, use address of receiving interface as source address */
src = netif_ip4_addr(inp); src = netif_ip4_addr(inp);
#else /* LWIP_MULTICAST_PING */ #else /* LWIP_MULTICAST_PING */
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n")); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n"));
goto icmperr; goto icmperr;
#endif /* LWIP_MULTICAST_PING */ #endif /* LWIP_MULTICAST_PING */
@ -133,7 +132,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
#if LWIP_BROADCAST_PING #if LWIP_BROADCAST_PING
/* For broadcast, use address of receiving interface as source address */ /* For broadcast, use address of receiving interface as source address */
src = netif_ip4_addr(inp); src = netif_ip4_addr(inp);
#else /* LWIP_BROADCAST_PING */ #else /* LWIP_BROADCAST_PING */
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n")); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n"));
goto icmperr; goto icmperr;
#endif /* LWIP_BROADCAST_PING */ #endif /* LWIP_BROADCAST_PING */
@ -144,8 +143,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
goto lenerr; goto lenerr;
} }
#if CHECKSUM_CHECK_ICMP #if CHECKSUM_CHECK_ICMP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) {
{
if (inet_chksum_pbuf(p) != 0) { if (inet_chksum_pbuf(p) != 0) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
pbuf_free(p); pbuf_free(p);
@ -216,8 +214,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
ip4_addr_copy(iphdr->dest, *ip4_current_src_addr()); ip4_addr_copy(iphdr->dest, *ip4_current_src_addr());
ICMPH_TYPE_SET(iecho, ICMP_ER); ICMPH_TYPE_SET(iecho, ICMP_ER);
#if CHECKSUM_GEN_ICMP #if CHECKSUM_GEN_ICMP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) {
{
/* adjust the checksum */ /* adjust the checksum */
if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS((u16_t)(ICMP_ECHO << 8)) + 1); iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS((u16_t)(ICMP_ECHO << 8)) + 1);
@ -226,9 +223,11 @@ icmp_input(struct pbuf *p, struct netif *inp)
} }
} }
#if LWIP_CHECKSUM_CTRL_PER_NETIF #if LWIP_CHECKSUM_CTRL_PER_NETIF
else { iecho->chksum = 0; } else {
iecho->chksum = 0;
}
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#else /* CHECKSUM_GEN_ICMP */ #else /* CHECKSUM_GEN_ICMP */
iecho->chksum = 0; iecho->chksum = 0;
#endif /* CHECKSUM_GEN_ICMP */ #endif /* CHECKSUM_GEN_ICMP */
@ -236,7 +235,9 @@ icmp_input(struct pbuf *p, struct netif *inp)
IPH_TTL_SET(iphdr, ICMP_TTL); IPH_TTL_SET(iphdr, ICMP_TTL);
IPH_CHKSUM_SET(iphdr, 0); IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP #if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen)); } IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen));
}
#endif /* CHECKSUM_GEN_IP */ #endif /* CHECKSUM_GEN_IP */
ICMP_STATS_INC(icmp.xmit); ICMP_STATS_INC(icmp.xmit);
@ -246,7 +247,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
MIB2_STATS_INC(mib2.icmpoutechoreps); MIB2_STATS_INC(mib2.icmpoutechoreps);
/* send an ICMP packet */ /* send an ICMP packet */
ret = ip4_output_if(p, src, LWIP_IP_HDRINCL, ICMP_TTL, 0, IP_PROTO_ICMP, inp); ret = ip4_output_if(p, src, LWIP_IP_HDRINCL,
ICMP_TTL, 0, IP_PROTO_ICMP, inp);
if (ret != ERR_OK) { if (ret != ERR_OK) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret))); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret)));
} }
@ -272,8 +274,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
} else if (type == ICMP_AMR) { } else if (type == ICMP_AMR) {
MIB2_STATS_INC(mib2.icmpinaddrmaskreps); MIB2_STATS_INC(mib2.icmpinaddrmaskreps);
} }
LWIP_DEBUGF(ICMP_DEBUG, LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n",
("icmp_input: ICMP type %" S16_F " code %" S16_F " not supported.\n", (s16_t)type, (s16_t)code)); (s16_t)type, (s16_t)code));
ICMP_STATS_INC(icmp.proterr); ICMP_STATS_INC(icmp.proterr);
ICMP_STATS_INC(icmp.drop); ICMP_STATS_INC(icmp.drop);
} }
@ -348,7 +350,8 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
MIB2_STATS_INC(mib2.icmpoutmsgs); MIB2_STATS_INC(mib2.icmpoutmsgs);
/* ICMP header + IP header + 8 bytes of data */ /* 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); q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
PBUF_RAM);
if (q == NULL) { if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
MIB2_STATS_INC(mib2.icmpouterrors); MIB2_STATS_INC(mib2.icmpouterrors);
@ -371,7 +374,8 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
icmphdr->seqno = 0; icmphdr->seqno = 0;
/* copy fields from original packet */ /* 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); SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
ip4_addr_copy(iphdr_src, iphdr->src); ip4_addr_copy(iphdr_src, iphdr->src);
#ifdef LWIP_HOOK_IP4_ROUTE_SRC #ifdef LWIP_HOOK_IP4_ROUTE_SRC
@ -387,7 +391,9 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
/* calculate checksum */ /* calculate checksum */
icmphdr->chksum = 0; icmphdr->chksum = 0;
#if CHECKSUM_GEN_ICMP #if CHECKSUM_GEN_ICMP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) { icmphdr->chksum = inet_chksum(icmphdr, q->len); } IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) {
icmphdr->chksum = inet_chksum(icmphdr, q->len);
}
#endif #endif
ICMP_STATS_INC(icmp.xmit); ICMP_STATS_INC(icmp.xmit);
ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif); ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif);

View File

@ -39,7 +39,7 @@
* The Swedish Institute of Computer Science and Adam Dunkels * The Swedish Institute of Computer Science and Adam Dunkels
* are specifically granted permission to redistribute this * are specifically granted permission to redistribute this
* source code. * source code.
*/ */
/*------------------------------------------------------------- /*-------------------------------------------------------------
Note 1) Note 1)
@ -70,9 +70,10 @@ Steve Reynolds
* RFC 988 - Host extensions for IP multicasting - V0 * RFC 988 - Host extensions for IP multicasting - V0
* RFC 1054 - Host extensions for IP multicasting - * RFC 1054 - Host extensions for IP multicasting -
* RFC 1112 - Host extensions for IP multicasting - V1 * RFC 1112 - Host extensions for IP multicasting - V1
* RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard)
*the "de facto" standard) RFC 3376 - Internet Group Management Protocol, Version 3 - V3 RFC 4604 - Using * RFC 3376 - Internet Group Management Protocol, Version 3 - V3
*Internet Group Management Protocol Version 3... - V3+ RFC 2113 - IP Router Alert Option - * RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+
* RFC 2113 - IP Router Alert Option -
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
@ -83,35 +84,28 @@ Steve Reynolds
#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ #if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/igmp.h"
#include "lwip/debug.h" #include "lwip/debug.h"
#include "lwip/def.h" #include "lwip/def.h"
#include "lwip/igmp.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/mem.h" #include "lwip/mem.h"
#include "lwip/ip.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/prot/igmp.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include "lwip/prot/igmp.h"
#include <string.h> #include <string.h>
static struct igmp_group * static struct igmp_group *igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr);
igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr); static err_t igmp_remove_group(struct netif *netif, struct igmp_group *group);
static err_t static void igmp_timeout(struct netif *netif, struct igmp_group *group);
igmp_remove_group(struct netif *netif, struct igmp_group *group); static void igmp_start_timer(struct igmp_group *group, u8_t max_time);
static void static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp);
igmp_timeout(struct netif *netif, struct igmp_group *group); static err_t igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif);
static void static void igmp_send(struct netif *netif, struct igmp_group *group, u8_t type);
igmp_start_timer(struct igmp_group *group, u8_t max_time);
static void
igmp_delaying_member(struct igmp_group *group, u8_t maxresp);
static err_t
igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif);
static void
igmp_send(struct netif *netif, struct igmp_group *group, u8_t type);
static ip4_addr_t allsystems; static ip4_addr_t allsystems;
static ip4_addr_t allrouters; static ip4_addr_t allrouters;
/** /**
* Initialize the IGMP module * Initialize the IGMP module
@ -263,15 +257,16 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
if (group != NULL) { if (group != NULL) {
ip4_addr_set(&(group->group_address), addr); ip4_addr_set(&(group->group_address), addr);
group->timer = 0; /* Not running */ group->timer = 0; /* Not running */
group->group_state = IGMP_GROUP_NON_MEMBER; group->group_state = IGMP_GROUP_NON_MEMBER;
group->last_reporter_flag = 0; group->last_reporter_flag = 0;
group->use = 0; group->use = 0;
/* Ensure allsystems group is always first in list */ /* Ensure allsystems group is always first in list */
if (list_head == NULL) { if (list_head == NULL) {
/* this is the first entry in linked list */ /* this is the first entry in linked list */
LWIP_ASSERT("igmp_lookup_group: first group must be allsystems", (ip4_addr_cmp(addr, &allsystems) != 0)); LWIP_ASSERT("igmp_lookup_group: first group must be allsystems",
(ip4_addr_cmp(addr, &allsystems) != 0));
group->next = NULL; group->next = NULL;
netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group); netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group);
} else { } else {
@ -283,8 +278,7 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
} }
} }
LWIP_DEBUGF(IGMP_DEBUG, LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group ? "" : "impossible to ")));
("igmp_lookup_group: %sallocated a new group with address ", (group ? "" : "impossible to ")));
ip4_addr_debug_print(IGMP_DEBUG, addr); ip4_addr_debug_print(IGMP_DEBUG, addr);
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)ifp)); LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)ifp));
@ -328,7 +322,7 @@ igmp_remove_group(struct netif *netif, struct igmp_group *group)
void void
igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest) igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
{ {
struct igmp_msg *igmp; struct igmp_msg *igmp;
struct igmp_group *group; struct igmp_group *group;
struct igmp_group *groupref; struct igmp_group *groupref;
@ -374,15 +368,11 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
/* IGMP_MEMB_QUERY to the "all systems" address ? */ /* IGMP_MEMB_QUERY to the "all systems" address ? */
if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) { if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) {
/* THIS IS THE GENERAL QUERY */ /* THIS IS THE GENERAL QUERY */
LWIP_DEBUGF(IGMP_DEBUG, LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n",
(int)(igmp->igmp_maxresp)));
if (igmp->igmp_maxresp == 0) { if (igmp->igmp_maxresp == 0) {
IGMP_STATS_INC(igmp.rx_v1); IGMP_STATS_INC(igmp.rx_v1);
LWIP_DEBUGF( LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
IGMP_DEBUG,
("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR; igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
} else { } else {
IGMP_STATS_INC(igmp.rx_general); IGMP_STATS_INC(igmp.rx_general);
@ -407,14 +397,12 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
ip4_addr_debug_print_val(IGMP_DEBUG, igmp->igmp_group_address); ip4_addr_debug_print_val(IGMP_DEBUG, igmp->igmp_group_address);
if (ip4_addr_cmp(dest, &allsystems)) { if (ip4_addr_cmp(dest, &allsystems)) {
ip4_addr_t groupaddr; ip4_addr_t groupaddr;
LWIP_DEBUGF(IGMP_DEBUG, LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
(" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
/* we first need to re-look for the group since we used dest last time */ /* we first need to re-look for the group since we used dest last time */
ip4_addr_copy(groupaddr, igmp->igmp_group_address); ip4_addr_copy(groupaddr, igmp->igmp_group_address);
group = igmp_lookfor_group(inp, &groupaddr); group = igmp_lookfor_group(inp, &groupaddr);
} else { } else {
LWIP_DEBUGF(IGMP_DEBUG, LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
(" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
} }
if (group != NULL) { if (group != NULL) {
@ -439,12 +427,8 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
} }
break; break;
default: default:
LWIP_DEBUGF(IGMP_DEBUG, LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n",
("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", igmp->igmp_msgtype, group->group_state, (void *)&group, (void *)inp));
igmp->igmp_msgtype,
group->group_state,
(void *)&group,
(void *)inp));
IGMP_STATS_INC(igmp.proterr); IGMP_STATS_INC(igmp.proterr);
break; break;
} }
@ -471,12 +455,10 @@ igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
/* make sure it is multicast address */ /* make sure it is multicast address */
LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR( LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
"igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* loop through netif's */ /* loop through netif's */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
/* Should we join this interface ? */ /* Should we join this interface ? */
if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) { if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
err = igmp_joingroup_netif(netif, groupaddr); err = igmp_joingroup_netif(netif, groupaddr);
@ -507,15 +489,11 @@ igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
/* make sure it is multicast address */ /* make sure it is multicast address */
LWIP_ERROR( LWIP_ERROR("igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
"igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); LWIP_ERROR("igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
LWIP_ERROR("igmp_joingroup_netif: attempt to join allsystems address",
(!ip4_addr_cmp(groupaddr, &allsystems)),
return ERR_VAL;);
/* make sure it is an igmp-enabled netif */ /* make sure it is an igmp-enabled netif */
LWIP_ERROR( LWIP_ERROR("igmp_joingroup_netif: attempt to join on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
"igmp_joingroup_netif: attempt to join on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
/* find group or create a new one if not found */ /* find group or create a new one if not found */
group = igmp_lookup_group(netif, groupaddr); group = igmp_lookup_group(netif, groupaddr);
@ -573,14 +551,11 @@ igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
/* make sure it is multicast address */ /* make sure it is multicast address */
LWIP_ERROR( LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
"igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
LWIP_ERROR(
"igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* loop through netif's */ /* loop through netif's */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
/* Should we leave this interface ? */ /* Should we leave this interface ? */
if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) { if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
err_t res = igmp_leavegroup_netif(netif, groupaddr); err_t res = igmp_leavegroup_netif(netif, groupaddr);
@ -610,15 +585,11 @@ igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
/* make sure it is multicast address */ /* make sure it is multicast address */
LWIP_ERROR( LWIP_ERROR("igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
"igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); LWIP_ERROR("igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave allsystems address",
(!ip4_addr_cmp(groupaddr, &allsystems)),
return ERR_VAL;);
/* make sure it is an igmp-enabled netif */ /* make sure it is an igmp-enabled netif */
LWIP_ERROR( LWIP_ERROR("igmp_leavegroup_netif: attempt to leave on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
"igmp_leavegroup_netif: attempt to leave on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
/* find group */ /* find group */
group = igmp_lookfor_group(netif, groupaddr); group = igmp_lookfor_group(netif, groupaddr);
@ -671,8 +642,7 @@ igmp_tmr(void)
{ {
struct netif *netif; struct netif *netif;
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
struct igmp_group *group = netif_igmp_data(netif); struct igmp_group *group = netif_igmp_data(netif);
while (group != NULL) { while (group != NULL) {
@ -698,7 +668,8 @@ igmp_timeout(struct netif *netif, struct igmp_group *group)
{ {
/* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group
(unless it is the allsystems group) */ (unless it is the allsystems group) */
if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && (!(ip4_addr_cmp(&(group->group_address), &allsystems)))) { if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
(!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address ")); LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address "));
ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address); ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address);
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)netif)); LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)netif));
@ -722,7 +693,7 @@ igmp_start_timer(struct igmp_group *group, u8_t max_time)
{ {
#ifdef LWIP_RAND #ifdef LWIP_RAND
group->timer = (u16_t)(max_time > 2 ? (LWIP_RAND() % max_time) : 1); group->timer = (u16_t)(max_time > 2 ? (LWIP_RAND() % max_time) : 1);
#else /* LWIP_RAND */ #else /* LWIP_RAND */
/* ATTENTION: use this only if absolutely necessary! */ /* ATTENTION: use this only if absolutely necessary! */
group->timer = max_time / 2; group->timer = max_time / 2;
#endif /* LWIP_RAND */ #endif /* LWIP_RAND */
@ -742,12 +713,14 @@ static void
igmp_delaying_member(struct igmp_group *group, u8_t maxresp) igmp_delaying_member(struct igmp_group *group, u8_t maxresp)
{ {
if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) ||
((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && ((group->timer == 0) || (maxresp < group->timer)))) { ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
((group->timer == 0) || (maxresp < group->timer)))) {
igmp_start_timer(group, maxresp); igmp_start_timer(group, maxresp);
group->group_state = IGMP_GROUP_DELAYING_MEMBER; group->group_state = IGMP_GROUP_DELAYING_MEMBER;
} }
} }
/** /**
* Sends an IP packet on a network interface. This function constructs the IP header * Sends an IP packet on a network interface. This function constructs the IP header
* and calculates the IP header checksum. If the source IP address is NULL, * and calculates the IP header checksum. If the source IP address is NULL,
@ -784,17 +757,18 @@ igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
static void static void
igmp_send(struct netif *netif, struct igmp_group *group, u8_t type) igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
{ {
struct pbuf *p = NULL; struct pbuf *p = NULL;
struct igmp_msg *igmp = NULL; struct igmp_msg *igmp = NULL;
ip4_addr_t src = *IP4_ADDR_ANY4; ip4_addr_t src = *IP4_ADDR_ANY4;
ip4_addr_t *dest = NULL; ip4_addr_t *dest = NULL;
/* IP header + "router alert" option + IGMP header */ /* IP header + "router alert" option + IGMP header */
p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM); p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM);
if (p) { if (p) {
igmp = (struct igmp_msg *)p->payload; igmp = (struct igmp_msg *)p->payload;
LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", (p->len >= sizeof(struct igmp_msg))); LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg",
(p->len >= sizeof(struct igmp_msg)));
ip4_addr_copy(src, *netif_ip4_addr(netif)); ip4_addr_copy(src, *netif_ip4_addr(netif));
if (type == IGMP_V2_MEMB_REPORT) { if (type == IGMP_V2_MEMB_REPORT) {
@ -809,8 +783,8 @@ igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
} }
if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) { if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) {
igmp->igmp_msgtype = type; igmp->igmp_msgtype = type;
igmp->igmp_maxresp = 0; igmp->igmp_maxresp = 0;
igmp->igmp_checksum = 0; igmp->igmp_checksum = 0;
igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN); igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN);

View File

@ -42,20 +42,20 @@
#if LWIP_IPV4 #if LWIP_IPV4
#include "lwip/autoip.h" #include "lwip/ip.h"
#include "lwip/def.h" #include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/ip4_frag.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/icmp.h" #include "lwip/icmp.h"
#include "lwip/igmp.h" #include "lwip/igmp.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/ip4_frag.h"
#include "lwip/mem.h"
#include "lwip/netif.h"
#include "lwip/priv/raw_priv.h" #include "lwip/priv/raw_priv.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/prot/iana.h"
#include "lwip/stats.h"
#include "lwip/udp.h" #include "lwip/udp.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/autoip.h"
#include "lwip/stats.h"
#include "lwip/prot/iana.h"
#include <string.h> #include <string.h>
@ -67,16 +67,16 @@
* generate the IP checksum (in contrast to calculating it on-the-fly). */ * generate the IP checksum (in contrast to calculating it on-the-fly). */
#ifndef LWIP_INLINE_IP_CHKSUM #ifndef LWIP_INLINE_IP_CHKSUM
#if LWIP_CHECKSUM_CTRL_PER_NETIF #if LWIP_CHECKSUM_CTRL_PER_NETIF
#define LWIP_INLINE_IP_CHKSUM 0 #define LWIP_INLINE_IP_CHKSUM 0
#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */ #else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#define LWIP_INLINE_IP_CHKSUM 1 #define LWIP_INLINE_IP_CHKSUM 1
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#endif #endif
#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP #if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
#define CHECKSUM_GEN_IP_INLINE 1 #define CHECKSUM_GEN_IP_INLINE 1
#else #else
#define CHECKSUM_GEN_IP_INLINE 0 #define CHECKSUM_GEN_IP_INLINE 0
#endif #endif
#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) #if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT)
@ -89,8 +89,8 @@
*/ */
#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) #if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT)
/* accept DHCP client port and custom port */ /* accept DHCP client port and custom port */
#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) \ #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT)) \
(((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT)) || (LWIP_IP_ACCEPT_UDP_PORT(port))) || (LWIP_IP_ACCEPT_UDP_PORT(port)))
#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ #elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
/* accept custom port only */ /* accept custom port only */
#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port))
@ -164,8 +164,7 @@ ip4_route(const ip4_addr_t *dest)
#endif /* LWIP_MULTICAST_TX_OPTIONS */ #endif /* LWIP_MULTICAST_TX_OPTIONS */
/* iterate through netifs */ /* iterate through netifs */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
/* is the netif up, does it have a link and a valid address? */ /* is the netif up, does it have a link and a valid address? */
if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
/* network mask matches? */ /* network mask matches? */
@ -189,8 +188,7 @@ ip4_route(const ip4_addr_t *dest)
return netif_default; return netif_default;
} }
/* default netif is not up, just use any netif for loopback traffic */ /* default netif is not up, just use any netif for loopback traffic */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
if (netif_is_up(netif)) { if (netif_is_up(netif)) {
return netif; return netif;
} }
@ -216,12 +214,8 @@ ip4_route(const ip4_addr_t *dest)
ip4_addr_isany_val(*netif_ip4_addr(netif_default))) { ip4_addr_isany_val(*netif_ip4_addr(netif_default))) {
/* No matching netif found and default netif is not usable. /* No matching netif found and default netif is not usable.
If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */ If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
("ip4_route: No route to %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
ip4_addr1_16(dest),
ip4_addr2_16(dest),
ip4_addr3_16(dest),
ip4_addr4_16(dest)));
IP_STATS_INC(ip.rterr); IP_STATS_INC(ip.rterr);
MIB2_STATS_INC(mib2.ipoutnoroutes); MIB2_STATS_INC(mib2.ipoutnoroutes);
return NULL; return NULL;
@ -294,24 +288,18 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
/* RFC3927 2.7: do not forward link-local addresses */ /* RFC3927 2.7: do not forward link-local addresses */
if (ip4_addr_islinklocal(ip4_current_dest_addr())) { if (ip4_addr_islinklocal(ip4_current_dest_addr())) {
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
("ip4_forward: not forwarding LLA %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
ip4_addr2_16(ip4_current_dest_addr()),
ip4_addr3_16(ip4_current_dest_addr()),
ip4_addr4_16(ip4_current_dest_addr())));
goto return_noroute; goto return_noroute;
} }
/* Find network interface where to forward this IP packet to. */ /* Find network interface where to forward this IP packet to. */
netif = ip4_route_src(ip4_current_src_addr(), ip4_current_dest_addr()); netif = ip4_route_src(ip4_current_src_addr(), ip4_current_dest_addr());
if (netif == NULL) { if (netif == NULL) {
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
("ip4_forward: no forwarding route for %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " found\n", ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
ip4_addr2_16(ip4_current_dest_addr()),
ip4_addr3_16(ip4_current_dest_addr()),
ip4_addr4_16(ip4_current_dest_addr())));
/* @todo: send ICMP_DUR_NET? */ /* @todo: send ICMP_DUR_NET? */
goto return_noroute; goto return_noroute;
} }
@ -345,12 +333,9 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
IPH_CHKSUM_SET(iphdr, (u16_t)(IPH_CHKSUM(iphdr) + PP_HTONS(0x100))); IPH_CHKSUM_SET(iphdr, (u16_t)(IPH_CHKSUM(iphdr) + PP_HTONS(0x100)));
} }
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
("ip4_forward: forwarding packet to %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
ip4_addr2_16(ip4_current_dest_addr()),
ip4_addr3_16(ip4_current_dest_addr()),
ip4_addr4_16(ip4_current_dest_addr())));
IP_STATS_INC(ip.fw); IP_STATS_INC(ip.fw);
MIB2_STATS_INC(mib2.ipforwdatagrams); MIB2_STATS_INC(mib2.ipforwdatagrams);
@ -362,7 +347,7 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
#if IP_FRAG #if IP_FRAG
ip4_frag(p, netif, ip4_current_dest_addr()); ip4_frag(p, netif, ip4_current_dest_addr());
#else /* IP_FRAG */ #else /* IP_FRAG */
/* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */ /* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */
#endif /* IP_FRAG */ #endif /* IP_FRAG */
} else { } else {
@ -385,14 +370,11 @@ return_noroute:
static int static int
ip4_input_accept(struct netif *netif) ip4_input_accept(struct netif *netif)
{ {
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
("ip_input: iphdr->dest 0x%" X32_F " netif->ip_addr 0x%" X32_F " (0x%" X32_F ", 0x%" X32_F ", 0x%" X32_F ip4_addr_get_u32(ip4_current_dest_addr()), ip4_addr_get_u32(netif_ip4_addr(netif)),
")\n", ip4_addr_get_u32(ip4_current_dest_addr()) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
ip4_addr_get_u32(ip4_current_dest_addr()), ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
ip4_addr_get_u32(netif_ip4_addr(netif)), ip4_addr_get_u32(ip4_current_dest_addr()) & ~ip4_addr_get_u32(netif_ip4_netmask(netif))));
ip4_addr_get_u32(ip4_current_dest_addr()) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
ip4_addr_get_u32(ip4_current_dest_addr()) & ~ip4_addr_get_u32(netif_ip4_netmask(netif))));
/* interface is up and configured? */ /* interface is up and configured? */
if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) { if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) {
@ -403,8 +385,9 @@ ip4_input_accept(struct netif *netif)
#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
|| (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK)) || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK))
#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
) { ) {
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n", netif->name[0], netif->name[1])); LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n",
netif->name[0], netif->name[1]));
/* accept on this netif */ /* accept on this netif */
return 1; return 1;
} }
@ -412,7 +395,8 @@ ip4_input_accept(struct netif *netif)
/* connections to link-local addresses must persist after changing /* connections to link-local addresses must persist after changing
the netif's address (RFC3927 ch. 1.9) */ the netif's address (RFC3927 ch. 1.9) */
if (autoip_accept_packet(netif, ip4_current_dest_addr())) { if (autoip_accept_packet(netif, ip4_current_dest_addr())) {
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n", netif->name[0], netif->name[1])); LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n",
netif->name[0], netif->name[1]));
/* accept on this netif */ /* accept on this netif */
return 1; return 1;
} }
@ -457,8 +441,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* identify the IP header */ /* identify the IP header */
iphdr = (struct ip_hdr *)p->payload; iphdr = (struct ip_hdr *)p->payload;
if (IPH_V(iphdr) != 4) { if (IPH_V(iphdr) != 4) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", (u16_t)IPH_V(iphdr)));
("IP packet dropped due to bad version number %" U16_F "\n", (u16_t)IPH_V(iphdr)));
ip4_debug_print(p); ip4_debug_print(p);
pbuf_free(p); pbuf_free(p);
IP_STATS_INC(ip.err); IP_STATS_INC(ip.err);
@ -488,18 +471,17 @@ ip4_input(struct pbuf *p, struct netif *inp)
if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) { if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) {
if (iphdr_hlen < IP_HLEN) { if (iphdr_hlen < IP_HLEN) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("ip4_input: short IP header (%" U16_F " bytes) received, IP packet dropped\n", iphdr_hlen)); ("ip4_input: short IP header (%"U16_F" bytes) received, IP packet dropped\n", iphdr_hlen));
} }
if (iphdr_hlen > p->len) { if (iphdr_hlen > p->len) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IP header (len %" U16_F ") does not fit in first pbuf (len %" U16_F "), IP packet dropped.\n", ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
iphdr_hlen, iphdr_hlen, p->len));
p->len));
} }
if (iphdr_len > p->tot_len) { if (iphdr_len > p->tot_len) {
LWIP_DEBUGF( LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
("IP (len %" U16_F ") is longer than pbuf (len %" U16_F "), IP packet dropped.\n", iphdr_len, p->tot_len)); iphdr_len, p->tot_len));
} }
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
pbuf_free(p); pbuf_free(p);
@ -511,12 +493,11 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* verify checksum */ /* verify checksum */
#if CHECKSUM_CHECK_IP #if CHECKSUM_CHECK_IP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) {
{
if (inet_chksum(iphdr, iphdr_hlen) != 0) { if (inet_chksum(iphdr, iphdr_hlen) != 0) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("Checksum (0x%" X16_F ") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
ip4_debug_print(p); ip4_debug_print(p);
pbuf_free(p); pbuf_free(p);
IP_STATS_INC(ip.chkerr); IP_STATS_INC(ip.chkerr);
@ -538,14 +519,15 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */ /* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */
ip4_addr_t allsystems; ip4_addr_t allsystems;
IP4_ADDR(&allsystems, 224, 0, 0, 1); IP4_ADDR(&allsystems, 224, 0, 0, 1);
if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) && ip4_addr_isany(ip4_current_src_addr())) { if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) &&
ip4_addr_isany(ip4_current_src_addr())) {
check_ip_src = 0; check_ip_src = 0;
} }
netif = inp; netif = inp;
} else { } else {
netif = NULL; netif = NULL;
} }
#else /* LWIP_IGMP */ #else /* LWIP_IGMP */
if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) { if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) {
netif = inp; netif = inp;
} else { } else {
@ -567,8 +549,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
{ {
#if !LWIP_SINGLE_NETIF #if !LWIP_SINGLE_NETIF
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
if (netif == inp) { if (netif == inp) {
/* we checked that before already */ /* we checked that before already */
continue; continue;
@ -596,8 +577,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* remote port is DHCP server? */ /* remote port is DHCP server? */
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
const struct udp_hdr *udphdr = (const struct udp_hdr *)((const u8_t *)iphdr + iphdr_hlen); const struct udp_hdr *udphdr = (const struct udp_hdr *)((const u8_t *)iphdr + iphdr_hlen);
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n",
("ip4_input: UDP packet to DHCP client port %" U16_F "\n", lwip_ntohs(udphdr->dest))); lwip_ntohs(udphdr->dest)));
if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n")); LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n"));
netif = inp; netif = inp;
@ -614,10 +595,11 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
&& !ip4_addr_isany_val(*ip4_current_src_addr()) && !ip4_addr_isany_val(*ip4_current_src_addr())
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
) )
#endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */ #endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */
{ {
if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) || (ip4_addr_ismulticast(ip4_current_src_addr()))) { if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) ||
(ip4_addr_ismulticast(ip4_current_src_addr()))) {
/* packet source is not valid */ /* packet source is not valid */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n")); LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n"));
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
@ -651,14 +633,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* packet consists of multiple fragments? */ /* packet consists of multiple fragments? */
if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
#if IP_REASSEMBLY /* packet fragment reassembly code present? */ #if IP_REASSEMBLY /* packet fragment reassembly code present? */
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip4_reass()\n",
("IP packet is a fragment (id=0x%04" X16_F " tot_len=%" U16_F " len=%" U16_F " MF=%" U16_F lwip_ntohs(IPH_ID(iphdr)), p->tot_len, lwip_ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK) * 8)));
" offset=%" U16_F "), calling ip4_reass()\n",
lwip_ntohs(IPH_ID(iphdr)),
p->tot_len,
lwip_ntohs(IPH_LEN(iphdr)),
(u16_t) !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)),
(u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK) * 8)));
/* reassemble the packet*/ /* reassemble the packet*/
p = ip4_reass(p); p = ip4_reass(p);
/* packet not fully reassembled yet? */ /* packet not fully reassembled yet? */
@ -666,11 +642,10 @@ ip4_input(struct pbuf *p, struct netif *inp)
return ERR_OK; return ERR_OK;
} }
iphdr = (const struct ip_hdr *)p->payload; iphdr = (const struct ip_hdr *)p->payload;
#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
pbuf_free(p); pbuf_free(p);
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
("IP packet dropped since it was fragmented (0x%" X16_F ") (while IP_REASSEMBLY == 0).\n", lwip_ntohs(IPH_OFFSET(iphdr))));
lwip_ntohs(IPH_OFFSET(iphdr))));
IP_STATS_INC(ip.opterr); IP_STATS_INC(ip.opterr);
IP_STATS_INC(ip.drop); IP_STATS_INC(ip.drop);
/* unsupported protocol feature */ /* unsupported protocol feature */
@ -683,12 +658,11 @@ ip4_input(struct pbuf *p, struct netif *inp)
#if LWIP_IGMP #if LWIP_IGMP
/* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
#else #else
if (iphdr_hlen > IP_HLEN) { if (iphdr_hlen > IP_HLEN) {
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
pbuf_free(p); pbuf_free(p);
IP_STATS_INC(ip.opterr); IP_STATS_INC(ip.opterr);
IP_STATS_INC(ip.drop); IP_STATS_INC(ip.drop);
@ -701,7 +675,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
/* send to upper layers */ /* send to upper layers */
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n")); LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n"));
ip4_debug_print(p); ip4_debug_print(p);
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %" U16_F " p->tot_len %" U16_F "\n", p->len, p->tot_len)); LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
ip_data.current_netif = netif; ip_data.current_netif = netif;
ip_data.current_input_netif = inp; ip_data.current_input_netif = inp;
@ -752,14 +726,14 @@ ip4_input(struct pbuf *p, struct netif *inp)
{ {
#if LWIP_ICMP #if LWIP_ICMP
/* send ICMP destination protocol unreachable unless is was a broadcast */ /* send ICMP destination protocol unreachable unless is was a broadcast */
if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) && !ip4_addr_ismulticast(ip4_current_dest_addr())) { if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
!ip4_addr_ismulticast(ip4_current_dest_addr())) {
pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */ pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */
icmp_dest_unreach(p, ICMP_DUR_PROTO); icmp_dest_unreach(p, ICMP_DUR_PROTO);
} }
#endif /* LWIP_ICMP */ #endif /* LWIP_ICMP */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr)));
("Unsupported transport protocol %" U16_F "\n", (u16_t)IPH_PROTO(iphdr)));
IP_STATS_INC(ip.proterr); IP_STATS_INC(ip.proterr);
IP_STATS_INC(ip.drop); IP_STATS_INC(ip.drop);
@ -807,13 +781,9 @@ ip4_input(struct pbuf *p, struct netif *inp)
* unique identifiers independent of destination" * unique identifiers independent of destination"
*/ */
err_t err_t
ip4_output_if(struct pbuf *p, ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
const ip4_addr_t *src, u8_t ttl, u8_t tos,
const ip4_addr_t *dest, u8_t proto, struct netif *netif)
u8_t ttl,
u8_t tos,
u8_t proto,
struct netif *netif)
{ {
#if IP_OPTIONS_SEND #if IP_OPTIONS_SEND
return ip4_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); return ip4_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
@ -826,14 +796,8 @@ ip4_output_if(struct pbuf *p,
* @ param optlen length of ip_options * @ param optlen length of ip_options
*/ */
err_t err_t
ip4_output_if_opt(struct pbuf *p, ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
const ip4_addr_t *src, u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
const ip4_addr_t *dest,
u8_t ttl,
u8_t tos,
u8_t proto,
struct netif *netif,
void *ip_options,
u16_t optlen) u16_t optlen)
{ {
#endif /* IP_OPTIONS_SEND */ #endif /* IP_OPTIONS_SEND */
@ -845,8 +809,9 @@ ip4_output_if_opt(struct pbuf *p,
} }
#if IP_OPTIONS_SEND #if IP_OPTIONS_SEND
return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif, ip_options, optlen); return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif,
#else /* IP_OPTIONS_SEND */ ip_options, optlen);
#else /* IP_OPTIONS_SEND */
return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif); return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif);
#endif /* IP_OPTIONS_SEND */ #endif /* IP_OPTIONS_SEND */
} }
@ -856,13 +821,9 @@ ip4_output_if_opt(struct pbuf *p,
* when it is 'any'. * when it is 'any'.
*/ */
err_t err_t
ip4_output_if_src(struct pbuf *p, ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
const ip4_addr_t *src, u8_t ttl, u8_t tos,
const ip4_addr_t *dest, u8_t proto, struct netif *netif)
u8_t ttl,
u8_t tos,
u8_t proto,
struct netif *netif)
{ {
#if IP_OPTIONS_SEND #if IP_OPTIONS_SEND
return ip4_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0); return ip4_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0);
@ -873,14 +834,8 @@ ip4_output_if_src(struct pbuf *p,
* when it is 'any'. * when it is 'any'.
*/ */
err_t err_t
ip4_output_if_opt_src(struct pbuf *p, ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
const ip4_addr_t *src, u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
const ip4_addr_t *dest,
u8_t ttl,
u8_t tos,
u8_t proto,
struct netif *netif,
void *ip_options,
u16_t optlen) u16_t optlen)
{ {
#endif /* IP_OPTIONS_SEND */ #endif /* IP_OPTIONS_SEND */
@ -943,7 +898,8 @@ ip4_output_if_opt_src(struct pbuf *p,
} }
iphdr = (struct ip_hdr *)p->payload; iphdr = (struct ip_hdr *)p->payload;
LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", (p->len >= sizeof(struct ip_hdr))); LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
(p->len >= sizeof(struct ip_hdr)));
IPH_TTL_SET(iphdr, ttl); IPH_TTL_SET(iphdr, ttl);
IPH_PROTO_SET(iphdr, proto); IPH_PROTO_SET(iphdr, proto);
@ -987,14 +943,20 @@ ip4_output_if_opt_src(struct pbuf *p,
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = (chk_sum >> 16) + chk_sum; chk_sum = (chk_sum >> 16) + chk_sum;
chk_sum = ~chk_sum; chk_sum = ~chk_sum;
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { iphdr->_chksum = (u16_t)chk_sum; /* network order */ } IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
iphdr->_chksum = (u16_t)chk_sum; /* network order */
}
#if LWIP_CHECKSUM_CTRL_PER_NETIF #if LWIP_CHECKSUM_CTRL_PER_NETIF
else { IPH_CHKSUM_SET(iphdr, 0); } else {
IPH_CHKSUM_SET(iphdr, 0);
}
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/ #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
#else /* CHECKSUM_GEN_IP_INLINE */ #else /* CHECKSUM_GEN_IP_INLINE */
IPH_CHKSUM_SET(iphdr, 0); IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP #if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); } IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
}
#endif /* CHECKSUM_GEN_IP */ #endif /* CHECKSUM_GEN_IP */
#endif /* CHECKSUM_GEN_IP_INLINE */ #endif /* CHECKSUM_GEN_IP_INLINE */
} else { } else {
@ -1012,7 +974,7 @@ ip4_output_if_opt_src(struct pbuf *p,
IP_STATS_INC(ip.xmit); IP_STATS_INC(ip.xmit);
LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%" U16_F "\n", netif->name[0], netif->name[1], (u16_t)netif->num)); LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
ip4_debug_print(p); ip4_debug_print(p);
#if ENABLE_LOOPBACK #if ENABLE_LOOPBACK
@ -1020,7 +982,7 @@ ip4_output_if_opt_src(struct pbuf *p,
#if !LWIP_HAVE_LOOPIF #if !LWIP_HAVE_LOOPIF
|| ip4_addr_isloopback(dest) || ip4_addr_isloopback(dest)
#endif /* !LWIP_HAVE_LOOPIF */ #endif /* !LWIP_HAVE_LOOPIF */
) { ) {
/* Packet to self, enqueue it for loopback */ /* Packet to self, enqueue it for loopback */
LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
return netif_loop_output(netif, p); return netif_loop_output(netif, p);
@ -1060,19 +1022,16 @@ ip4_output_if_opt_src(struct pbuf *p,
* see ip_output_if() for more return values * see ip_output_if() for more return values
*/ */
err_t err_t
ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto) ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
u8_t ttl, u8_t tos, u8_t proto)
{ {
struct netif *netif; struct netif *netif;
LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
if ((netif = ip4_route_src(src, dest)) == NULL) { if ((netif = ip4_route_src(src, dest)) == NULL) {
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
("ip4_output: No route to %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
ip4_addr1_16(dest),
ip4_addr2_16(dest),
ip4_addr3_16(dest),
ip4_addr4_16(dest)));
IP_STATS_INC(ip.rterr); IP_STATS_INC(ip.rterr);
return ERR_RTE; return ERR_RTE;
} }
@ -1100,13 +1059,8 @@ ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, u8_t t
* see ip_output_if() for more return values * see ip_output_if() for more return values
*/ */
err_t err_t
ip4_output_hinted(struct pbuf *p, ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
const ip4_addr_t *src, u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint)
const ip4_addr_t *dest,
u8_t ttl,
u8_t tos,
u8_t proto,
struct netif_hint *netif_hint)
{ {
struct netif *netif; struct netif *netif;
err_t err; err_t err;
@ -1114,12 +1068,8 @@ ip4_output_hinted(struct pbuf *p,
LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
if ((netif = ip4_route_src(src, dest)) == NULL) { if ((netif = ip4_route_src(src, dest)) == NULL) {
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
("ip4_output: No route to %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n", ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
ip4_addr1_16(dest),
ip4_addr2_16(dest),
ip4_addr3_16(dest),
ip4_addr4_16(dest)));
IP_STATS_INC(ip.rterr); IP_STATS_INC(ip.rterr);
return ERR_RTE; return ERR_RTE;
} }
@ -1143,40 +1093,35 @@ ip4_debug_print(struct pbuf *p)
LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n",
("|%2" S16_F " |%2" S16_F " | 0x%02" X16_F " | %5" U16_F " | (v, hl, tos, len)\n", (u16_t)IPH_V(iphdr),
(u16_t)IPH_V(iphdr), (u16_t)IPH_HL(iphdr),
(u16_t)IPH_HL(iphdr), (u16_t)IPH_TOS(iphdr),
(u16_t)IPH_TOS(iphdr), lwip_ntohs(IPH_LEN(iphdr))));
lwip_ntohs(IPH_LEN(iphdr))));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n",
("| %5" U16_F " |%" U16_F "%" U16_F "%" U16_F "| %4" U16_F " | (id, flags, offset)\n", lwip_ntohs(IPH_ID(iphdr)),
lwip_ntohs(IPH_ID(iphdr)), (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1),
(u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1), (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1),
(u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1), (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1),
(u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1), (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
(u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n",
("| %3" U16_F " | %3" U16_F " | 0x%04" X16_F " | (ttl, proto, chksum)\n", (u16_t)IPH_TTL(iphdr),
(u16_t)IPH_TTL(iphdr), (u16_t)IPH_PROTO(iphdr),
(u16_t)IPH_PROTO(iphdr), lwip_ntohs(IPH_CHKSUM(iphdr))));
lwip_ntohs(IPH_CHKSUM(iphdr))));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n",
("| %3" U16_F " | %3" U16_F " | %3" U16_F " | %3" U16_F " | (src)\n", ip4_addr1_16_val(iphdr->src),
ip4_addr1_16_val(iphdr->src), ip4_addr2_16_val(iphdr->src),
ip4_addr2_16_val(iphdr->src), ip4_addr3_16_val(iphdr->src),
ip4_addr3_16_val(iphdr->src), ip4_addr4_16_val(iphdr->src)));
ip4_addr4_16_val(iphdr->src)));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP_DEBUG, LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n",
("| %3" U16_F " | %3" U16_F " | %3" U16_F " | %3" U16_F " | (dest)\n", ip4_addr1_16_val(iphdr->dest),
ip4_addr1_16_val(iphdr->dest), ip4_addr2_16_val(iphdr->dest),
ip4_addr2_16_val(iphdr->dest), ip4_addr3_16_val(iphdr->dest),
ip4_addr3_16_val(iphdr->dest), ip4_addr4_16_val(iphdr->dest)));
ip4_addr4_16_val(iphdr->dest)));
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
} }
#endif /* IP_DEBUG */ #endif /* IP_DEBUG */

View File

@ -61,7 +61,8 @@ ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif)
ip4_addr_set_u32(&ipaddr, addr); ip4_addr_set_u32(&ipaddr, addr);
/* all ones (broadcast) or all zeroes (old skool broadcast) */ /* all ones (broadcast) or all zeroes (old skool broadcast) */
if ((~addr == IPADDR_ANY) || (addr == IPADDR_ANY)) { if ((~addr == IPADDR_ANY) ||
(addr == IPADDR_ANY)) {
return 1; return 1;
/* no broadcast support on this network interface? */ /* no broadcast support on this network interface? */
} else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
@ -95,7 +96,7 @@ ip4_addr_netmask_valid(u32_t netmask)
u32_t nm_hostorder = lwip_htonl(netmask); u32_t nm_hostorder = lwip_htonl(netmask);
/* first, check for the first zero */ /* first, check for the first zero */
for (mask = 1UL << 31; mask != 0; mask >>= 1) { for (mask = 1UL << 31 ; mask != 0; mask >>= 1) {
if ((nm_hostorder & mask) == 0) { if ((nm_hostorder & mask) == 0) {
break; break;
} }
@ -210,12 +211,12 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
switch (pp - parts + 1) { switch (pp - parts + 1) {
case 0: case 0:
return 0; /* initial nondigit */ return 0; /* initial nondigit */
case 1: /* a -- 32 bits */ case 1: /* a -- 32 bits */
break; break;
case 2: /* a.b -- 8.24 bits */ case 2: /* a.b -- 8.24 bits */
if (val > 0xffffffUL) { if (val > 0xffffffUL) {
return 0; return 0;
} }
@ -225,7 +226,7 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
val |= parts[0] << 24; val |= parts[0] << 24;
break; break;
case 3: /* a.b.c -- 8.8.16 bits */ case 3: /* a.b.c -- 8.8.16 bits */
if (val > 0xffff) { if (val > 0xffff) {
return 0; return 0;
} }
@ -235,7 +236,7 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
val |= (parts[0] << 24) | (parts[1] << 16); val |= (parts[0] << 24) | (parts[1] << 16);
break; break;
case 4: /* a.b.c.d -- 8.8.8.8 bits */ case 4: /* a.b.c.d -- 8.8.8.8 bits */
if (val > 0xff) { if (val > 0xff) {
return 0; return 0;
} }

View File

@ -42,12 +42,12 @@
#if LWIP_IPV4 #if LWIP_IPV4
#include "lwip/def.h"
#include "lwip/icmp.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip4_frag.h" #include "lwip/ip4_frag.h"
#include "lwip/def.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include "lwip/icmp.h"
#include <string.h> #include <string.h>
@ -79,9 +79,9 @@
#define IP_REASS_FLAG_LASTFRAG 0x01 #define IP_REASS_FLAG_LASTFRAG 0x01
#define IP_REASS_VALIDATE_TELEGRAM_FINISHED 1 #define IP_REASS_VALIDATE_TELEGRAM_FINISHED 1
#define IP_REASS_VALIDATE_PBUF_QUEUED 0 #define IP_REASS_VALIDATE_PBUF_QUEUED 0
#define IP_REASS_VALIDATE_PBUF_DROPPED -1 #define IP_REASS_VALIDATE_PBUF_DROPPED -1
/** This is a helper struct which holds the starting /** This is a helper struct which holds the starting
* offset and the ending offset of this fragment to * offset and the ending offset of this fragment to
@ -92,35 +92,31 @@
* this struct doesn't need packing, too.) * this struct doesn't need packing, too.)
*/ */
#ifdef PACK_STRUCT_USE_INCLUDES #ifdef PACK_STRUCT_USE_INCLUDES
#include "arch/bpstruct.h" # include "arch/bpstruct.h"
#endif #endif
PACK_STRUCT_BEGIN PACK_STRUCT_BEGIN
struct ip_reass_helper struct ip_reass_helper {
{
PACK_STRUCT_FIELD(struct pbuf *next_pbuf); PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
PACK_STRUCT_FIELD(u16_t start); PACK_STRUCT_FIELD(u16_t start);
PACK_STRUCT_FIELD(u16_t end); PACK_STRUCT_FIELD(u16_t end);
} PACK_STRUCT_STRUCT; } PACK_STRUCT_STRUCT;
PACK_STRUCT_END PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES #ifdef PACK_STRUCT_USE_INCLUDES
#include "arch/epstruct.h" # include "arch/epstruct.h"
#endif #endif
#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ #define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \
(ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ (ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \
IPH_ID(iphdrA) == IPH_ID(iphdrB)) \ ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \
? 1 \ IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0
: 0
/* global variables */ /* global variables */
static struct ip_reassdata *reassdatagrams; static struct ip_reassdata *reassdatagrams;
static u16_t ip_reass_pbufcount; static u16_t ip_reass_pbufcount;
/* function prototypes */ /* function prototypes */
static void static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
static int
ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
/** /**
* Reassembly timer base function * Reassembly timer base function
@ -139,7 +135,7 @@ ip_reass_tmr(void)
* clean up the incomplete fragment assembly */ * clean up the incomplete fragment assembly */
if (r->timer > 0) { if (r->timer > 0) {
r->timer--; r->timer--;
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %" U16_F "\n", (u16_t)r->timer)); LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n", (u16_t)r->timer));
prev = r; prev = r;
r = r->next; r = r->next;
} else { } else {
@ -282,7 +278,7 @@ static struct ip_reassdata *
ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen)
{ {
struct ip_reassdata *ipr; struct ip_reassdata *ipr;
#if !IP_REASS_FREE_OLDEST #if ! IP_REASS_FREE_OLDEST
LWIP_UNUSED_ARG(clen); LWIP_UNUSED_ARG(clen);
#endif #endif
@ -368,7 +364,8 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
/* overwrite the fragment's ip header from the pbuf with our helper struct, /* overwrite the fragment's ip header from the pbuf with our helper struct,
* and setup the embedded helper structure. */ * and setup the embedded helper structure. */
/* make sure the struct ip_reass_helper fits into the IP header */ /* make sure the struct ip_reass_helper fits into the IP header */
LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", sizeof(struct ip_reass_helper) <= IP_HLEN); LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN",
sizeof(struct ip_reass_helper) <= IP_HLEN);
iprh = (struct ip_reass_helper *)new_p->payload; iprh = (struct ip_reass_helper *)new_p->payload;
iprh->next_pbuf = NULL; iprh->next_pbuf = NULL;
iprh->start = offset; iprh->start = offset;
@ -446,7 +443,8 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
} }
} else { } else {
#if IP_REASS_CHECK_OVERLAP #if IP_REASS_CHECK_OVERLAP
LWIP_ASSERT("no previous fragment, this must be the first fragment!", ipr->p == NULL); LWIP_ASSERT("no previous fragment, this must be the first fragment!",
ipr->p == NULL);
#endif /* IP_REASS_CHECK_OVERLAP */ #endif /* IP_REASS_CHECK_OVERLAP */
/* this is the first fragment we ever received for this ip datagram */ /* this is the first fragment we ever received for this ip datagram */
ipr->p = new_p; ipr->p = new_p;
@ -479,8 +477,10 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
* (because to the MF==0 already arrived */ * (because to the MF==0 already arrived */
if (valid) { if (valid) {
LWIP_ASSERT("sanity check", ipr->p != NULL); LWIP_ASSERT("sanity check", ipr->p != NULL);
LWIP_ASSERT("sanity check", ((struct ip_reass_helper *)ipr->p->payload) != iprh); LWIP_ASSERT("sanity check",
LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", iprh->next_pbuf == NULL); ((struct ip_reass_helper *)ipr->p->payload) != iprh);
LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
iprh->next_pbuf == NULL);
} }
} }
} }
@ -535,13 +535,13 @@ ip4_reass(struct pbuf *p)
clen = pbuf_clen(p); clen = pbuf_clen(p);
if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
#if IP_REASS_FREE_OLDEST #if IP_REASS_FREE_OLDEST
if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) if (!ip_reass_remove_oldest_datagram(fraghdr, clen) ||
((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
#endif /* IP_REASS_FREE_OLDEST */ #endif /* IP_REASS_FREE_OLDEST */
{ {
/* No datagram could be freed and still too many pbufs enqueued */ /* No datagram could be freed and still too many pbufs enqueued */
LWIP_DEBUGF( LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n",
IP_REASS_DEBUG, ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
IPFRAG_STATS_INC(ip_frag.memerr); IPFRAG_STATS_INC(ip_frag.memerr);
/* @todo: send ICMP time exceeded here? */ /* @todo: send ICMP time exceeded here? */
/* drop this pbuf */ /* drop this pbuf */
@ -556,8 +556,8 @@ ip4_reass(struct pbuf *p)
in the reassembly buffer. If so, we proceed with copying the in the reassembly buffer. If so, we proceed with copying the
fragment into the buffer. */ fragment into the buffer. */
if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
LWIP_DEBUGF(IP_REASS_DEBUG, LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n",
("ip4_reass: matching previous fragment ID=%" X16_F "\n", lwip_ntohs(IPH_ID(fraghdr)))); lwip_ntohs(IPH_ID(fraghdr))));
IPFRAG_STATS_INC(ip_frag.cachehit); IPFRAG_STATS_INC(ip_frag.cachehit);
break; break;
} }
@ -609,7 +609,9 @@ ip4_reass(struct pbuf *p)
u16_t datagram_len = (u16_t)(offset + len); u16_t datagram_len = (u16_t)(offset + len);
ipr->datagram_len = datagram_len; ipr->datagram_len = datagram_len;
ipr->flags |= IP_REASS_FLAG_LASTFRAG; ipr->flags |= IP_REASS_FLAG_LASTFRAG;
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: last fragment seen, total len %" S16_F "\n", ipr->datagram_len)); LWIP_DEBUGF(IP_REASS_DEBUG,
("ip4_reass: last fragment seen, total len %"S16_F"\n",
ipr->datagram_len));
} }
if (valid == IP_REASS_VALIDATE_TELEGRAM_FINISHED) { if (valid == IP_REASS_VALIDATE_TELEGRAM_FINISHED) {
@ -629,8 +631,7 @@ ip4_reass(struct pbuf *p)
IPH_CHKSUM_SET(fraghdr, 0); IPH_CHKSUM_SET(fraghdr, 0);
/* @todo: do we need to set/calculate the correct checksum? */ /* @todo: do we need to set/calculate the correct checksum? */
#if CHECKSUM_GEN_IP #if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) IF__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) {
{
IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
} }
#endif /* CHECKSUM_GEN_IP */ #endif /* CHECKSUM_GEN_IP */
@ -779,7 +780,8 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
if (rambuf == NULL) { if (rambuf == NULL) {
goto memerr; goto memerr;
} }
LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); LWIP_ASSERT("this needs a pbuf in one piece!",
(rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff); poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff);
/* make room for the IP header */ /* make room for the IP header */
if (pbuf_add_header(rambuf, IP_HLEN)) { if (pbuf_add_header(rambuf, IP_HLEN)) {
@ -789,7 +791,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
/* fill in the IP header */ /* fill in the IP header */
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
iphdr = (struct ip_hdr *)rambuf->payload; iphdr = (struct ip_hdr *)rambuf->payload;
#else /* LWIP_NETIF_TX_SINGLE_PBUF */ #else /* LWIP_NETIF_TX_SINGLE_PBUF */
/* When not using a static buffer, create a chain of pbufs. /* When not using a static buffer, create a chain of pbufs.
* The first will be a PBUF_RAM holding the link and IP header. * The first will be a PBUF_RAM holding the link and IP header.
* The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
@ -799,7 +801,8 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
if (rambuf == NULL) { if (rambuf == NULL) {
goto memerr; goto memerr;
} }
LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len >= (IP_HLEN))); LWIP_ASSERT("this needs a pbuf in one piece!",
(rambuf->len >= (IP_HLEN)));
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
iphdr = (struct ip_hdr *)rambuf->payload; iphdr = (struct ip_hdr *)rambuf->payload;
@ -821,7 +824,8 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
goto memerr; goto memerr;
} }
/* Mirror this pbuf, although we might not need all of it. */ /* Mirror this pbuf, although we might not need all of it. */
newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, (u8_t *)p->payload + poff, newpbuflen); newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc,
(u8_t *)p->payload + poff, newpbuflen);
if (newpbuf == NULL) { if (newpbuf == NULL) {
ip_frag_free_pbuf_custom_ref(pcr); ip_frag_free_pbuf_custom_ref(pcr);
pbuf_free(rambuf); pbuf_free(rambuf);
@ -857,7 +861,9 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
IPH_LEN_SET(iphdr, lwip_htons((u16_t)(fragsize + IP_HLEN))); IPH_LEN_SET(iphdr, lwip_htons((u16_t)(fragsize + IP_HLEN)));
IPH_CHKSUM_SET(iphdr, 0); IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP #if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); } IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */ #endif /* CHECKSUM_GEN_IP */
/* No need for separate header pbuf - we allowed room for it in rambuf /* No need for separate header pbuf - we allowed room for it in rambuf

View File

@ -59,11 +59,11 @@
#if LWIP_IPV6 && LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ #if LWIP_IPV6 && LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/dhcp6.h" #include "lwip/dhcp6.h"
#include "lwip/dns.h"
#include "lwip/prot/dhcp6.h" #include "lwip/prot/dhcp6.h"
#include "lwip/def.h"
#include "lwip/udp.h" #include "lwip/udp.h"
#include "lwip/dns.h"
#include <string.h> #include <string.h>
@ -74,10 +74,7 @@
#define LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len) #define LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, state, msg, msg_type, options_len_ptr, max_len)
#endif #endif
#ifndef LWIP_HOOK_DHCP6_PARSE_OPTION #ifndef LWIP_HOOK_DHCP6_PARSE_OPTION
#define LWIP_HOOK_DHCP6_PARSE_OPTION(netif, dhcp6, state, msg, msg_type, option, len, pbuf, offset) \ #define LWIP_HOOK_DHCP6_PARSE_OPTION(netif, dhcp6, state, msg, msg_type, option, len, pbuf, offset) do { LWIP_UNUSED_ARG(msg); } while(0)
do { \
LWIP_UNUSED_ARG(msg); \
} while (0)
#endif #endif
#if LWIP_DNS && LWIP_DHCP6_MAX_DNS_SERVERS #if LWIP_DNS && LWIP_DHCP6_MAX_DNS_SERVERS
@ -90,13 +87,13 @@
#define LWIP_DHCP6_PROVIDE_DNS_SERVERS 0 #define LWIP_DHCP6_PROVIDE_DNS_SERVERS 0
#endif #endif
/** Option handling: options are parsed in dhcp6_parse_reply /** Option handling: options are parsed in dhcp6_parse_reply
* and saved in an array where other functions can load them from. * and saved in an array where other functions can load them from.
* This might be moved into the struct dhcp6 (not necessarily since * This might be moved into the struct dhcp6 (not necessarily since
* lwIP is single-threaded and the array is only used while in recv * lwIP is single-threaded and the array is only used while in recv
* callback). */ * callback). */
enum dhcp6_option_idx enum dhcp6_option_idx {
{
DHCP6_OPTION_IDX_CLI_ID = 0, DHCP6_OPTION_IDX_CLI_ID = 0,
DHCP6_OPTION_IDX_SERVER_ID, DHCP6_OPTION_IDX_SERVER_ID,
#if LWIP_DHCP6_PROVIDE_DNS_SERVERS #if LWIP_DHCP6_PROVIDE_DNS_SERVERS
@ -109,8 +106,7 @@ enum dhcp6_option_idx
DHCP6_OPTION_IDX_MAX DHCP6_OPTION_IDX_MAX
}; };
struct dhcp6_option_info struct dhcp6_option_info {
{
u8_t option_given; u8_t option_given;
u16_t val_start; u16_t val_start;
u16_t val_length; u16_t val_length;
@ -119,17 +115,14 @@ struct dhcp6_option_info
/** Holds the decoded option info, only valid while in dhcp6_recv. */ /** Holds the decoded option info, only valid while in dhcp6_recv. */
struct dhcp6_option_info dhcp6_rx_options[DHCP6_OPTION_IDX_MAX]; struct dhcp6_option_info dhcp6_rx_options[DHCP6_OPTION_IDX_MAX];
#define dhcp6_option_given(dhcp6, idx) (dhcp6_rx_options[idx].option_given != 0) #define dhcp6_option_given(dhcp6, idx) (dhcp6_rx_options[idx].option_given != 0)
#define dhcp6_got_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 1) #define dhcp6_got_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 1)
#define dhcp6_clear_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 0) #define dhcp6_clear_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 0)
#define dhcp6_clear_all_options(dhcp6) (memset(dhcp6_rx_options, 0, sizeof(dhcp6_rx_options))) #define dhcp6_clear_all_options(dhcp6) (memset(dhcp6_rx_options, 0, sizeof(dhcp6_rx_options)))
#define dhcp6_get_option_start(dhcp6, idx) (dhcp6_rx_options[idx].val_start) #define dhcp6_get_option_start(dhcp6, idx) (dhcp6_rx_options[idx].val_start)
#define dhcp6_get_option_length(dhcp6, idx) (dhcp6_rx_options[idx].val_length) #define dhcp6_get_option_length(dhcp6, idx) (dhcp6_rx_options[idx].val_length)
#define dhcp6_set_option(dhcp6, idx, start, len) \ #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)
do { \
dhcp6_rx_options[idx].val_start = (start); \
dhcp6_rx_options[idx].val_length = (len); \
} while (0)
const ip_addr_t dhcp6_All_DHCP6_Relay_Agents_and_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x00010002); const ip_addr_t dhcp6_All_DHCP6_Relay_Agents_and_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x00010002);
const ip_addr_t dhcp6_All_DHCP6_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x00010003); const ip_addr_t dhcp6_All_DHCP6_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x00010003);
@ -137,9 +130,9 @@ const ip_addr_t dhcp6_All_DHCP6_Servers = IPADDR6_INIT_HOST(0xFF020000, 0, 0, 0x
static struct udp_pcb *dhcp6_pcb; static struct udp_pcb *dhcp6_pcb;
static u8_t dhcp6_pcb_refcount; static u8_t dhcp6_pcb_refcount;
/* receive, unfold, parse and free incoming messages */ /* receive, unfold, parse and free incoming messages */
static void static void dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
/** Ensure DHCP PCB is allocated and bound */ /** Ensure DHCP PCB is allocated and bound */
static err_t static err_t
@ -210,8 +203,7 @@ dhcp6_set_struct(struct netif *netif, struct dhcp6 *dhcp6)
* *
* @param netif the netif from which to remove the struct dhcp * @param netif the netif from which to remove the struct dhcp
*/ */
void void dhcp6_cleanup(struct netif *netif)
dhcp6_cleanup(struct netif *netif)
{ {
LWIP_ASSERT("netif != NULL", netif != NULL); LWIP_ASSERT("netif != NULL", netif != NULL);
@ -221,7 +213,7 @@ dhcp6_cleanup(struct netif *netif)
} }
} }
static struct dhcp6 * static struct dhcp6*
dhcp6_get_struct(struct netif *netif, const char *dbg_requester) dhcp6_get_struct(struct netif *netif, const char *dbg_requester)
{ {
struct dhcp6 *dhcp6 = netif_dhcp6_data(netif); struct dhcp6 *dhcp6 = netif_dhcp6_data(netif);
@ -261,8 +253,8 @@ dhcp6_get_struct(struct netif *netif, const char *dbg_requester)
static void static void
dhcp6_set_state(struct dhcp6 *dhcp6, u8_t new_state, const char *dbg_caller) dhcp6_set_state(struct dhcp6 *dhcp6, u8_t new_state, const char *dbg_caller)
{ {
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("DHCPv6 state: %d -> %d (%s)\n",
("DHCPv6 state: %d -> %d (%s)\n", dhcp6->state, new_state, dbg_caller)); dhcp6->state, new_state, dbg_caller));
if (new_state != dhcp6->state) { if (new_state != dhcp6->state) {
dhcp6->state = new_state; dhcp6->state = new_state;
dhcp6->tries = 0; dhcp6->tries = 0;
@ -273,7 +265,8 @@ dhcp6_set_state(struct dhcp6 *dhcp6, u8_t new_state, const char *dbg_caller)
static int static int
dhcp6_stateless_enabled(struct dhcp6 *dhcp6) dhcp6_stateless_enabled(struct dhcp6 *dhcp6)
{ {
if ((dhcp6->state == DHCP6_STATE_STATELESS_IDLE) || (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG)) { if ((dhcp6->state == DHCP6_STATE_STATELESS_IDLE) ||
(dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG)) {
return 1; return 1;
} }
return 0; return 0;
@ -324,12 +317,7 @@ dhcp6_enable_stateless(struct netif *netif)
{ {
struct dhcp6 *dhcp6; struct dhcp6 *dhcp6;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_enable_stateless(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
("dhcp6_enable_stateless(netif=%p) %c%c%" U16_F "\n",
(void *)netif,
netif->name[0],
netif->name[1],
(u16_t)netif->num));
dhcp6 = dhcp6_get_struct(netif, "dhcp6_enable_stateless()"); dhcp6 = dhcp6_get_struct(netif, "dhcp6_enable_stateless()");
if (dhcp6 == NULL) { if (dhcp6 == NULL) {
@ -359,16 +347,13 @@ dhcp6_disable(struct netif *netif)
{ {
struct dhcp6 *dhcp6; struct dhcp6 *dhcp6;
LWIP_DEBUGF( LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_disable(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp6_disable(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
dhcp6 = netif_dhcp6_data(netif); dhcp6 = netif_dhcp6_data(netif);
if (dhcp6 != NULL) { if (dhcp6 != NULL) {
if (dhcp6->state != DHCP6_STATE_OFF) { if (dhcp6->state != DHCP6_STATE_OFF) {
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_disable(): DHCPv6 disabled (old state: %s)\n",
("dhcp6_disable(): DHCPv6 disabled (old state: %s)\n", (dhcp6_stateless_enabled(dhcp6) ? "stateless" : "stateful")));
(dhcp6_stateless_enabled(dhcp6) ? "stateless" : "stateful")));
dhcp6_set_state(dhcp6, DHCP6_STATE_OFF, "dhcp6_disable"); dhcp6_set_state(dhcp6, DHCP6_STATE_OFF, "dhcp6_disable");
if (dhcp6->pcb_allocated != 0) { if (dhcp6->pcb_allocated != 0) {
dhcp6_dec_pcb_refcount(); /* free DHCPv6 PCB if not needed any more */ dhcp6_dec_pcb_refcount(); /* free DHCPv6 PCB if not needed any more */
@ -389,11 +374,8 @@ dhcp6_disable(struct netif *netif)
* @return a pbuf for the message * @return a pbuf for the message
*/ */
static struct pbuf * static struct pbuf *
dhcp6_create_msg(struct netif *netif, dhcp6_create_msg(struct netif *netif, struct dhcp6 *dhcp6, u8_t message_type,
struct dhcp6 *dhcp6, u16_t opt_len_alloc, u16_t *options_out_len)
u8_t message_type,
u16_t opt_len_alloc,
u16_t *options_out_len)
{ {
struct pbuf *p_out; struct pbuf *p_out;
struct dhcp6_msg *msg_out; struct dhcp6_msg *msg_out;
@ -415,7 +397,8 @@ dhcp6_create_msg(struct netif *netif,
dhcp6->xid = LWIP_RAND() & 0xFFFFFF; dhcp6->xid = LWIP_RAND() & 0xFFFFFF;
} }
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("transaction id xid(%" X32_F ")\n", dhcp6->xid)); LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE,
("transaction id xid(%"X32_F")\n", dhcp6->xid));
msg_out = (struct dhcp6_msg *)p_out->payload; msg_out = (struct dhcp6_msg *)p_out->payload;
memset(msg_out, 0, sizeof(struct dhcp6_msg) + opt_len_alloc); memset(msg_out, 0, sizeof(struct dhcp6_msg) + opt_len_alloc);
@ -432,22 +415,19 @@ static u16_t
dhcp6_option_short(u16_t options_out_len, u8_t *options, u16_t value) dhcp6_option_short(u16_t options_out_len, u8_t *options, u16_t value)
{ {
options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8); options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
options[options_out_len++] = (u8_t)(value & 0x00ffU); options[options_out_len++] = (u8_t) (value & 0x00ffU);
return options_out_len; return options_out_len;
} }
static u16_t static u16_t
dhcp6_option_optionrequest(u16_t options_out_len, dhcp6_option_optionrequest(u16_t options_out_len, u8_t *options, const u16_t *req_options,
u8_t *options, u16_t num_req_options, u16_t max_len)
const u16_t *req_options,
u16_t num_req_options,
u16_t max_len)
{ {
size_t i; size_t i;
u16_t ret; u16_t ret;
LWIP_ASSERT("dhcp6_option_optionrequest: options_out_len + sizeof(struct dhcp6_msg) + addlen <= max_len", LWIP_ASSERT("dhcp6_option_optionrequest: options_out_len + sizeof(struct dhcp6_msg) + addlen <= max_len",
sizeof(struct dhcp6_msg) + options_out_len + 4U + (2U * num_req_options) <= max_len); sizeof(struct dhcp6_msg) + options_out_len + 4U + (2U * num_req_options) <= max_len);
LWIP_UNUSED_ARG(max_len); LWIP_UNUSED_ARG(max_len);
ret = dhcp6_option_short(options_out_len, options, DHCP6_OPTION_ORO); ret = dhcp6_option_short(options_out_len, options, DHCP6_OPTION_ORO);
@ -466,11 +446,12 @@ dhcp6_msg_finalize(u16_t options_out_len, struct pbuf *p_out)
pbuf_realloc(p_out, (u16_t)(sizeof(struct dhcp6_msg) + options_out_len)); pbuf_realloc(p_out, (u16_t)(sizeof(struct dhcp6_msg) + options_out_len));
} }
#if LWIP_IPV6_DHCP6_STATELESS #if LWIP_IPV6_DHCP6_STATELESS
static void static void
dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6) 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[] = {DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_SNTP_SERVERS};
u16_t msecs; u16_t msecs;
struct pbuf *p_out; struct pbuf *p_out;
u16_t options_out_len; u16_t options_out_len;
@ -483,20 +464,18 @@ dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)
u8_t *options = (u8_t *)(msg_out + 1); u8_t *options = (u8_t *)(msg_out + 1);
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_information_request: making request\n")); LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_information_request: making request\n"));
options_out_len = dhcp6_option_optionrequest( options_out_len = dhcp6_option_optionrequest(options_out_len, options, requested_options,
options_out_len, options, requested_options, LWIP_ARRAYSIZE(requested_options), p_out->len); LWIP_ARRAYSIZE(requested_options), p_out->len);
LWIP_HOOK_DHCP6_APPEND_OPTIONS( LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, DHCP6_STATE_REQUESTING_CONFIG, msg_out,
netif, dhcp6, DHCP6_STATE_REQUESTING_CONFIG, msg_out, DHCP6_INFOREQUEST, options_out_len, p_out->len); DHCP6_INFOREQUEST, options_out_len, p_out->len);
dhcp6_msg_finalize(options_out_len, p_out); dhcp6_msg_finalize(options_out_len, p_out);
err = udp_sendto_if(dhcp6_pcb, p_out, &dhcp6_All_DHCP6_Relay_Agents_and_Servers, DHCP6_SERVER_PORT, netif); err = udp_sendto_if(dhcp6_pcb, p_out, &dhcp6_All_DHCP6_Relay_Agents_and_Servers, DHCP6_SERVER_PORT, netif);
pbuf_free(p_out); pbuf_free(p_out);
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_information_request: INFOREQUESTING -> %d\n", (int)err));
("dhcp6_information_request: INFOREQUESTING -> %d\n", (int)err));
LWIP_UNUSED_ARG(err); LWIP_UNUSED_ARG(err);
} else { } else {
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp6_information_request: could not allocate DHCP6 request\n"));
("dhcp6_information_request: could not allocate DHCP6 request\n"));
} }
dhcp6_set_state(dhcp6, DHCP6_STATE_REQUESTING_CONFIG, "dhcp6_information_request"); dhcp6_set_state(dhcp6, DHCP6_STATE_REQUESTING_CONFIG, "dhcp6_information_request");
if (dhcp6->tries < 255) { if (dhcp6->tries < 255) {
@ -504,8 +483,7 @@ dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)
} }
msecs = (u16_t)((dhcp6->tries < 6 ? 1 << dhcp6->tries : 60) * 1000); msecs = (u16_t)((dhcp6->tries < 6 ? 1 << dhcp6->tries : 60) * 1000);
dhcp6->request_timeout = (u16_t)((msecs + DHCP6_TIMER_MSECS - 1) / DHCP6_TIMER_MSECS); dhcp6->request_timeout = (u16_t)((msecs + DHCP6_TIMER_MSECS - 1) / DHCP6_TIMER_MSECS);
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp6_information_request(): set request timeout %"U16_F" msecs\n", msecs));
("dhcp6_information_request(): set request timeout %" U16_F " msecs\n", msecs));
} }
static err_t static err_t
@ -698,9 +676,9 @@ dhcp6_parse_reply(struct pbuf *p, struct dhcp6 *dhcp6)
break; break;
#endif /* LWIP_DHCP6_GET_NTP_SRV*/ #endif /* LWIP_DHCP6_GET_NTP_SRV*/
default: default:
LWIP_DEBUGF(DHCP6_DEBUG, ("skipping option %" U16_F " in options\n", op)); LWIP_DEBUGF(DHCP6_DEBUG, ("skipping option %"U16_F" in options\n", op));
LWIP_HOOK_DHCP6_PARSE_OPTION( LWIP_HOOK_DHCP6_PARSE_OPTION(ip_current_netif(), dhcp6, dhcp6->state, msg_in,
ip_current_netif(), dhcp6, dhcp6->state, msg_in, msg_in->msgtype, op, len, q, val_offset); msg_in->msgtype, op, len, q, val_offset);
break; break;
} }
} }
@ -725,10 +703,10 @@ dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr
LWIP_ERROR("invalid server address type", IP_IS_V6(addr), goto free_pbuf_and_return;); LWIP_ERROR("invalid server address type", IP_IS_V6(addr), goto free_pbuf_and_return;);
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_recv(pbuf = %p) from DHCPv6 server %s port %"U16_F"\n", (void *)p,
("dhcp6_recv(pbuf = %p) from DHCPv6 server %s port %" U16_F "\n", (void *)p, ipaddr_ntoa(addr), port)); ipaddr_ntoa(addr), port));
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %" U16_F "\n", p->len)); LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len));
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %" U16_F "\n", p->tot_len)); LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len));
/* prevent warnings about unused arguments */ /* prevent warnings about unused arguments */
LWIP_UNUSED_ARG(pcb); LWIP_UNUSED_ARG(pcb);
LWIP_UNUSED_ARG(addr); LWIP_UNUSED_ARG(addr);
@ -745,7 +723,7 @@ dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr
xid |= reply_msg->transaction_id[2]; xid |= reply_msg->transaction_id[2];
if (xid != dhcp6->xid) { if (xid != dhcp6->xid) {
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("transaction id mismatch reply_msg->xid(%" X32_F ")!= dhcp6->xid(%" X32_F ")\n", xid, dhcp6->xid)); ("transaction id mismatch reply_msg->xid(%"X32_F")!= dhcp6->xid(%"X32_F")\n", xid, dhcp6->xid));
goto free_pbuf_and_return; goto free_pbuf_and_return;
} }
/* option fields could be unfold? */ /* option fields could be unfold? */
@ -813,8 +791,7 @@ dhcp6_tmr(void)
{ {
struct netif *netif; struct netif *netif;
/* loop through netif's */ /* loop through netif's */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
struct dhcp6 *dhcp6 = netif_dhcp6_data(netif); struct dhcp6 *dhcp6 = netif_dhcp6_data(netif);
/* only act on DHCPv6 configured interfaces */ /* only act on DHCPv6 configured interfaces */
if (dhcp6 != NULL) { if (dhcp6 != NULL) {

View File

@ -44,13 +44,13 @@
#if LWIP_IPV6 && LWIP_ETHERNET #if LWIP_IPV6 && LWIP_ETHERNET
#include "lwip/ethip6.h" #include "lwip/ethip6.h"
#include "lwip/icmp6.h" #include "lwip/nd6.h"
#include "lwip/inet_chksum.h" #include "lwip/pbuf.h"
#include "lwip/ip6.h" #include "lwip/ip6.h"
#include "lwip/ip6_addr.h" #include "lwip/ip6_addr.h"
#include "lwip/nd6.h" #include "lwip/inet_chksum.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/pbuf.h" #include "lwip/icmp6.h"
#include "lwip/prot/ethernet.h" #include "lwip/prot/ethernet.h"
#include "netif/ethernet.h" #include "netif/ethernet.h"
@ -98,7 +98,7 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3]; dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3];
/* Send out. */ /* Send out. */
return ethernet_output(netif, q, (const struct eth_addr *)(netif->hwaddr), &dest, ETHTYPE_IPV6); return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
} }
/* We have a unicast destination IP address */ /* We have a unicast destination IP address */
@ -117,7 +117,7 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
/* Send out the packet using the returned hardware address. */ /* Send out the packet using the returned hardware address. */
SMEMCPY(dest.addr, hwaddr, 6); SMEMCPY(dest.addr, hwaddr, 6);
return ethernet_output(netif, q, (const struct eth_addr *)(netif->hwaddr), &dest, ETHTYPE_IPV6); return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
} }
#endif /* LWIP_IPV6 && LWIP_ETHERNET */ #endif /* LWIP_IPV6 && LWIP_ETHERNET */

View File

@ -44,42 +44,31 @@
#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ #if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/icmp6.h" #include "lwip/icmp6.h"
#include "lwip/inet_chksum.h" #include "lwip/prot/icmp6.h"
#include "lwip/ip.h"
#include "lwip/ip6.h" #include "lwip/ip6.h"
#include "lwip/ip6_addr.h" #include "lwip/ip6_addr.h"
#include "lwip/mld6.h" #include "lwip/inet_chksum.h"
#include "lwip/nd6.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "lwip/prot/icmp6.h" #include "lwip/netif.h"
#include "lwip/nd6.h"
#include "lwip/mld6.h"
#include "lwip/ip.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include <string.h> #include <string.h>
#if LWIP_ICMP6_DATASIZE == 0 #if LWIP_ICMP6_DATASIZE == 0
#undef LWIP_ICMP6_DATASIZE #undef LWIP_ICMP6_DATASIZE
#define LWIP_ICMP6_DATASIZE 8 #define LWIP_ICMP6_DATASIZE 8
#endif #endif
/* Forward declarations */ /* Forward declarations */
static void static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type);
icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type); static void icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data,
static void u8_t type, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr);
icmp6_send_response_with_addrs(struct pbuf *p, static void icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data,
u8_t code, u8_t type, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr, struct netif *netif);
u32_t data,
u8_t type,
const ip6_addr_t *src_addr,
const ip6_addr_t *dest_addr);
static void
icmp6_send_response_with_addrs_and_netif(struct pbuf *p,
u8_t code,
u32_t data,
u8_t type,
const ip6_addr_t *src_addr,
const ip6_addr_t *dest_addr,
struct netif *netif);
/** /**
* Process an input ICMPv6 message. Called by ip6_input. * Process an input ICMPv6 message. Called by ip6_input.
@ -111,9 +100,9 @@ icmp6_input(struct pbuf *p, struct netif *inp)
icmp6hdr = (struct icmp6_hdr *)p->payload; icmp6hdr = (struct icmp6_hdr *)p->payload;
#if CHECKSUM_CHECK_ICMP6 #if CHECKSUM_CHECK_ICMP6
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP6) IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP6) {
{ if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(),
if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(), ip6_current_dest_addr()) != 0) { ip6_current_dest_addr()) != 0) {
/* Checksum failed */ /* Checksum failed */
pbuf_free(p); pbuf_free(p);
ICMP6_STATS_INC(icmp6.chkerr); ICMP6_STATS_INC(icmp6.chkerr);
@ -124,97 +113,99 @@ icmp6_input(struct pbuf *p, struct netif *inp)
#endif /* CHECKSUM_CHECK_ICMP6 */ #endif /* CHECKSUM_CHECK_ICMP6 */
switch (icmp6hdr->type) { switch (icmp6hdr->type) {
case ICMP6_TYPE_NA: /* Neighbor advertisement */ case ICMP6_TYPE_NA: /* Neighbor advertisement */
case ICMP6_TYPE_NS: /* Neighbor solicitation */ case ICMP6_TYPE_NS: /* Neighbor solicitation */
case ICMP6_TYPE_RA: /* Router advertisement */ case ICMP6_TYPE_RA: /* Router advertisement */
case ICMP6_TYPE_RD: /* Redirect */ case ICMP6_TYPE_RD: /* Redirect */
case ICMP6_TYPE_PTB: /* Packet too big */ case ICMP6_TYPE_PTB: /* Packet too big */
nd6_input(p, inp); nd6_input(p, inp);
return; return;
case ICMP6_TYPE_RS: case ICMP6_TYPE_RS:
#if LWIP_IPV6_FORWARD #if LWIP_IPV6_FORWARD
/* @todo implement router functionality */ /* @todo implement router functionality */
#endif #endif
break; break;
#if LWIP_IPV6_MLD #if LWIP_IPV6_MLD
case ICMP6_TYPE_MLQ: case ICMP6_TYPE_MLQ:
case ICMP6_TYPE_MLR: case ICMP6_TYPE_MLR:
case ICMP6_TYPE_MLD: case ICMP6_TYPE_MLD:
mld6_input(p, inp); mld6_input(p, inp);
return; return;
#endif #endif
case ICMP6_TYPE_EREQ: case ICMP6_TYPE_EREQ:
#if !LWIP_MULTICAST_PING #if !LWIP_MULTICAST_PING
/* multicast destination address? */ /* multicast destination address? */
if (ip6_addr_ismulticast(ip6_current_dest_addr())) { if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
/* drop */ /* drop */
pbuf_free(p); pbuf_free(p);
ICMP6_STATS_INC(icmp6.drop); ICMP6_STATS_INC(icmp6.drop);
return; return;
} }
#endif /* LWIP_MULTICAST_PING */ #endif /* LWIP_MULTICAST_PING */
/* Allocate reply. */ /* Allocate reply. */
r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM); r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM);
if (r == NULL) { if (r == NULL) {
/* drop */ /* drop */
pbuf_free(p); pbuf_free(p);
ICMP6_STATS_INC(icmp6.memerr); ICMP6_STATS_INC(icmp6.memerr);
return; return;
} }
/* Copy echo request. */ /* Copy echo request. */
if (pbuf_copy(r, p) != ERR_OK) { if (pbuf_copy(r, p) != ERR_OK) {
/* drop */
pbuf_free(p);
pbuf_free(r);
ICMP6_STATS_INC(icmp6.err);
return;
}
/* Determine reply source IPv6 address. */
#if LWIP_MULTICAST_PING
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
reply_src = ip_2_ip6(ip6_select_source_address(inp, ip6_current_src_addr()));
if (reply_src == NULL) {
/* drop */ /* drop */
pbuf_free(p); pbuf_free(p);
pbuf_free(r); pbuf_free(r);
ICMP6_STATS_INC(icmp6.err); ICMP6_STATS_INC(icmp6.rterr);
return; return;
} }
}
/* Determine reply source IPv6 address. */ else
#if LWIP_MULTICAST_PING
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
reply_src = ip_2_ip6(ip6_select_source_address(inp, ip6_current_src_addr()));
if (reply_src == NULL) {
/* drop */
pbuf_free(p);
pbuf_free(r);
ICMP6_STATS_INC(icmp6.rterr);
return;
}
} else
#endif /* LWIP_MULTICAST_PING */ #endif /* LWIP_MULTICAST_PING */
{ {
reply_src = ip6_current_dest_addr(); reply_src = ip6_current_dest_addr();
} }
/* Set fields in reply. */ /* Set fields in reply. */
((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP; ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP;
((struct icmp6_echo_hdr *)(r->payload))->chksum = 0; ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0;
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP6) IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP6) {
{ ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r,
((struct icmp6_echo_hdr *)(r->payload))->chksum = IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr());
ip6_chksum_pseudo(r, IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr()); }
}
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Send reply. */ /* Send reply. */
ICMP6_STATS_INC(icmp6.xmit); ICMP6_STATS_INC(icmp6.xmit);
ip6_output_if(r, reply_src, ip6_current_src_addr(), LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp); ip6_output_if(r, reply_src, ip6_current_src_addr(),
pbuf_free(r); LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp);
pbuf_free(r);
break; break;
default: default:
ICMP6_STATS_INC(icmp6.proterr); ICMP6_STATS_INC(icmp6.proterr);
ICMP6_STATS_INC(icmp6.drop); ICMP6_STATS_INC(icmp6.drop);
break; break;
} }
pbuf_free(p); pbuf_free(p);
} }
/** /**
* Send an icmpv6 'destination unreachable' packet. * Send an icmpv6 'destination unreachable' packet.
* *
@ -279,10 +270,8 @@ icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c)
* information * information
*/ */
void void
icmp6_time_exceeded_with_addrs(struct pbuf *p, icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c,
enum icmp6_te_code c, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr)
const ip6_addr_t *src_addr,
const ip6_addr_t *dest_addr)
{ {
icmp6_send_response_with_addrs(p, c, 0, ICMP6_TYPE_TE, src_addr, dest_addr); icmp6_send_response_with_addrs(p, c, 0, ICMP6_TYPE_TE, src_addr, dest_addr);
} }
@ -354,12 +343,8 @@ icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type)
* @param dest_addr original destination address * @param dest_addr original destination address
*/ */
static void static void
icmp6_send_response_with_addrs(struct pbuf *p, icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, u8_t type,
u8_t code, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr)
u32_t data,
u8_t type,
const ip6_addr_t *src_addr,
const ip6_addr_t *dest_addr)
{ {
const struct ip6_addr *reply_src, *reply_dest; const struct ip6_addr *reply_src, *reply_dest;
struct netif *netif; struct netif *netif;
@ -380,7 +365,8 @@ icmp6_send_response_with_addrs(struct pbuf *p,
ICMP6_STATS_INC(icmp6.rterr); ICMP6_STATS_INC(icmp6.rterr);
return; return;
} }
icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src, reply_dest, netif); icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src,
reply_dest, netif);
} }
/** /**
@ -396,26 +382,22 @@ icmp6_send_response_with_addrs(struct pbuf *p,
* @param netif netif to send the packet * @param netif netif to send the packet
*/ */
static void static void
icmp6_send_response_with_addrs_and_netif(struct pbuf *p, icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data, u8_t type,
u8_t code, const ip6_addr_t *reply_src, const ip6_addr_t *reply_dest, struct netif *netif)
u32_t data,
u8_t type,
const ip6_addr_t *reply_src,
const ip6_addr_t *reply_dest,
struct netif *netif)
{ {
struct pbuf *q; struct pbuf *q;
struct icmp6_hdr *icmp6hdr; struct icmp6_hdr *icmp6hdr;
/* ICMPv6 header + IPv6 header + data */ /* ICMPv6 header + IPv6 header + data */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE, PBUF_RAM); q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE,
PBUF_RAM);
if (q == NULL) { if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n")); LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n"));
ICMP6_STATS_INC(icmp6.memerr); ICMP6_STATS_INC(icmp6.memerr);
return; return;
} }
LWIP_ASSERT("check that first pbuf can hold icmp 6message", LWIP_ASSERT("check that first pbuf can hold icmp 6message",
(q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE))); (q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));
icmp6hdr = (struct icmp6_hdr *)q->payload; icmp6hdr = (struct icmp6_hdr *)q->payload;
icmp6hdr->type = type; icmp6hdr->type = type;
@ -423,14 +405,15 @@ icmp6_send_response_with_addrs_and_netif(struct pbuf *p,
icmp6hdr->data = lwip_htonl(data); icmp6hdr->data = lwip_htonl(data);
/* copy fields from original packet */ /* copy fields from original packet */
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload, IP6_HLEN + LWIP_ICMP6_DATASIZE); SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload,
IP6_HLEN + LWIP_ICMP6_DATASIZE);
/* calculate checksum */ /* calculate checksum */
icmp6hdr->chksum = 0; icmp6hdr->chksum = 0;
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
{ icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len,
icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len, reply_src, reply_dest); reply_src, reply_dest);
} }
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */

File diff suppressed because it is too large Load Diff

View File

@ -42,21 +42,21 @@
#include "lwip/opt.h" #include "lwip/opt.h"
#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ #if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
#include "lwip/def.h"
#include <string.h> #include <string.h>
#if LWIP_IPV4 #if LWIP_IPV4
#include "lwip/ip4_addr.h" /* for ip6addr_aton to handle IPv4-mapped addresses */ #include "lwip/ip4_addr.h" /* for ip6addr_aton to handle IPv4-mapped addresses */
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
/* used by IP6_ADDR_ANY(6) in ip6_addr.h */ /* used by IP6_ADDR_ANY(6) in ip6_addr.h */
const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul); const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul);
#define lwip_xchar(i) ((char)((i) < 10 ? '0' + (i) : 'A' + (i)-10)) #define lwip_xchar(i) ((char)((i) < 10 ? '0' + (i) : 'A' + (i) - 10))
/** /**
* Check whether "cp" is a valid ascii representation * Check whether "cp" is a valid ascii representation
@ -84,7 +84,7 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
zero_blocks--; zero_blocks--;
#if LWIP_IPV4 #if LWIP_IPV4
} else if (*s == '.') { } else if (*s == '.') {
if ((zero_blocks == 5) || (zero_blocks == 2)) { if ((zero_blocks == 5) ||(zero_blocks == 2)) {
check_ipv4_mapped = 1; check_ipv4_mapped = 1;
/* last block could be the start of an IPv4 address */ /* last block could be the start of an IPv4 address */
zero_blocks--; zero_blocks--;
@ -108,7 +108,8 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
if (addr) { if (addr) {
if (current_block_index & 0x1) { if (current_block_index & 0x1) {
addr->addr[addr_index++] |= current_block_value; addr->addr[addr_index++] |= current_block_value;
} else { }
else {
addr->addr[addr_index] = current_block_value << 16; addr->addr[addr_index] = current_block_value << 16;
} }
} }
@ -159,9 +160,9 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
} }
} else if (lwip_isxdigit(*s)) { } else if (lwip_isxdigit(*s)) {
/* add current digit */ /* add current digit */
current_block_value = current_block_value = (current_block_value << 4) +
(current_block_value << 4) + (lwip_isdigit(*s) ? (u32_t)(*s - '0') :
(lwip_isdigit(*s) ? (u32_t)(*s - '0') : (u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A'))); (u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A')));
} else { } else {
/* unexpected digit, space? CRLF? */ /* unexpected digit, space? CRLF? */
break; break;
@ -171,11 +172,12 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
if (addr) { if (addr) {
if (current_block_index & 0x1) { if (current_block_index & 0x1) {
addr->addr[addr_index++] |= current_block_value; addr->addr[addr_index++] |= current_block_value;
} else { }
else {
addr->addr[addr_index] = current_block_value << 16; addr->addr[addr_index] = current_block_value << 16;
} }
#if LWIP_IPV4 #if LWIP_IPV4
fix_byte_order_and_return: fix_byte_order_and_return:
#endif #endif
/* convert to network byte order. */ /* convert to network byte order. */
for (addr_index = 0; addr_index < 4; addr_index++) { for (addr_index = 0; addr_index < 4; addr_index++) {
@ -269,7 +271,7 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
* according to current formatting suggestions RFC 5952. */ * according to current formatting suggestions RFC 5952. */
next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]); next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]);
if ((current_block_index & 0x1) == 0x01) { if ((current_block_index & 0x1) == 0x01) {
next_block_value = next_block_value >> 16; next_block_value = next_block_value >> 16;
} }
next_block_value &= 0xffff; next_block_value &= 0xffff;
if (next_block_value == 0) { if (next_block_value == 0) {
@ -318,7 +320,8 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
if (((current_block_value & 0xf0) == 0) && (zero_flag)) { if (((current_block_value & 0xf0) == 0) && (zero_flag)) {
/* do nothing */ /* do nothing */
} else { }
else {
buf[i++] = lwip_xchar(((current_block_value & 0xf0) >> 4)); buf[i++] = lwip_xchar(((current_block_value & 0xf0) >> 4));
zero_flag = 0; zero_flag = 0;
if (i >= buflen) { if (i >= buflen) {

View File

@ -39,20 +39,21 @@
* <delamer@inicotech.com> * <delamer@inicotech.com>
*/ */
#include "lwip/ip6_frag.h"
#include "lwip/icmp6.h"
#include "lwip/ip.h"
#include "lwip/ip6.h"
#include "lwip/nd6.h"
#include "lwip/opt.h" #include "lwip/opt.h"
#include "lwip/ip6_frag.h"
#include "lwip/ip6.h"
#include "lwip/icmp6.h"
#include "lwip/nd6.h"
#include "lwip/ip.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "lwip/memp.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include <string.h> #include <string.h>
#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ #if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */
/** Setting this to 0, you can turn off checking the fragments for overlapping /** Setting this to 0, you can turn off checking the fragments for overlapping
* regions. The code gets a little smaller. Only use this if you know that * regions. The code gets a little smaller. Only use this if you know that
@ -85,18 +86,17 @@
* track of the various fragments. * track of the various fragments.
*/ */
#ifdef PACK_STRUCT_USE_INCLUDES #ifdef PACK_STRUCT_USE_INCLUDES
#include "arch/bpstruct.h" # include "arch/bpstruct.h"
#endif #endif
PACK_STRUCT_BEGIN PACK_STRUCT_BEGIN
struct ip6_reass_helper struct ip6_reass_helper {
{
PACK_STRUCT_FIELD(struct pbuf *next_pbuf); PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
PACK_STRUCT_FIELD(u16_t start); PACK_STRUCT_FIELD(u16_t start);
PACK_STRUCT_FIELD(u16_t end); PACK_STRUCT_FIELD(u16_t end);
} PACK_STRUCT_STRUCT; } PACK_STRUCT_STRUCT;
PACK_STRUCT_END PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES #ifdef PACK_STRUCT_USE_INCLUDES
#include "arch/epstruct.h" # include "arch/epstruct.h"
#endif #endif
/* static variables */ /* static variables */
@ -104,11 +104,9 @@ static struct ip6_reassdata *reassdatagrams;
static u16_t ip6_reass_pbufcount; static u16_t ip6_reass_pbufcount;
/* Forward declarations. */ /* Forward declarations. */
static void static void ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr);
ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr);
#if IP_REASS_FREE_OLDEST #if IP_REASS_FREE_OLDEST
static void static void ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed);
ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed);
#endif /* IP_REASS_FREE_OLDEST */ #endif /* IP_REASS_FREE_OLDEST */
void void
@ -118,7 +116,7 @@ ip6_reass_tmr(void)
#if !IPV6_FRAG_COPYHEADER #if !IPV6_FRAG_COPYHEADER
LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1", LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN); sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
#endif /* !IPV6_FRAG_COPYHEADER */ #endif /* !IPV6_FRAG_COPYHEADER */
r = reassdatagrams; r = reassdatagrams;
@ -135,8 +133,8 @@ ip6_reass_tmr(void)
r = r->next; r = r->next;
/* free the helper struct and all enqueued pbufs */ /* free the helper struct and all enqueued pbufs */
ip6_reass_free_complete_datagram(tmp); ip6_reass_free_complete_datagram(tmp);
} }
} }
} }
/** /**
@ -167,9 +165,10 @@ ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr)
MEMCPY(p->payload, ipr->orig_hdr, sizeof(iprh)); MEMCPY(p->payload, ipr->orig_hdr, sizeof(iprh));
/* Then, move back to the original ipv6 header (we are now pointing to Fragment header). /* Then, move back to the original ipv6 header (we are now pointing to Fragment header).
This cannot fail since we already checked when receiving this fragment. */ This cannot fail since we already checked when receiving this fragment. */
if (pbuf_header_force(p, (s16_t)((u8_t *)p->payload - (u8_t *)ipr->iphdr))) { if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr))) {
LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0); LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0);
} else { }
else {
/* Reconstruct the zoned source and destination addresses, so that we do /* Reconstruct the zoned source and destination addresses, so that we do
* not end up sending the ICMP response over the wrong link. */ * not end up sending the ICMP response over the wrong link. */
ip6_addr_t src_addr, dest_addr; ip6_addr_t src_addr, dest_addr;
@ -273,7 +272,7 @@ struct pbuf *
ip6_reass(struct pbuf *p) ip6_reass(struct pbuf *p)
{ {
struct ip6_reassdata *ipr, *ipr_prev; struct ip6_reassdata *ipr, *ipr_prev;
struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev = NULL; struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
struct ip6_frag_hdr *frag_hdr; struct ip6_frag_hdr *frag_hdr;
u16_t offset, len, start, end; u16_t offset, len, start, end;
ptrdiff_t hdrdiff; ptrdiff_t hdrdiff;
@ -284,9 +283,10 @@ ip6_reass(struct pbuf *p)
IP6_FRAG_STATS_INC(ip6_frag.recv); IP6_FRAG_STATS_INC(ip6_frag.recv);
/* ip6_frag_hdr must be in the first pbuf, not chained. Checked by caller. */ /* ip6_frag_hdr must be in the first pbuf, not chained. Checked by caller. */
LWIP_ASSERT("IPv6 fragment header does not fit in first pbuf", p->len >= sizeof(struct ip6_frag_hdr)); LWIP_ASSERT("IPv6 fragment header does not fit in first pbuf",
p->len >= sizeof(struct ip6_frag_hdr));
frag_hdr = (struct ip6_frag_hdr *)p->payload; frag_hdr = (struct ip6_frag_hdr *) p->payload;
clen = pbuf_clen(p); clen = pbuf_clen(p);
@ -296,7 +296,7 @@ ip6_reass(struct pbuf *p)
* Adjust for headers before Fragment Header. * Adjust for headers before Fragment Header.
* And finally adjust by Fragment Header length. */ * And finally adjust by Fragment Header length. */
len = lwip_ntohs(ip6_current_header()->_plen); len = lwip_ntohs(ip6_current_header()->_plen);
hdrdiff = (u8_t *)p->payload - (const u8_t *)ip6_current_header(); hdrdiff = (u8_t*)p->payload - (const u8_t*)ip6_current_header();
LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff <= 0xFFFF); LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff <= 0xFFFF);
LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff >= IP6_HLEN); LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff >= IP6_HLEN);
hdrdiff -= IP6_HLEN; hdrdiff -= IP6_HLEN;
@ -329,7 +329,7 @@ ip6_reass(struct pbuf *p)
} }
if (ipr == NULL) { if (ipr == NULL) {
/* Enqueue a new datagram into the datagram queue */ /* Enqueue a new datagram into the datagram queue */
ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA);
if (ipr == NULL) { if (ipr == NULL) {
#if IP_REASS_FREE_OLDEST #if IP_REASS_FREE_OLDEST
@ -414,9 +414,9 @@ ip6_reass(struct pbuf *p)
LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */ LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0); LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
} }
#else /* IPV6_FRAG_COPYHEADER */ #else /* IPV6_FRAG_COPYHEADER */
LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1", LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN); sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
#endif /* IPV6_FRAG_COPYHEADER */ #endif /* IPV6_FRAG_COPYHEADER */
/* Prepare the pointer to the helper structure, and its initial values. /* Prepare the pointer to the helper structure, and its initial values.
@ -431,7 +431,7 @@ ip6_reass(struct pbuf *p)
/* Iterate through until we either get to the end of the list (append), /* Iterate through until we either get to the end of the list (append),
* or we find on with a larger offset (insert). */ * or we find on with a larger offset (insert). */
for (q = ipr->p; q != NULL;) { for (q = ipr->p; q != NULL;) {
iprh_tmp = (struct ip6_reass_helper *)q->payload; iprh_tmp = (struct ip6_reass_helper*)q->payload;
if (start < iprh_tmp->start) { if (start < iprh_tmp->start) {
#if IP_REASS_CHECK_OVERLAP #if IP_REASS_CHECK_OVERLAP
if (end > iprh_tmp->start) { if (end > iprh_tmp->start) {
@ -494,7 +494,8 @@ ip6_reass(struct pbuf *p)
} }
} else { } else {
#if IP_REASS_CHECK_OVERLAP #if IP_REASS_CHECK_OVERLAP
LWIP_ASSERT("no previous fragment, this must be the first fragment!", ipr->p == NULL); LWIP_ASSERT("no previous fragment, this must be the first fragment!",
ipr->p == NULL);
#endif /* IP_REASS_CHECK_OVERLAP */ #endif /* IP_REASS_CHECK_OVERLAP */
/* this is the first fragment we ever received for this ip datagram */ /* this is the first fragment we ever received for this ip datagram */
ipr->p = p; ipr->p = p;
@ -527,7 +528,7 @@ ip6_reass(struct pbuf *p)
} }
/* Additional validity tests: we have received first and last fragment. */ /* Additional validity tests: we have received first and last fragment. */
iprh_tmp = (struct ip6_reass_helper *)ipr->p->payload; iprh_tmp = (struct ip6_reass_helper*)ipr->p->payload;
if (iprh_tmp->start != 0) { if (iprh_tmp->start != 0) {
valid = 0; valid = 0;
} }
@ -539,7 +540,7 @@ ip6_reass(struct pbuf *p)
iprh_prev = iprh; iprh_prev = iprh;
q = iprh->next_pbuf; q = iprh->next_pbuf;
while ((q != NULL) && valid) { while ((q != NULL) && valid) {
iprh = (struct ip6_reass_helper *)q->payload; iprh = (struct ip6_reass_helper*)q->payload;
if (iprh_prev->end != iprh->start) { if (iprh_prev->end != iprh->start) {
valid = 0; valid = 0;
break; break;
@ -550,15 +551,15 @@ ip6_reass(struct pbuf *p)
if (valid) { if (valid) {
/* All fragments have been received */ /* All fragments have been received */
struct ip6_hdr *iphdr_ptr; struct ip6_hdr* iphdr_ptr;
/* chain together the pbufs contained within the ip6_reassdata list. */ /* chain together the pbufs contained within the ip6_reassdata list. */
iprh = (struct ip6_reass_helper *)ipr->p->payload; iprh = (struct ip6_reass_helper*) ipr->p->payload;
while (iprh != NULL) { while (iprh != NULL) {
next_pbuf = iprh->next_pbuf; next_pbuf = iprh->next_pbuf;
if (next_pbuf != NULL) { if (next_pbuf != NULL) {
/* Save next helper struct (will be hidden in next step). */ /* Save next helper struct (will be hidden in next step). */
iprh_tmp = (struct ip6_reass_helper *)next_pbuf->payload; iprh_tmp = (struct ip6_reass_helper*)next_pbuf->payload;
/* hide the fragment header for every succeeding fragment */ /* hide the fragment header for every succeeding fragment */
pbuf_remove_header(next_pbuf, IP6_FRAG_HLEN); pbuf_remove_header(next_pbuf, IP6_FRAG_HLEN);
@ -571,7 +572,8 @@ ip6_reass(struct pbuf *p)
} }
#endif #endif
pbuf_cat(ipr->p, next_pbuf); pbuf_cat(ipr->p, next_pbuf);
} else { }
else {
iprh_tmp = NULL; iprh_tmp = NULL;
} }
@ -604,14 +606,16 @@ ip6_reass(struct pbuf *p)
* accordingly. This works because all these headers are in the first pbuf * accordingly. This works because all these headers are in the first pbuf
* of the chain, and because the caller adjusts all its pointers on * of the chain, and because the caller adjusts all its pointers on
* successful reassembly. */ * successful reassembly. */
MEMMOVE( MEMMOVE((u8_t*)ipr->iphdr + sizeof(struct ip6_frag_hdr), ipr->iphdr,
(u8_t *)ipr->iphdr + sizeof(struct ip6_frag_hdr), ipr->iphdr, (size_t)((u8_t *)p->payload - (u8_t *)ipr->iphdr)); (size_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr));
/* This is where the IPv6 header is now. */ /* This is where the IPv6 header is now. */
iphdr_ptr = (struct ip6_hdr *)((u8_t *)ipr->iphdr + sizeof(struct ip6_frag_hdr)); iphdr_ptr = (struct ip6_hdr*)((u8_t*)ipr->iphdr +
sizeof(struct ip6_frag_hdr));
/* Adjust datagram length by adding header lengths. */ /* Adjust datagram length by adding header lengths. */
ipr->datagram_len = (u16_t)(ipr->datagram_len + ((u8_t *)p->payload - (u8_t *)iphdr_ptr) - IP6_HLEN); ipr->datagram_len = (u16_t)(ipr->datagram_len + ((u8_t*)p->payload - (u8_t*)iphdr_ptr)
- IP6_HLEN);
/* Set payload length in ip header. */ /* Set payload length in ip header. */
iphdr_ptr->_plen = lwip_htons(ipr->datagram_len); iphdr_ptr->_plen = lwip_htons(ipr->datagram_len);
@ -647,7 +651,7 @@ ip6_reass(struct pbuf *p)
ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount - clen); ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount - clen);
/* Move pbuf back to IPv6 header. This should never fail. */ /* Move pbuf back to IPv6 header. This should never fail. */
if (pbuf_header_force(p, (s16_t)((u8_t *)p->payload - (u8_t *)iphdr_ptr))) { if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)iphdr_ptr))) {
LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0); LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0);
pbuf_free(p); pbuf_free(p);
return NULL; return NULL;
@ -671,15 +675,15 @@ nullreturn:
#if !LWIP_NETIF_TX_SINGLE_PBUF #if !LWIP_NETIF_TX_SINGLE_PBUF
/** Allocate a new struct pbuf_custom_ref */ /** Allocate a new struct pbuf_custom_ref */
static struct pbuf_custom_ref * static struct pbuf_custom_ref*
ip6_frag_alloc_pbuf_custom_ref(void) ip6_frag_alloc_pbuf_custom_ref(void)
{ {
return (struct pbuf_custom_ref *)memp_malloc(MEMP_FRAG_PBUF); return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF);
} }
/** Free a struct pbuf_custom_ref */ /** Free a struct pbuf_custom_ref */
static void static void
ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref *p) ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p)
{ {
LWIP_ASSERT("p != NULL", p != NULL); LWIP_ASSERT("p != NULL", p != NULL);
memp_free(MEMP_FRAG_PBUF, p); memp_free(MEMP_FRAG_PBUF, p);
@ -690,9 +694,9 @@ ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref *p)
static void static void
ip6_frag_free_pbuf_custom(struct pbuf *p) ip6_frag_free_pbuf_custom(struct pbuf *p)
{ {
struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref *)p; struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p;
LWIP_ASSERT("pcr != NULL", pcr != NULL); LWIP_ASSERT("pcr != NULL", pcr != NULL);
LWIP_ASSERT("pcr == p", (void *)pcr == (void *)p); LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p);
if (pcr->original != NULL) { if (pcr->original != NULL) {
pbuf_free(pcr->original); pbuf_free(pcr->original);
} }
@ -752,8 +756,9 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
IP6_FRAG_STATS_INC(ip6_frag.memerr); IP6_FRAG_STATS_INC(ip6_frag.memerr);
return ERR_MEM; return ERR_MEM;
} }
LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); LWIP_ASSERT("this needs a pbuf in one piece!",
poff += pbuf_copy_partial(p, (u8_t *)rambuf->payload + IP6_FRAG_HLEN, cop, poff); (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff);
/* make room for the IP header */ /* make room for the IP header */
if (pbuf_add_header(rambuf, IP6_HLEN)) { if (pbuf_add_header(rambuf, IP6_HLEN)) {
pbuf_free(rambuf); pbuf_free(rambuf);
@ -763,7 +768,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
/* fill in the IP header */ /* fill in the IP header */
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
ip6hdr = (struct ip6_hdr *)rambuf->payload; ip6hdr = (struct ip6_hdr *)rambuf->payload;
frag_hdr = (struct ip6_frag_hdr *)((u8_t *)rambuf->payload + IP6_HLEN); frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
#else #else
/* When not using a static buffer, create a chain of pbufs. /* When not using a static buffer, create a chain of pbufs.
* The first will be a PBUF_RAM holding the link, IPv6, and Fragment header. * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header.
@ -775,10 +780,11 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
IP6_FRAG_STATS_INC(ip6_frag.memerr); IP6_FRAG_STATS_INC(ip6_frag.memerr);
return ERR_MEM; return ERR_MEM;
} }
LWIP_ASSERT("this needs a pbuf in one piece!", (p->len >= (IP6_HLEN))); LWIP_ASSERT("this needs a pbuf in one piece!",
(p->len >= (IP6_HLEN)));
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
ip6hdr = (struct ip6_hdr *)rambuf->payload; ip6hdr = (struct ip6_hdr *)rambuf->payload;
frag_hdr = (struct ip6_frag_hdr *)((u8_t *)rambuf->payload + IP6_HLEN); frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
/* Can just adjust p directly for needed offset. */ /* Can just adjust p directly for needed offset. */
p->payload = (u8_t *)p->payload + poff; p->payload = (u8_t *)p->payload + poff;
@ -827,8 +833,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
/* Set headers */ /* Set headers */
frag_hdr->_nexth = original_ip6hdr->_nexth; frag_hdr->_nexth = original_ip6hdr->_nexth;
frag_hdr->reserved = 0; frag_hdr->reserved = 0;
frag_hdr->_fragment_offset = frag_hdr->_fragment_offset = lwip_htons((u16_t)((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG)));
lwip_htons((u16_t)((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG)));
frag_hdr->_identification = lwip_htonl(identification); frag_hdr->_identification = lwip_htonl(identification);
IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT); IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT);

View File

@ -6,7 +6,7 @@
* @ingroup ip6 * @ingroup ip6
* Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710.
* No support for MLDv2.\n * No support for MLDv2.\n
* Note: The allnodes (ff01::1, ff02::1) group is assumed be received by your * Note: The allnodes (ff01::1, ff02::1) group is assumed be received by your
* netif since it must always be received for correct IPv6 operation (e.g. SLAAC). * netif since it must always be received for correct IPv6 operation (e.g. SLAAC).
* Ensure the netif filters are configured accordingly!\n * Ensure the netif filters are configured accordingly!\n
* The netif flags also need NETIF_FLAG_MLD6 flag set to enable MLD6 on a * The netif flags also need NETIF_FLAG_MLD6 flag set to enable MLD6 on a
@ -53,41 +53,39 @@
#include "lwip/opt.h" #include "lwip/opt.h"
#if LWIP_IPV6 && LWIP_IPV6_MLD /* don't build if not configured for use in lwipopts.h */ #if LWIP_IPV6 && LWIP_IPV6_MLD /* don't build if not configured for use in lwipopts.h */
#include "lwip/mld6.h"
#include "lwip/prot/mld6.h"
#include "lwip/icmp6.h" #include "lwip/icmp6.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/ip6.h" #include "lwip/ip6.h"
#include "lwip/ip6_addr.h" #include "lwip/ip6_addr.h"
#include "lwip/memp.h" #include "lwip/ip.h"
#include "lwip/mld6.h" #include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "lwip/prot/mld6.h" #include "lwip/netif.h"
#include "lwip/memp.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include <string.h> #include <string.h>
/* /*
* MLD constants * MLD constants
*/ */
#define MLD6_HL 1 #define MLD6_HL 1
#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500) #define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500)
#define MLD6_GROUP_NON_MEMBER 0 #define MLD6_GROUP_NON_MEMBER 0
#define MLD6_GROUP_DELAYING_MEMBER 1 #define MLD6_GROUP_DELAYING_MEMBER 1
#define MLD6_GROUP_IDLE_MEMBER 2 #define MLD6_GROUP_IDLE_MEMBER 2
/* Forward declarations. */ /* Forward declarations. */
static struct mld_group * static struct mld_group *mld6_new_group(struct netif *ifp, const ip6_addr_t *addr);
mld6_new_group(struct netif *ifp, const ip6_addr_t *addr); static err_t mld6_remove_group(struct netif *netif, struct mld_group *group);
static err_t static void mld6_delayed_report(struct mld_group *group, u16_t maxresp);
mld6_remove_group(struct netif *netif, struct mld_group *group); static void mld6_send(struct netif *netif, struct mld_group *group, u8_t type);
static void
mld6_delayed_report(struct mld_group *group, u16_t maxresp);
static void
mld6_send(struct netif *netif, struct mld_group *group, u8_t type);
/** /**
* Stop MLD processing on interface * Stop MLD processing on interface
@ -157,6 +155,7 @@ mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr)
return NULL; return NULL;
} }
/** /**
* create a new group * create a new group
* *
@ -173,11 +172,11 @@ mld6_new_group(struct netif *ifp, const ip6_addr_t *addr)
group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP); group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP);
if (group != NULL) { if (group != NULL) {
ip6_addr_set(&(group->group_address), addr); ip6_addr_set(&(group->group_address), addr);
group->timer = 0; /* Not running */ group->timer = 0; /* Not running */
group->group_state = MLD6_GROUP_IDLE_MEMBER; group->group_state = MLD6_GROUP_IDLE_MEMBER;
group->last_reporter_flag = 0; group->last_reporter_flag = 0;
group->use = 0; group->use = 0;
group->next = netif_mld6_data(ifp); group->next = netif_mld6_data(ifp);
netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group); netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group);
} }
@ -217,6 +216,7 @@ mld6_remove_group(struct netif *netif, struct mld_group *group)
return err; return err;
} }
/** /**
* Process an input MLD message. Called by icmp6_input. * Process an input MLD message. Called by icmp6_input.
* *
@ -243,53 +243,54 @@ mld6_input(struct pbuf *p, struct netif *inp)
mld_hdr = (struct mld_header *)p->payload; mld_hdr = (struct mld_header *)p->payload;
switch (mld_hdr->type) { switch (mld_hdr->type) {
case ICMP6_TYPE_MLQ: /* Multicast listener query. */ case ICMP6_TYPE_MLQ: /* Multicast listener query. */
/* Is it a general query? */ /* Is it a general query? */
if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && ip6_addr_isany(&(mld_hdr->multicast_address))) { if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) &&
MLD6_STATS_INC(mld6.rx_general); ip6_addr_isany(&(mld_hdr->multicast_address))) {
/* Report all groups, except all nodes group, and if-local groups. */ MLD6_STATS_INC(mld6.rx_general);
group = netif_mld6_data(inp); /* Report all groups, except all nodes group, and if-local groups. */
while (group != NULL) { group = netif_mld6_data(inp);
if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) && while (group != NULL) {
(!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) { if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
mld6_delayed_report(group, mld_hdr->max_resp_delay); (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
}
group = group->next;
}
} else {
/* Have we joined this group?
* We use IP6 destination address to have a memory aligned copy.
* mld_hdr->multicast_address should be the same. */
MLD6_STATS_INC(mld6.rx_group);
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, mld_hdr->max_resp_delay);
} }
group = group->next;
} }
break; /* ICMP6_TYPE_MLQ */ } else {
case ICMP6_TYPE_MLR: /* Multicast listener report. */
/* Have we joined this group? /* Have we joined this group?
* We use IP6 destination address to have a memory aligned copy. * We use IP6 destination address to have a memory aligned copy.
* mld_hdr->multicast_address should be the same. */ * mld_hdr->multicast_address should be the same. */
MLD6_STATS_INC(mld6.rx_report); MLD6_STATS_INC(mld6.rx_group);
group = mld6_lookfor_group(inp, ip6_current_dest_addr()); group = mld6_lookfor_group(inp, ip6_current_dest_addr());
if (group != NULL) { if (group != NULL) {
/* If we are waiting to report, cancel it. */ /* Schedule a report. */
if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { mld6_delayed_report(group, mld_hdr->max_resp_delay);
group->timer = 0; /* stopped */
group->group_state = MLD6_GROUP_IDLE_MEMBER;
group->last_reporter_flag = 0;
}
} }
break; /* ICMP6_TYPE_MLR */ }
case ICMP6_TYPE_MLD: /* Multicast listener done. */ break; /* ICMP6_TYPE_MLQ */
/* Do nothing, router will query us. */ case ICMP6_TYPE_MLR: /* Multicast listener report. */
break; /* ICMP6_TYPE_MLD */ /* Have we joined this group?
default: * We use IP6 destination address to have a memory aligned copy.
MLD6_STATS_INC(mld6.proterr); * mld_hdr->multicast_address should be the same. */
MLD6_STATS_INC(mld6.drop); MLD6_STATS_INC(mld6.rx_report);
break; group = mld6_lookfor_group(inp, ip6_current_dest_addr());
if (group != NULL) {
/* If we are waiting to report, cancel it. */
if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
group->timer = 0; /* stopped */
group->group_state = MLD6_GROUP_IDLE_MEMBER;
group->last_reporter_flag = 0;
}
}
break; /* ICMP6_TYPE_MLR */
case ICMP6_TYPE_MLD: /* Multicast listener done. */
/* Do nothing, router will query us. */
break; /* ICMP6_TYPE_MLD */
default:
MLD6_STATS_INC(mld6.proterr);
MLD6_STATS_INC(mld6.drop);
break;
} }
pbuf_free(p); pbuf_free(p);
@ -313,16 +314,16 @@ mld6_input(struct pbuf *p, struct netif *inp)
err_t err_t
mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
{ {
err_t err = ERR_VAL; /* no matching interface */ err_t err = ERR_VAL; /* no matching interface */
struct netif *netif; struct netif *netif;
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
/* loop through netif's */ /* loop through netif's */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
/* Should we join this interface ? */ /* Should we join this interface ? */
if (ip6_addr_isany(srcaddr) || netif_get_ip6_addr_match(netif, srcaddr) >= 0) { if (ip6_addr_isany(srcaddr) ||
netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
err = mld6_joingroup_netif(netif, groupaddr); err = mld6_joingroup_netif(netif, groupaddr);
if (err != ERR_OK) { if (err != ERR_OK) {
return err; return err;
@ -402,16 +403,16 @@ mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
err_t err_t
mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
{ {
err_t err = ERR_VAL; /* no matching interface */ err_t err = ERR_VAL; /* no matching interface */
struct netif *netif; struct netif *netif;
LWIP_ASSERT_CORE_LOCKED(); LWIP_ASSERT_CORE_LOCKED();
/* loop through netif's */ /* loop through netif's */
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
/* Should we leave this interface ? */ /* Should we leave this interface ? */
if (ip6_addr_isany(srcaddr) || netif_get_ip6_addr_match(netif, srcaddr) >= 0) { if (ip6_addr_isany(srcaddr) ||
netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
err_t res = mld6_leavegroup_netif(netif, groupaddr); err_t res = mld6_leavegroup_netif(netif, groupaddr);
if (err != ERR_OK) { if (err != ERR_OK) {
/* Store this result if we have not yet gotten a success */ /* Store this result if we have not yet gotten a success */
@ -484,6 +485,7 @@ mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
return ERR_VAL; return ERR_VAL;
} }
/** /**
* Periodic timer for mld processing. Must be called every * Periodic timer for mld processing. Must be called every
* MLD6_TMR_INTERVAL milliseconds (100). * MLD6_TMR_INTERVAL milliseconds (100).
@ -495,8 +497,7 @@ mld6_tmr(void)
{ {
struct netif *netif; struct netif *netif;
NETIF_FOREACH(netif) NETIF_FOREACH(netif) {
{
struct mld_group *group = netif_mld6_data(netif); struct mld_group *group = netif_mld6_data(netif);
while (group != NULL) { while (group != NULL) {
@ -542,7 +543,8 @@ mld6_delayed_report(struct mld_group *group, u16_t maxresp_in)
/* Apply timer value if no report has been scheduled already. */ /* Apply timer value if no report has been scheduled already. */
if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) || if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) ||
((group->group_state == MLD6_GROUP_DELAYING_MEMBER) && ((group->timer == 0) || (maxresp < group->timer)))) { ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) &&
((group->timer == 0) || (maxresp < group->timer)))) {
group->timer = maxresp; group->timer = maxresp;
group->group_state = MLD6_GROUP_DELAYING_MEMBER; group->group_state = MLD6_GROUP_DELAYING_MEMBER;
} }
@ -600,9 +602,9 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
ip6_addr_copy_to_packed(mld_hdr->multicast_address, group->group_address); ip6_addr_copy_to_packed(mld_hdr->multicast_address, group->group_address);
#if CHECKSUM_GEN_ICMP6 #if CHECKSUM_GEN_ICMP6
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) {
{ mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len,
mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, &(group->group_address)); src_addr, &(group->group_address));
} }
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
@ -616,8 +618,8 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
/* Send the packet out. */ /* Send the packet out. */
MLD6_STATS_INC(mld6.xmit); MLD6_STATS_INC(mld6.xmit);
ip6_output_if( ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address),
p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif); MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif);
pbuf_free(p); pbuf_free(p);
} }

File diff suppressed because it is too large Load Diff