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

Does it compile? Does it look good (enough)?
This commit is contained in:
Dirk Ziegelmeier 2018-07-17 21:15:48 +02:00
parent 4e74421dac
commit 8b4a8159a8
25 changed files with 3021 additions and 2721 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
@ -92,18 +92,22 @@
#endif /* TCP_LISTEN_BACKLOG */ #endif /* TCP_LISTEN_BACKLOG */
#if LWIP_NETCONN_FULLDUPLEX #if LWIP_NETCONN_FULLDUPLEX
#define NETCONN_RECVMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->recvmbox) && (((conn)->flags & NETCONN_FLAG_MBOXINVALID) == 0)) #define NETCONN_RECVMBOX_WAITABLE(conn) \
#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & (NETCONN_FLAG_MBOXCLOSED|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_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) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & NETCONN_FLAG_MBOXCLOSED) == 0)) #define NETCONN_ACCEPTMBOX_WAITABLE(conn) \
(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 netconn_close_shutdown(struct netconn *conn, u8_t how); static err_t
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
@ -322,8 +326,7 @@ 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) && if ((netconn_get_ipv6only(conn) == 0) && ip_addr_cmp(addr, IP6_ADDR_ANY)) {
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 */
@ -595,8 +598,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) || if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) || (conn->flags & NETCONN_FLAG_MBOXCLOSED) ||
(conn->flags & NETCONN_FLAG_MBOXCLOSED) || (conn->pending_err != ERR_OK)) { (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);
@ -676,8 +679,9 @@ 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", (conn != NULL) && LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn",
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); (conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
return ERR_ARG;);
msg->conn = conn; msg->conn = conn;
msg->msg.r.len = len; msg->msg.r.len = len;
@ -690,8 +694,9 @@ 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", (conn != NULL) && LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn",
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); (conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
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));
@ -781,8 +786,9 @@ handle_fin:
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", (conn != NULL) && LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn",
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); (conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
return ERR_ARG;);
return netconn_recv_data_tcp(conn, new_buf, 0); return netconn_recv_data_tcp(conn, new_buf, 0);
} }
@ -802,8 +808,9 @@ 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", (conn != NULL) && LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn",
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); (conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
return ERR_ARG;);
return netconn_recv_data_tcp(conn, new_buf, apiflags); return netconn_recv_data_tcp(conn, new_buf, apiflags);
} }
@ -821,8 +828,9 @@ 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", (conn != NULL) && LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn",
NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;); (conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP,
return ERR_ARG;);
return netconn_recv_data(conn, (void **)new_buf, 0); return netconn_recv_data(conn, (void **)new_buf, 0);
} }
@ -841,8 +849,9 @@ 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", (conn != NULL) && LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn",
NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;); (conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP,
return ERR_ARG;);
return netconn_recv_data(conn, (void **)new_buf, apiflags); return netconn_recv_data(conn, (void **)new_buf, apiflags);
} }
@ -971,8 +980,7 @@ 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, netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags, size_t *bytes_written)
u8_t apiflags, size_t *bytes_written)
{ {
struct netvector vector; struct netvector vector;
vector.ptr = dataptr; vector.ptr = dataptr;
@ -994,8 +1002,11 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
* @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, struct netvector *vectors, u16_t vectorcnt, netconn_write_vectors_partly(struct netconn *conn,
u8_t apiflags, size_t *bytes_written) struct netvector *vectors,
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;

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/udp.h"
#include "lwip/tcp.h"
#include "lwip/raw.h" #include "lwip/raw.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "lwip/memp.h"
#include "lwip/igmp.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "lwip/igmp.h"
#include "lwip/memp.h"
#include "lwip/mld6.h" #include "lwip/mld6.h"
#include "lwip/priv/tcpip_priv.h" #include "lwip/priv/tcpip_priv.h"
@ -59,10 +59,14 @@
/* 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) do { if (val) { \ #define SET_NONBLOCKING_CONNECT(conn, val) \
do { \
if (val) { \
netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \ netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \
} else { \ } else { \
netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); }} while(0) 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
@ -80,16 +84,22 @@
#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 lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM); static err_t
static err_t lwip_netconn_do_close_internal(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);
#endif #endif
static void netconn_drain(struct netconn *conn); static void
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) do { sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0) #define TCPIP_APIMSG_ACK(m) \
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
@ -146,7 +156,6 @@ 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.
@ -156,8 +165,7 @@ 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, recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
const ip_addr_t *addr)
{ {
struct pbuf *q; struct pbuf *q;
struct netbuf *buf; struct netbuf *buf;
@ -215,8 +223,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
* @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, recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
const ip_addr_t *addr, u16_t port)
{ {
struct netbuf *buf; struct netbuf *buf;
struct netconn *conn; struct netconn *conn;
@ -239,8 +246,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
#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) || if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) || ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
((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 */
@ -473,8 +479,7 @@ 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) || if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || (old_state == NETCONN_CONNECT)) {
(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);
@ -800,11 +805,9 @@ 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", LWIP_ASSERT("recvmbox must be deallocated before calling this function", !sys_mbox_valid(&conn->recvmbox));
!sys_mbox_valid(&conn->recvmbox));
#if LWIP_TCP #if LWIP_TCP
LWIP_ASSERT("acceptmbox must be deallocated before calling this function", LWIP_ASSERT("acceptmbox must be deallocated before calling this function", !sys_mbox_valid(&conn->acceptmbox));
!sys_mbox_valid(&conn->acceptmbox));
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
#if !LWIP_NETCONN_SEM_PER_THREAD #if !LWIP_NETCONN_SEM_PER_THREAD
@ -941,10 +944,7 @@ 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 && } else if (shut_rx && ((tpcb->state == FIN_WAIT_1) || (tpcb->state == FIN_WAIT_2) || (tpcb->state == CLOSING))) {
((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,8 +988,7 @@ 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) >= } else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= (conn->linger * 1000)) {
(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);
@ -1120,8 +1119,7 @@ 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) || if ((state == NETCONN_WRITE) || ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
((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);
@ -1133,9 +1131,7 @@ lwip_netconn_do_delconn(void *m)
} }
} }
#else /* LWIP_NETCONN_FULLDUPLEX */ #else /* LWIP_NETCONN_FULLDUPLEX */
if (((state != NETCONN_NONE) && if (((state != NETCONN_NONE) && (state != NETCONN_LISTEN) && (state != NETCONN_CONNECT)) ||
(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) */
@ -1143,8 +1139,7 @@ lwip_netconn_do_delconn(void *m)
} else } else
#endif /* LWIP_NETCONN_FULLDUPLEX */ #endif /* LWIP_NETCONN_FULLDUPLEX */
{ {
LWIP_ASSERT("blocking connect in progress", LWIP_ASSERT("blocking connect in progress", (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
(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 */
@ -1326,8 +1321,7 @@ 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);
@ -1376,8 +1370,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(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), err = tcp_connect(
msg->msg.bc.port, lwip_netconn_do_connected); msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), 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;
@ -1402,9 +1396,7 @@ lwip_netconn_do_connect(void *m)
break; break;
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
default: default:
LWIP_ERROR("Invalid netconn type", 0, do { LWIP_ERROR("Invalid netconn type", 0, do { err = ERR_VAL; } while (0));
err = ERR_VAL;
} while (0));
break; break;
} }
} }
@ -1469,8 +1461,7 @@ lwip_netconn_do_listen(void *m)
/* "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) && if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) && (netconn_get_ipv6only(msg->conn) == 0)) {
(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);
@ -1550,12 +1541,15 @@ 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(msg->conn->pcb.udp, msg->msg.b->p, err = udp_send_chksum(
msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
} else { } else {
err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, err = udp_sendto_chksum(msg->conn->pcb.udp,
&msg->msg.b->addr, msg->msg.b->port, msg->msg.b->p,
msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); &msg->msg.b->addr,
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)) {
@ -1660,8 +1654,7 @@ 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) && if ((conn->send_timeout != 0) && ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
((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 */
@ -1702,8 +1695,7 @@ 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) || if ((len == 0xffff && diff > 0xffffUL) || (len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) {
(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 {
@ -1732,8 +1724,7 @@ err_mem:
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) || } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
(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);
@ -1870,11 +1861,9 @@ 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), ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->local_ip);
msg->conn->pcb.ip->local_ip);
} else { } else {
ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->remote_ip);
msg->conn->pcb.ip->remote_ip);
} }
msg->err = ERR_OK; msg->err = ERR_OK;
@ -1909,7 +1898,8 @@ 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) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port); API_EXPR_DEREF(msg->msg.ad.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 */
@ -1939,8 +1929,7 @@ 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) && if ((msg->conn->pcb.tcp != NULL) && (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) &&
(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) {
@ -2075,22 +2064,18 @@ 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, msg->err = mld6_joingroup_netif(netif, ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
} else { } else {
msg->err = mld6_leavegroup_netif(netif, msg->err = mld6_leavegroup_netif(netif, ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
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, msg->err = igmp_joingroup_netif(netif, ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
} else { } else {
msg->err = igmp_leavegroup_netif(netif, msg->err = igmp_leavegroup_netif(netif, ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
} }
#endif /* LWIP_IGMP */ #endif /* LWIP_IGMP */
} }
@ -2150,8 +2135,8 @@ lwip_netconn_do_gethostbyname(void *arg)
LWIP_DNS_ADDRTYPE_DEFAULT; LWIP_DNS_ADDRTYPE_DEFAULT;
#endif #endif
API_EXPR_DEREF(msg->err) = dns_gethostbyname_addrtype(msg->name, API_EXPR_DEREF(msg->err) =
API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype); dns_gethostbyname_addrtype(msg->name, 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) {

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/netbuf.h"
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/netbuf.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 struct netbuf *
netbuf *netbuf_new(void) netbuf_new(void)
{ {
struct netbuf *buf; struct netbuf *buf;
@ -111,8 +111,7 @@ 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", LWIP_ASSERT("check that first pbuf can hold size", (buf->p->len >= size));
(buf->p->len >= size));
buf->ptr = buf->p; buf->ptr = buf->p;
return buf->p->payload; return buf->p->payload;
} }

View File

@ -39,18 +39,19 @@
#if LWIP_DNS && LWIP_SOCKET #if LWIP_DNS && LWIP_SOCKET
#include "lwip/err.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/ip_addr.h"
#include "lwip/api.h" #include "lwip/api.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "lwip/err.h"
#include "lwip/ip_addr.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include <string.h> /* memset */
#include <stdlib.h> /* atoi */ #include <stdlib.h> /* atoi */
#include <string.h> /* memset */
/** 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;
@ -129,7 +130,8 @@ 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, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx]))); LWIP_DEBUGF(DNS_DEBUG,
("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
} }
} }
#endif /* DNS_DEBUG */ #endif /* DNS_DEBUG */
@ -159,8 +161,12 @@ 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, struct hostent *ret, char *buf, lwip_gethostbyname_r(const char *name,
size_t buflen, struct hostent **result, int *h_errnop) struct hostent *ret,
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;
@ -266,8 +272,7 @@ 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, lwip_getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
const struct addrinfo *hints, struct addrinfo **res)
{ {
err_t err; err_t err;
ip_addr_t addr; ip_addr_t addr;
@ -319,8 +324,7 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
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) || if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) || (IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) {
(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 */
@ -359,8 +363,7 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
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!", LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", total_size <= NETDB_ELEM_SIZE);
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,8 +43,8 @@
#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/netifapi.h"
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/netifapi.h"
#include "lwip/priv/tcpip_priv.h" #include "lwip/priv/tcpip_priv.h"
#include <string.h> /* strncpy */ #include <string.h> /* strncpy */
@ -90,10 +90,8 @@ 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( msg->netif, netif_set_addr(
API_EXPR_REF(msg->msg.add.ipaddr), 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.netmask),
API_EXPR_REF(msg->msg.add.gw));
return ERR_OK; return ERR_OK;
} }
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
@ -221,9 +219,13 @@ 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 *netmask, const ip4_addr_t *gw, const ip4_addr_t *ipaddr,
const ip4_addr_t *netmask,
const ip4_addr_t *gw,
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
void *state, netif_init_fn init, netif_input_fn input) void *state,
netif_init_fn init,
netif_input_fn input)
{ {
err_t err; err_t err;
NETIFAPI_VAR_DECLARE(msg); NETIFAPI_VAR_DECLARE(msg);
@ -264,10 +266,7 @@ 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, netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw)
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);
@ -300,8 +299,7 @@ netifapi_netif_set_addr(struct netif *netif,
* @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_netif_common(struct netif *netif, netifapi_void_fn voidfunc, netifapi_errt_fn errtfunc)
netifapi_errt_fn errtfunc)
{ {
err_t err; err_t err;
NETIFAPI_VAR_DECLARE(msg); NETIFAPI_VAR_DECLARE(msg);

File diff suppressed because it is too large Load Diff

View File

@ -40,14 +40,14 @@
#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/priv/tcpip_priv.h" #include "lwip/etharp.h"
#include "lwip/sys.h"
#include "lwip/memp.h"
#include "lwip/mem.h"
#include "lwip/init.h" #include "lwip/init.h"
#include "lwip/ip.h" #include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "lwip/etharp.h" #include "lwip/priv/tcpip_priv.h"
#include "lwip/sys.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)
@ -65,7 +65,8 @@ 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 tcpip_thread_handle_msg(struct tcpip_msg *msg); static void
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) */
@ -420,7 +421,6 @@ 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,

View File

@ -62,10 +62,10 @@
#include "lwip/mem.h" #include "lwip/mem.h"
/* #include "lwip/udp.h" */ /* #include "lwip/udp.h" */
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/autoip.h" #include "lwip/autoip.h"
#include "lwip/etharp.h" #include "lwip/etharp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/prot/autoip.h" #include "lwip/prot/autoip.h"
#include <string.h> #include <string.h>
@ -73,10 +73,9 @@
/** 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) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ #define LWIP_AUTOIP_RAND(netif) \
((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ ((((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | ((u32_t)((netif->hwaddr[4]) & 0xff))) + \
((u32_t)((netif->hwaddr[4]) & 0xff))) + \
(netif_autoip_data(netif) ? netif_autoip_data(netif)->tried_llipaddr : 0)) (netif_autoip_data(netif) ? netif_autoip_data(netif)->tried_llipaddr : 0))
#endif /* LWIP_AUTOIP_RAND */ #endif /* LWIP_AUTOIP_RAND */
@ -86,13 +85,14 @@
*/ */
#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])) | \ lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
((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 autoip_arp_announce(struct netif *netif); static err_t
static void autoip_start_probing(struct netif *netif); autoip_arp_announce(struct netif *netif);
static void
autoip_start_probing(struct netif *netif);
/** /**
* @ingroup autoip * @ingroup autoip
@ -108,8 +108,7 @@ 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", LWIP_ASSERT("netif already has a struct autoip set", netif_autoip_data(netif) == NULL);
netif_autoip_data(netif) == NULL);
/* clear data structure */ /* clear data structure */
memset(autoip, 0, sizeof(struct autoip)); memset(autoip, 0, sizeof(struct autoip));
@ -185,14 +184,16 @@ 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) && LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && (addr <= AUTOIP_RANGE_END));
(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), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), (u16_t)(autoip->tried_llipaddr),
ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); ip4_addr1_16(ipaddr),
ip4_addr2_16(ipaddr),
ip4_addr3_16(ipaddr),
ip4_addr4_16(ipaddr)));
} }
/** /**
@ -232,9 +233,14 @@ autoip_bind(struct netif *netif)
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, netif->name[0], netif->name[1], (u16_t)netif->num, (void *)netif,
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), netif->name[0],
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); netif->name[1],
(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);
@ -265,17 +271,15 @@ 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(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, LWIP_DEBUGF(
("autoip_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0], AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
netif->name[1], (u16_t)netif->num)); ("autoip_start(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], 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, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): starting new AUTOIP client\n"));
("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, LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): could not allocate autoip\n"));
("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 */
@ -304,8 +308,10 @@ autoip_start_probing(struct netif *netif)
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_addr2_16(&autoip->llipaddr), ip4_addr1_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); ip4_addr2_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.
@ -368,7 +374,8 @@ 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) {
@ -377,8 +384,7 @@ 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", ("autoip_tmr() AutoIP-State: %" U16_F ", ttw=%" U16_F "\n", (u16_t)(autoip->state), autoip->ttw));
(u16_t)(autoip->state), autoip->ttw));
if (autoip->ttw > 0) { if (autoip->ttw > 0) {
autoip->ttw--; autoip->ttw--;
@ -397,8 +403,10 @@ autoip_tmr(void)
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_addr2_16(&autoip->llipaddr), ip4_addr1_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); ip4_addr2_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"));
@ -408,8 +416,7 @@ 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) % autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND)) +
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
PROBE_MIN * AUTOIP_TICKS_PER_SECOND); PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
} }
} }
@ -429,8 +436,10 @@ autoip_tmr(void)
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_addr2_16(&autoip->llipaddr), ip4_addr1_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); ip4_addr2_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr),
ip4_addr4_16(&autoip->llipaddr)));
} }
} }
break; break;
@ -479,8 +488,7 @@ 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_isany_val(sipaddr) && ip4_addr_cmp(&dipaddr, &autoip->llipaddr) &&
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"));
@ -491,8 +499,7 @@ 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) && if (ip4_addr_cmp(&sipaddr, &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(): 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/stats.h" #include "lwip/autoip.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,7 +89,10 @@
#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) do { LWIP_UNUSED_ARG(msg); } while(0) #define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \
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
@ -132,7 +135,8 @@
* 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,
@ -160,15 +164,16 @@ u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
@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[] = { static u8_t dhcp_discover_request_options[] = { DHCP_OPTION_SUBNET_MASK,
DHCP_OPTION_SUBNET_MASK,
DHCP_OPTION_ROUTER, DHCP_OPTION_ROUTER,
DHCP_OPTION_BROADCAST 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 */
}; };
@ -188,38 +193,56 @@ 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 dhcp_discover(struct netif *netif); static err_t
static err_t dhcp_select(struct netif *netif); dhcp_discover(struct netif *netif);
static void dhcp_bind(struct netif *netif); static err_t
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 dhcp_decline(struct netif *netif); static err_t
dhcp_decline(struct netif *netif);
#endif /* DHCP_DOES_ARP_CHECK */ #endif /* DHCP_DOES_ARP_CHECK */
static err_t dhcp_rebind(struct netif *netif); static err_t
static err_t dhcp_reboot(struct netif *netif); dhcp_rebind(struct netif *netif);
static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state); static err_t
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 dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); static void
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 dhcp_timeout(struct netif *netif); static void
static void dhcp_t1_timeout(struct netif *netif); dhcp_timeout(struct netif *netif);
static void dhcp_t2_timeout(struct netif *netif); static void
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 *dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t *options_out_len); static struct pbuf *
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 dhcp_option(u16_t options_out_len, u8_t *options, u8_t option_type, u8_t option_len); static u16_t
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 dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value); static u16_t
static u16_t dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value); dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value);
static u16_t dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value); static u16_t
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 dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif); static u16_t
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 dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out); static void
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
@ -278,8 +301,9 @@ dhcp_handle_nak(struct netif *netif)
{ {
struct dhcp *dhcp = netif_dhcp_data(netif); struct dhcp *dhcp = netif_dhcp_data(netif);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", LWIP_DEBUGF(
(void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); DHCP_DEBUG | LWIP_DBG_TRACE,
("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);
@ -305,8 +329,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, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
(s16_t)netif->name[1])); ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], (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. */
@ -319,7 +343,8 @@ 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, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_check(): set request timeout %" U16_F " msecs\n", msecs));
} }
#endif /* DHCP_DOES_ARP_CHECK */ #endif /* DHCP_DOES_ARP_CHECK */
@ -333,19 +358,20 @@ 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(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n", LWIP_DEBUGF(
(void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); DHCP_DEBUG | LWIP_DBG_TRACE,
("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, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE,
ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr)))); ("dhcp_handle_offer(): server 0x%08" X32_F "\n", 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, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE,
ip4_addr_get_u32(&dhcp->offered_ip_addr))); ("dhcp_handle_offer(): offer for 0x%08" X32_F "\n", ip4_addr_get_u32(&dhcp->offered_ip_addr)));
dhcp_select(netif); dhcp_select(netif);
} else { } else {
@ -376,24 +402,32 @@ 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(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)); 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_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 = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); options_out_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 = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); options_out_len =
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, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr)))); 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 = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); options_out_len = dhcp_option(options_out_len,
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]);
} }
@ -410,7 +444,8 @@ 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, ("dhcp_select: could not allocate DHCP request\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("dhcp_select: could not allocate DHCP request\n"));
result = ERR_MEM; result = ERR_MEM;
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
@ -432,7 +467,8 @@ 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)) {
@ -469,7 +505,8 @@ 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) {
@ -511,7 +548,8 @@ 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, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_timeout(): REQUESTING, releasing, restarting\n"));
dhcp_release_and_stop(netif); dhcp_release_and_stop(netif);
dhcp_start(netif); dhcp_start(netif);
} }
@ -552,8 +590,7 @@ 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, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));
("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);
@ -578,8 +615,7 @@ 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, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout(): must rebind\n"));
("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);
@ -709,7 +745,8 @@ 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 dhcp_cleanup(struct netif *netif) void
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);
@ -743,7 +780,9 @@ 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(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)); 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));
/* 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) {
@ -792,7 +831,6 @@ 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) {
@ -834,7 +872,8 @@ 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 = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); options_out_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);
@ -846,7 +885,8 @@ 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, ("dhcp_inform: could not allocate DHCP request\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("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 */
@ -912,8 +952,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, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
ip4_addr_get_u32(addr))); ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08" X32_F "\n", 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)) {
@ -950,7 +990,8 @@ 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 = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); options_out_len =
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);
@ -974,7 +1015,6 @@ dhcp_decline(struct netif *netif)
} }
#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.
* *
@ -1000,23 +1040,29 @@ 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 = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); options_out_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, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); options_out_len = dhcp_option(options_out_len,
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, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, LWIP_IANA_PORT_DHCP_SERVER)\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
("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, ("dhcp_discover: could not allocate DHCP request\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("dhcp_discover: could not allocate DHCP request\n"));
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
dhcp->tries++; dhcp->tries++;
@ -1029,11 +1075,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, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("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.
* *
@ -1048,14 +1094,17 @@ 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(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)); 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));
/* 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, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
("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;
@ -1064,13 +1113,15 @@ 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, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease * 1000)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("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, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
("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;
@ -1079,12 +1130,14 @@ 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, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew * 1000)); 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->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, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
("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;
@ -1093,7 +1146,8 @@ 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, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind * 1000)); 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->t2_rebind_time = dhcp->t2_timeout; dhcp->t2_rebind_time = dhcp->t2_timeout;
} }
@ -1133,8 +1187,11 @@ dhcp_bind(struct netif *netif)
} }
#endif /* LWIP_DHCP_AUTOIP_COOP */ #endif /* LWIP_DHCP_AUTOIP_COOP */
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", LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE,
ip4_addr_get_u32(&dhcp->offered_ip_addr), ip4_addr_get_u32(&sn_mask), ip4_addr_get_u32(&gw_addr))); ("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)));
/* 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);
@ -1167,10 +1224,14 @@ 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 = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); options_out_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, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); options_out_len = dhcp_option(options_out_len,
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]);
} }
@ -1187,7 +1248,8 @@ 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, ("dhcp_renew: could not allocate DHCP request\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("dhcp_renew: could not allocate DHCP request\n"));
result = ERR_MEM; result = ERR_MEM;
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
@ -1196,7 +1258,8 @@ 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, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_renew(): set request timeout %" U16_F " msecs\n", msecs));
return result; return result;
} }
@ -1222,10 +1285,14 @@ 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 = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); options_out_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, msg_out->options, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); options_out_len = dhcp_option(options_out_len,
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]);
} }
@ -1242,7 +1309,8 @@ 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, ("dhcp_rebind: could not allocate DHCP request\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("dhcp_rebind: could not allocate DHCP request\n"));
result = ERR_MEM; result = ERR_MEM;
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
@ -1250,7 +1318,8 @@ 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, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_rebind(): set request timeout %" U16_F " msecs\n", msecs));
return result; return result;
} }
@ -1276,13 +1345,18 @@ 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 = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); options_out_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 = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); options_out_len =
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_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); options_out_len = dhcp_option(options_out_len,
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]);
} }
@ -1299,7 +1373,8 @@ 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, ("dhcp_reboot: could not allocate DHCP request\n")); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("dhcp_reboot: could not allocate DHCP request\n"));
result = ERR_MEM; result = ERR_MEM;
} }
if (dhcp->tries < 255) { if (dhcp->tries < 255) {
@ -1307,7 +1382,8 @@ 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, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp_reboot(): set request timeout %" U16_F " msecs\n", msecs));
return result; return result;
} }
@ -1356,7 +1432,8 @@ 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 = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr)))); options_out_len =
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);
@ -1365,8 +1442,10 @@ 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"));
} }
} }
@ -1434,7 +1513,8 @@ 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", options_out_len + 2U + 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[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;
@ -1639,9 +1719,17 @@ again:
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(), dhcp, dhcp->state, msg_in, LWIP_HOOK_DHCP_PARSE_OPTION(ip_current_netif(),
dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) ? (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) : 0, dhcp,
op, len, q, val_offset); dhcp->state,
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) {
@ -1772,8 +1860,14 @@ 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, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void *)p, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
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)); ("dhcp_recv(pbuf = %p) from DHCP server %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " port %" U16_F "\n",
(void *)p,
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));
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %" U16_F "\n", p->len)); 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)); 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 */
@ -1787,7 +1881,8 @@ 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, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op)); 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));
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 */
@ -1795,14 +1890,19 @@ dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
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)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i])); (u16_t)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", lwip_ntohl(reply_msg->xid), dhcp->xid)); ("transaction id mismatch reply_msg->xid(%" X32_F ")!=dhcp->xid(%" X32_F ")\n",
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? */
@ -1849,8 +1949,7 @@ 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) && else if ((msg_type == DHCP_NAK) && ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) ||
((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) ||
(dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING))) { (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);
@ -1901,8 +2000,7 @@ 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, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_create_msg(): could not allocate pbuf\n"));
("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",
@ -1920,8 +2018,7 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t
} }
dhcp->xid = xid; dhcp->xid = xid;
} }
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("transaction id xid(%" X32_F ")\n", xid));
("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));
@ -1964,8 +2061,7 @@ 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)) && while (((options_out_len < DHCP_MIN_OPTIONS_LEN) || (options_out_len & 3)) && (options_out_len < DHCP_OPTIONS_LEN)) {
(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/etharp.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h" #include "lwip/autoip.h"
#include "lwip/dhcp.h"
#include "lwip/etharp.h"
#include "lwip/prot/iana.h" #include "lwip/prot/iana.h"
#include "lwip/snmp.h"
#include "lwip/stats.h"
#include "netif/ethernet.h" #include "netif/ethernet.h"
#include <string.h> #include <string.h>
@ -76,18 +76,21 @@
#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;
@ -117,24 +120,31 @@ static netif_addr_idx_t etharp_cached_entry;
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
#if LWIP_NETIF_HWADDRHINT #if LWIP_NETIF_HWADDRHINT
#define ETHARP_SET_ADDRHINT(netif, addrhint) do { if (((netif) != NULL) && ((netif)->hints != NULL)) { \ #define ETHARP_SET_ADDRHINT(netif, addrhint) \
(netif)->hints->addr_hint = (addrhint); }} while(0) do { \
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
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);
static err_t etharp_raw(struct netif *netif, static err_t
const struct eth_addr *ethsrc_addr, const struct eth_addr *ethdst_addr, etharp_raw(struct netif *netif,
const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr, const struct eth_addr *ethsrc_addr,
const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr, const struct eth_addr *ethdst_addr,
const struct eth_addr *hwsrc_addr,
const ip4_addr_t *ipsrc_addr,
const struct eth_addr *hwdst_addr,
const ip4_addr_t *ipdst_addr,
const u16_t opcode); const u16_t opcode);
#if ARP_QUEUEING #if ARP_QUEUEING
@ -172,7 +182,9 @@ 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(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); LWIP_DEBUGF(
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;
} }
@ -209,11 +221,12 @@ etharp_tmr(void)
) { ) {
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].state == ETHARP_STATE_PENDING) && (arp_table[i].ctime >= ARP_MAXPENDING))) {
(arp_table[i].ctime >= ARP_MAXPENDING))) {
/* pending or stable entry has become old! */ /* pending or stable entry has become old! */
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %d.\n", LWIP_DEBUGF(ETHARP_DEBUG,
arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i)); ("etharp_timer: expired %s entry %d.\n",
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) {
@ -338,7 +351,8 @@ 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, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
("etharp_find_entry: no empty entry found and not allowed to recycle\n"));
return (s16_t)ERR_MEM; return (s16_t)ERR_MEM;
} }
@ -367,12 +381,16 @@ 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, ("etharp_find_entry: selecting oldest pending entry %d (without queue)\n", (int)i)); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
("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, ("etharp_find_entry: selecting oldest pending entry %d, freeing packet queue %p\n", (int)i, (void *)(arp_table[i].q))); 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)));
/* 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"));
@ -385,8 +403,7 @@ 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", LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", 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) {
@ -423,15 +440,23 @@ 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, ("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", LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), ("etharp_update_arp_entry: %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " - %02" X16_F ":%02" X16_F
(u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2], ":%02" X16_F ":%02" X16_F ":%02" X16_F ":%02" X16_F "\n",
(u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5])); ip4_addr1_16(ipaddr),
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) || if (ip4_addr_isany(ipaddr) || ip4_addr_isbroadcast(ipaddr, netif) || ip4_addr_ismulticast(ipaddr)) {
ip4_addr_isbroadcast(ipaddr, netif) || LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
ip4_addr_ismulticast(ipaddr)) { ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
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 */
@ -504,10 +529,19 @@ 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, ("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", LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), ("etharp_add_static_entry: %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " - %02" X16_F ":%02" X16_F
(u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2], ":%02" X16_F ":%02" X16_F ":%02" X16_F ":%02" X16_F "\n",
(u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5])); ip4_addr1_16(ipaddr),
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) {
@ -530,8 +564,12 @@ 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, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); ("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)));
/* 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);
@ -580,13 +618,11 @@ 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, etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr **eth_ret, const ip4_addr_t **ip_ret)
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", LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", eth_ret != NULL && ip_ret != NULL);
eth_ret != NULL && ip_ret != NULL);
LWIP_UNUSED_ARG(netif); LWIP_UNUSED_ARG(netif);
@ -652,13 +688,15 @@ 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)) || if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) || (hdr->hwlen != ETH_HWADDR_LEN) ||
(hdr->hwlen != ETH_HWADDR_LEN) || (hdr->protolen != sizeof(ip4_addr_t)) || (hdr->proto != PP_HTONS(ETHTYPE_IP))) {
(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"/%"U16_F"/%"U16_F"/%"U16_F")\n", ("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%" U16_F
hdr->hwtype, (u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen)); "/%" U16_F "/%" U16_F "/%" U16_F ")\n",
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);
@ -691,8 +729,7 @@ 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), etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
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) {
@ -707,9 +744,12 @@ etharp_input(struct pbuf *p, struct netif *netif)
if (for_us) { if (for_us) {
/* send ARP response */ /* send ARP response */
etharp_raw(netif, etharp_raw(netif,
(struct eth_addr *)netif->hwaddr, &hdr->shwaddr, (struct eth_addr *)netif->hwaddr,
(struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), &hdr->shwaddr,
&hdr->shwaddr, &sipaddr, (struct eth_addr *)netif->hwaddr,
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))) {
@ -733,7 +773,8 @@ 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, ("etharp_input: ARP unknown opcode type %"S16_F"\n", lwip_htons(hdr->opcode))); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
("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;
} }
@ -747,8 +788,7 @@ 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", LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", 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. */
@ -822,8 +862,7 @@ 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)) && if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) && !ip4_addr_islinklocal(ipaddr)) {
!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
@ -939,9 +978,7 @@ 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) || if (ip4_addr_isbroadcast(ipaddr, netif) || ip4_addr_ismulticast(ipaddr) || ip4_addr_isany(ipaddr)) {
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;
} }
@ -971,8 +1008,7 @@ 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_PENDING) || (arp_table[i].state >= ETHARP_STATE_STABLE)));
(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)) {
@ -1055,27 +1091,33 @@ 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, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, i)); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
("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, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); 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));
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(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"U16_F"\n", (void *)q, (u16_t)i)); 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));
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, ("etharp_query: queued packet %p on ARP entry %"U16_F"\n", (void *)q, (u16_t)i)); LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
("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, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); 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));
result = ERR_MEM; result = ERR_MEM;
} }
} }
@ -1098,10 +1140,13 @@ 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, const struct eth_addr *ethsrc_addr, etharp_raw(struct netif *netif,
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 ip4_addr_t *ipsrc_addr, const struct eth_addr *hwsrc_addr,
const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr, const ip4_addr_t *ipsrc_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;
@ -1119,8 +1164,7 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
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", LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", (p->len >= SIZEOF_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"));
@ -1180,9 +1224,14 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
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, (struct eth_addr *)netif->hwaddr, hw_dst_addr, return etharp_raw(netif,
(struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), &ethzero, (struct eth_addr *)netif->hwaddr,
ipaddr, ARP_REQUEST); hw_dst_addr,
(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,7 +65,8 @@
/* 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 icmp_send_response(struct pbuf *p, u8_t type, u8_t code); static void
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().
@ -143,7 +144,8 @@ 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);
@ -214,7 +216,8 @@ 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);
@ -223,9 +226,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
} }
} }
#if LWIP_CHECKSUM_CTRL_PER_NETIF #if LWIP_CHECKSUM_CTRL_PER_NETIF
else { else { iecho->chksum = 0; }
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;
@ -235,9 +236,7 @@ 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) { IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen)); }
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);
@ -247,8 +246,7 @@ 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, ret = ip4_output_if(p, src, LWIP_IP_HDRINCL, ICMP_TTL, 0, IP_PROTO_ICMP, inp);
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)));
} }
@ -274,8 +272,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, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", LWIP_DEBUGF(ICMP_DEBUG,
(s16_t)type, (s16_t)code)); ("icmp_input: ICMP type %" S16_F " code %" S16_F " not supported.\n", (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);
} }
@ -350,8 +348,7 @@ 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, q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, PBUF_RAM);
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);
@ -374,8 +371,7 @@ 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, SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
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
@ -391,9 +387,7 @@ 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) { IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) { icmphdr->chksum = inet_chksum(icmphdr, q->len); }
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

@ -70,10 +70,9 @@ 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 the "de facto" standard) * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's
* RFC 3376 - Internet Group Management Protocol, Version 3 - V3 *the "de facto" standard) RFC 3376 - Internet Group Management Protocol, Version 3 - V3 RFC 4604 - Using
* RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+ *Internet Group Management Protocol Version 3... - V3+ RFC 2113 - IP Router Alert Option -
* RFC 2113 - IP Router Alert Option -
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
@ -84,25 +83,32 @@ 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/mem.h" #include "lwip/igmp.h"
#include "lwip/ip.h"
#include "lwip/inet_chksum.h" #include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/stats.h"
#include "lwip/prot/igmp.h" #include "lwip/prot/igmp.h"
#include "lwip/stats.h"
#include <string.h> #include <string.h>
static struct igmp_group *igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr); static struct igmp_group *
static err_t igmp_remove_group(struct netif *netif, struct igmp_group *group); igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr);
static void igmp_timeout(struct netif *netif, struct igmp_group *group); static err_t
static void igmp_start_timer(struct igmp_group *group, u8_t max_time); igmp_remove_group(struct netif *netif, struct igmp_group *group);
static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp); static void
static err_t igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif); igmp_timeout(struct netif *netif, struct igmp_group *group);
static void igmp_send(struct netif *netif, struct igmp_group *group, u8_t type); static void
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;
@ -265,8 +271,7 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
/* 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", LWIP_ASSERT("igmp_lookup_group: first group must be allsystems", (ip4_addr_cmp(addr, &allsystems) != 0));
(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 {
@ -278,7 +283,8 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
} }
} }
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group ? "" : "impossible to "))); LWIP_DEBUGF(IGMP_DEBUG,
("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));
@ -368,11 +374,15 @@ 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, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); 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)));
if (igmp->igmp_maxresp == 0) { if (igmp->igmp_maxresp == 0) {
IGMP_STATS_INC(igmp.rx_v1); IGMP_STATS_INC(igmp.rx_v1);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); 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->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);
@ -397,12 +407,14 @@ 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, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); LWIP_DEBUGF(IGMP_DEBUG,
(" 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, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); LWIP_DEBUGF(IGMP_DEBUG,
(" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
} }
if (group != NULL) { if (group != NULL) {
@ -427,8 +439,12 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
} }
break; break;
default: default:
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", LWIP_DEBUGF(IGMP_DEBUG,
igmp->igmp_msgtype, group->group_state, (void *)&group, (void *)inp)); ("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_STATS_INC(igmp.proterr); IGMP_STATS_INC(igmp.proterr);
break; break;
} }
@ -455,10 +471,12 @@ 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("igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); LWIP_ERROR(
"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);
@ -489,11 +507,15 @@ 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("igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); LWIP_ERROR(
LWIP_ERROR("igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), 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;);
/* make sure it is an igmp-enabled netif */ /* make sure it is an igmp-enabled netif */
LWIP_ERROR("igmp_joingroup_netif: attempt to join on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;); LWIP_ERROR(
"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);
@ -551,11 +573,14 @@ 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("igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); LWIP_ERROR(
LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), 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;);
/* 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);
@ -585,11 +610,15 @@ 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("igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); LWIP_ERROR(
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), 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;);
/* make sure it is an igmp-enabled netif */ /* make sure it is an igmp-enabled netif */
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;); LWIP_ERROR(
"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);
@ -642,7 +671,8 @@ 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) {
@ -668,8 +698,7 @@ 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) && if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && (!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
(!(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));
@ -713,14 +742,12 @@ 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->group_state == IGMP_GROUP_DELAYING_MEMBER) && ((group->timer == 0) || (maxresp < group->timer)))) {
((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,
@ -767,8 +794,7 @@ igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
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", LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", (p->len >= sizeof(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) {

View File

@ -42,20 +42,20 @@
#if LWIP_IPV4 #if LWIP_IPV4
#include "lwip/ip.h" #include "lwip/autoip.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/udp.h"
#include "lwip/priv/tcp_priv.h" #include "lwip/priv/tcp_priv.h"
#include "lwip/autoip.h"
#include "lwip/stats.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,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) (((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT)) \ #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) \
|| (LWIP_IP_ACCEPT_UDP_PORT(port))) (((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT)) || (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,7 +164,8 @@ 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? */
@ -188,7 +189,8 @@ 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;
} }
@ -214,8 +216,12 @@ 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, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); ("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)));
IP_STATS_INC(ip.rterr); IP_STATS_INC(ip.rterr);
MIB2_STATS_INC(mib2.ipoutnoroutes); MIB2_STATS_INC(mib2.ipoutnoroutes);
return NULL; return NULL;
@ -288,18 +294,24 @@ 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, ("ip4_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", LWIP_DEBUGF(IP_DEBUG,
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), ("ip4_forward: not forwarding LLA %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n",
ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); ip4_addr1_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, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", LWIP_DEBUGF(IP_DEBUG,
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), ("ip4_forward: no forwarding route for %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " found\n",
ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); ip4_addr1_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;
} }
@ -333,9 +345,12 @@ 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, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", LWIP_DEBUGF(IP_DEBUG,
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), ("ip4_forward: forwarding packet to %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n",
ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); ip4_addr1_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);
@ -370,8 +385,11 @@ return_noroute:
static int static int
ip4_input_accept(struct netif *netif) ip4_input_accept(struct netif *netif)
{ {
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", LWIP_DEBUGF(IP_DEBUG,
ip4_addr_get_u32(ip4_current_dest_addr()), ip4_addr_get_u32(netif_ip4_addr(netif)), ("ip_input: iphdr->dest 0x%" X32_F " netif->ip_addr 0x%" X32_F " (0x%" X32_F ", 0x%" X32_F ", 0x%" X32_F
")\n",
ip4_addr_get_u32(ip4_current_dest_addr()),
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(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)))); ip4_addr_get_u32(ip4_current_dest_addr()) & ~ip4_addr_get_u32(netif_ip4_netmask(netif))));
@ -386,8 +404,7 @@ ip4_input_accept(struct netif *netif)
|| (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", LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n", netif->name[0], netif->name[1]));
netif->name[0], netif->name[1]));
/* accept on this netif */ /* accept on this netif */
return 1; return 1;
} }
@ -395,8 +412,7 @@ 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", LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n", netif->name[0], netif->name[1]));
netif->name[0], netif->name[1]));
/* accept on this netif */ /* accept on this netif */
return 1; return 1;
} }
@ -441,7 +457,8 @@ 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, ("IP packet dropped due to bad version number %"U16_F"\n", (u16_t)IPH_V(iphdr))); LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING,
("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);
@ -476,12 +493,13 @@ ip4_input(struct pbuf *p, struct netif *inp)
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, p->len)); iphdr_hlen,
p->len));
} }
if (iphdr_len > p->tot_len) { if (iphdr_len > p->tot_len) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(
("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
iphdr_len, p->tot_len)); ("IP (len %" U16_F ") is longer than pbuf (len %" U16_F "), IP packet dropped.\n", iphdr_len, p->tot_len));
} }
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
pbuf_free(p); pbuf_free(p);
@ -493,7 +511,8 @@ 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,
@ -519,8 +538,7 @@ 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) && if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) && ip4_addr_isany(ip4_current_src_addr())) {
ip4_addr_isany(ip4_current_src_addr())) {
check_ip_src = 0; check_ip_src = 0;
} }
netif = inp; netif = inp;
@ -549,7 +567,8 @@ 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;
@ -577,8 +596,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, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n", LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE,
lwip_ntohs(udphdr->dest))); ("ip4_input: UDP packet to DHCP client port %" U16_F "\n", 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;
@ -598,8 +617,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
) )
#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)) || if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) || (ip4_addr_ismulticast(ip4_current_src_addr()))) {
(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 */
@ -633,8 +651,14 @@ 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, ("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", LWIP_DEBUGF(IP_DEBUG,
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))); ("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",
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? */
@ -644,7 +668,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
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, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("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);
@ -662,7 +687,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
#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, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("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);
@ -726,14 +752,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) && if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) && !ip4_addr_ismulticast(ip4_current_dest_addr())) {
!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, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr))); LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("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);
@ -781,9 +807,13 @@ 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, const ip4_addr_t *src, const ip4_addr_t *dest, ip4_output_if(struct pbuf *p,
u8_t ttl, u8_t tos, const ip4_addr_t *src,
u8_t proto, struct netif *netif) const ip4_addr_t *dest,
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);
@ -796,8 +826,14 @@ ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
* @ param optlen length of ip_options * @ param optlen length of ip_options
*/ */
err_t err_t
ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, ip4_output_if_opt(struct pbuf *p,
u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, const ip4_addr_t *src,
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 */
@ -809,8 +845,7 @@ ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
} }
#if IP_OPTIONS_SEND #if IP_OPTIONS_SEND
return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif, return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif, ip_options, optlen);
ip_options, optlen);
#else /* IP_OPTIONS_SEND */ #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 */
@ -821,9 +856,13 @@ ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
* when it is 'any'. * when it is 'any'.
*/ */
err_t err_t
ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, ip4_output_if_src(struct pbuf *p,
u8_t ttl, u8_t tos, const ip4_addr_t *src,
u8_t proto, struct netif *netif) const ip4_addr_t *dest,
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);
@ -834,8 +873,14 @@ ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
* when it is 'any'. * when it is 'any'.
*/ */
err_t err_t
ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, ip4_output_if_opt_src(struct pbuf *p,
u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, const ip4_addr_t *src,
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 */
@ -898,8 +943,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
} }
iphdr = (struct ip_hdr *)p->payload; iphdr = (struct ip_hdr *)p->payload;
LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", (p->len >= sizeof(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);
@ -943,20 +987,14 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
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) { IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { iphdr->_chksum = (u16_t)chk_sum; /* network order */ }
iphdr->_chksum = (u16_t)chk_sum; /* network order */
}
#if LWIP_CHECKSUM_CTRL_PER_NETIF #if LWIP_CHECKSUM_CTRL_PER_NETIF
else { else { IPH_CHKSUM_SET(iphdr, 0); }
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) { IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); }
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 {
@ -1022,16 +1060,19 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
* 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, ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto)
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, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", LWIP_DEBUGF(IP_DEBUG,
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); ("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)));
IP_STATS_INC(ip.rterr); IP_STATS_INC(ip.rterr);
return ERR_RTE; return ERR_RTE;
} }
@ -1059,8 +1100,13 @@ ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
* 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, const ip4_addr_t *src, const ip4_addr_t *dest, ip4_output_hinted(struct pbuf *p,
u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint) const ip4_addr_t *src,
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;
@ -1068,8 +1114,12 @@ ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
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, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", LWIP_DEBUGF(IP_DEBUG,
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); ("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)));
IP_STATS_INC(ip.rterr); IP_STATS_INC(ip.rterr);
return ERR_RTE; return ERR_RTE;
} }
@ -1093,31 +1143,36 @@ 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, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", LWIP_DEBUGF(IP_DEBUG,
("|%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, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", LWIP_DEBUGF(IP_DEBUG,
("| %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, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", LWIP_DEBUGF(IP_DEBUG,
("| %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, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", LWIP_DEBUGF(IP_DEBUG,
("| %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, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", LWIP_DEBUGF(IP_DEBUG,
("| %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),

View File

@ -61,8 +61,7 @@ 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) || if ((~addr == IPADDR_ANY) || (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) {

View File

@ -42,12 +42,12 @@
#if LWIP_IPV4 #if LWIP_IPV4
#include "lwip/ip4_frag.h"
#include "lwip/def.h" #include "lwip/def.h"
#include "lwip/icmp.h"
#include "lwip/inet_chksum.h" #include "lwip/inet_chksum.h"
#include "lwip/ip4_frag.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>
@ -95,7 +95,8 @@
#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);
@ -106,17 +107,20 @@ PACK_STRUCT_END
#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)->src, &(iphdrB)->src) && ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \
ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ IPH_ID(iphdrA) == IPH_ID(iphdrB)) \
IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 ? 1 \
: 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 ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); static void
static int ip_reass_free_complete_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);
/** /**
* Reassembly timer base function * Reassembly timer base function
@ -364,8 +368,7 @@ 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", LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", 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;
@ -443,8 +446,7 @@ 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!", LWIP_ASSERT("no previous fragment, this must be the first fragment!", ipr->p == NULL);
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;
@ -477,10 +479,8 @@ 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", LWIP_ASSERT("sanity check", ((struct ip_reass_helper *)ipr->p->payload) != iprh);
((struct ip_reass_helper *)ipr->p->payload) != iprh); LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", iprh->next_pbuf == NULL);
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) || if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
((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(IP_REASS_DEBUG, ("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", LWIP_DEBUGF(
ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); IP_REASS_DEBUG,
("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, ("ip4_reass: matching previous fragment ID=%"X16_F"\n", LWIP_DEBUGF(IP_REASS_DEBUG,
lwip_ntohs(IPH_ID(fraghdr)))); ("ip4_reass: matching previous fragment ID=%" X16_F "\n", lwip_ntohs(IPH_ID(fraghdr))));
IPFRAG_STATS_INC(ip_frag.cachehit); IPFRAG_STATS_INC(ip_frag.cachehit);
break; break;
} }
@ -609,9 +609,7 @@ 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, LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: last fragment seen, total len %" S16_F "\n", ipr->datagram_len));
("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) {
@ -631,7 +629,8 @@ 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 */
@ -780,8 +779,7 @@ 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!", LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
(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)) {
@ -801,8 +799,7 @@ 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!", LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len >= (IP_HLEN)));
(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;
@ -824,8 +821,7 @@ 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, newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, (u8_t *)p->payload + poff, newpbuflen);
(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);
@ -861,9 +857,7 @@ 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) { IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); }
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/dhcp6.h"
#include "lwip/prot/dhcp6.h"
#include "lwip/def.h" #include "lwip/def.h"
#include "lwip/udp.h" #include "lwip/dhcp6.h"
#include "lwip/dns.h" #include "lwip/dns.h"
#include "lwip/prot/dhcp6.h"
#include "lwip/udp.h"
#include <string.h> #include <string.h>
@ -74,7 +74,10 @@
#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) do { LWIP_UNUSED_ARG(msg); } while(0) #define LWIP_HOOK_DHCP6_PARSE_OPTION(netif, dhcp6, state, msg, msg_type, option, len, pbuf, offset) \
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
@ -87,13 +90,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
@ -106,7 +109,8 @@ 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;
@ -121,8 +125,11 @@ struct dhcp6_option_info dhcp6_rx_options[DHCP6_OPTION_IDX_MAX];
#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) do { dhcp6_rx_options[idx].val_start = (start); dhcp6_rx_options[idx].val_length = (len); }while(0) #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)
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);
@ -130,9 +137,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 dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); static void
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
@ -203,7 +210,8 @@ 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 dhcp6_cleanup(struct netif *netif) void
dhcp6_cleanup(struct netif *netif)
{ {
LWIP_ASSERT("netif != NULL", netif != NULL); LWIP_ASSERT("netif != NULL", netif != NULL);
@ -253,8 +261,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, ("DHCPv6 state: %d -> %d (%s)\n", LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
dhcp6->state, new_state, dbg_caller)); ("DHCPv6 state: %d -> %d (%s)\n", 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;
@ -265,8 +273,7 @@ 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) || if ((dhcp6->state == DHCP6_STATE_STATELESS_IDLE) || (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG)) {
(dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG)) {
return 1; return 1;
} }
return 0; return 0;
@ -317,7 +324,12 @@ dhcp6_enable_stateless(struct netif *netif)
{ {
struct dhcp6 *dhcp6; struct dhcp6 *dhcp6;
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)); 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 = dhcp6_get_struct(netif, "dhcp6_enable_stateless()"); dhcp6 = dhcp6_get_struct(netif, "dhcp6_enable_stateless()");
if (dhcp6 == NULL) { if (dhcp6 == NULL) {
@ -347,12 +359,15 @@ dhcp6_disable(struct netif *netif)
{ {
struct dhcp6 *dhcp6; struct dhcp6 *dhcp6;
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)); 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));
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, ("dhcp6_disable(): DHCPv6 disabled (old state: %s)\n", LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE,
("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) {
@ -374,8 +389,11 @@ 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, struct dhcp6 *dhcp6, u8_t message_type, dhcp6_create_msg(struct netif *netif,
u16_t opt_len_alloc, u16_t *options_out_len) struct dhcp6 *dhcp6,
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;
@ -397,8 +415,7 @@ dhcp6_create_msg(struct netif *netif, struct dhcp6 *dhcp6, u8_t message_type,
dhcp6->xid = LWIP_RAND() & 0xFFFFFF; dhcp6->xid = LWIP_RAND() & 0xFFFFFF;
} }
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("transaction id xid(%" X32_F ")\n", dhcp6->xid));
("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);
@ -420,8 +437,11 @@ dhcp6_option_short(u16_t options_out_len, u8_t *options, u16_t value)
} }
static u16_t static u16_t
dhcp6_option_optionrequest(u16_t options_out_len, u8_t *options, const u16_t *req_options, dhcp6_option_optionrequest(u16_t options_out_len,
u16_t num_req_options, u16_t max_len) u8_t *options,
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;
@ -446,7 +466,6 @@ 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)
@ -464,18 +483,20 @@ 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, options, requested_options, options_out_len = dhcp6_option_optionrequest(
LWIP_ARRAYSIZE(requested_options), p_out->len); options_out_len, options, requested_options, LWIP_ARRAYSIZE(requested_options), p_out->len);
LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, DHCP6_STATE_REQUESTING_CONFIG, msg_out, LWIP_HOOK_DHCP6_APPEND_OPTIONS(
DHCP6_INFOREQUEST, options_out_len, p_out->len); netif, dhcp6, DHCP6_STATE_REQUESTING_CONFIG, msg_out, 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, ("dhcp6_information_request: INFOREQUESTING -> %d\n", (int)err)); LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("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, ("dhcp6_information_request: could not allocate DHCP6 request\n")); LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("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) {
@ -483,7 +504,8 @@ 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, ("dhcp6_information_request(): set request timeout %"U16_F" msecs\n", msecs)); LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("dhcp6_information_request(): set request timeout %" U16_F " msecs\n", msecs));
} }
static err_t static err_t
@ -677,8 +699,8 @@ dhcp6_parse_reply(struct pbuf *p, struct dhcp6 *dhcp6)
#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(ip_current_netif(), dhcp6, dhcp6->state, msg_in, LWIP_HOOK_DHCP6_PARSE_OPTION(
msg_in->msgtype, op, len, q, val_offset); ip_current_netif(), dhcp6, dhcp6->state, msg_in, msg_in->msgtype, op, len, q, val_offset);
break; break;
} }
} }
@ -703,8 +725,8 @@ 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, ("dhcp6_recv(pbuf = %p) from DHCPv6 server %s port %"U16_F"\n", (void *)p, LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE,
ipaddr_ntoa(addr), port)); ("dhcp6_recv(pbuf = %p) from DHCPv6 server %s port %" U16_F "\n", (void *)p, 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 */
@ -791,7 +813,8 @@ 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/nd6.h" #include "lwip/icmp6.h"
#include "lwip/pbuf.h" #include "lwip/inet_chksum.h"
#include "lwip/ip6.h" #include "lwip/ip6.h"
#include "lwip/ip6_addr.h" #include "lwip/ip6_addr.h"
#include "lwip/inet_chksum.h" #include "lwip/nd6.h"
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/icmp6.h" #include "lwip/pbuf.h"
#include "lwip/prot/ethernet.h" #include "lwip/prot/ethernet.h"
#include "netif/ethernet.h" #include "netif/ethernet.h"

View File

@ -44,15 +44,15 @@
#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/prot/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/inet_chksum.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#include "lwip/nd6.h"
#include "lwip/mld6.h" #include "lwip/mld6.h"
#include "lwip/ip.h" #include "lwip/nd6.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
#include "lwip/prot/icmp6.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include <string.h> #include <string.h>
@ -63,12 +63,23 @@
#endif #endif
/* Forward declarations */ /* Forward declarations */
static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type); static void
static void icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type);
u8_t type, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr); static void
static void icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data, icmp6_send_response_with_addrs(struct pbuf *p,
u8_t type, const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr, struct netif *netif); u8_t code,
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.
@ -100,9 +111,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(), {
ip6_current_dest_addr()) != 0) { if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(), 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);
@ -172,8 +183,7 @@ icmp6_input(struct pbuf *p, struct netif *inp)
ICMP6_STATS_INC(icmp6.rterr); ICMP6_STATS_INC(icmp6.rterr);
return; return;
} }
} } else
else
#endif /* LWIP_MULTICAST_PING */ #endif /* LWIP_MULTICAST_PING */
{ {
reply_src = ip6_current_dest_addr(); reply_src = ip6_current_dest_addr();
@ -183,16 +193,16 @@ icmp6_input(struct pbuf *p, struct netif *inp)
((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, {
IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr()); ((struct icmp6_echo_hdr *)(r->payload))->chksum =
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(), ip6_output_if(r, reply_src, ip6_current_src_addr(), LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp);
LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp);
pbuf_free(r); pbuf_free(r);
break; break;
@ -205,7 +215,6 @@ icmp6_input(struct pbuf *p, struct netif *inp)
pbuf_free(p); pbuf_free(p);
} }
/** /**
* Send an icmpv6 'destination unreachable' packet. * Send an icmpv6 'destination unreachable' packet.
* *
@ -270,8 +279,10 @@ icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c)
* information * information
*/ */
void void
icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c, icmp6_time_exceeded_with_addrs(struct pbuf *p,
const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr) enum icmp6_te_code c,
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);
} }
@ -343,8 +354,12 @@ 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, u8_t code, u32_t data, u8_t type, icmp6_send_response_with_addrs(struct pbuf *p,
const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr) u8_t code,
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;
@ -365,8 +380,7 @@ icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, u8_t type,
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, icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src, reply_dest, netif);
reply_dest, netif);
} }
/** /**
@ -382,15 +396,19 @@ icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, u8_t type,
* @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, u8_t code, u32_t data, u8_t type, icmp6_send_response_with_addrs_and_netif(struct pbuf *p,
const ip6_addr_t *reply_src, const ip6_addr_t *reply_dest, struct netif *netif) u8_t code,
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, q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE, PBUF_RAM);
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);
@ -405,15 +423,14 @@ icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data,
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, SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload, IP6_HLEN + LWIP_ICMP6_DATASIZE);
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, {
reply_src, reply_dest); icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len, reply_src, reply_dest);
} }
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */

View File

@ -43,22 +43,22 @@
#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/debug.h"
#include "lwip/def.h" #include "lwip/def.h"
#include "lwip/mem.h" #include "lwip/dhcp6.h"
#include "lwip/netif.h" #include "lwip/icmp6.h"
#include "lwip/ip.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/ip6_frag.h" #include "lwip/ip6_frag.h"
#include "lwip/icmp6.h" #include "lwip/mem.h"
#include "lwip/priv/raw_priv.h"
#include "lwip/udp.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/dhcp6.h"
#include "lwip/nd6.h"
#include "lwip/mld6.h" #include "lwip/mld6.h"
#include "lwip/debug.h" #include "lwip/nd6.h"
#include "lwip/netif.h"
#include "lwip/priv/raw_priv.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include "lwip/udp.h"
#ifdef LWIP_HOOK_FILENAME #ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME #include LWIP_HOOK_FILENAME
@ -113,9 +113,9 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
IP6_ADDR_ZONECHECK(dest); IP6_ADDR_ZONECHECK(dest);
/* Find a netif based on the zone. For custom mappings, one zone may map /* Find a netif based on the zone. For custom mappings, one zone may map
* to multiple netifs, so find one that can actually send a packet. */ * to multiple netifs, so find one that can actually send a packet. */
NETIF_FOREACH(netif) { NETIF_FOREACH(netif)
if (ip6_addr_test_zone(dest, netif) && {
netif_is_up(netif) && netif_is_link_up(netif)) { if (ip6_addr_test_zone(dest, netif) && netif_is_up(netif) && netif_is_link_up(netif)) {
return netif; return netif;
} }
} }
@ -140,19 +140,18 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
* wants, regardless of whether the source address is scoped. Finally, some * wants, regardless of whether the source address is scoped. Finally, some
* of this story also applies if scoping is disabled altogether. */ * of this story also applies if scoping is disabled altogether. */
#if LWIP_IPV6_SCOPES #if LWIP_IPV6_SCOPES
if (ip6_addr_has_scope(dest, IP6_UNKNOWN) || if (ip6_addr_has_scope(dest, IP6_UNKNOWN) || ip6_addr_has_scope(src, IP6_UNICAST) ||
ip6_addr_has_scope(src, IP6_UNICAST) ||
#else /* LWIP_IPV6_SCOPES */ #else /* LWIP_IPV6_SCOPES */
if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_iflocal(dest) || if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_iflocal(dest) || ip6_addr_ismulticast_linklocal(dest) ||
ip6_addr_ismulticast_linklocal(dest) || ip6_addr_islinklocal(src) || ip6_addr_islinklocal(src) ||
#endif /* LWIP_IPV6_SCOPES */ #endif /* LWIP_IPV6_SCOPES */
ip6_addr_isloopback(src)) { ip6_addr_isloopback(src)) {
#if LWIP_IPV6_SCOPES #if LWIP_IPV6_SCOPES
if (ip6_addr_has_zone(src)) { if (ip6_addr_has_zone(src)) {
/* Find a netif matching the source zone (relatively cheap). */ /* Find a netif matching the source zone (relatively cheap). */
NETIF_FOREACH(netif) { NETIF_FOREACH(netif)
if (netif_is_up(netif) && netif_is_link_up(netif) && {
ip6_addr_test_zone(src, netif)) { if (netif_is_up(netif) && netif_is_link_up(netif) && ip6_addr_test_zone(src, netif)) {
return netif; return netif;
} }
} }
@ -160,7 +159,8 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
#endif /* LWIP_IPV6_SCOPES */ #endif /* LWIP_IPV6_SCOPES */
{ {
/* Find a netif matching the source address (relatively expensive). */ /* Find a netif matching the source address (relatively expensive). */
NETIF_FOREACH(netif) { NETIF_FOREACH(netif)
{
if (!netif_is_up(netif) || !netif_is_link_up(netif)) { if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
continue; continue;
} }
@ -193,15 +193,14 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
* such, the destination address may still match a local address, and so we * such, the destination address may still match a local address, and so we
* still need to check for exact matches here. By (lwIP) policy, statically * still need to check for exact matches here. By (lwIP) policy, statically
* configured addresses do always have an implied local /64 subnet. */ * configured addresses do always have an implied local /64 subnet. */
NETIF_FOREACH(netif) { NETIF_FOREACH(netif)
{
if (!netif_is_up(netif) || !netif_is_link_up(netif)) { if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
continue; continue;
} }
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_netcmp(dest, netif_ip6_addr(netif, i)) &&
ip6_addr_netcmp(dest, netif_ip6_addr(netif, i)) && (netif_ip6_addr_isstatic(netif, i) || ip6_addr_nethostcmp(dest, netif_ip6_addr(netif, i)))) {
(netif_ip6_addr_isstatic(netif, i) ||
ip6_addr_nethostcmp(dest, netif_ip6_addr(netif, i)))) {
return netif; return netif;
} }
} }
@ -216,13 +215,13 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest)
/* Try with the netif that matches the source address. Given the earlier rule /* Try with the netif that matches the source address. Given the earlier rule
* for scoped source addresses, this applies to unscoped addresses only. */ * for scoped source addresses, this applies to unscoped addresses only. */
if (!ip6_addr_isany(src)) { if (!ip6_addr_isany(src)) {
NETIF_FOREACH(netif) { NETIF_FOREACH(netif)
{
if (!netif_is_up(netif) || !netif_is_link_up(netif)) { if (!netif_is_up(netif) || !netif_is_link_up(netif)) {
continue; continue;
} }
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
ip6_addr_cmp(src, netif_ip6_addr(netif, i))) {
return netif; return netif;
} }
} }
@ -237,7 +236,8 @@ ip6_route(const ip6_addr_t *src, const ip6_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;
} }
@ -368,8 +368,7 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
struct netif *netif; struct netif *netif;
/* do not forward link-local or loopback addresses */ /* do not forward link-local or loopback addresses */
if (ip6_addr_islinklocal(ip6_current_dest_addr()) || if (ip6_addr_islinklocal(ip6_current_dest_addr()) || ip6_addr_isloopback(ip6_current_dest_addr())) {
ip6_addr_isloopback(ip6_current_dest_addr())) {
LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n")); LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n"));
IP6_STATS_INC(ip6.rterr); IP6_STATS_INC(ip6.rterr);
IP6_STATS_INC(ip6.drop); IP6_STATS_INC(ip6.drop);
@ -379,7 +378,9 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
/* Find network interface where to forward this IP packet to. */ /* Find network interface where to forward this IP packet to. */
netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr()); netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr());
if (netif == NULL) { if (netif == NULL) {
LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", LWIP_DEBUGF(IP6_DEBUG,
("ip6_forward: no route for %" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F
":%" X16_F "\n",
IP6_ADDR_BLOCK1(ip6_current_dest_addr()), IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
IP6_ADDR_BLOCK2(ip6_current_dest_addr()), IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
IP6_ADDR_BLOCK3(ip6_current_dest_addr()), IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
@ -403,8 +404,7 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
* outside of their zone. We determined the zone a bit earlier, so we know * outside of their zone. We determined the zone a bit earlier, so we know
* that the address is properly zoned here, so we can safely use has_zone. * that the address is properly zoned here, so we can safely use has_zone.
* Also skip packets with a loopback source address (link-local implied). */ * Also skip packets with a loopback source address (link-local implied). */
if ((ip6_addr_has_zone(ip6_current_src_addr()) && if ((ip6_addr_has_zone(ip6_current_src_addr()) && !ip6_addr_test_zone(ip6_current_src_addr(), netif)) ||
!ip6_addr_test_zone(ip6_current_src_addr(), netif)) ||
ip6_addr_isloopback(ip6_current_src_addr())) { ip6_addr_isloopback(ip6_current_src_addr())) {
LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding packet beyond its source address zone.\n")); LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding packet beyond its source address zone.\n"));
IP6_STATS_INC(ip6.rterr); IP6_STATS_INC(ip6.rterr);
@ -446,7 +446,9 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
return; return;
} }
LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: forwarding packet to %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", LWIP_DEBUGF(IP6_DEBUG,
("ip6_forward: forwarding packet to %" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F
":%" X16_F ":%" X16_F "\n",
IP6_ADDR_BLOCK1(ip6_current_dest_addr()), IP6_ADDR_BLOCK1(ip6_current_dest_addr()),
IP6_ADDR_BLOCK2(ip6_current_dest_addr()), IP6_ADDR_BLOCK2(ip6_current_dest_addr()),
IP6_ADDR_BLOCK3(ip6_current_dest_addr()), IP6_ADDR_BLOCK3(ip6_current_dest_addr()),
@ -479,8 +481,7 @@ ip6_input_accept(struct netif *netif)
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i)) ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))
#if IPV6_CUSTOM_SCOPES #if IPV6_CUSTOM_SCOPES
&& (!ip6_addr_has_zone(ip6_current_src_addr()) || && (!ip6_addr_has_zone(ip6_current_src_addr()) || ip6_addr_test_zone(ip6_current_src_addr(), netif))
ip6_addr_test_zone(ip6_current_src_addr(), netif))
#endif /* IPV6_CUSTOM_SCOPES */ #endif /* IPV6_CUSTOM_SCOPES */
) { ) {
/* accept on this netif */ /* accept on this netif */
@ -527,8 +528,8 @@ ip6_input(struct pbuf *p, struct netif *inp)
/* identify the IP header */ /* identify the IP header */
ip6hdr = (struct ip6_hdr *)p->payload; ip6hdr = (struct ip6_hdr *)p->payload;
if (IP6H_V(ip6hdr) != 6) { if (IP6H_V(ip6hdr) != 6) {
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n", LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING,
IP6H_V(ip6hdr))); ("IPv6 packet dropped due to bad version number %" U32_F "\n", IP6H_V(ip6hdr)));
pbuf_free(p); pbuf_free(p);
IP6_STATS_INC(ip6.err); IP6_STATS_INC(ip6.err);
IP6_STATS_INC(ip6.drop); IP6_STATS_INC(ip6.drop);
@ -547,12 +548,14 @@ ip6_input(struct pbuf *p, struct netif *inp)
if (IP6_HLEN > p->len) { if (IP6_HLEN > p->len) {
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IPv6 header (len %" U16_F ") does not fit in first pbuf (len %" U16_F "), IP packet dropped.\n", ("IPv6 header (len %" U16_F ") does not fit in first pbuf (len %" U16_F "), IP packet dropped.\n",
(u16_t)IP6_HLEN, p->len)); (u16_t)IP6_HLEN,
p->len));
} }
if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) { if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) {
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IPv6 (plen %" U16_F ") is longer than pbuf (len %" U16_F "), IP packet dropped.\n", ("IPv6 (plen %" U16_F ") is longer than pbuf (len %" U16_F "), IP packet dropped.\n",
(u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN), p->tot_len)); (u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN),
p->tot_len));
} }
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
pbuf_free(p); pbuf_free(p);
@ -613,8 +616,9 @@ ip6_input(struct pbuf *p, struct netif *inp)
if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) && if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) &&
ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) { ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) {
netif = inp; netif = inp;
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n", LWIP_DEBUGF(
netif->name[0], netif->name[1])); IP6_DEBUG,
("ip6_input: solicited node packet accepted on interface %c%c\n", netif->name[0], netif->name[1]));
break; break;
} }
} }
@ -634,8 +638,7 @@ ip6_input(struct pbuf *p, struct netif *inp)
/* Shortcut: stop looking for other interfaces if either the source or /* Shortcut: stop looking for other interfaces if either the source or
* the destination has a scope constrained to this interface. Custom * the destination has a scope constrained to this interface. Custom
* scopes may break the 1:1 link/interface mapping, however. */ * scopes may break the 1:1 link/interface mapping, however. */
if (ip6_addr_islinklocal(ip6_current_dest_addr()) || if (ip6_addr_islinklocal(ip6_current_dest_addr()) || ip6_addr_islinklocal(ip6_current_src_addr())) {
ip6_addr_islinklocal(ip6_current_src_addr())) {
goto netif_found; goto netif_found;
} }
#endif /* !IPV6_CUSTOM_SCOPES */ #endif /* !IPV6_CUSTOM_SCOPES */
@ -646,13 +649,13 @@ ip6_input(struct pbuf *p, struct netif *inp)
* not be accepted on other interfaces, either. These requirements * not be accepted on other interfaces, either. These requirements
* cannot be implemented in the case that loopback traffic is sent * cannot be implemented in the case that loopback traffic is sent
* across a non-loopback interface, however. */ * across a non-loopback interface, however. */
if (ip6_addr_isloopback(ip6_current_dest_addr()) || if (ip6_addr_isloopback(ip6_current_dest_addr()) || ip6_addr_isloopback(ip6_current_src_addr())) {
ip6_addr_isloopback(ip6_current_src_addr())) {
goto netif_found; goto netif_found;
} }
#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;
@ -664,13 +667,13 @@ ip6_input(struct pbuf *p, struct netif *inp)
#endif /* !LWIP_SINGLE_NETIF */ #endif /* !LWIP_SINGLE_NETIF */
} }
netif_found: netif_found:
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n", LWIP_DEBUGF(
netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X')); IP6_DEBUG,
("ip6_input: packet accepted on interface %c%c\n", netif ? netif->name[0] : 'X', netif ? netif->name[1] : 'X'));
} }
/* "::" packet source address? (used in duplicate address detection) */ /* "::" packet source address? (used in duplicate address detection) */
if (ip6_addr_isany(ip6_current_src_addr()) && if (ip6_addr_isany(ip6_current_src_addr()) && (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) {
(!ip6_addr_issolicitednode(ip6_current_dest_addr()))) {
/* packet source is not valid */ /* packet source is not valid */
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n")); LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n"));
@ -707,11 +710,9 @@ netif_found:
pbuf_remove_header(p, IP6_HLEN); pbuf_remove_header(p, IP6_HLEN);
/* Process known option extension headers, if present. */ /* Process known option extension headers, if present. */
while (*nexth != IP6_NEXTH_NONE) while (*nexth != IP6_NEXTH_NONE) {
{
switch (*nexth) { switch (*nexth) {
case IP6_NEXTH_HOPBYHOP: case IP6_NEXTH_HOPBYHOP: {
{
s32_t opt_offset; s32_t opt_offset;
struct ip6_hbh_hdr *hbh_hdr; struct ip6_hbh_hdr *hbh_hdr;
struct ip6_opt_hdr *opt_hdr; struct ip6_opt_hdr *opt_hdr;
@ -728,8 +729,10 @@ netif_found:
if ((p->len < 8) || (hlen > p->len)) { if ((p->len < 8) || (hlen > p->len)) {
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", ("IPv6 options header (hlen %" U16_F ") does not fit in first pbuf (len %" U16_F
hlen, p->len)); "), IPv6 packet dropped.\n",
hlen,
p->len));
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
pbuf_free(p); pbuf_free(p);
IP6_STATS_INC(ip6.lenerr); IP6_STATS_INC(ip6.lenerr);
@ -741,8 +744,7 @@ netif_found:
/* The extended option header starts right after Hop-by-Hop header. */ /* The extended option header starts right after Hop-by-Hop header. */
opt_offset = IP6_HBH_HLEN; opt_offset = IP6_HBH_HLEN;
while (opt_offset < hlen) while (opt_offset < hlen) {
{
s32_t opt_dlen = 0; s32_t opt_dlen = 0;
opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + opt_offset); opt_hdr = (struct ip6_opt_hdr *)((u8_t *)hbh_hdr + opt_offset);
@ -801,8 +803,7 @@ netif_found:
pbuf_remove_header(p, hlen); pbuf_remove_header(p, hlen);
break; break;
} }
case IP6_NEXTH_DESTOPTS: case IP6_NEXTH_DESTOPTS: {
{
s32_t opt_offset; s32_t opt_offset;
struct ip6_dest_hdr *dest_hdr; struct ip6_dest_hdr *dest_hdr;
struct ip6_opt_hdr *opt_hdr; struct ip6_opt_hdr *opt_hdr;
@ -817,8 +818,10 @@ netif_found:
hlen = 8 * (1 + dest_hdr->_hlen); hlen = 8 * (1 + dest_hdr->_hlen);
if ((p->len < 8) || (hlen > p->len)) { if ((p->len < 8) || (hlen > p->len)) {
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", ("IPv6 options header (hlen %" U16_F ") does not fit in first pbuf (len %" U16_F
hlen, p->len)); "), IPv6 packet dropped.\n",
hlen,
p->len));
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
pbuf_free(p); pbuf_free(p);
IP6_STATS_INC(ip6.lenerr); IP6_STATS_INC(ip6.lenerr);
@ -830,14 +833,12 @@ netif_found:
/* The extended option header starts right after Destination header. */ /* The extended option header starts right after Destination header. */
opt_offset = IP6_DEST_HLEN; opt_offset = IP6_DEST_HLEN;
while (opt_offset < hlen) while (opt_offset < hlen) {
{
s32_t opt_dlen = 0; s32_t opt_dlen = 0;
opt_hdr = (struct ip6_opt_hdr *)((u8_t *)dest_hdr + opt_offset); opt_hdr = (struct ip6_opt_hdr *)((u8_t *)dest_hdr + opt_offset);
switch (IP6_OPT_TYPE(opt_hdr)) switch (IP6_OPT_TYPE(opt_hdr)) {
{
/* @todo: process IPV6 Destination option data */ /* @todo: process IPV6 Destination option data */
case IP6_PAD1_OPTION: case IP6_PAD1_OPTION:
/* PAD1 option deosn't have length and value field */ /* PAD1 option deosn't have length and value field */
@ -857,8 +858,7 @@ netif_found:
break; break;
default: default:
/* Check 2 MSB of Destination header type. */ /* Check 2 MSB of Destination header type. */
switch (IP6_OPT_TYPE_ACTION(opt_hdr)) switch (IP6_OPT_TYPE_ACTION(opt_hdr)) {
{
case 1: case 1:
/* Discard the packet. */ /* Discard the packet. */
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n")); LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with invalid destination option type dropped.\n"));
@ -896,8 +896,7 @@ netif_found:
pbuf_remove_header(p, hlen); pbuf_remove_header(p, hlen);
break; break;
} }
case IP6_NEXTH_ROUTING: case IP6_NEXTH_ROUTING: {
{
struct ip6_rout_hdr *rout_hdr; struct ip6_rout_hdr *rout_hdr;
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n")); LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n"));
@ -911,8 +910,10 @@ netif_found:
if ((p->len < 8) || (hlen > p->len)) { if ((p->len < 8) || (hlen > p->len)) {
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", ("IPv6 options header (hlen %" U16_F ") does not fit in first pbuf (len %" U16_F
hlen, p->len)); "), IPv6 packet dropped.\n",
hlen,
p->len));
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
pbuf_free(p); pbuf_free(p);
IP6_STATS_INC(ip6.lenerr); IP6_STATS_INC(ip6.lenerr);
@ -935,8 +936,7 @@ netif_found:
goto ip6_input_cleanup; goto ip6_input_cleanup;
} }
switch (IP6_ROUT_TYPE(rout_hdr)) switch (IP6_ROUT_TYPE(rout_hdr)) {
{
/* TODO: process routing by the type */ /* TODO: process routing by the type */
case IP6_ROUT_TYPE2: case IP6_ROUT_TYPE2:
break; break;
@ -955,8 +955,7 @@ netif_found:
pbuf_remove_header(p, hlen); pbuf_remove_header(p, hlen);
break; break;
} }
case IP6_NEXTH_FRAGMENT: case IP6_NEXTH_FRAGMENT: {
{
struct ip6_frag_hdr *frag_hdr; struct ip6_frag_hdr *frag_hdr;
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n")); LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n"));
@ -971,8 +970,10 @@ netif_found:
/* Make sure this header fits in current pbuf. */ /* Make sure this header fits in current pbuf. */
if (hlen > p->len) { if (hlen > p->len) {
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", ("IPv6 options header (hlen %" U16_F ") does not fit in first pbuf (len %" U16_F
hlen, p->len)); "), IPv6 packet dropped.\n",
hlen,
p->len));
/* free (drop) packet pbufs */ /* free (drop) packet pbufs */
pbuf_free(p); pbuf_free(p);
IP6_FRAG_STATS_INC(ip6_frag.lenerr); IP6_FRAG_STATS_INC(ip6_frag.lenerr);
@ -993,8 +994,7 @@ netif_found:
} }
/* Offset == 0 and more_fragments == 0? */ /* Offset == 0 and more_fragments == 0? */
if ((frag_hdr->_fragment_offset & if ((frag_hdr->_fragment_offset & PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) {
PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) {
/* This is a 1-fragment packet. Skip this header and continue. */ /* This is a 1-fragment packet. Skip this header and continue. */
pbuf_remove_header(p, hlen); pbuf_remove_header(p, hlen);
} else { } else {
@ -1032,7 +1032,8 @@ netif_found:
if (*nexth == IP6_NEXTH_HOPBYHOP) { if (*nexth == IP6_NEXTH_HOPBYHOP) {
/* Hop-by-Hop header comes only as a first option */ /* Hop-by-Hop header comes only as a first option */
icmp6_param_problem(p, ICMP6_PP_HEADER, nexth); icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header dropped (only valid as a first option)\n")); LWIP_DEBUGF(IP6_DEBUG,
("ip6_input: packet with Hop-by-Hop options header dropped (only valid as a first option)\n"));
pbuf_free(p); pbuf_free(p);
IP6_STATS_INC(ip6.drop); IP6_STATS_INC(ip6.drop);
goto ip6_input_cleanup; goto ip6_input_cleanup;
@ -1053,8 +1054,7 @@ options_done:
pbuf_add_header_force(p, hlen_tot); pbuf_add_header_force(p, hlen_tot);
/* raw input did not eat the packet? */ /* raw input did not eat the packet? */
raw_status = raw_input(p, inp); raw_status = raw_input(p, inp);
if (raw_status != RAW_INPUT_EATEN) if (raw_status != RAW_INPUT_EATEN) {
{
/* Point to payload. */ /* Point to payload. */
pbuf_remove_header(p, hlen_tot); pbuf_remove_header(p, hlen_tot);
#else /* LWIP_RAW */ #else /* LWIP_RAW */
@ -1093,12 +1093,12 @@ options_done:
/* p points to IPv6 header again for raw_input. */ /* p points to IPv6 header again for raw_input. */
pbuf_add_header_force(p, hlen_tot); pbuf_add_header_force(p, hlen_tot);
/* send ICMP parameter problem unless it was a multicast or ICMPv6 */ /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
(IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
icmp6_param_problem(p, ICMP6_PP_HEADER, nexth); icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
} }
#endif /* LWIP_ICMP */ #endif /* LWIP_ICMP */
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr))); LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("ip6_input: Unsupported transport protocol %" U16_F "\n", (u16_t)IP6H_NEXTH(ip6hdr)));
IP6_STATS_INC(ip6.proterr); IP6_STATS_INC(ip6.proterr);
IP6_STATS_INC(ip6.drop); IP6_STATS_INC(ip6.drop);
} }
@ -1118,7 +1118,6 @@ ip6_input_cleanup:
return ERR_OK; return ERR_OK;
} }
/** /**
* Sends an IPv6 packet on a network interface. This function constructs * Sends an IPv6 packet on a network interface. This function constructs
* the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is
@ -1146,9 +1145,13 @@ ip6_input_cleanup:
* returns errors returned by netif->output_ip6 * returns errors returned by netif->output_ip6
*/ */
err_t err_t
ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, ip6_output_if(struct pbuf *p,
u8_t hl, u8_t tc, const ip6_addr_t *src,
u8_t nexth, struct netif *netif) const ip6_addr_t *dest,
u8_t hl,
u8_t tc,
u8_t nexth,
struct netif *netif)
{ {
const ip6_addr_t *src_used = src; const ip6_addr_t *src_used = src;
if (dest != LWIP_IP_HDRINCL) { if (dest != LWIP_IP_HDRINCL) {
@ -1170,9 +1173,13 @@ ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
* when it is 'any'. * when it is 'any'.
*/ */
err_t err_t
ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, ip6_output_if_src(struct pbuf *p,
u8_t hl, u8_t tc, const ip6_addr_t *src,
u8_t nexth, struct netif *netif) const ip6_addr_t *dest,
u8_t hl,
u8_t tc,
u8_t nexth,
struct netif *netif)
{ {
struct ip6_hdr *ip6hdr; struct ip6_hdr *ip6hdr;
ip6_addr_t dest_addr; ip6_addr_t dest_addr;
@ -1204,8 +1211,7 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
} }
ip6hdr = (struct ip6_hdr *)p->payload; ip6hdr = (struct ip6_hdr *)p->payload;
LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr", LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr", (p->len >= sizeof(struct ip6_hdr)));
(p->len >= sizeof(struct ip6_hdr)));
IP6H_HOPLIM_SET(ip6hdr, hl); IP6H_HOPLIM_SET(ip6hdr, hl);
IP6H_NEXTH_SET(ip6hdr, nexth); IP6H_NEXTH_SET(ip6hdr, nexth);
@ -1244,8 +1250,7 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
} }
#endif /* !LWIP_HAVE_LOOPIF */ #endif /* !LWIP_HAVE_LOOPIF */
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
/* Packet to self, enqueue it for loopback */ /* Packet to self, enqueue it for loopback */
LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n")); LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
return netif_loop_output(netif, p); return netif_loop_output(netif, p);
@ -1288,8 +1293,7 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
* see ip_output_if() for more return values * see ip_output_if() for more return values
*/ */
err_t err_t
ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, u8_t hl, u8_t tc, u8_t nexth)
u8_t hl, u8_t tc, u8_t nexth)
{ {
struct netif *netif; struct netif *netif;
struct ip6_hdr *ip6hdr; struct ip6_hdr *ip6hdr;
@ -1308,7 +1312,9 @@ ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
} }
if (netif == NULL) { if (netif == NULL) {
LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", LWIP_DEBUGF(IP6_DEBUG,
("ip6_output: no route for %" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F
":%" X16_F "\n",
IP6_ADDR_BLOCK1(dest), IP6_ADDR_BLOCK1(dest),
IP6_ADDR_BLOCK2(dest), IP6_ADDR_BLOCK2(dest),
IP6_ADDR_BLOCK3(dest), IP6_ADDR_BLOCK3(dest),
@ -1324,7 +1330,6 @@ ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
return ip6_output_if(p, src, dest, hl, tc, nexth, netif); return ip6_output_if(p, src, dest, hl, tc, nexth, netif);
} }
#if LWIP_NETIF_USE_HINTS #if LWIP_NETIF_USE_HINTS
/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint /** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
* before calling ip6_output_if. * before calling ip6_output_if.
@ -1346,8 +1351,13 @@ ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
* see ip_output_if() for more return values * see ip_output_if() for more return values
*/ */
err_t err_t
ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, ip6_output_hinted(struct pbuf *p,
u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint) const ip6_addr_t *src,
const ip6_addr_t *dest,
u8_t hl,
u8_t tc,
u8_t nexth,
struct netif_hint *netif_hint)
{ {
struct netif *netif; struct netif *netif;
struct ip6_hdr *ip6hdr; struct ip6_hdr *ip6hdr;
@ -1367,7 +1377,9 @@ ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
} }
if (netif == NULL) { if (netif == NULL) {
LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", LWIP_DEBUGF(IP6_DEBUG,
("ip6_output: no route for %" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F
":%" X16_F "\n",
IP6_ADDR_BLOCK1(dest), IP6_ADDR_BLOCK1(dest),
IP6_ADDR_BLOCK2(dest), IP6_ADDR_BLOCK2(dest),
IP6_ADDR_BLOCK3(dest), IP6_ADDR_BLOCK3(dest),
@ -1454,33 +1466,39 @@ ip6_debug_print(struct pbuf *p)
LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n")); LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n"));
LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n", LWIP_DEBUGF(IP6_DEBUG,
("| %2" U16_F " | %3" U16_F " | %7" U32_F " | (ver, class, flow)\n",
IP6H_V(ip6hdr), IP6H_V(ip6hdr),
IP6H_TC(ip6hdr), IP6H_TC(ip6hdr),
IP6H_FL(ip6hdr))); IP6H_FL(ip6hdr)));
LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n", LWIP_DEBUGF(IP6_DEBUG,
("| %5" U16_F " | %3" U16_F " | %3" U16_F " | (plen, nexth, hopl)\n",
IP6H_PLEN(ip6hdr), IP6H_PLEN(ip6hdr),
IP6H_NEXTH(ip6hdr), IP6H_NEXTH(ip6hdr),
IP6H_HOPLIM(ip6hdr))); IP6H_HOPLIM(ip6hdr)));
LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n", LWIP_DEBUGF(IP6_DEBUG,
("| %4" X32_F " | %4" X32_F " | %4" X32_F " | %4" X32_F " | (src)\n",
IP6_ADDR_BLOCK1(&(ip6hdr->src)), IP6_ADDR_BLOCK1(&(ip6hdr->src)),
IP6_ADDR_BLOCK2(&(ip6hdr->src)), IP6_ADDR_BLOCK2(&(ip6hdr->src)),
IP6_ADDR_BLOCK3(&(ip6hdr->src)), IP6_ADDR_BLOCK3(&(ip6hdr->src)),
IP6_ADDR_BLOCK4(&(ip6hdr->src)))); IP6_ADDR_BLOCK4(&(ip6hdr->src))));
LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", LWIP_DEBUGF(IP6_DEBUG,
("| %4" X32_F " | %4" X32_F " | %4" X32_F " | %4" X32_F " |\n",
IP6_ADDR_BLOCK5(&(ip6hdr->src)), IP6_ADDR_BLOCK5(&(ip6hdr->src)),
IP6_ADDR_BLOCK6(&(ip6hdr->src)), IP6_ADDR_BLOCK6(&(ip6hdr->src)),
IP6_ADDR_BLOCK7(&(ip6hdr->src)), IP6_ADDR_BLOCK7(&(ip6hdr->src)),
IP6_ADDR_BLOCK8(&(ip6hdr->src)))); IP6_ADDR_BLOCK8(&(ip6hdr->src))));
LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n"));
LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n", LWIP_DEBUGF(IP6_DEBUG,
("| %4" X32_F " | %4" X32_F " | %4" X32_F " | %4" X32_F " | (dest)\n",
IP6_ADDR_BLOCK1(&(ip6hdr->dest)), IP6_ADDR_BLOCK1(&(ip6hdr->dest)),
IP6_ADDR_BLOCK2(&(ip6hdr->dest)), IP6_ADDR_BLOCK2(&(ip6hdr->dest)),
IP6_ADDR_BLOCK3(&(ip6hdr->dest)), IP6_ADDR_BLOCK3(&(ip6hdr->dest)),
IP6_ADDR_BLOCK4(&(ip6hdr->dest)))); IP6_ADDR_BLOCK4(&(ip6hdr->dest))));
LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", LWIP_DEBUGF(IP6_DEBUG,
("| %4" X32_F " | %4" X32_F " | %4" X32_F " | %4" X32_F " |\n",
IP6_ADDR_BLOCK5(&(ip6hdr->dest)), IP6_ADDR_BLOCK5(&(ip6hdr->dest)),
IP6_ADDR_BLOCK6(&(ip6hdr->dest)), IP6_ADDR_BLOCK6(&(ip6hdr->dest)),
IP6_ADDR_BLOCK7(&(ip6hdr->dest)), IP6_ADDR_BLOCK7(&(ip6hdr->dest)),

View File

@ -44,8 +44,8 @@
#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/ip_addr.h"
#include "lwip/def.h" #include "lwip/def.h"
#include "lwip/ip_addr.h"
#include <string.h> #include <string.h>
@ -108,8 +108,7 @@ 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;
} }
} }
@ -160,9 +159,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 << 4) + current_block_value =
(lwip_isdigit(*s) ? (u32_t)(*s - '0') : (current_block_value << 4) +
(u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A'))); (lwip_isdigit(*s) ? (u32_t)(*s - '0') : (u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A')));
} else { } else {
/* unexpected digit, space? CRLF? */ /* unexpected digit, space? CRLF? */
break; break;
@ -172,8 +171,7 @@ 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
@ -320,8 +318,7 @@ 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,22 +39,21 @@
* <delamer@inicotech.com> * <delamer@inicotech.com>
*/ */
#include "lwip/opt.h"
#include "lwip/ip6_frag.h" #include "lwip/ip6_frag.h"
#include "lwip/ip6.h"
#include "lwip/icmp6.h" #include "lwip/icmp6.h"
#include "lwip/nd6.h"
#include "lwip/ip.h" #include "lwip/ip.h"
#include "lwip/ip6.h"
#include "lwip/nd6.h"
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/pbuf.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
* overlapping won't occur on your network! */ * overlapping won't occur on your network! */
@ -89,7 +88,8 @@
#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);
@ -104,9 +104,11 @@ static struct ip6_reassdata *reassdatagrams;
static u16_t ip6_reass_pbufcount; static u16_t ip6_reass_pbufcount;
/* Forward declarations. */ /* Forward declarations. */
static void ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr); static void
ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr);
#if IP_REASS_FREE_OLDEST #if IP_REASS_FREE_OLDEST
static void ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed); static void
ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed);
#endif /* IP_REASS_FREE_OLDEST */ #endif /* IP_REASS_FREE_OLDEST */
void void
@ -167,8 +169,7 @@ ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr)
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;
@ -283,8 +284,7 @@ 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", LWIP_ASSERT("IPv6 fragment header does not fit in first pbuf", p->len >= sizeof(struct ip6_frag_hdr));
p->len >= sizeof(struct ip6_frag_hdr));
frag_hdr = (struct ip6_frag_hdr *)p->payload; frag_hdr = (struct ip6_frag_hdr *)p->payload;
@ -494,8 +494,7 @@ 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!", LWIP_ASSERT("no previous fragment, this must be the first fragment!", ipr->p == NULL);
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;
@ -572,8 +571,7 @@ 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;
} }
@ -606,16 +604,14 @@ 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((u8_t*)ipr->iphdr + sizeof(struct ip6_frag_hdr), ipr->iphdr, MEMMOVE(
(size_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr)); (u8_t *)ipr->iphdr + sizeof(struct ip6_frag_hdr), 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 + iphdr_ptr = (struct ip6_hdr *)((u8_t *)ipr->iphdr + sizeof(struct ip6_frag_hdr));
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) ipr->datagram_len = (u16_t)(ipr->datagram_len + ((u8_t *)p->payload - (u8_t *)iphdr_ptr) - IP6_HLEN);
- 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);
@ -756,8 +752,7 @@ 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!", LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
(rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
poff += pbuf_copy_partial(p, (u8_t *)rambuf->payload + IP6_FRAG_HLEN, cop, poff); 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)) {
@ -780,8 +775,7 @@ 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!", LWIP_ASSERT("this needs a pbuf in one piece!", (p->len >= (IP6_HLEN)));
(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);
@ -833,7 +827,8 @@ 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 = lwip_htons((u16_t)((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG))); frag_hdr->_fragment_offset =
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

@ -55,21 +55,20 @@
#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/ip.h"
#include "lwip/inet_chksum.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#include "lwip/memp.h" #include "lwip/memp.h"
#include "lwip/mld6.h"
#include "lwip/netif.h"
#include "lwip/pbuf.h"
#include "lwip/prot/mld6.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include <string.h> #include <string.h>
/* /*
* MLD constants * MLD constants
*/ */
@ -81,11 +80,14 @@
#define MLD6_GROUP_IDLE_MEMBER 2 #define MLD6_GROUP_IDLE_MEMBER 2
/* Forward declarations. */ /* Forward declarations. */
static struct mld_group *mld6_new_group(struct netif *ifp, const ip6_addr_t *addr); static struct mld_group *
static err_t mld6_remove_group(struct netif *netif, struct mld_group *group); mld6_new_group(struct netif *ifp, const ip6_addr_t *addr);
static void mld6_delayed_report(struct mld_group *group, u16_t maxresp); static err_t
static void mld6_send(struct netif *netif, struct mld_group *group, u8_t type); mld6_remove_group(struct netif *netif, struct mld_group *group);
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
@ -155,7 +157,6 @@ mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr)
return NULL; return NULL;
} }
/** /**
* create a new group * create a new group
* *
@ -216,7 +217,6 @@ 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.
* *
@ -245,8 +245,7 @@ mld6_input(struct pbuf *p, struct netif *inp)
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()) && if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && ip6_addr_isany(&(mld_hdr->multicast_address))) {
ip6_addr_isany(&(mld_hdr->multicast_address))) {
MLD6_STATS_INC(mld6.rx_general); MLD6_STATS_INC(mld6.rx_general);
/* Report all groups, except all nodes group, and if-local groups. */ /* Report all groups, except all nodes group, and if-local groups. */
group = netif_mld6_data(inp); group = netif_mld6_data(inp);
@ -320,10 +319,10 @@ mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
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) || if (ip6_addr_isany(srcaddr) || netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
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;
@ -409,10 +408,10 @@ mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
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) || if (ip6_addr_isany(srcaddr) || netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
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 */
@ -485,7 +484,6 @@ 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).
@ -497,7 +495,8 @@ 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) {
@ -543,8 +542,7 @@ 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->group_state == MLD6_GROUP_DELAYING_MEMBER) && ((group->timer == 0) || (maxresp < group->timer)))) {
((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;
} }
@ -602,9 +600,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, {
src_addr, &(group->group_address)); mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, &(group->group_address));
} }
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
@ -618,8 +616,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(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), ip6_output_if(
MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif); p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif);
pbuf_free(p); pbuf_free(p);
} }

View File

@ -45,23 +45,23 @@
#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/nd6.h" #include "lwip/dhcp6.h"
#include "lwip/priv/nd6_priv.h" #include "lwip/dns.h"
#include "lwip/prot/nd6.h" #include "lwip/icmp6.h"
#include "lwip/prot/icmp6.h" #include "lwip/inet_chksum.h"
#include "lwip/pbuf.h" #include "lwip/ip.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/ip6.h" #include "lwip/ip6.h"
#include "lwip/ip6_addr.h" #include "lwip/ip6_addr.h"
#include "lwip/inet_chksum.h" #include "lwip/mem.h"
#include "lwip/netif.h" #include "lwip/memp.h"
#include "lwip/icmp6.h"
#include "lwip/mld6.h" #include "lwip/mld6.h"
#include "lwip/dhcp6.h" #include "lwip/nd6.h"
#include "lwip/ip.h" #include "lwip/netif.h"
#include "lwip/pbuf.h"
#include "lwip/priv/nd6_priv.h"
#include "lwip/prot/icmp6.h"
#include "lwip/prot/nd6.h"
#include "lwip/stats.h" #include "lwip/stats.h"
#include "lwip/dns.h"
#include <string.h> #include <string.h>
@ -93,7 +93,8 @@ static ip6_addr_t multicast_address;
static u8_t nd6_tmr_rs_reduction; static u8_t nd6_tmr_rs_reduction;
/* Static buffer to parse RA packet options */ /* Static buffer to parse RA packet options */
union ra_options { union ra_options
{
struct lladdr_option lladdr; struct lladdr_option lladdr;
struct mtu_option mtu; struct mtu_option mtu;
struct prefix_option prefix; struct prefix_option prefix;
@ -104,37 +105,55 @@ union ra_options {
static union ra_options nd6_ra_buffer; static union ra_options nd6_ra_buffer;
/* Forward declarations. */ /* Forward declarations. */
static s8_t nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr); static s8_t
static s8_t nd6_new_neighbor_cache_entry(void); nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr);
static void nd6_free_neighbor_cache_entry(s8_t i); static s8_t
static s16_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr); nd6_new_neighbor_cache_entry(void);
static s16_t nd6_new_destination_cache_entry(void); static void
static int nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif); nd6_free_neighbor_cache_entry(s8_t i);
static s8_t nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif); static s16_t
static s8_t nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif); nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr);
static s8_t nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif); static s16_t
static s8_t nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif); nd6_new_destination_cache_entry(void);
static s8_t nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif); static int
static s8_t nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif); nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif);
static err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf *q); static s8_t
nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif);
static s8_t
nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif);
static s8_t
nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif);
static s8_t
nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif);
static s8_t
nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif);
static s8_t
nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif);
static err_t
nd6_queue_packet(s8_t neighbor_index, struct pbuf *q);
#define ND6_SEND_FLAG_MULTICAST_DEST 0x01 #define ND6_SEND_FLAG_MULTICAST_DEST 0x01
#define ND6_SEND_FLAG_ALLNODES_DEST 0x02 #define ND6_SEND_FLAG_ALLNODES_DEST 0x02
#define ND6_SEND_FLAG_ANY_SRC 0x04 #define ND6_SEND_FLAG_ANY_SRC 0x04
static void nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags); static void
static void nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags); nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags);
static void nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags); static void
nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags);
static void
nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags);
#if LWIP_IPV6_SEND_ROUTER_SOLICIT #if LWIP_IPV6_SEND_ROUTER_SOLICIT
static err_t nd6_send_rs(struct netif *netif); static err_t
nd6_send_rs(struct netif *netif);
#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
#if LWIP_ND6_QUEUEING #if LWIP_ND6_QUEUEING
static void nd6_free_q(struct nd6_q_entry *q); static void
nd6_free_q(struct nd6_q_entry *q);
#else /* LWIP_ND6_QUEUEING */ #else /* LWIP_ND6_QUEUEING */
#define nd6_free_q(q) pbuf_free(q) #define nd6_free_q(q) pbuf_free(q)
#endif /* LWIP_ND6_QUEUEING */ #endif /* LWIP_ND6_QUEUEING */
static void nd6_send_q(s8_t i); static void
nd6_send_q(s8_t i);
/** /**
* A local address has been determined to be a duplicate. Take the appropriate * A local address has been determined to be a duplicate. Take the appropriate
@ -163,8 +182,7 @@ nd6_duplicate_addr_detected(struct netif *netif, s8_t addr_idx)
if (addr_idx == 0) { if (addr_idx == 0) {
s8_t i; s8_t i;
for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) && if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) && !netif_ip6_addr_isstatic(netif, i)) {
!netif_ip6_addr_isstatic(netif, i)) {
netif_ip6_addr_set_state(netif, i, IP6_ADDR_DUPLICATED); netif_ip6_addr_set_state(netif, i, IP6_ADDR_DUPLICATED);
} }
} }
@ -183,8 +201,7 @@ nd6_duplicate_addr_detected(struct netif *netif, s8_t addr_idx)
* @param prefix_addr an aligned copy of the prefix address * @param prefix_addr an aligned copy of the prefix address
*/ */
static void static void
nd6_process_autoconfig_prefix(struct netif *netif, nd6_process_autoconfig_prefix(struct netif *netif, struct prefix_option *prefix_opt, const ip6_addr_t *prefix_addr)
struct prefix_option *prefix_opt, const ip6_addr_t *prefix_addr)
{ {
ip6_addr_t ip6addr; ip6_addr_t ip6addr;
u32_t valid_life, pref_life; u32_t valid_life, pref_life;
@ -241,8 +258,8 @@ nd6_process_autoconfig_prefix(struct netif *netif,
* creating addresses even if the link-local address is still in tentative * creating addresses even if the link-local address is still in tentative
* state though, and deal with the fallout of that upon DAD collision. */ * state though, and deal with the fallout of that upon DAD collision. */
addr_state = netif_ip6_addr_state(netif, 0); addr_state = netif_ip6_addr_state(netif, 0);
if (!netif->ip6_autoconfig_enabled || valid_life == IP6_ADDR_LIFE_STATIC || if (!netif->ip6_autoconfig_enabled || valid_life == IP6_ADDR_LIFE_STATIC || ip6_addr_isinvalid(addr_state) ||
ip6_addr_isinvalid(addr_state) || ip6_addr_isduplicated(addr_state)) { ip6_addr_isduplicated(addr_state)) {
return; return;
} }
@ -251,8 +268,11 @@ nd6_process_autoconfig_prefix(struct netif *netif,
* all. As a side effect, find a free slot. Note that we cannot use * all. As a side effect, find a free slot. Note that we cannot use
* netif_add_ip6_address() here, as it would return ERR_OK if the address * netif_add_ip6_address() here, as it would return ERR_OK if the address
* already did exist, resulting in that address being given lifetimes. */ * already did exist, resulting in that address being given lifetimes. */
IP6_ADDR(&ip6addr, prefix_addr->addr[0], prefix_addr->addr[1], IP6_ADDR(&ip6addr,
netif_ip6_addr(netif, 0)->addr[2], netif_ip6_addr(netif, 0)->addr[3]); prefix_addr->addr[0],
prefix_addr->addr[1],
netif_ip6_addr(netif, 0)->addr[2],
netif_ip6_addr(netif, 0)->addr[3]);
ip6_addr_assign_zone(&ip6addr, IP6_UNICAST, netif); ip6_addr_assign_zone(&ip6addr, IP6_UNICAST, netif);
free_idx = 0; free_idx = 0;
@ -388,8 +408,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
} }
/* Update cache entry. */ /* Update cache entry. */
if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || (neighbor_cache[i].state == ND6_INCOMPLETE)) {
(neighbor_cache[i].state == ND6_INCOMPLETE)) {
/* Check that link-layer address option also fits in packet. */ /* Check that link-layer address option also fits in packet. */
if (p->len < (sizeof(struct na_header) + 2)) { if (p->len < (sizeof(struct na_header) + 2)) {
/* @todo debug message */ /* @todo debug message */
@ -473,8 +492,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
accepted = 0; accepted = 0;
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) || if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) ||
(ip6_addr_istentative(netif_ip6_addr_state(inp, i)) && (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) && ip6_addr_isany(ip6_current_src_addr()))) &&
ip6_addr_isany(ip6_current_src_addr()))) &&
ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) { ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) {
accepted = 1; accepted = 1;
break; break;
@ -573,8 +591,8 @@ nd6_input(struct pbuf *p, struct netif *inp)
ra_hdr = (struct ra_header *)p->payload; ra_hdr = (struct ra_header *)p->payload;
/* Check a subset of the other RFC 4861 Sec. 6.1.2 requirements. */ /* Check a subset of the other RFC 4861 Sec. 6.1.2 requirements. */
if (!ip6_addr_islinklocal(ip6_current_src_addr()) || if (!ip6_addr_islinklocal(ip6_current_src_addr()) || IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM ||
IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM || ra_hdr->code != 0) { ra_hdr->code != 0) {
pbuf_free(p); pbuf_free(p);
ND6_STATS_INC(nd6.proterr); ND6_STATS_INC(nd6.proterr);
ND6_STATS_INC(nd6.drop); ND6_STATS_INC(nd6.drop);
@ -586,8 +604,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
/* If we are sending RS messages, stop. */ /* If we are sending RS messages, stop. */
#if LWIP_IPV6_SEND_ROUTER_SOLICIT #if LWIP_IPV6_SEND_ROUTER_SOLICIT
/* ensure at least one solicitation is sent (see RFC 4861, ch. 6.3.7) */ /* ensure at least one solicitation is sent (see RFC 4861, ch. 6.3.7) */
if ((inp->rs_count < LWIP_ND6_MAX_MULTICAST_SOLICIT) || if ((inp->rs_count < LWIP_ND6_MAX_MULTICAST_SOLICIT) || (nd6_send_rs(inp) == ERR_OK)) {
(nd6_send_rs(inp) == ERR_OK)) {
inp->rs_count = 0; inp->rs_count = 0;
} else { } else {
inp->rs_count = 1; inp->rs_count = 1;
@ -629,8 +646,8 @@ nd6_input(struct pbuf *p, struct netif *inp)
#if LWIP_IPV6_DHCP6 #if LWIP_IPV6_DHCP6
/* Trigger DHCPv6 if enabled */ /* Trigger DHCPv6 if enabled */
dhcp6_nd6_ra_trigger(inp, ra_hdr->flags & ND6_RA_FLAG_MANAGED_ADDR_CONFIG, dhcp6_nd6_ra_trigger(
ra_hdr->flags & ND6_RA_FLAG_OTHER_CONFIG); inp, ra_hdr->flags & ND6_RA_FLAG_MANAGED_ADDR_CONFIG, ra_hdr->flags & ND6_RA_FLAG_OTHER_CONFIG);
#endif #endif
/* Offset to options. */ /* Offset to options. */
@ -669,8 +686,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
} }
option_type = buffer[0]; option_type = buffer[0];
switch (option_type) { switch (option_type) {
case ND6_OPTION_TYPE_SOURCE_LLADDR: case ND6_OPTION_TYPE_SOURCE_LLADDR: {
{
struct lladdr_option *lladdr_opt; struct lladdr_option *lladdr_opt;
if (option_len < sizeof(struct lladdr_option)) { if (option_len < sizeof(struct lladdr_option)) {
goto lenerr_drop_free_return; goto lenerr_drop_free_return;
@ -684,8 +700,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
} }
break; break;
} }
case ND6_OPTION_TYPE_MTU: case ND6_OPTION_TYPE_MTU: {
{
struct mtu_option *mtu_opt; struct mtu_option *mtu_opt;
u32_t mtu32; u32_t mtu32;
if (option_len < sizeof(struct mtu_option)) { if (option_len < sizeof(struct mtu_option)) {
@ -705,8 +720,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
} }
break; break;
} }
case ND6_OPTION_TYPE_PREFIX_INFO: case ND6_OPTION_TYPE_PREFIX_INFO: {
{
struct prefix_option *prefix_opt; struct prefix_option *prefix_opt;
ip6_addr_t prefix_addr; ip6_addr_t prefix_addr;
if (option_len < sizeof(struct prefix_option)) { if (option_len < sizeof(struct prefix_option)) {
@ -720,8 +734,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
ip6_addr_assign_zone(&prefix_addr, IP6_UNICAST, inp); ip6_addr_assign_zone(&prefix_addr, IP6_UNICAST, inp);
if (!ip6_addr_islinklocal(&prefix_addr)) { if (!ip6_addr_islinklocal(&prefix_addr)) {
if ((prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) && if ((prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) && (prefix_opt->prefix_length == 64)) {
(prefix_opt->prefix_length == 64)) {
/* Add to on-link prefix list. */ /* Add to on-link prefix list. */
u32_t valid_life; u32_t valid_life;
s8_t prefix; s8_t prefix;
@ -755,8 +768,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
break; break;
#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS #if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
case ND6_OPTION_TYPE_RDNSS: case ND6_OPTION_TYPE_RDNSS: {
{
u8_t num, n; u8_t num, n;
u16_t copy_offset = offset + SIZEOF_RDNSS_OPTION_BASE; u16_t copy_offset = offset + SIZEOF_RDNSS_OPTION_BASE;
struct rdnss_option *rdnss_opt; struct rdnss_option *rdnss_opt;
@ -825,8 +837,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
ip6_addr_assign_zone(&destination_address, IP6_UNICAST, inp); ip6_addr_assign_zone(&destination_address, IP6_UNICAST, inp);
/* Check a subset of the other RFC 4861 Sec. 8.1 requirements. */ /* Check a subset of the other RFC 4861 Sec. 8.1 requirements. */
if (!ip6_addr_islinklocal(ip6_current_src_addr()) || if (!ip6_addr_islinklocal(ip6_current_src_addr()) || IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM ||
IP6H_HOPLIM(ip6_current_header()) != ND6_HOPLIM ||
redir_hdr->code != 0 || ip6_addr_ismulticast(&destination_address)) { redir_hdr->code != 0 || ip6_addr_ismulticast(&destination_address)) {
pbuf_free(p); pbuf_free(p);
ND6_STATS_INC(nd6.proterr); ND6_STATS_INC(nd6.proterr);
@ -944,7 +955,6 @@ lenerr_drop_free_return:
pbuf_free(p); pbuf_free(p);
} }
/** /**
* Periodic timer for Neighbor discovery functions: * Periodic timer for Neighbor discovery functions:
* *
@ -1061,7 +1071,8 @@ nd6_tmr(void)
} }
/* Process our own addresses, updating address lifetimes and/or DAD state. */ /* Process our own addresses, updating address lifetimes and/or DAD state. */
NETIF_FOREACH(netif) { NETIF_FOREACH(netif)
{
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
u8_t addr_state; u8_t addr_state;
#if LWIP_IPV6_ADDRESS_LIFETIMES #if LWIP_IPV6_ADDRESS_LIFETIMES
@ -1080,8 +1091,7 @@ nd6_tmr(void)
* late/never could clog up address slots on the netif. * late/never could clog up address slots on the netif.
* As a result, we may end up expiring addresses of either type here. * As a result, we may end up expiring addresses of either type here.
*/ */
if (!ip6_addr_isinvalid(addr_state) && if (!ip6_addr_isinvalid(addr_state) && !netif_ip6_addr_isstatic(netif, i)) {
!netif_ip6_addr_isstatic(netif, i)) {
u32_t life = netif_ip6_addr_valid_life(netif, i); u32_t life = netif_ip6_addr_valid_life(netif, i);
if (life <= ND6_TMR_INTERVAL / 1000) { if (life <= ND6_TMR_INTERVAL / 1000) {
/* The address has expired. */ /* The address has expired. */
@ -1119,8 +1129,7 @@ nd6_tmr(void)
* deprecated right away. That should almost never happen, though. */ * deprecated right away. That should almost never happen, though. */
addr_state = IP6_ADDR_PREFERRED; addr_state = IP6_ADDR_PREFERRED;
#if LWIP_IPV6_ADDRESS_LIFETIMES #if LWIP_IPV6_ADDRESS_LIFETIMES
if (!netif_ip6_addr_isstatic(netif, i) && if (!netif_ip6_addr_isstatic(netif, i) && netif_ip6_addr_pref_life(netif, i) == 0) {
netif_ip6_addr_pref_life(netif, i) == 0) {
addr_state = IP6_ADDR_DEPRECATED; addr_state = IP6_ADDR_DEPRECATED;
} }
#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ #endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
@ -1131,8 +1140,7 @@ nd6_tmr(void)
/* Send a NS for this address. Use the unspecified address as source /* Send a NS for this address. Use the unspecified address as source
* address in all cases (RFC 4862 Sec. 5.4.2), not in the least * address in all cases (RFC 4862 Sec. 5.4.2), not in the least
* because as it is, we only consider multicast replies for DAD. */ * because as it is, we only consider multicast replies for DAD. */
nd6_send_ns(netif, netif_ip6_addr(netif, i), nd6_send_ns(netif, netif_ip6_addr(netif, i), ND6_SEND_FLAG_MULTICAST_DEST | ND6_SEND_FLAG_ANY_SRC);
ND6_SEND_FLAG_MULTICAST_DEST | ND6_SEND_FLAG_ANY_SRC);
} }
} }
} }
@ -1142,9 +1150,9 @@ nd6_tmr(void)
/* Send router solicitation messages, if necessary. */ /* Send router solicitation messages, if necessary. */
if (!nd6_tmr_rs_reduction) { if (!nd6_tmr_rs_reduction) {
nd6_tmr_rs_reduction = (ND6_RTR_SOLICITATION_INTERVAL / ND6_TMR_INTERVAL) - 1; nd6_tmr_rs_reduction = (ND6_RTR_SOLICITATION_INTERVAL / ND6_TMR_INTERVAL) - 1;
NETIF_FOREACH(netif) { NETIF_FOREACH(netif)
if ((netif->rs_count > 0) && netif_is_up(netif) && {
netif_is_link_up(netif) && if ((netif->rs_count > 0) && netif_is_up(netif) && netif_is_link_up(netif) &&
!ip6_addr_isinvalid(netif_ip6_addr_state(netif, 0)) && !ip6_addr_isinvalid(netif_ip6_addr_state(netif, 0)) &&
!ip6_addr_isduplicated(netif_ip6_addr_state(netif, 0))) { !ip6_addr_isduplicated(netif_ip6_addr_state(netif, 0))) {
if (nd6_send_rs(netif) == ERR_OK) { if (nd6_send_rs(netif) == ERR_OK) {
@ -1156,7 +1164,6 @@ nd6_tmr(void)
nd6_tmr_rs_reduction--; nd6_tmr_rs_reduction--;
} }
#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ #endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
} }
/** Send a neighbor solicitation message for a specific neighbor cache entry /** Send a neighbor solicitation message for a specific neighbor cache entry
@ -1187,8 +1194,7 @@ nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags)
LWIP_ASSERT("target address is required", target_addr != NULL); LWIP_ASSERT("target address is required", target_addr != NULL);
if (!(flags & ND6_SEND_FLAG_ANY_SRC) && if (!(flags & ND6_SEND_FLAG_ANY_SRC) && ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) {
ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) {
/* Use link-local address as source address. */ /* Use link-local address as source address. */
src_addr = netif_ip6_addr(netif, 0); src_addr = netif_ip6_addr(netif, 0);
/* calculate option length (in 8-byte-blocks) */ /* calculate option length (in 8-byte-blocks) */
@ -1230,16 +1236,15 @@ nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags)
} }
#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)
ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, {
target_addr); ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, target_addr);
} }
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Send the packet out. */ /* Send the packet out. */
ND6_STATS_INC(nd6.xmit); ND6_STATS_INC(nd6.xmit);
ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, target_addr, ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, target_addr, ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
pbuf_free(p); pbuf_free(p);
} }
@ -1306,16 +1311,15 @@ nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags)
} }
#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)
na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, {
dest_addr); na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, dest_addr);
} }
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Send the packet out. */ /* Send the packet out. */
ND6_STATS_INC(nd6.xmit); ND6_STATS_INC(nd6.xmit);
ip6_output_if(p, src_addr, dest_addr, ip6_output_if(p, src_addr, dest_addr, ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
pbuf_free(p); pbuf_free(p);
} }
@ -1373,17 +1377,17 @@ nd6_send_rs(struct netif *netif)
} }
#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)
rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, {
&multicast_address); rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, &multicast_address);
} }
#endif /* CHECKSUM_GEN_ICMP6 */ #endif /* CHECKSUM_GEN_ICMP6 */
/* Send the packet out. */ /* Send the packet out. */
ND6_STATS_INC(nd6.xmit); ND6_STATS_INC(nd6.xmit);
err = ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, &multicast_address, err = ip6_output_if(
ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif); p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, &multicast_address, ND6_HOPLIM, 0, IP6_NEXTH_ICMP6, netif);
pbuf_free(p); pbuf_free(p);
return err; return err;
@ -1425,7 +1429,6 @@ nd6_new_neighbor_cache_entry(void)
s8_t j; s8_t j;
u32_t time; u32_t time;
/* First, try to find an empty entry. */ /* First, try to find an empty entry. */
for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
if (neighbor_cache[i].state == ND6_NO_ENTRY) { if (neighbor_cache[i].state == ND6_NO_ENTRY) {
@ -1437,8 +1440,7 @@ nd6_new_neighbor_cache_entry(void)
/* Next, try to find a Stale entry. */ /* Next, try to find a Stale entry. */
for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
if ((neighbor_cache[i].state == ND6_STALE) && if ((neighbor_cache[i].state == ND6_STALE) && (!neighbor_cache[i].isrouter)) {
(!neighbor_cache[i].isrouter)) {
nd6_free_neighbor_cache_entry(i); nd6_free_neighbor_cache_entry(i);
return i; return i;
} }
@ -1446,8 +1448,7 @@ nd6_new_neighbor_cache_entry(void)
/* Next, try to find a Probe entry. */ /* Next, try to find a Probe entry. */
for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
if ((neighbor_cache[i].state == ND6_PROBE) && if ((neighbor_cache[i].state == ND6_PROBE) && (!neighbor_cache[i].isrouter)) {
(!neighbor_cache[i].isrouter)) {
nd6_free_neighbor_cache_entry(i); nd6_free_neighbor_cache_entry(i);
return i; return i;
} }
@ -1455,8 +1456,7 @@ nd6_new_neighbor_cache_entry(void)
/* Next, try to find a Delayed entry. */ /* Next, try to find a Delayed entry. */
for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
if ((neighbor_cache[i].state == ND6_DELAY) && if ((neighbor_cache[i].state == ND6_DELAY) && (!neighbor_cache[i].isrouter)) {
(!neighbor_cache[i].isrouter)) {
nd6_free_neighbor_cache_entry(i); nd6_free_neighbor_cache_entry(i);
return i; return i;
} }
@ -1466,8 +1466,7 @@ nd6_new_neighbor_cache_entry(void)
time = 0xfffffffful; time = 0xfffffffful;
j = -1; j = -1;
for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
if ((neighbor_cache[i].state == ND6_REACHABLE) && if ((neighbor_cache[i].state == ND6_REACHABLE) && (!neighbor_cache[i].isrouter)) {
(!neighbor_cache[i].isrouter)) {
if (neighbor_cache[i].counter.reachable_time < time) { if (neighbor_cache[i].counter.reachable_time < time) {
j = i; j = i;
time = neighbor_cache[i].counter.reachable_time; time = neighbor_cache[i].counter.reachable_time;
@ -1483,10 +1482,7 @@ nd6_new_neighbor_cache_entry(void)
time = 0; time = 0;
j = -1; j = -1;
for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
if ( if ((neighbor_cache[i].q == NULL) && (neighbor_cache[i].state == ND6_INCOMPLETE) && (!neighbor_cache[i].isrouter)) {
(neighbor_cache[i].q == NULL) &&
(neighbor_cache[i].state == ND6_INCOMPLETE) &&
(!neighbor_cache[i].isrouter)) {
if (neighbor_cache[i].counter.probes_sent >= time) { if (neighbor_cache[i].counter.probes_sent >= time) {
j = i; j = i;
time = neighbor_cache[i].counter.probes_sent; time = neighbor_cache[i].counter.probes_sent;
@ -1502,8 +1498,7 @@ nd6_new_neighbor_cache_entry(void)
time = 0; time = 0;
j = -1; j = -1;
for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) {
if ((neighbor_cache[i].state == ND6_INCOMPLETE) && if ((neighbor_cache[i].state == ND6_INCOMPLETE) && (!neighbor_cache[i].isrouter)) {
(!neighbor_cache[i].isrouter)) {
if (neighbor_cache[i].counter.probes_sent >= time) { if (neighbor_cache[i].counter.probes_sent >= time) {
j = i; j = i;
time = neighbor_cache[i].counter.probes_sent; time = neighbor_cache[i].counter.probes_sent;
@ -1633,8 +1628,7 @@ nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif)
/* Check to see if the address matches an on-link prefix. */ /* Check to see if the address matches an on-link prefix. */
for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) {
if ((prefix_list[i].netif == netif) && if ((prefix_list[i].netif == netif) && (prefix_list[i].invalidation_timer > 0) &&
(prefix_list[i].invalidation_timer > 0) &&
ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) { ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) {
return 1; return 1;
} }
@ -1644,8 +1638,7 @@ nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif)
* addresses (from autoconfiguration) have no implied subnet assignment, and * addresses (from autoconfiguration) have no implied subnet assignment, and
* are thus effectively /128 assignments. See RFC 5942 for more on this. */ * are thus effectively /128 assignments. See RFC 5942 for more on this. */
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && netif_ip6_addr_isstatic(netif, i) &&
netif_ip6_addr_isstatic(netif, i) &&
ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) { ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) {
return 1; return 1;
} }
@ -1683,8 +1676,8 @@ nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif)
/* Is the router netif both set and apppropriate? */ /* Is the router netif both set and apppropriate? */
if (default_router_list[i].neighbor_entry != NULL) { if (default_router_list[i].neighbor_entry != NULL) {
router_netif = default_router_list[i].neighbor_entry->netif; router_netif = default_router_list[i].neighbor_entry->netif;
if ((router_netif != NULL) && (netif != NULL ? netif == router_netif : if ((router_netif != NULL) &&
(netif_is_up(router_netif) && netif_is_link_up(router_netif)))) { (netif != NULL ? netif == router_netif : (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) {
/* Is the router valid, i.e., reachable or probably reachable as per /* Is the router valid, i.e., reachable or probably reachable as per
* RFC 4861 Sec. 6.3.6? Note that we will never return a router that * RFC 4861 Sec. 6.3.6? Note that we will never return a router that
* has no neighbor cache entry, due to the netif association tests. */ * has no neighbor cache entry, due to the netif association tests. */
@ -1714,8 +1707,8 @@ nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif)
for (j = 0; j < LWIP_ND6_NUM_ROUTERS; j++) { for (j = 0; j < LWIP_ND6_NUM_ROUTERS; j++) {
if (default_router_list[i].neighbor_entry != NULL) { if (default_router_list[i].neighbor_entry != NULL) {
router_netif = default_router_list[i].neighbor_entry->netif; router_netif = default_router_list[i].neighbor_entry->netif;
if ((router_netif != NULL) && (netif != NULL ? netif == router_netif : if ((router_netif != NULL) &&
(netif_is_up(router_netif) && netif_is_link_up(router_netif)))) { (netif != NULL ? netif == router_netif : (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) {
return i; return i;
} }
} }
@ -1750,8 +1743,8 @@ nd6_find_route(const ip6_addr_t *ip6addr)
* matches. Pick the first one that is associated with a suitable netif. */ * matches. Pick the first one that is associated with a suitable netif. */
for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) {
netif = prefix_list[i].netif; netif = prefix_list[i].netif;
if ((netif != NULL) && ip6_addr_netcmp(&prefix_list[i].prefix, ip6addr) && if ((netif != NULL) && ip6_addr_netcmp(&prefix_list[i].prefix, ip6addr) && netif_is_up(netif) &&
netif_is_up(netif) && netif_is_link_up(netif)) { netif_is_link_up(netif)) {
return netif; return netif;
} }
} }
@ -1759,8 +1752,7 @@ nd6_find_route(const ip6_addr_t *ip6addr)
/* No on-link prefix match. Find a router that can forward the packet. */ /* No on-link prefix match. Find a router that can forward the packet. */
i = nd6_select_router(ip6addr, NULL); i = nd6_select_router(ip6addr, NULL);
if (i >= 0) { if (i >= 0) {
LWIP_ASSERT("selected router must have a neighbor entry", LWIP_ASSERT("selected router must have a neighbor entry", default_router_list[i].neighbor_entry != NULL);
default_router_list[i].neighbor_entry != NULL);
return default_router_list[i].neighbor_entry->netif; return default_router_list[i].neighbor_entry->netif;
} }
@ -1871,8 +1863,7 @@ nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif)
/* Look for prefix in list. */ /* Look for prefix in list. */
for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) {
if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) && if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) && (prefix_list[i].netif == netif)) {
(prefix_list[i].netif == netif)) {
return i; return i;
} }
} }
@ -1895,8 +1886,7 @@ nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif)
/* Create new entry. */ /* Create new entry. */
for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) {
if ((prefix_list[i].netif == NULL) || if ((prefix_list[i].netif == NULL) || (prefix_list[i].invalidation_timer == 0)) {
(prefix_list[i].invalidation_timer == 0)) {
/* Found empty prefix entry. */ /* Found empty prefix entry. */
prefix_list[i].netif = netif; prefix_list[i].netif = netif;
ip6_addr_set(&(prefix_list[i].prefix), prefix); ip6_addr_set(&(prefix_list[i].prefix), prefix);
@ -1969,11 +1959,11 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr); ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr);
/* Now find the next hop. is it a neighbor? */ /* Now find the next hop. is it a neighbor? */
if (ip6_addr_islinklocal(ip6addr) || if (ip6_addr_islinklocal(ip6addr) || nd6_is_prefix_in_netif(ip6addr, netif)) {
nd6_is_prefix_in_netif(ip6addr, netif)) {
/* Destination in local link. */ /* Destination in local link. */
destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif); destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif);
ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr,
destination_cache[nd6_cached_destination_index].destination_addr);
#ifdef LWIP_HOOK_ND6_GET_GW #ifdef LWIP_HOOK_ND6_GET_GW
} else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) { } else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) {
/* Next hop for destination provided by hook function. */ /* Next hop for destination provided by hook function. */
@ -1988,8 +1978,10 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr)); ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr));
return ERR_RTE; return ERR_RTE;
} }
destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif); /* Start with netif mtu, correct through ICMPv6 if necessary */ destination_cache[nd6_cached_destination_index].pmtu =
ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address); netif_mtu6(netif); /* Start with netif mtu, correct through ICMPv6 if necessary */
ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr,
default_router_list[i].neighbor_entry->next_hop_address);
} }
} }
} }
@ -2024,8 +2016,7 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
} }
/* Initialize fields. */ /* Initialize fields. */
ip6_addr_copy(neighbor_cache[i].next_hop_address, ip6_addr_copy(neighbor_cache[i].next_hop_address, destination_cache[nd6_cached_destination_index].next_hop_addr);
destination_cache[nd6_cached_destination_index].next_hop_addr);
neighbor_cache[i].isrouter = 0; neighbor_cache[i].isrouter = 0;
neighbor_cache[i].netif = netif; neighbor_cache[i].netif = netif;
neighbor_cache[i].state = ND6_INCOMPLETE; neighbor_cache[i].state = ND6_INCOMPLETE;
@ -2120,7 +2111,8 @@ nd6_queue_packet(s8_t neighbor_index, struct pbuf *q)
/* queue did not exist, first item in queue */ /* queue did not exist, first item in queue */
neighbor_cache[neighbor_index].q = new_entry; neighbor_cache[neighbor_index].q = new_entry;
} }
LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); LWIP_DEBUGF(LWIP_DBG_TRACE,
("ipv6: queued packet %p on neighbor entry %" S16_F "\n", (void *)p, (s16_t)neighbor_index));
result = ERR_OK; result = ERR_OK;
} else { } else {
/* the pool MEMP_ND6_QUEUE is empty */ /* the pool MEMP_ND6_QUEUE is empty */
@ -2134,7 +2126,8 @@ nd6_queue_packet(s8_t neighbor_index, struct pbuf *q)
pbuf_free(neighbor_cache[neighbor_index].q); pbuf_free(neighbor_cache[neighbor_index].q);
} }
neighbor_cache[neighbor_index].q = p; neighbor_cache[neighbor_index].q = p;
LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); LWIP_DEBUGF(LWIP_DBG_TRACE,
("ipv6: queued packet %p on neighbor entry %" S16_F "\n", (void *)p, (s16_t)neighbor_index));
result = ERR_OK; result = ERR_OK;
#endif /* LWIP_ND6_QUEUEING */ #endif /* LWIP_ND6_QUEUEING */
} else { } else {
@ -2262,8 +2255,7 @@ nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_ad
neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL;
} }
/* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */ /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */
if ((neighbor_cache[i].state == ND6_REACHABLE) || if ((neighbor_cache[i].state == ND6_REACHABLE) || (neighbor_cache[i].state == ND6_DELAY) ||
(neighbor_cache[i].state == ND6_DELAY) ||
(neighbor_cache[i].state == ND6_PROBE)) { (neighbor_cache[i].state == ND6_PROBE)) {
/* Tell the caller to send out the packet now. */ /* Tell the caller to send out the packet now. */
@ -2276,7 +2268,6 @@ nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_ad
return nd6_queue_packet(i, q); return nd6_queue_packet(i, q);
} }
/** /**
* Get the Path MTU for a destination. * Get the Path MTU for a destination.
* *
@ -2303,7 +2294,6 @@ nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif)
return 1280; /* Minimum MTU */ return 1280; /* Minimum MTU */
} }
#if LWIP_ND6_TCP_REACHABILITY_HINTS #if LWIP_ND6_TCP_REACHABILITY_HINTS
/** /**
* Provide the Neighbor discovery process with a hint that a * Provide the Neighbor discovery process with a hint that a
@ -2332,7 +2322,8 @@ nd6_reachability_hint(const ip6_addr_t *ip6addr)
} }
/* Find next hop neighbor in cache. */ /* Find next hop neighbor in cache. */
if (ip6_addr_cmp(&(destination_cache[dst_idx].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { if (ip6_addr_cmp(&(destination_cache[dst_idx].next_hop_addr),
&(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) {
i = nd6_cached_neighbor_index; i = nd6_cached_neighbor_index;
ND6_STATS_INC(nd6.cachehit); ND6_STATS_INC(nd6.cachehit);
} else { } else {