mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-02-04 21:39:49 +00:00
Test / RFC: Reformat a few files using clang-format
Does it compile? Does it look good (enough)?
This commit is contained in:
parent
4e74421dac
commit
8b4a8159a8
@ -63,11 +63,11 @@
|
||||
#include "lwip/memp.h"
|
||||
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/raw.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/priv/api_msg.h"
|
||||
#include "lwip/priv/tcp_priv.h"
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
#include "lwip/raw.h"
|
||||
#include "lwip/udp.h"
|
||||
|
||||
#ifdef LWIP_HOOK_FILENAME
|
||||
#include LWIP_HOOK_FILENAME
|
||||
@ -75,11 +75,11 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define API_MSG_VAR_REF(name) API_VAR_REF(name)
|
||||
#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name)
|
||||
#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM)
|
||||
#define API_MSG_VAR_REF(name) API_VAR_REF(name)
|
||||
#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name)
|
||||
#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM)
|
||||
#define API_MSG_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, NULL)
|
||||
#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name)
|
||||
#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name)
|
||||
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
/* need to allocate API message for accept so empty message pool does not result in event loss
|
||||
@ -92,18 +92,22 @@
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
#define NETCONN_RECVMBOX_WAITABLE(conn) (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_RECVMBOX_WAITABLE(conn) \
|
||||
(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_DEC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1)
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
#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_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_MBOX_WAITING_INC(conn)
|
||||
#define NETCONN_MBOX_WAITING_DEC(conn)
|
||||
#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
|
||||
@ -282,7 +286,7 @@ netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
|
||||
err = netconn_apimsg(lwip_netconn_do_getaddr, &API_MSG_VAR_REF(msg));
|
||||
*addr = msg->msg.ad.ipaddr;
|
||||
*port = msg->msg.ad.port;
|
||||
#else /* LWIP_MPU_COMPATIBLE */
|
||||
#else /* LWIP_MPU_COMPATIBLE */
|
||||
msg.msg.ad.ipaddr = addr;
|
||||
msg.msg.ad.port = port;
|
||||
err = netconn_apimsg(lwip_netconn_do_getaddr, &msg);
|
||||
@ -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,
|
||||
* and NETCONN_FLAG_IPV6_V6ONLY is 0, use IP_ANY_TYPE to bind
|
||||
*/
|
||||
if ((netconn_get_ipv6only(conn) == 0) &&
|
||||
ip_addr_cmp(addr, IP6_ADDR_ANY)) {
|
||||
if ((netconn_get_ipv6only(conn) == 0) && ip_addr_cmp(addr, IP6_ADDR_ANY)) {
|
||||
addr = IP_ANY_TYPE;
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
@ -451,7 +454,7 @@ netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
||||
API_MSG_VAR_FREE(msg);
|
||||
|
||||
return err;
|
||||
#else /* LWIP_TCP */
|
||||
#else /* LWIP_TCP */
|
||||
LWIP_UNUSED_ARG(conn);
|
||||
LWIP_UNUSED_ARG(backlog);
|
||||
return ERR_ARG;
|
||||
@ -478,9 +481,9 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
||||
API_MSG_VAR_DECLARE(msg);
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
|
||||
LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
|
||||
*new_conn = NULL;
|
||||
LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
|
||||
/* NOTE: Although the opengroup spec says a pending error shall be returned to
|
||||
send/recv/getsockopt(SO_ERROR) only, we return it for listening
|
||||
@ -552,7 +555,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
||||
*new_conn = newconn;
|
||||
/* don't set conn->last_err: it's only ERR_OK, anyway */
|
||||
return ERR_OK;
|
||||
#else /* LWIP_TCP */
|
||||
#else /* LWIP_TCP */
|
||||
LWIP_UNUSED_ARG(conn);
|
||||
LWIP_UNUSED_ARG(new_conn);
|
||||
return ERR_ARG;
|
||||
@ -583,7 +586,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
|
||||
|
||||
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
|
||||
*new_buf = NULL;
|
||||
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
|
||||
if (!NETCONN_RECVMBOX_WAITABLE(conn)) {
|
||||
err_t err = netconn_err(conn);
|
||||
@ -595,8 +598,8 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
|
||||
}
|
||||
|
||||
NETCONN_MBOX_WAITING_INC(conn);
|
||||
if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) ||
|
||||
(conn->flags & NETCONN_FLAG_MBOXCLOSED) || (conn->pending_err != ERR_OK)) {
|
||||
if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) || (conn->flags & NETCONN_FLAG_MBOXCLOSED) ||
|
||||
(conn->pending_err != ERR_OK)) {
|
||||
if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_ARCH_TIMEOUT) {
|
||||
err_t err;
|
||||
NETCONN_MBOX_WAITING_DEC(conn);
|
||||
@ -665,7 +668,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
|
||||
|
||||
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
|
||||
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%" U16_F "\n", buf, len));
|
||||
|
||||
*new_buf = buf;
|
||||
/* don't set conn->last_err: it's only ERR_OK, anyway */
|
||||
@ -676,8 +679,9 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
|
||||
static err_t
|
||||
netconn_tcp_recvd_msg(struct netconn *conn, size_t len, struct api_msg *msg)
|
||||
{
|
||||
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
|
||||
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn",
|
||||
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
|
||||
return ERR_ARG;);
|
||||
|
||||
msg->conn = conn;
|
||||
msg->msg.r.len = len;
|
||||
@ -690,8 +694,9 @@ netconn_tcp_recvd(struct netconn *conn, size_t len)
|
||||
{
|
||||
err_t err;
|
||||
API_MSG_VAR_DECLARE(msg);
|
||||
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
|
||||
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn",
|
||||
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
|
||||
return ERR_ARG;);
|
||||
|
||||
API_MSG_VAR_ALLOC(msg);
|
||||
err = netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg));
|
||||
@ -720,7 +725,7 @@ netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags
|
||||
|
||||
if (!(apiflags & NETCONN_NOAUTORCVD)) {
|
||||
/* need to allocate API message here so empty message pool does not result in event loss
|
||||
* see bug #47512: MPU_COMPATIBLE may fail on empty pool */
|
||||
* see bug #47512: MPU_COMPATIBLE may fail on empty pool */
|
||||
API_MSG_VAR_ALLOC(msg);
|
||||
}
|
||||
|
||||
@ -737,7 +742,7 @@ netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags
|
||||
u16_t len = buf ? buf->tot_len : 1;
|
||||
/* don't care for the return value of lwip_netconn_do_recv */
|
||||
/* @todo: this should really be fixed, e.g. by retrying in poll on error */
|
||||
netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg));
|
||||
netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg));
|
||||
API_MSG_VAR_FREE(msg);
|
||||
}
|
||||
|
||||
@ -749,7 +754,7 @@ netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags
|
||||
netconn_set_flags(conn, NETCONN_FIN_RX_PENDING);
|
||||
return ERR_WOULDBLOCK;
|
||||
} else {
|
||||
handle_fin:
|
||||
handle_fin:
|
||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
|
||||
if (conn->pcb.ip == NULL) {
|
||||
/* race condition: RST during recv */
|
||||
@ -781,8 +786,9 @@ handle_fin:
|
||||
err_t
|
||||
netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
|
||||
{
|
||||
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
|
||||
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn",
|
||||
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
|
||||
return ERR_ARG;);
|
||||
|
||||
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
|
||||
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) &&
|
||||
NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn",
|
||||
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP,
|
||||
return ERR_ARG;);
|
||||
|
||||
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
|
||||
netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf)
|
||||
{
|
||||
LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
|
||||
NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn",
|
||||
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP,
|
||||
return ERR_ARG;);
|
||||
|
||||
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
|
||||
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) &&
|
||||
NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn",
|
||||
(conn != NULL) && NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP,
|
||||
return ERR_ARG;);
|
||||
|
||||
return netconn_recv_data(conn, (void **)new_buf, apiflags);
|
||||
}
|
||||
@ -866,7 +875,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
||||
|
||||
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
|
||||
*new_buf = NULL;
|
||||
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
|
||||
#if LWIP_TCP
|
||||
#if (LWIP_UDP || LWIP_RAW)
|
||||
@ -943,9 +952,9 @@ netconn_send(struct netconn *conn, struct netbuf *buf)
|
||||
API_MSG_VAR_DECLARE(msg);
|
||||
err_t err;
|
||||
|
||||
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
|
||||
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
|
||||
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %" U16_F " bytes\n", buf->p->tot_len));
|
||||
|
||||
API_MSG_VAR_ALLOC(msg);
|
||||
API_MSG_VAR_REF(msg).conn = conn;
|
||||
@ -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
|
||||
*/
|
||||
err_t
|
||||
netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
|
||||
u8_t apiflags, size_t *bytes_written)
|
||||
netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags, size_t *bytes_written)
|
||||
{
|
||||
struct netvector vector;
|
||||
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
|
||||
*/
|
||||
err_t
|
||||
netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt,
|
||||
u8_t apiflags, size_t *bytes_written)
|
||||
netconn_write_vectors_partly(struct netconn *conn,
|
||||
struct netvector *vectors,
|
||||
u16_t vectorcnt,
|
||||
u8_t apiflags,
|
||||
size_t *bytes_written)
|
||||
{
|
||||
API_MSG_VAR_DECLARE(msg);
|
||||
err_t err;
|
||||
@ -1003,8 +1014,8 @@ netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u1
|
||||
size_t size;
|
||||
int i;
|
||||
|
||||
LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP), return ERR_VAL;);
|
||||
LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP), return ERR_VAL;);
|
||||
dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
if (conn->send_timeout != 0) {
|
||||
@ -1092,7 +1103,7 @@ netconn_close_shutdown(struct netconn *conn, u8_t how)
|
||||
err_t err;
|
||||
LWIP_UNUSED_ARG(how);
|
||||
|
||||
LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
|
||||
API_MSG_VAR_ALLOC(msg);
|
||||
API_MSG_VAR_REF(msg).conn = conn;
|
||||
@ -1103,7 +1114,7 @@ netconn_close_shutdown(struct netconn *conn, u8_t how)
|
||||
/* get the time we started, which is later compared to
|
||||
sys_now() + conn->send_timeout */
|
||||
API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
|
||||
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
|
||||
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
|
||||
API_MSG_VAR_REF(msg).msg.sd.polls_left =
|
||||
((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
|
||||
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
|
||||
@ -1186,7 +1197,7 @@ netconn_join_leave_group(struct netconn *conn,
|
||||
API_MSG_VAR_DECLARE(msg);
|
||||
err_t err;
|
||||
|
||||
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
|
||||
API_MSG_VAR_ALLOC(msg);
|
||||
|
||||
@ -1228,7 +1239,7 @@ netconn_join_leave_group_netif(struct netconn *conn,
|
||||
API_MSG_VAR_DECLARE(msg);
|
||||
err_t err;
|
||||
|
||||
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
|
||||
API_MSG_VAR_ALLOC(msg);
|
||||
|
||||
@ -1303,7 +1314,7 @@ netconn_gethostbyname(const char *name, ip_addr_t *addr)
|
||||
#if LWIP_MPU_COMPATIBLE
|
||||
strncpy(API_VAR_REF(msg).name, name, DNS_MAX_NAME_LENGTH - 1);
|
||||
API_VAR_REF(msg).name[DNS_MAX_NAME_LENGTH - 1] = 0;
|
||||
#else /* LWIP_MPU_COMPATIBLE */
|
||||
#else /* LWIP_MPU_COMPATIBLE */
|
||||
msg.err = &err;
|
||||
msg.sem = &sem;
|
||||
API_VAR_REF(msg).addr = API_VAR_REF(addr);
|
||||
@ -1314,7 +1325,7 @@ netconn_gethostbyname(const char *name, ip_addr_t *addr)
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||
API_VAR_REF(msg).sem = LWIP_NETCONN_THREAD_SEM_GET();
|
||||
#else /* LWIP_NETCONN_SEM_PER_THREAD*/
|
||||
#else /* LWIP_NETCONN_SEM_PER_THREAD*/
|
||||
err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0);
|
||||
if (err != ERR_OK) {
|
||||
API_VAR_FREE(MEMP_DNS_API_MSG, msg);
|
||||
|
@ -44,13 +44,13 @@
|
||||
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/tcp.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/igmp.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/mld6.h"
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
|
||||
@ -59,10 +59,14 @@
|
||||
/* netconns are polled once per second (e.g. continue write on memory error) */
|
||||
#define NETCONN_TCP_POLL_INTERVAL 2
|
||||
|
||||
#define SET_NONBLOCKING_CONNECT(conn, val) do { if (val) { \
|
||||
netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \
|
||||
} else { \
|
||||
netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); }} while(0)
|
||||
#define SET_NONBLOCKING_CONNECT(conn, val) \
|
||||
do { \
|
||||
if (val) { \
|
||||
netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \
|
||||
} else { \
|
||||
netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \
|
||||
} \
|
||||
} while (0)
|
||||
#define IN_NONBLOCKING_CONNECT(conn) netconn_is_flag_set(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT)
|
||||
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
@ -74,22 +78,28 @@
|
||||
/* forward declarations */
|
||||
#if LWIP_TCP
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
#define WRITE_DELAYED , 1
|
||||
#define WRITE_DELAYED_PARAM , u8_t delayed
|
||||
#define WRITE_DELAYED , 1
|
||||
#define WRITE_DELAYED_PARAM , u8_t delayed
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
#define WRITE_DELAYED
|
||||
#define WRITE_DELAYED_PARAM
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM);
|
||||
static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM);
|
||||
static err_t
|
||||
lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM);
|
||||
static err_t
|
||||
lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM);
|
||||
#endif
|
||||
|
||||
static void netconn_drain(struct netconn *conn);
|
||||
static void
|
||||
netconn_drain(struct netconn *conn);
|
||||
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
#define TCPIP_APIMSG_ACK(m)
|
||||
#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 */
|
||||
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
@ -146,7 +156,6 @@ lwip_netconn_is_err_msg(void *msg, err_t *err)
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
|
||||
#if LWIP_RAW
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
static u8_t
|
||||
recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
||||
const ip_addr_t *addr)
|
||||
recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
|
||||
{
|
||||
struct pbuf *q;
|
||||
struct 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
|
||||
*/
|
||||
static void
|
||||
recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
const ip_addr_t *addr, u16_t port)
|
||||
recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
|
||||
{
|
||||
struct netbuf *buf;
|
||||
struct netconn *conn;
|
||||
@ -239,8 +246,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_GET(conn->recv_avail, recv_avail);
|
||||
if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) ||
|
||||
((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
|
||||
if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) || ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
|
||||
#else /* LWIP_SO_RCVBUF */
|
||||
if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
@ -362,14 +368,14 @@ poll_tcp(void *arg, struct tcp_pcb *pcb)
|
||||
LWIP_ASSERT("conn != NULL", (conn != NULL));
|
||||
|
||||
if (conn->state == NETCONN_WRITE) {
|
||||
lwip_netconn_do_writemore(conn WRITE_DELAYED);
|
||||
lwip_netconn_do_writemore(conn WRITE_DELAYED);
|
||||
} else if (conn->state == NETCONN_CLOSE) {
|
||||
#if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER
|
||||
if (conn->current_msg && conn->current_msg->msg.sd.polls_left) {
|
||||
conn->current_msg->msg.sd.polls_left--;
|
||||
}
|
||||
#endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */
|
||||
lwip_netconn_do_close_internal(conn WRITE_DELAYED);
|
||||
lwip_netconn_do_close_internal(conn WRITE_DELAYED);
|
||||
}
|
||||
/* @todo: implement connect timeout here? */
|
||||
|
||||
@ -404,9 +410,9 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
|
||||
|
||||
if (conn) {
|
||||
if (conn->state == NETCONN_WRITE) {
|
||||
lwip_netconn_do_writemore(conn WRITE_DELAYED);
|
||||
lwip_netconn_do_writemore(conn WRITE_DELAYED);
|
||||
} else if (conn->state == NETCONN_CLOSE) {
|
||||
lwip_netconn_do_close_internal(conn WRITE_DELAYED);
|
||||
lwip_netconn_do_close_internal(conn WRITE_DELAYED);
|
||||
}
|
||||
|
||||
/* If the queued byte- or pbuf-count drops below the configured low-water limit,
|
||||
@ -473,8 +479,7 @@ err_tcp(void *arg, err_t err)
|
||||
sys_mbox_trypost(&conn->acceptmbox, mbox_msg);
|
||||
}
|
||||
|
||||
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
|
||||
(old_state == NETCONN_CONNECT)) {
|
||||
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || (old_state == NETCONN_CONNECT)) {
|
||||
/* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary
|
||||
since the pcb has already been deleted! */
|
||||
int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn);
|
||||
@ -755,14 +760,14 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
||||
#if LWIP_TCP
|
||||
sys_mbox_set_invalid(&conn->acceptmbox);
|
||||
#endif
|
||||
conn->state = NETCONN_NONE;
|
||||
conn->state = NETCONN_NONE;
|
||||
#if LWIP_SOCKET
|
||||
/* initialize socket to -1 since 0 is a valid socket */
|
||||
conn->socket = -1;
|
||||
conn->socket = -1;
|
||||
#endif /* LWIP_SOCKET */
|
||||
conn->callback = callback;
|
||||
conn->callback = callback;
|
||||
#if LWIP_TCP
|
||||
conn->current_msg = NULL;
|
||||
conn->current_msg = NULL;
|
||||
#endif /* LWIP_TCP */
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
conn->send_timeout = 0;
|
||||
@ -772,7 +777,7 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
||||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
#if LWIP_SO_RCVBUF
|
||||
conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
|
||||
conn->recv_avail = 0;
|
||||
conn->recv_avail = 0;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
#if LWIP_SO_LINGER
|
||||
conn->linger = -1;
|
||||
@ -800,11 +805,9 @@ netconn_free(struct netconn *conn)
|
||||
netconn_drain(conn);
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
|
||||
LWIP_ASSERT("recvmbox must be deallocated before calling this function",
|
||||
!sys_mbox_valid(&conn->recvmbox));
|
||||
LWIP_ASSERT("recvmbox must be deallocated before calling this function", !sys_mbox_valid(&conn->recvmbox));
|
||||
#if LWIP_TCP
|
||||
LWIP_ASSERT("acceptmbox must be deallocated before calling this function",
|
||||
!sys_mbox_valid(&conn->acceptmbox));
|
||||
LWIP_ASSERT("acceptmbox must be deallocated before calling this function", !sys_mbox_valid(&conn->acceptmbox));
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
#if !LWIP_NETCONN_SEM_PER_THREAD
|
||||
@ -917,7 +920,7 @@ netconn_mark_mbox_invalid(struct netconn *conn)
|
||||
* @param conn the TCP netconn to close
|
||||
*/
|
||||
static err_t
|
||||
lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
|
||||
lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
|
||||
{
|
||||
err_t err;
|
||||
u8_t shut, shut_rx, shut_tx, shut_close;
|
||||
@ -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) */
|
||||
if (shut == NETCONN_SHUT_RDWR) {
|
||||
shut_close = 1;
|
||||
} else if (shut_rx &&
|
||||
((tpcb->state == FIN_WAIT_1) ||
|
||||
(tpcb->state == FIN_WAIT_2) ||
|
||||
(tpcb->state == CLOSING))) {
|
||||
} else if (shut_rx && ((tpcb->state == FIN_WAIT_1) || (tpcb->state == FIN_WAIT_2) || (tpcb->state == CLOSING))) {
|
||||
shut_close = 1;
|
||||
} else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) {
|
||||
shut_close = 1;
|
||||
@ -988,8 +988,7 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
|
||||
if (netconn_is_nonblocking(conn)) {
|
||||
/* data left on a nonblocking netconn -> cannot linger */
|
||||
err = ERR_WOULDBLOCK;
|
||||
} else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >=
|
||||
(conn->linger * 1000)) {
|
||||
} else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= (conn->linger * 1000)) {
|
||||
/* data left but linger timeout has expired (this happens on further
|
||||
calls to this function through poll_tcp */
|
||||
tcp_abort(tpcb);
|
||||
@ -1038,7 +1037,7 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
|
||||
}
|
||||
#endif
|
||||
if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) {
|
||||
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
|
||||
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
|
||||
if (conn->current_msg->msg.sd.polls_left == 0) {
|
||||
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
|
||||
close_finished = 1;
|
||||
@ -1120,8 +1119,7 @@ lwip_netconn_do_delconn(void *m)
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
/* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */
|
||||
if (state != NETCONN_NONE) {
|
||||
if ((state == NETCONN_WRITE) ||
|
||||
((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
|
||||
if ((state == NETCONN_WRITE) || ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
|
||||
/* close requested, abort running write/connect */
|
||||
sys_sem_t *op_completed_sem;
|
||||
LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
|
||||
@ -1132,10 +1130,8 @@ lwip_netconn_do_delconn(void *m)
|
||||
sys_sem_signal(op_completed_sem);
|
||||
}
|
||||
}
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
if (((state != NETCONN_NONE) &&
|
||||
(state != NETCONN_LISTEN) &&
|
||||
(state != NETCONN_CONNECT)) ||
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
if (((state != NETCONN_NONE) && (state != NETCONN_LISTEN) && (state != NETCONN_CONNECT)) ||
|
||||
((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
|
||||
/* This means either a blocking write or blocking connect is running
|
||||
(nonblocking write returns and sets state to NONE) */
|
||||
@ -1143,13 +1139,12 @@ lwip_netconn_do_delconn(void *m)
|
||||
} else
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
{
|
||||
LWIP_ASSERT("blocking connect in progress",
|
||||
(state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
|
||||
LWIP_ASSERT("blocking connect in progress", (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
|
||||
msg->err = ERR_OK;
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
/* Mark mboxes invalid */
|
||||
netconn_mark_mbox_invalid(msg->conn);
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
netconn_drain(msg->conn);
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
|
||||
@ -1181,7 +1176,7 @@ lwip_netconn_do_delconn(void *m)
|
||||
LOCK_TCPIP_CORE();
|
||||
LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
|
||||
}
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
lwip_netconn_do_close_internal(msg->conn);
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
/* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing
|
||||
@ -1326,8 +1321,7 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||
was_blocking = !IN_NONBLOCKING_CONNECT(conn);
|
||||
SET_NONBLOCKING_CONNECT(conn, 0);
|
||||
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->state = NETCONN_NONE;
|
||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
@ -1376,8 +1370,8 @@ lwip_netconn_do_connect(void *m)
|
||||
err = ERR_ISCONN;
|
||||
} else {
|
||||
setup_tcp(msg->conn);
|
||||
err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr),
|
||||
msg->msg.bc.port, lwip_netconn_do_connected);
|
||||
err = tcp_connect(
|
||||
msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port, lwip_netconn_do_connected);
|
||||
if (err == ERR_OK) {
|
||||
u8_t non_blocking = netconn_is_nonblocking(msg->conn);
|
||||
msg->conn->state = NETCONN_CONNECT;
|
||||
@ -1402,9 +1396,7 @@ lwip_netconn_do_connect(void *m)
|
||||
break;
|
||||
#endif /* LWIP_TCP */
|
||||
default:
|
||||
LWIP_ERROR("Invalid netconn type", 0, do {
|
||||
err = ERR_VAL;
|
||||
} while (0));
|
||||
LWIP_ERROR("Invalid netconn type", 0, do { err = ERR_VAL; } while (0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1467,12 +1459,11 @@ lwip_netconn_do_listen(void *m)
|
||||
#endif /* TCP_LISTEN_BACKLOG */
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
/* "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
|
||||
*/
|
||||
if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) &&
|
||||
(netconn_get_ipv6only(msg->conn) == 0)) {
|
||||
* and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen
|
||||
*/
|
||||
if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) && (netconn_get_ipv6only(msg->conn) == 0)) {
|
||||
/* 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);
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
@ -1550,14 +1541,17 @@ lwip_netconn_do_send(void *m)
|
||||
case NETCONN_UDP:
|
||||
#if LWIP_CHECKSUM_ON_COPY
|
||||
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,
|
||||
msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
|
||||
err = udp_send_chksum(
|
||||
msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
|
||||
} else {
|
||||
err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p,
|
||||
&msg->msg.b->addr, msg->msg.b->port,
|
||||
msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
|
||||
err = udp_sendto_chksum(msg->conn->pcb.udp,
|
||||
msg->msg.b->p,
|
||||
&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)) {
|
||||
err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
|
||||
} else {
|
||||
@ -1637,7 +1631,7 @@ lwip_netconn_do_accepted(void *m)
|
||||
* ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
|
||||
*/
|
||||
static err_t
|
||||
lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
|
||||
lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
|
||||
{
|
||||
err_t err;
|
||||
const void *dataptr;
|
||||
@ -1660,8 +1654,7 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
|
||||
dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
|
||||
|
||||
#if LWIP_SO_SNDTIMEO
|
||||
if ((conn->send_timeout != 0) &&
|
||||
((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
|
||||
if ((conn->send_timeout != 0) && ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
|
||||
write_finished = 1;
|
||||
if (conn->current_msg->msg.w.offset == 0) {
|
||||
/* 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.
|
||||
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 */
|
||||
if ((len == 0xffff && diff > 0xffffUL) ||
|
||||
(len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) {
|
||||
if ((len == 0xffff && diff > 0xffffUL) || (len == (u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) {
|
||||
write_more = 1;
|
||||
apiflags |= TCP_WRITE_FLAG_MORE;
|
||||
} else {
|
||||
@ -1726,14 +1718,13 @@ lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
|
||||
} while (write_more && err == ERR_OK);
|
||||
/* if OK or memory error, check available space */
|
||||
if ((err == ERR_OK) || (err == ERR_MEM)) {
|
||||
err_mem:
|
||||
err_mem:
|
||||
if (dontblock && (conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len)) {
|
||||
/* non-blocking write did not write everything: mark the pcb non-writable
|
||||
and let poll_tcp check writable space to mark the pcb writable again */
|
||||
API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0);
|
||||
conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
|
||||
} else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
|
||||
(tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
|
||||
} else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
|
||||
/* The queued byte- or pbuf-count exceeds the configured low-water limit,
|
||||
let select mark this pcb as non-writable. */
|
||||
API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0);
|
||||
@ -1835,7 +1826,7 @@ lwip_netconn_do_write(void *m)
|
||||
LOCK_TCPIP_CORE();
|
||||
LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE);
|
||||
}
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
lwip_netconn_do_writemore(msg->conn);
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
/* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG
|
||||
@ -1844,7 +1835,7 @@ lwip_netconn_do_write(void *m)
|
||||
} else {
|
||||
err = ERR_CONN;
|
||||
}
|
||||
#else /* LWIP_TCP */
|
||||
#else /* LWIP_TCP */
|
||||
err = ERR_VAL;
|
||||
#endif /* LWIP_TCP */
|
||||
#if (LWIP_UDP || LWIP_RAW)
|
||||
@ -1870,11 +1861,9 @@ lwip_netconn_do_getaddr(void *m)
|
||||
|
||||
if (msg->conn->pcb.ip != NULL) {
|
||||
if (msg->msg.ad.local) {
|
||||
ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr),
|
||||
msg->conn->pcb.ip->local_ip);
|
||||
ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->local_ip);
|
||||
} else {
|
||||
ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr),
|
||||
msg->conn->pcb.ip->remote_ip);
|
||||
ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->remote_ip);
|
||||
}
|
||||
|
||||
msg->err = ERR_OK;
|
||||
@ -1909,7 +1898,8 @@ lwip_netconn_do_getaddr(void *m)
|
||||
/* pcb is not connected and remote name is requested */
|
||||
msg->err = ERR_CONN;
|
||||
} 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;
|
||||
#endif /* LWIP_TCP */
|
||||
@ -1939,8 +1929,7 @@ lwip_netconn_do_close(void *m)
|
||||
enum netconn_state state = msg->conn->state;
|
||||
/* First check if this is a TCP netconn and if it is in a correct state
|
||||
(LISTEN doesn't support half shutdown) */
|
||||
if ((msg->conn->pcb.tcp != NULL) &&
|
||||
(NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) &&
|
||||
if ((msg->conn->pcb.tcp != NULL) && (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) &&
|
||||
((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) {
|
||||
/* Check if we are in a connected state */
|
||||
if (state == NETCONN_CONNECT) {
|
||||
@ -1966,7 +1955,7 @@ lwip_netconn_do_close(void *m)
|
||||
}
|
||||
}
|
||||
if (state == NETCONN_NONE) {
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
msg->err = ERR_INPROGRESS;
|
||||
} else {
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
@ -1974,7 +1963,7 @@ lwip_netconn_do_close(void *m)
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
/* Mark mboxes invalid */
|
||||
netconn_mark_mbox_invalid(msg->conn);
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
netconn_drain(msg->conn);
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
}
|
||||
@ -1989,7 +1978,7 @@ lwip_netconn_do_close(void *m)
|
||||
LOCK_TCPIP_CORE();
|
||||
LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
|
||||
}
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
lwip_netconn_do_close_internal(msg->conn);
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
/* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */
|
||||
@ -2075,22 +2064,18 @@ lwip_netconn_do_join_leave_group_netif(void *m)
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
if (NETCONNTYPE_ISIPV6(msg->conn->type)) {
|
||||
if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
|
||||
msg->err = mld6_joingroup_netif(netif,
|
||||
ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
|
||||
msg->err = mld6_joingroup_netif(netif, ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
|
||||
} else {
|
||||
msg->err = mld6_leavegroup_netif(netif,
|
||||
ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
|
||||
msg->err = mld6_leavegroup_netif(netif, ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
|
||||
}
|
||||
} else
|
||||
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
|
||||
{
|
||||
#if LWIP_IGMP
|
||||
if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
|
||||
msg->err = igmp_joingroup_netif(netif,
|
||||
ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
|
||||
msg->err = igmp_joingroup_netif(netif, ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
|
||||
} else {
|
||||
msg->err = igmp_leavegroup_netif(netif,
|
||||
ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
|
||||
msg->err = igmp_leavegroup_netif(netif, ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
|
||||
}
|
||||
#endif /* LWIP_IGMP */
|
||||
}
|
||||
@ -2150,8 +2135,8 @@ lwip_netconn_do_gethostbyname(void *arg)
|
||||
LWIP_DNS_ADDRTYPE_DEFAULT;
|
||||
#endif
|
||||
|
||||
API_EXPR_DEREF(msg->err) = dns_gethostbyname_addrtype(msg->name,
|
||||
API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype);
|
||||
API_EXPR_DEREF(msg->err) =
|
||||
dns_gethostbyname_addrtype(msg->name, API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype);
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
/* For core locking, only block if we need to wait for answer/timeout */
|
||||
if (API_EXPR_DEREF(msg->err) == ERR_INPROGRESS) {
|
||||
@ -2160,7 +2145,7 @@ lwip_netconn_do_gethostbyname(void *arg)
|
||||
LOCK_TCPIP_CORE();
|
||||
LWIP_ASSERT("do_gethostbyname still in progress!!", API_EXPR_DEREF(msg->err) != ERR_INPROGRESS);
|
||||
}
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) {
|
||||
/* on error or immediate success, wake up the application
|
||||
* task waiting in netconn_gethostbyname */
|
||||
|
@ -44,25 +44,25 @@
|
||||
|
||||
#if !NO_SYS
|
||||
/** Table to quickly map an lwIP error (err_t) to a socket error
|
||||
* by using -err as an index */
|
||||
* by using -err as an index */
|
||||
static const int err_to_errno_table[] = {
|
||||
0, /* ERR_OK 0 No error, everything OK. */
|
||||
ENOMEM, /* ERR_MEM -1 Out of memory error. */
|
||||
ENOBUFS, /* ERR_BUF -2 Buffer error. */
|
||||
EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
|
||||
EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
|
||||
EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
|
||||
EINVAL, /* ERR_VAL -6 Illegal value. */
|
||||
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
|
||||
EADDRINUSE, /* ERR_USE -8 Address in use. */
|
||||
EALREADY, /* ERR_ALREADY -9 Already connecting. */
|
||||
EISCONN, /* ERR_ISCONN -10 Conn already established.*/
|
||||
ENOTCONN, /* ERR_CONN -11 Not connected. */
|
||||
-1, /* ERR_IF -12 Low-level netif error */
|
||||
ECONNABORTED, /* ERR_ABRT -13 Connection aborted. */
|
||||
ECONNRESET, /* ERR_RST -14 Connection reset. */
|
||||
ENOTCONN, /* ERR_CLSD -15 Connection closed. */
|
||||
EIO /* ERR_ARG -16 Illegal argument. */
|
||||
0, /* ERR_OK 0 No error, everything OK. */
|
||||
ENOMEM, /* ERR_MEM -1 Out of memory error. */
|
||||
ENOBUFS, /* ERR_BUF -2 Buffer error. */
|
||||
EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
|
||||
EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
|
||||
EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
|
||||
EINVAL, /* ERR_VAL -6 Illegal value. */
|
||||
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
|
||||
EADDRINUSE, /* ERR_USE -8 Address in use. */
|
||||
EALREADY, /* ERR_ALREADY -9 Already connecting. */
|
||||
EISCONN, /* ERR_ISCONN -10 Conn already established.*/
|
||||
ENOTCONN, /* ERR_CONN -11 Not connected. */
|
||||
-1, /* ERR_IF -12 Low-level netif error */
|
||||
ECONNABORTED, /* ERR_ABRT -13 Connection aborted. */
|
||||
ECONNRESET, /* ERR_RST -14 Connection reset. */
|
||||
ENOTCONN, /* ERR_CLSD -15 Connection closed. */
|
||||
EIO /* ERR_ARG -16 Illegal argument. */
|
||||
};
|
||||
|
||||
int
|
||||
|
@ -67,7 +67,7 @@ lwip_if_indextoname(unsigned int ifindex, char *ifname)
|
||||
return ifname;
|
||||
}
|
||||
}
|
||||
#else /* LWIP_NETIF_API */
|
||||
#else /* LWIP_NETIF_API */
|
||||
LWIP_UNUSED_ARG(ifindex);
|
||||
LWIP_UNUSED_ARG(ifname);
|
||||
#endif /* LWIP_NETIF_API */
|
||||
@ -93,9 +93,9 @@ lwip_if_nametoindex(const char *ifname)
|
||||
if (!err) {
|
||||
return idx;
|
||||
}
|
||||
#else /* LWIP_NETIF_API */
|
||||
#else /* LWIP_NETIF_API */
|
||||
LWIP_UNUSED_ARG(ifname);
|
||||
#endif /* LWIP_NETIF_API */
|
||||
#endif /* LWIP_NETIF_API */
|
||||
return 0; /* invalid index */
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,8 @@
|
||||
|
||||
#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/netbuf.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/netbuf.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -59,8 +59,8 @@
|
||||
* @return a pointer to a new netbuf
|
||||
* NULL on lack of memory
|
||||
*/
|
||||
struct
|
||||
netbuf *netbuf_new(void)
|
||||
struct netbuf *
|
||||
netbuf_new(void)
|
||||
{
|
||||
struct netbuf *buf;
|
||||
|
||||
@ -111,8 +111,7 @@ netbuf_alloc(struct netbuf *buf, u16_t size)
|
||||
if (buf->p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
LWIP_ASSERT("check that first pbuf can hold size",
|
||||
(buf->p->len >= size));
|
||||
LWIP_ASSERT("check that first pbuf can hold size", (buf->p->len >= size));
|
||||
buf->ptr = buf->p;
|
||||
return buf->p->payload;
|
||||
}
|
||||
|
@ -39,18 +39,19 @@
|
||||
|
||||
#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/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 <string.h> /* memset */
|
||||
|
||||
/** 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;
|
||||
char *aliases;
|
||||
@ -129,7 +130,8 @@ lwip_gethostbyname(const char *name)
|
||||
u8_t idx;
|
||||
for (idx = 0; s_hostent.h_addr_list[idx]; idx++) {
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
|
||||
LWIP_DEBUGF(DNS_DEBUG,
|
||||
("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
|
||||
}
|
||||
}
|
||||
#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
|
||||
*/
|
||||
int
|
||||
lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
|
||||
size_t buflen, struct hostent **result, int *h_errnop)
|
||||
lwip_gethostbyname_r(const char *name,
|
||||
struct hostent *ret,
|
||||
char *buf,
|
||||
size_t buflen,
|
||||
struct hostent **result,
|
||||
int *h_errnop)
|
||||
{
|
||||
err_t err;
|
||||
struct gethostbyname_r_helper *h;
|
||||
@ -266,8 +272,7 @@ lwip_freeaddrinfo(struct addrinfo *ai)
|
||||
* @todo: implement AI_V4MAPPED, AI_ADDRCONFIG
|
||||
*/
|
||||
int
|
||||
lwip_getaddrinfo(const char *nodename, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res)
|
||||
lwip_getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
|
||||
{
|
||||
err_t err;
|
||||
ip_addr_t addr;
|
||||
@ -295,7 +300,7 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
|
||||
#if LWIP_IPV6
|
||||
&& (ai_family != AF_INET6)
|
||||
#endif /* LWIP_IPV6 */
|
||||
) {
|
||||
) {
|
||||
return EAI_FAMILY;
|
||||
}
|
||||
} else {
|
||||
@ -319,8 +324,7 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
|
||||
return EAI_NONAME;
|
||||
}
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) ||
|
||||
(IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) {
|
||||
if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) || (IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) {
|
||||
return EAI_NONAME;
|
||||
}
|
||||
#endif /* LWIP_IPV4 && LWIP_IPV6 */
|
||||
@ -359,8 +363,7 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
|
||||
total_size += namelen + 1;
|
||||
}
|
||||
/* If this fails, please report to lwip-devel! :-) */
|
||||
LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!",
|
||||
total_size <= NETDB_ELEM_SIZE);
|
||||
LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", total_size <= NETDB_ELEM_SIZE);
|
||||
ai = (struct addrinfo *)memp_malloc(MEMP_NETDB);
|
||||
if (ai == NULL) {
|
||||
return EAI_MEMORY;
|
||||
|
@ -43,16 +43,16 @@
|
||||
#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/etharp.h"
|
||||
#include "lwip/netifapi.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/netifapi.h"
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
|
||||
#include <string.h> /* strncpy */
|
||||
|
||||
#define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
|
||||
#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
|
||||
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
|
||||
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
|
||||
#define NETIFAPI_VAR_REF(name) API_VAR_REF(name)
|
||||
#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name)
|
||||
#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
|
||||
#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
|
||||
|
||||
/**
|
||||
* Call netif_add() inside the tcpip_thread context.
|
||||
@ -64,15 +64,15 @@ netifapi_do_netif_add(struct tcpip_api_call_data *m)
|
||||
* We know it works because the structs have been instantiated as struct netifapi_msg */
|
||||
struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
|
||||
|
||||
if (!netif_add( msg->netif,
|
||||
if (!netif_add(msg->netif,
|
||||
#if LWIP_IPV4
|
||||
API_EXPR_REF(msg->msg.add.ipaddr),
|
||||
API_EXPR_REF(msg->msg.add.netmask),
|
||||
API_EXPR_REF(msg->msg.add.gw),
|
||||
API_EXPR_REF(msg->msg.add.ipaddr),
|
||||
API_EXPR_REF(msg->msg.add.netmask),
|
||||
API_EXPR_REF(msg->msg.add.gw),
|
||||
#endif /* LWIP_IPV4 */
|
||||
msg->msg.add.state,
|
||||
msg->msg.add.init,
|
||||
msg->msg.add.input)) {
|
||||
msg->msg.add.state,
|
||||
msg->msg.add.init,
|
||||
msg->msg.add.input)) {
|
||||
return ERR_IF;
|
||||
} else {
|
||||
return ERR_OK;
|
||||
@ -90,17 +90,15 @@ 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 */
|
||||
struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
|
||||
|
||||
netif_set_addr( msg->netif,
|
||||
API_EXPR_REF(msg->msg.add.ipaddr),
|
||||
API_EXPR_REF(msg->msg.add.netmask),
|
||||
API_EXPR_REF(msg->msg.add.gw));
|
||||
netif_set_addr(
|
||||
msg->netif, API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), API_EXPR_REF(msg->msg.add.gw));
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
/**
|
||||
* Call netif_name_to_index() inside the tcpip_thread context.
|
||||
*/
|
||||
* Call netif_name_to_index() inside the tcpip_thread context.
|
||||
*/
|
||||
static err_t
|
||||
netifapi_do_name_to_index(struct tcpip_api_call_data *m)
|
||||
{
|
||||
@ -113,8 +111,8 @@ netifapi_do_name_to_index(struct tcpip_api_call_data *m)
|
||||
}
|
||||
|
||||
/**
|
||||
* Call netif_index_to_name() inside the tcpip_thread context.
|
||||
*/
|
||||
* Call netif_index_to_name() inside the tcpip_thread context.
|
||||
*/
|
||||
static err_t
|
||||
netifapi_do_index_to_name(struct tcpip_api_call_data *m)
|
||||
{
|
||||
@ -221,9 +219,13 @@ netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type)
|
||||
err_t
|
||||
netifapi_netif_add(struct netif *netif,
|
||||
#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 */
|
||||
void *state, netif_init_fn init, netif_input_fn input)
|
||||
void *state,
|
||||
netif_init_fn init,
|
||||
netif_input_fn input)
|
||||
{
|
||||
err_t err;
|
||||
NETIFAPI_VAR_DECLARE(msg);
|
||||
@ -243,13 +245,13 @@ netifapi_netif_add(struct netif *netif,
|
||||
|
||||
NETIFAPI_VAR_REF(msg).netif = netif;
|
||||
#if LWIP_IPV4
|
||||
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
|
||||
#endif /* LWIP_IPV4 */
|
||||
NETIFAPI_VAR_REF(msg).msg.add.state = state;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.init = init;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.input = input;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.state = state;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.init = init;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.input = input;
|
||||
err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
|
||||
NETIFAPI_VAR_FREE(msg);
|
||||
return err;
|
||||
@ -264,10 +266,7 @@ netifapi_netif_add(struct netif *netif,
|
||||
* @note for params @see netif_set_addr()
|
||||
*/
|
||||
err_t
|
||||
netifapi_netif_set_addr(struct netif *netif,
|
||||
const ip4_addr_t *ipaddr,
|
||||
const ip4_addr_t *netmask,
|
||||
const ip4_addr_t *gw)
|
||||
netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw)
|
||||
{
|
||||
err_t err;
|
||||
NETIFAPI_VAR_DECLARE(msg);
|
||||
@ -284,9 +283,9 @@ netifapi_netif_set_addr(struct netif *netif,
|
||||
}
|
||||
|
||||
NETIFAPI_VAR_REF(msg).netif = netif;
|
||||
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
|
||||
NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw);
|
||||
err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
|
||||
NETIFAPI_VAR_FREE(msg);
|
||||
return err;
|
||||
@ -300,8 +299,7 @@ netifapi_netif_set_addr(struct netif *netif,
|
||||
* @note use only for functions where there is only "netif" parameter.
|
||||
*/
|
||||
err_t
|
||||
netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
|
||||
netifapi_errt_fn errtfunc)
|
||||
netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, netifapi_errt_fn errtfunc)
|
||||
{
|
||||
err_t err;
|
||||
NETIFAPI_VAR_DECLARE(msg);
|
||||
@ -316,13 +314,13 @@ netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netifapi_netif
|
||||
* Call netif_name_to_index() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*
|
||||
* @param name the interface name of the netif
|
||||
* @param idx output index of the found netif
|
||||
*/
|
||||
* @ingroup netifapi_netif
|
||||
* Call netif_name_to_index() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*
|
||||
* @param name the interface name of the netif
|
||||
* @param idx output index of the found netif
|
||||
*/
|
||||
err_t
|
||||
netifapi_netif_name_to_index(const char *name, u8_t *idx)
|
||||
{
|
||||
@ -347,14 +345,14 @@ netifapi_netif_name_to_index(const char *name, u8_t *idx)
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup netifapi_netif
|
||||
* Call netif_index_to_name() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*
|
||||
* @param idx the interface index of the netif
|
||||
* @param name output name of the found netif, empty '\0' string if netif not found.
|
||||
* name should be of at least NETIF_NAMESIZE bytes
|
||||
*/
|
||||
* @ingroup netifapi_netif
|
||||
* Call netif_index_to_name() in a thread-safe way by running that function inside the
|
||||
* tcpip_thread context.
|
||||
*
|
||||
* @param idx the interface index of the netif
|
||||
* @param name output name of the found netif, empty '\0' string if netif not found.
|
||||
* name should be of at least NETIF_NAMESIZE bytes
|
||||
*/
|
||||
err_t
|
||||
netifapi_netif_index_to_name(u8_t idx, char *name)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -40,20 +40,20 @@
|
||||
|
||||
#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "lwip/init.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name)
|
||||
#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name)
|
||||
#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name)
|
||||
#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM)
|
||||
#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
|
||||
#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM)
|
||||
#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
|
||||
|
||||
/* global variables */
|
||||
static tcpip_init_done_fn tcpip_init_done;
|
||||
@ -65,7 +65,8 @@ static sys_mbox_t tcpip_mbox;
|
||||
sys_mutex_t lock_tcpip_core;
|
||||
#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
|
||||
/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */
|
||||
@ -136,7 +137,7 @@ tcpip_thread(void *arg)
|
||||
tcpip_init_done(tcpip_init_done_arg);
|
||||
}
|
||||
|
||||
while (1) { /* MAIN Loop */
|
||||
while (1) { /* MAIN Loop */
|
||||
LWIP_TCPIP_THREAD_ALIVE();
|
||||
/* wait for a message, timeouts are processed while waiting */
|
||||
TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg);
|
||||
@ -246,7 +247,7 @@ tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
|
||||
ret = input_fn(p, inp);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
return ret;
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
|
||||
@ -420,7 +421,6 @@ tcpip_untimeout(sys_timeout_handler h, void *arg)
|
||||
}
|
||||
#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
|
||||
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@ -442,7 +442,7 @@ tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
|
||||
fn(apimsg);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
return ERR_OK;
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
TCPIP_MSG_VAR_DECLARE(msg);
|
||||
|
||||
LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
|
||||
@ -496,7 +496,7 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn;
|
||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET();
|
||||
#else /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
#else /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem;
|
||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg));
|
||||
@ -519,7 +519,7 @@ tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
|
||||
* e.g. the message is allocated once and posted several times from an IRQ
|
||||
* using tcpip_callbackmsg_trycallback().
|
||||
* Example usage: Trigger execution of an ethernet IRQ DPC routine in lwIP thread context.
|
||||
*
|
||||
*
|
||||
* @param function the function to call
|
||||
* @param ctx parameter passed to function
|
||||
* @return a struct pointer to pass to tcpip_callbackmsg_trycallback().
|
||||
|
@ -62,10 +62,10 @@
|
||||
|
||||
#include "lwip/mem.h"
|
||||
/* #include "lwip/udp.h" */
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/autoip.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/prot/autoip.h"
|
||||
|
||||
#include <string.h>
|
||||
@ -73,11 +73,10 @@
|
||||
/** Pseudo random macro based on netif informations.
|
||||
* You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
|
||||
#ifndef LWIP_AUTOIP_RAND
|
||||
#define LWIP_AUTOIP_RAND(netif) ( (((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[4]) & 0xff))) + \
|
||||
(netif_autoip_data(netif)? netif_autoip_data(netif)->tried_llipaddr : 0))
|
||||
#define LWIP_AUTOIP_RAND(netif) \
|
||||
((((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[4]) & 0xff))) + \
|
||||
(netif_autoip_data(netif) ? netif_autoip_data(netif)->tried_llipaddr : 0))
|
||||
#endif /* LWIP_AUTOIP_RAND */
|
||||
|
||||
/**
|
||||
@ -85,14 +84,15 @@
|
||||
* If you want to override this, define it to something else in lwipopts.h.
|
||||
*/
|
||||
#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
|
||||
#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
|
||||
lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
|
||||
((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
|
||||
#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
|
||||
lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
|
||||
#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
|
||||
|
||||
/* static functions */
|
||||
static err_t autoip_arp_announce(struct netif *netif);
|
||||
static void autoip_start_probing(struct netif *netif);
|
||||
static err_t
|
||||
autoip_arp_announce(struct netif *netif);
|
||||
static void
|
||||
autoip_start_probing(struct netif *netif);
|
||||
|
||||
/**
|
||||
* @ingroup autoip
|
||||
@ -108,8 +108,7 @@ autoip_set_struct(struct netif *netif, struct autoip *autoip)
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
LWIP_ASSERT("netif != NULL", netif != NULL);
|
||||
LWIP_ASSERT("autoip != NULL", autoip != NULL);
|
||||
LWIP_ASSERT("netif already has a struct autoip set",
|
||||
netif_autoip_data(netif) == NULL);
|
||||
LWIP_ASSERT("netif already has a struct autoip set", netif_autoip_data(netif) == NULL);
|
||||
|
||||
/* clear data structure */
|
||||
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) {
|
||||
addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
|
||||
}
|
||||
LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
|
||||
(addr <= AUTOIP_RANGE_END));
|
||||
LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && (addr <= AUTOIP_RANGE_END));
|
||||
ip4_addr_set_u32(ipaddr, lwip_htonl(addr));
|
||||
|
||||
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",
|
||||
(u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
|
||||
ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
|
||||
("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),
|
||||
ip4_addr3_16(ipaddr),
|
||||
ip4_addr4_16(ipaddr)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,10 +232,15 @@ autoip_bind(struct netif *netif)
|
||||
ip4_addr_t sn_mask, gw_addr;
|
||||
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
|
||||
("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,
|
||||
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
|
||||
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
|
||||
("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,
|
||||
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(&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);
|
||||
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
|
||||
("autoip_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0],
|
||||
netif->name[1], (u16_t)netif->num));
|
||||
LWIP_DEBUGF(
|
||||
AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
|
||||
("autoip_start(netif=%p) %c%c%" U16_F "\n", (void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
|
||||
if (autoip == NULL) {
|
||||
/* no AutoIP client attached yet? */
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
|
||||
("autoip_start(): starting new AUTOIP client\n"));
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): starting new AUTOIP client\n"));
|
||||
autoip = (struct autoip *)mem_calloc(1, sizeof(struct autoip));
|
||||
if (autoip == NULL) {
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
|
||||
("autoip_start(): could not allocate autoip\n"));
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): could not allocate autoip\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
/* store this AutoIP client in the netif */
|
||||
@ -303,9 +307,11 @@ autoip_start_probing(struct netif *netif)
|
||||
autoip->state = AUTOIP_STATE_PROBING;
|
||||
autoip->sent_num = 0;
|
||||
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",
|
||||
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
|
||||
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
|
||||
("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_addr3_16(&autoip->llipaddr),
|
||||
ip4_addr4_16(&autoip->llipaddr)));
|
||||
|
||||
/* time to wait to first probe, this is randomly
|
||||
* chosen out of 0 to PROBE_WAIT seconds.
|
||||
@ -368,7 +374,8 @@ autoip_tmr(void)
|
||||
{
|
||||
struct netif *netif;
|
||||
/* loop through netif's */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
struct autoip *autoip = netif_autoip_data(netif);
|
||||
/* only act on AutoIP configured interfaces */
|
||||
if (autoip != NULL) {
|
||||
@ -377,8 +384,7 @@ autoip_tmr(void)
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
|
||||
("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
|
||||
(u16_t)(autoip->state), autoip->ttw));
|
||||
("autoip_tmr() AutoIP-State: %" U16_F ", ttw=%" U16_F "\n", (u16_t)(autoip->state), autoip->ttw));
|
||||
|
||||
if (autoip->ttw > 0) {
|
||||
autoip->ttw--;
|
||||
@ -396,9 +402,11 @@ autoip_tmr(void)
|
||||
autoip->sent_num = 1;
|
||||
autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
|
||||
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",
|
||||
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
|
||||
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
|
||||
("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_addr3_16(&autoip->llipaddr),
|
||||
ip4_addr4_16(&autoip->llipaddr)));
|
||||
} else {
|
||||
autoip_arp_probe(netif);
|
||||
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;
|
||||
} else {
|
||||
/* calculate time to wait to next probe */
|
||||
autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
|
||||
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
|
||||
autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND)) +
|
||||
PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
|
||||
}
|
||||
}
|
||||
@ -428,9 +435,11 @@ autoip_tmr(void)
|
||||
autoip->sent_num = 0;
|
||||
autoip->ttw = 0;
|
||||
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",
|
||||
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
|
||||
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
|
||||
("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_addr3_16(&autoip->llipaddr),
|
||||
ip4_addr4_16(&autoip->llipaddr)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -479,8 +488,7 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
|
||||
* ip.dst == llipaddr && hw.src != own hwaddr
|
||||
*/
|
||||
if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) ||
|
||||
(ip4_addr_isany_val(sipaddr) &&
|
||||
ip4_addr_cmp(&dipaddr, &autoip->llipaddr) &&
|
||||
(ip4_addr_isany_val(sipaddr) && ip4_addr_cmp(&dipaddr, &autoip->llipaddr) &&
|
||||
!eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
|
||||
("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
|
||||
* ip.src == llipaddr && hw.src != own hwaddr
|
||||
*/
|
||||
if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) &&
|
||||
!eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
|
||||
if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) && !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
|
||||
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
|
||||
("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
|
||||
autoip_handle_arp_conflict(netif);
|
||||
|
@ -67,18 +67,18 @@
|
||||
|
||||
#if LWIP_IPV4 && LWIP_DHCP /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/autoip.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/autoip.h"
|
||||
#include "lwip/dns.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/iana.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/udp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -89,14 +89,17 @@
|
||||
#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr)
|
||||
#endif
|
||||
#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
|
||||
|
||||
/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using
|
||||
* LWIP_RAND() (this overrides DHCP_GLOBAL_XID)
|
||||
*/
|
||||
#ifndef DHCP_CREATE_RAND_XID
|
||||
#define DHCP_CREATE_RAND_XID 1
|
||||
#define DHCP_CREATE_RAND_XID 1
|
||||
#endif
|
||||
|
||||
/** Default for DHCP_GLOBAL_XID is 0xABCD0000
|
||||
@ -110,12 +113,12 @@
|
||||
|
||||
/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU
|
||||
* MTU is checked to be big enough in dhcp_start */
|
||||
#define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
|
||||
#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
|
||||
#define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
|
||||
#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
|
||||
/** Minimum length for reply before packet is parsed */
|
||||
#define DHCP_MIN_REPLY_LEN 44
|
||||
#define DHCP_MIN_REPLY_LEN 44
|
||||
|
||||
#define REBOOT_TRIES 2
|
||||
#define REBOOT_TRIES 2
|
||||
|
||||
#if LWIP_DNS && LWIP_DHCP_MAX_DNS_SERVERS
|
||||
#if DNS_MAX_SERVERS > LWIP_DHCP_MAX_DNS_SERVERS
|
||||
@ -132,7 +135,8 @@
|
||||
* This might be moved into the struct dhcp (not necessarily since
|
||||
* lwIP is single-threaded and the array is only used while in recv
|
||||
* callback). */
|
||||
enum dhcp_option_idx {
|
||||
enum dhcp_option_idx
|
||||
{
|
||||
DHCP_OPTION_IDX_OVERLOAD = 0,
|
||||
DHCP_OPTION_IDX_MSG_TYPE,
|
||||
DHCP_OPTION_IDX_SERVER_ID,
|
||||
@ -158,17 +162,18 @@ u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX];
|
||||
/** Holds a flag which option was received and is contained in dhcp_rx_options_val,
|
||||
only valid while in dhcp_recv.
|
||||
@todo: move this into struct dhcp? */
|
||||
u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
|
||||
u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX];
|
||||
|
||||
static u8_t dhcp_discover_request_options[] = {
|
||||
DHCP_OPTION_SUBNET_MASK,
|
||||
DHCP_OPTION_ROUTER,
|
||||
DHCP_OPTION_BROADCAST
|
||||
static u8_t dhcp_discover_request_options[] = { DHCP_OPTION_SUBNET_MASK,
|
||||
DHCP_OPTION_ROUTER,
|
||||
DHCP_OPTION_BROADCAST
|
||||
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
|
||||
, DHCP_OPTION_DNS_SERVER
|
||||
,
|
||||
DHCP_OPTION_DNS_SERVER
|
||||
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
|
||||
#if LWIP_DHCP_GET_NTP_SRV
|
||||
, DHCP_OPTION_NTP
|
||||
,
|
||||
DHCP_OPTION_NTP
|
||||
#endif /* LWIP_DHCP_GET_NTP_SRV */
|
||||
};
|
||||
|
||||
@ -177,49 +182,67 @@ static u32_t xid;
|
||||
static u8_t xid_initialised;
|
||||
#endif /* DHCP_GLOBAL_XID */
|
||||
|
||||
#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0)
|
||||
#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1)
|
||||
#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0)
|
||||
#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
|
||||
#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx])
|
||||
#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0)
|
||||
#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1)
|
||||
#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0)
|
||||
#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given)))
|
||||
#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx])
|
||||
#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val))
|
||||
|
||||
static struct udp_pcb *dhcp_pcb;
|
||||
static u8_t dhcp_pcb_refcount;
|
||||
|
||||
/* DHCP client state machine functions */
|
||||
static err_t dhcp_discover(struct netif *netif);
|
||||
static err_t dhcp_select(struct netif *netif);
|
||||
static void dhcp_bind(struct netif *netif);
|
||||
static err_t
|
||||
dhcp_discover(struct netif *netif);
|
||||
static err_t
|
||||
dhcp_select(struct netif *netif);
|
||||
static void
|
||||
dhcp_bind(struct netif *netif);
|
||||
#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 */
|
||||
static err_t dhcp_rebind(struct netif *netif);
|
||||
static err_t dhcp_reboot(struct netif *netif);
|
||||
static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
|
||||
static err_t
|
||||
dhcp_rebind(struct netif *netif);
|
||||
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 */
|
||||
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 */
|
||||
static void dhcp_timeout(struct netif *netif);
|
||||
static void dhcp_t1_timeout(struct netif *netif);
|
||||
static void dhcp_t2_timeout(struct netif *netif);
|
||||
static void
|
||||
dhcp_timeout(struct netif *netif);
|
||||
static void
|
||||
dhcp_t1_timeout(struct netif *netif);
|
||||
static void
|
||||
dhcp_t2_timeout(struct netif *netif);
|
||||
|
||||
/* build outgoing messages */
|
||||
/* 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) */
|
||||
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 */
|
||||
static u16_t dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value);
|
||||
static u16_t dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value);
|
||||
static u16_t dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value);
|
||||
static u16_t
|
||||
dhcp_option_byte(u16_t options_out_len, u8_t *options, u8_t value);
|
||||
static u16_t
|
||||
dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value);
|
||||
static u16_t
|
||||
dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value);
|
||||
#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 */
|
||||
/* 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 */
|
||||
static err_t
|
||||
@ -278,8 +301,9 @@ dhcp_handle_nak(struct netif *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",
|
||||
(void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num));
|
||||
LWIP_DEBUGF(
|
||||
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
|
||||
to ensure the callback can use dhcp_supplied_address() */
|
||||
dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF);
|
||||
@ -305,8 +329,8 @@ dhcp_check(struct netif *netif)
|
||||
struct dhcp *dhcp = netif_dhcp_data(netif);
|
||||
err_t result;
|
||||
u16_t msecs;
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0],
|
||||
(s16_t)netif->name[1]));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
|
||||
("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);
|
||||
/* create an ARP query for the offered IP address, expecting that no host
|
||||
responds, as the IP address should not be in use. */
|
||||
@ -319,7 +343,8 @@ dhcp_check(struct netif *netif)
|
||||
}
|
||||
msecs = 500;
|
||||
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 */
|
||||
|
||||
@ -333,19 +358,20 @@ dhcp_handle_offer(struct netif *netif, struct dhcp_msg *msg_in)
|
||||
{
|
||||
struct dhcp *dhcp = netif_dhcp_data(netif);
|
||||
|
||||
LWIP_DEBUGF(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));
|
||||
LWIP_DEBUGF(
|
||||
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 */
|
||||
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) {
|
||||
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)));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n",
|
||||
ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE,
|
||||
("dhcp_handle_offer(): server 0x%08" X32_F "\n", ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr))));
|
||||
/* remember offered address */
|
||||
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",
|
||||
ip4_addr_get_u32(&dhcp->offered_ip_addr)));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE,
|
||||
("dhcp_handle_offer(): offer for 0x%08" X32_F "\n", ip4_addr_get_u32(&dhcp->offered_ip_addr)));
|
||||
|
||||
dhcp_select(netif);
|
||||
} else {
|
||||
@ -376,24 +402,32 @@ dhcp_select(struct netif *netif)
|
||||
dhcp = netif_dhcp_data(netif);
|
||||
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);
|
||||
|
||||
/* create and initialize the DHCP message header */
|
||||
p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
|
||||
if (p_out != NULL) {
|
||||
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));
|
||||
|
||||
/* 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_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_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++) {
|
||||
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);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
|
||||
} 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;
|
||||
}
|
||||
if (dhcp->tries < 255) {
|
||||
@ -418,7 +453,7 @@ dhcp_select(struct netif *netif)
|
||||
}
|
||||
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);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %" U16_F " msecs\n", msecs));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -432,7 +467,8 @@ dhcp_coarse_tmr(void)
|
||||
struct netif *netif;
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n"));
|
||||
/* iterate through all network interfaces */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
/* only act on DHCP configured interfaces */
|
||||
struct dhcp *dhcp = netif_dhcp_data(netif);
|
||||
if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) {
|
||||
@ -469,7 +505,8 @@ dhcp_fine_tmr(void)
|
||||
{
|
||||
struct netif *netif;
|
||||
/* loop through netif's */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
struct dhcp *dhcp = netif_dhcp_data(netif);
|
||||
/* only act on DHCP configured interfaces */
|
||||
if (dhcp != NULL) {
|
||||
@ -511,7 +548,8 @@ dhcp_timeout(struct netif *netif)
|
||||
if (dhcp->tries <= 5) {
|
||||
dhcp_select(netif);
|
||||
} 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_start(netif);
|
||||
}
|
||||
@ -552,8 +590,7 @@ dhcp_t1_timeout(struct netif *netif)
|
||||
(dhcp->state == DHCP_STATE_RENEWING)) {
|
||||
/* just retry to renew - note that the rebind timer (t2) will
|
||||
* eventually time-out if renew tries fail. */
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
|
||||
("dhcp_t1_timeout(): must renew\n"));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t1_timeout(): must renew\n"));
|
||||
/* This slightly different to RFC2131: DHCPREQUEST will be sent from state
|
||||
DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */
|
||||
dhcp_renew(netif);
|
||||
@ -578,8 +615,7 @@ dhcp_t2_timeout(struct netif *netif)
|
||||
if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
|
||||
(dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) {
|
||||
/* just retry to rebind */
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
|
||||
("dhcp_t2_timeout(): must rebind\n"));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout(): must rebind\n"));
|
||||
/* This slightly different to RFC2131: DHCPREQUEST will be sent from state
|
||||
DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */
|
||||
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
|
||||
*/
|
||||
void dhcp_cleanup(struct netif *netif)
|
||||
void
|
||||
dhcp_cleanup(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
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 is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
|
||||
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 */
|
||||
if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) {
|
||||
@ -792,7 +831,6 @@ dhcp_start(struct netif *netif)
|
||||
}
|
||||
#endif /* LWIP_DHCP_CHECK_LINK_UP */
|
||||
|
||||
|
||||
/* (re)start the DHCP negotiation */
|
||||
result = dhcp_discover(netif);
|
||||
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);
|
||||
if (p_out != NULL) {
|
||||
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));
|
||||
|
||||
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);
|
||||
} 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 */
|
||||
@ -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"));
|
||||
/* is a DHCP client doing an ARP check? */
|
||||
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",
|
||||
ip4_addr_get_u32(addr)));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
|
||||
("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
|
||||
were offered by the DHCP server? */
|
||||
if (ip4_addr_cmp(addr, &dhcp->offered_ip_addr)) {
|
||||
@ -950,7 +990,8 @@ dhcp_decline(struct netif *netif)
|
||||
if (p_out != NULL) {
|
||||
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_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);
|
||||
dhcp_option_trailer(options_out_len, msg_out->options, p_out);
|
||||
@ -969,12 +1010,11 @@ dhcp_decline(struct netif *netif)
|
||||
}
|
||||
msecs = 10 * 1000;
|
||||
dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %" U16_F " msecs\n", msecs));
|
||||
return result;
|
||||
}
|
||||
#endif /* DHCP_DOES_ARP_CHECK */
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
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(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++) {
|
||||
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);
|
||||
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);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
|
||||
pbuf_free(p_out);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
|
||||
} 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) {
|
||||
dhcp->tries++;
|
||||
@ -1029,11 +1075,11 @@ dhcp_discover(struct netif *netif)
|
||||
#endif /* LWIP_DHCP_AUTOIP_COOP */
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;);
|
||||
dhcp = netif_dhcp_data(netif);
|
||||
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 */
|
||||
dhcp->lease_used = 0;
|
||||
|
||||
if (dhcp->offered_t0_lease != 0xffffffffUL) {
|
||||
/* 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;
|
||||
if (timeout > 0xffff) {
|
||||
timeout = 0xffff;
|
||||
@ -1064,13 +1113,15 @@ dhcp_bind(struct netif *netif)
|
||||
if (dhcp->t0_timeout == 0) {
|
||||
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? */
|
||||
if (dhcp->offered_t1_renew != 0xffffffffUL) {
|
||||
/* 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;
|
||||
if (timeout > 0xffff) {
|
||||
timeout = 0xffff;
|
||||
@ -1079,12 +1130,14 @@ dhcp_bind(struct netif *netif)
|
||||
if (dhcp->t1_timeout == 0) {
|
||||
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;
|
||||
}
|
||||
/* set renewal period timer */
|
||||
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;
|
||||
if (timeout > 0xffff) {
|
||||
timeout = 0xffff;
|
||||
@ -1093,7 +1146,8 @@ dhcp_bind(struct netif *netif)
|
||||
if (dhcp->t2_timeout == 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1133,8 +1187,11 @@ dhcp_bind(struct netif *netif)
|
||||
}
|
||||
#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",
|
||||
ip4_addr_get_u32(&dhcp->offered_ip_addr), ip4_addr_get_u32(&sn_mask), ip4_addr_get_u32(&gw_addr)));
|
||||
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",
|
||||
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
|
||||
to ensure the callback can use dhcp_supplied_address() */
|
||||
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);
|
||||
if (p_out != NULL) {
|
||||
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(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++) {
|
||||
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"));
|
||||
} 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;
|
||||
}
|
||||
if (dhcp->tries < 255) {
|
||||
@ -1196,7 +1258,8 @@ dhcp_renew(struct netif *netif)
|
||||
/* back-off on retries, but to a maximum of 20 seconds */
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1222,10 +1285,14 @@ dhcp_rebind(struct netif *netif)
|
||||
p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
|
||||
if (p_out != NULL) {
|
||||
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(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++) {
|
||||
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);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
|
||||
} 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;
|
||||
}
|
||||
if (dhcp->tries < 255) {
|
||||
@ -1250,7 +1318,8 @@ dhcp_rebind(struct netif *netif)
|
||||
}
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1276,13 +1345,18 @@ dhcp_reboot(struct netif *netif)
|
||||
p_out = dhcp_create_msg(netif, dhcp, DHCP_REQUEST, &options_out_len);
|
||||
if (p_out != NULL) {
|
||||
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(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++) {
|
||||
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);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
|
||||
} 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;
|
||||
}
|
||||
if (dhcp->tries < 255) {
|
||||
@ -1307,7 +1382,8 @@ dhcp_reboot(struct netif *netif)
|
||||
}
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1356,7 +1432,8 @@ dhcp_release_and_stop(struct netif *netif)
|
||||
if (p_out != NULL) {
|
||||
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_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);
|
||||
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);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n"));
|
||||
} else {
|
||||
/* 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"));
|
||||
/* 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"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1434,7 +1513,8 @@ dhcp_set_state(struct dhcp *dhcp, u8_t new_state)
|
||||
static u16_t
|
||||
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_len;
|
||||
return options_out_len;
|
||||
@ -1456,7 +1536,7 @@ dhcp_option_short(u16_t options_out_len, u8_t *options, u16_t value)
|
||||
{
|
||||
LWIP_ASSERT("dhcp_option_short: options_out_len + 2 <= DHCP_OPTIONS_LEN", options_out_len + 2U <= DHCP_OPTIONS_LEN);
|
||||
options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
|
||||
options[options_out_len++] = (u8_t) (value & 0x00ffU);
|
||||
options[options_out_len++] = (u8_t)(value & 0x00ffU);
|
||||
return options_out_len;
|
||||
}
|
||||
|
||||
@ -1638,10 +1718,18 @@ again:
|
||||
break;
|
||||
default:
|
||||
decode_len = 0;
|
||||
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,
|
||||
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);
|
||||
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,
|
||||
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;
|
||||
}
|
||||
if (op == DHCP_OPTION_PAD) {
|
||||
@ -1655,7 +1743,7 @@ again:
|
||||
if (decode_len > 0) {
|
||||
u32_t value = 0;
|
||||
u16_t copy_len;
|
||||
decode_next:
|
||||
decode_next:
|
||||
LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX);
|
||||
if (!dhcp_option_given(dhcp, decode_idx)) {
|
||||
copy_len = LWIP_MIN(decode_len, 4);
|
||||
@ -1738,15 +1826,15 @@ decode_next:
|
||||
if (!file_overloaded) {
|
||||
/* only do this for ACK messages */
|
||||
if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) &&
|
||||
(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
|
||||
/* copy bootp file name, don't care for sname (server hostname) */
|
||||
if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS) != (DHCP_FILE_LEN-1)) {
|
||||
return ERR_BUF;
|
||||
}
|
||||
(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK))
|
||||
/* copy bootp file name, don't care for sname (server hostname) */
|
||||
if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN - 1, DHCP_FILE_OFS) != (DHCP_FILE_LEN - 1)) {
|
||||
return ERR_BUF;
|
||||
}
|
||||
/* make sure the string is really NULL-terminated */
|
||||
dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0;
|
||||
dhcp->boot_file_name[DHCP_FILE_LEN - 1] = 0;
|
||||
}
|
||||
#endif /* LWIP_DHCP_BOOTP_FILE */
|
||||
#endif /* LWIP_DHCP_BOOTP_FILE */
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@ -1772,10 +1860,16 @@ 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_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,
|
||||
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->tot_len = %"U16_F"\n", p->tot_len));
|
||||
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,
|
||||
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->tot_len = %" U16_F "\n", p->tot_len));
|
||||
/* prevent warnings about unused arguments */
|
||||
LWIP_UNUSED_ARG(pcb);
|
||||
LWIP_UNUSED_ARG(addr);
|
||||
@ -1787,22 +1881,28 @@ dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/* iterate through hardware address and match against DHCP message */
|
||||
for (i = 0; i < netif->hwaddr_len && i < LWIP_MIN(DHCP_CHADDR_LEN, NETIF_MAX_HWADDR_LEN); i++) {
|
||||
if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
|
||||
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",
|
||||
(u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i]));
|
||||
("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]));
|
||||
goto free_pbuf_and_return;
|
||||
}
|
||||
}
|
||||
/* match transaction ID against what we expected */
|
||||
if (lwip_ntohl(reply_msg->xid) != dhcp->xid) {
|
||||
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;
|
||||
}
|
||||
/* option fields could be unfold? */
|
||||
@ -1849,9 +1949,8 @@ dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
|
||||
}
|
||||
}
|
||||
/* received a DHCP_NAK in appropriate state? */
|
||||
else if ((msg_type == DHCP_NAK) &&
|
||||
((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) ||
|
||||
(dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING ))) {
|
||||
else if ((msg_type == DHCP_NAK) && ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) ||
|
||||
(dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING))) {
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n"));
|
||||
dhcp_handle_nak(netif);
|
||||
}
|
||||
@ -1888,7 +1987,7 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t
|
||||
* at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */
|
||||
#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
|
||||
static u32_t xid;
|
||||
#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
|
||||
#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
|
||||
static u32_t xid = 0xABCD0000;
|
||||
#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
|
||||
#else
|
||||
@ -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;);
|
||||
p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM);
|
||||
if (p_out == NULL) {
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("dhcp_create_msg(): could not allocate pbuf\n"));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_create_msg(): could not allocate pbuf\n"));
|
||||
return NULL;
|
||||
}
|
||||
LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg",
|
||||
@ -1914,14 +2012,13 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t
|
||||
if (dhcp->tries == 0) {
|
||||
#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
|
||||
xid = LWIP_RAND();
|
||||
#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
|
||||
#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
|
||||
xid++;
|
||||
#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */
|
||||
}
|
||||
dhcp->xid = xid;
|
||||
}
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE,
|
||||
("transaction id xid(%"X32_F")\n", xid));
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("transaction id xid(%" X32_F ")\n", xid));
|
||||
|
||||
msg_out = (struct dhcp_msg *)p_out->payload;
|
||||
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;
|
||||
/* packet is too small, or not 4 byte aligned? */
|
||||
while (((options_out_len < DHCP_MIN_OPTIONS_LEN) || (options_out_len & 3)) &&
|
||||
(options_out_len < DHCP_OPTIONS_LEN)) {
|
||||
while (((options_out_len < DHCP_MIN_OPTIONS_LEN) || (options_out_len & 3)) && (options_out_len < DHCP_OPTIONS_LEN)) {
|
||||
/* add a fill/padding byte */
|
||||
options[options_out_len++] = 0;
|
||||
}
|
||||
|
@ -47,12 +47,12 @@
|
||||
|
||||
#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/dhcp.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "lwip/prot/iana.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
#include <string.h>
|
||||
@ -63,7 +63,7 @@
|
||||
|
||||
/** Re-request a used ARP entry 1 minute before it would expire to prevent
|
||||
* breaking a steadily used connection because the ARP entry timed out. */
|
||||
#define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30)
|
||||
#define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30)
|
||||
#define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15)
|
||||
|
||||
/** the time an ARP entry stays pending after first request,
|
||||
@ -76,22 +76,25 @@
|
||||
#define ARP_MAXPENDING 5
|
||||
|
||||
/** ARP states */
|
||||
enum etharp_state {
|
||||
enum etharp_state
|
||||
{
|
||||
ETHARP_STATE_EMPTY = 0,
|
||||
ETHARP_STATE_PENDING,
|
||||
ETHARP_STATE_STABLE,
|
||||
ETHARP_STATE_STABLE_REREQUESTING_1,
|
||||
ETHARP_STATE_STABLE_REREQUESTING_2
|
||||
#if ETHARP_SUPPORT_STATIC_ENTRIES
|
||||
, ETHARP_STATE_STATIC
|
||||
,
|
||||
ETHARP_STATE_STATIC
|
||||
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
|
||||
};
|
||||
|
||||
struct etharp_entry {
|
||||
struct etharp_entry
|
||||
{
|
||||
#if ARP_QUEUEING
|
||||
/** Pointer to queue of pending outgoing packets on this ARP entry. */
|
||||
struct etharp_q_entry *q;
|
||||
#else /* ARP_QUEUEING */
|
||||
#else /* ARP_QUEUEING */
|
||||
/** Pointer to a single pending outgoing packet on this ARP entry. */
|
||||
struct pbuf *q;
|
||||
#endif /* ARP_QUEUEING */
|
||||
@ -110,32 +113,39 @@ static netif_addr_idx_t etharp_cached_entry;
|
||||
|
||||
/** Try hard to create a new entry - we want the IP address to appear in
|
||||
the cache (even if this means removing an active entry or so). */
|
||||
#define ETHARP_FLAG_TRY_HARD 1
|
||||
#define ETHARP_FLAG_FIND_ONLY 2
|
||||
#define ETHARP_FLAG_TRY_HARD 1
|
||||
#define ETHARP_FLAG_FIND_ONLY 2
|
||||
#if ETHARP_SUPPORT_STATIC_ENTRIES
|
||||
#define ETHARP_FLAG_STATIC_ENTRY 4
|
||||
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
|
||||
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
#define ETHARP_SET_ADDRHINT(netif, addrhint) do { if (((netif) != NULL) && ((netif)->hints != NULL)) { \
|
||||
(netif)->hints->addr_hint = (addrhint); }} while(0)
|
||||
#define ETHARP_SET_ADDRHINT(netif, addrhint) \
|
||||
do { \
|
||||
if (((netif) != NULL) && ((netif)->hints != NULL)) { \
|
||||
(netif)->hints->addr_hint = (addrhint); \
|
||||
} \
|
||||
} while (0)
|
||||
#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 */
|
||||
|
||||
|
||||
/* Check for maximum ARP_TABLE_SIZE */
|
||||
#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"
|
||||
#endif
|
||||
|
||||
|
||||
static err_t etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr);
|
||||
static err_t etharp_raw(struct netif *netif,
|
||||
const struct eth_addr *ethsrc_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);
|
||||
static err_t
|
||||
etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr *hw_dst_addr);
|
||||
static err_t
|
||||
etharp_raw(struct netif *netif,
|
||||
const struct eth_addr *ethsrc_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);
|
||||
|
||||
#if ARP_QUEUEING
|
||||
/**
|
||||
@ -172,7 +182,9 @@ etharp_free_entry(int i)
|
||||
/* and empty packet queue */
|
||||
if (arp_table[i].q != NULL) {
|
||||
/* 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);
|
||||
arp_table[i].q = NULL;
|
||||
}
|
||||
@ -206,14 +218,15 @@ etharp_tmr(void)
|
||||
#if ETHARP_SUPPORT_STATIC_ENTRIES
|
||||
&& (state != ETHARP_STATE_STATIC)
|
||||
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
|
||||
) {
|
||||
) {
|
||||
arp_table[i].ctime++;
|
||||
if ((arp_table[i].ctime >= ARP_MAXAGE) ||
|
||||
((arp_table[i].state == ETHARP_STATE_PENDING) &&
|
||||
(arp_table[i].ctime >= ARP_MAXPENDING))) {
|
||||
((arp_table[i].state == ETHARP_STATE_PENDING) && (arp_table[i].ctime >= ARP_MAXPENDING))) {
|
||||
/* pending or stable entry has become old! */
|
||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %d.\n",
|
||||
arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG,
|
||||
("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 */
|
||||
etharp_free_entry(i);
|
||||
} else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
|
||||
@ -295,7 +308,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
#if ETHARP_TABLE_MATCH_NETIF
|
||||
&& ((netif == NULL) || (netif == arp_table[i].netif))
|
||||
#endif /* ETHARP_TABLE_MATCH_NETIF */
|
||||
) {
|
||||
) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %d\n", (int)i));
|
||||
/* found exact IP address match, simply bail out */
|
||||
return i;
|
||||
@ -309,7 +322,7 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif)
|
||||
age_queue = arp_table[i].ctime;
|
||||
}
|
||||
} else
|
||||
/* pending without queued packets? */
|
||||
/* pending without queued packets? */
|
||||
{
|
||||
if (arp_table[i].ctime >= age_pending) {
|
||||
old_pending = i;
|
||||
@ -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) ||
|
||||
/* or no empty entry found and not allowed to recycle? */
|
||||
((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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
/* recycle oldest 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? */
|
||||
} else if (old_queue < ARP_TABLE_SIZE) {
|
||||
/* recycle oldest pending (queued packets are free in etharp_free_entry) */
|
||||
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 */
|
||||
} else {
|
||||
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("arp_table[i].state == ETHARP_STATE_EMPTY",
|
||||
arp_table[i].state == ETHARP_STATE_EMPTY);
|
||||
LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY);
|
||||
|
||||
/* IP address given? */
|
||||
if (ipaddr != NULL) {
|
||||
@ -423,15 +440,23 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et
|
||||
{
|
||||
s16_t i;
|
||||
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",
|
||||
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]));
|
||||
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",
|
||||
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? */
|
||||
if (ip4_addr_isany(ipaddr) ||
|
||||
ip4_addr_isbroadcast(ipaddr, netif) ||
|
||||
ip4_addr_ismulticast(ipaddr)) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
|
||||
if (ip4_addr_isany(ipaddr) || ip4_addr_isbroadcast(ipaddr, netif) || ip4_addr_ismulticast(ipaddr)) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
|
||||
("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
|
||||
return ERR_ARG;
|
||||
}
|
||||
/* find or create ARP entry */
|
||||
@ -460,7 +485,7 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et
|
||||
/* insert in SNMP ARP index tree */
|
||||
mib2_add_arp_entry(netif, &arp_table[i].ipaddr);
|
||||
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", i));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %" S16_F "\n", i));
|
||||
/* update address */
|
||||
SMEMCPY(&arp_table[i].ethaddr, ethaddr, ETH_HWADDR_LEN);
|
||||
/* reset time stamp */
|
||||
@ -477,7 +502,7 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et
|
||||
p = q->p;
|
||||
/* now queue entry can be freed */
|
||||
memp_free(MEMP_ARP_QUEUE, q);
|
||||
#else /* ARP_QUEUEING */
|
||||
#else /* ARP_QUEUEING */
|
||||
if (arp_table[i].q != NULL) {
|
||||
struct pbuf *p = arp_table[i].q;
|
||||
arp_table[i].q = NULL;
|
||||
@ -504,10 +529,19 @@ etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr)
|
||||
{
|
||||
struct netif *netif;
|
||||
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",
|
||||
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]));
|
||||
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",
|
||||
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);
|
||||
if (netif == NULL) {
|
||||
@ -530,8 +564,12 @@ etharp_remove_static_entry(const ip4_addr_t *ipaddr)
|
||||
{
|
||||
s16_t i;
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("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)));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
|
||||
("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 */
|
||||
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
|
||||
*/
|
||||
ssize_t
|
||||
etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr,
|
||||
struct eth_addr **eth_ret, const ip4_addr_t **ip_ret)
|
||||
etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr **eth_ret, const ip4_addr_t **ip_ret)
|
||||
{
|
||||
s16_t i;
|
||||
|
||||
LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",
|
||||
eth_ret != NULL && ip_ret != NULL);
|
||||
LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", eth_ret != NULL && ip_ret != NULL);
|
||||
|
||||
LWIP_UNUSED_ARG(netif);
|
||||
|
||||
@ -616,8 +652,8 @@ etharp_get_entry(size_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth
|
||||
LWIP_ASSERT("eth_ret != NULL", eth_ret != NULL);
|
||||
|
||||
if ((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
|
||||
*ipaddr = &arp_table[i].ipaddr;
|
||||
*netif = arp_table[i].netif;
|
||||
*ipaddr = &arp_table[i].ipaddr;
|
||||
*netif = arp_table[i].netif;
|
||||
*eth_ret = &arp_table[i].ethaddr;
|
||||
return 1;
|
||||
} else {
|
||||
@ -652,13 +688,15 @@ etharp_input(struct pbuf *p, struct netif *netif)
|
||||
hdr = (struct etharp_hdr *)p->payload;
|
||||
|
||||
/* RFC 826 "Packet Reception": */
|
||||
if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) ||
|
||||
(hdr->hwlen != ETH_HWADDR_LEN) ||
|
||||
(hdr->protolen != sizeof(ip4_addr_t)) ||
|
||||
(hdr->proto != PP_HTONS(ETHTYPE_IP))) {
|
||||
if ((hdr->hwtype != PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET)) || (hdr->hwlen != ETH_HWADDR_LEN) ||
|
||||
(hdr->protolen != sizeof(ip4_addr_t)) || (hdr->proto != PP_HTONS(ETHTYPE_IP))) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
|
||||
("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
|
||||
hdr->hwtype, (u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen));
|
||||
("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%" U16_F
|
||||
"/%" 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.drop);
|
||||
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.
|
||||
ARP message not directed to us?
|
||||
-> update the source IP address in the cache, if present */
|
||||
etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr),
|
||||
for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
|
||||
etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY);
|
||||
|
||||
/* now act on the message itself */
|
||||
switch (hdr->opcode) {
|
||||
@ -702,14 +739,17 @@ etharp_input(struct pbuf *p, struct netif *netif)
|
||||
* reply. In any case, we time-stamp any existing ARP entry,
|
||||
* and possibly send out an IP packet that was queued on it. */
|
||||
|
||||
LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n"));
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n"));
|
||||
/* ARP request for our address? */
|
||||
if (for_us) {
|
||||
/* send ARP response */
|
||||
etharp_raw(netif,
|
||||
(struct eth_addr *)netif->hwaddr, &hdr->shwaddr,
|
||||
(struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif),
|
||||
&hdr->shwaddr, &sipaddr,
|
||||
(struct eth_addr *)netif->hwaddr,
|
||||
&hdr->shwaddr,
|
||||
(struct eth_addr *)netif->hwaddr,
|
||||
netif_ip4_addr(netif),
|
||||
&hdr->shwaddr,
|
||||
&sipaddr,
|
||||
ARP_REPLY);
|
||||
/* we are not configured? */
|
||||
} 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) */
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
@ -747,8 +788,7 @@ etharp_input(struct pbuf *p, struct netif *netif)
|
||||
static err_t
|
||||
etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, netif_addr_idx_t arp_idx)
|
||||
{
|
||||
LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
|
||||
arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
|
||||
LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", arp_table[arp_idx].state >= ETHARP_STATE_STABLE);
|
||||
/* if arp table entry is about to expire: re-request it,
|
||||
but only if its state is ETHARP_STATE_STABLE to prevent flooding the
|
||||
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;
|
||||
/* outside local network? if so, this can neither be a global broadcast nor
|
||||
a subnet broadcast. */
|
||||
if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) &&
|
||||
!ip4_addr_islinklocal(ipaddr)) {
|
||||
if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) && !ip4_addr_islinklocal(ipaddr)) {
|
||||
#if LWIP_AUTOIP
|
||||
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
|
||||
@ -939,9 +978,7 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
|
||||
netif_addr_idx_t i;
|
||||
|
||||
/* non-unicast address? */
|
||||
if (ip4_addr_isbroadcast(ipaddr, netif) ||
|
||||
ip4_addr_ismulticast(ipaddr) ||
|
||||
ip4_addr_isany(ipaddr)) {
|
||||
if (ip4_addr_isbroadcast(ipaddr, netif) || ip4_addr_ismulticast(ipaddr) || ip4_addr_isany(ipaddr)) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
|
||||
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 } */
|
||||
LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
|
||||
((arp_table[i].state == ETHARP_STATE_PENDING) ||
|
||||
(arp_table[i].state >= ETHARP_STATE_STABLE)));
|
||||
((arp_table[i].state == ETHARP_STATE_PENDING) || (arp_table[i].state >= ETHARP_STATE_STABLE)));
|
||||
|
||||
/* do we have a new entry? or an implicit query request? */
|
||||
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);
|
||||
}
|
||||
#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;
|
||||
} else {
|
||||
/* the pool MEMP_ARP_QUEUE is empty */
|
||||
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;
|
||||
}
|
||||
#else /* ARP_QUEUEING */
|
||||
#else /* ARP_QUEUEING */
|
||||
/* always queue one packet per ARP request only, freeing a previously queued packet */
|
||||
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);
|
||||
}
|
||||
arp_table[i].q = p;
|
||||
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 */
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -1098,10 +1140,13 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
|
||||
* any other err_t on failure
|
||||
*/
|
||||
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 *hwsrc_addr, const ip4_addr_t *ipsrc_addr,
|
||||
const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_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)
|
||||
{
|
||||
struct pbuf *p;
|
||||
@ -1119,8 +1164,7 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
|
||||
ETHARP_STATS_INC(etharp.memerr);
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
|
||||
(p->len >= SIZEOF_ETHARP_HDR));
|
||||
LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", (p->len >= SIZEOF_ETHARP_HDR));
|
||||
|
||||
hdr = (struct etharp_hdr *)p->payload;
|
||||
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
|
||||
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,
|
||||
(struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), ðzero,
|
||||
ipaddr, ARP_REQUEST);
|
||||
return etharp_raw(netif,
|
||||
(struct eth_addr *)netif->hwaddr,
|
||||
hw_dst_addr,
|
||||
(struct eth_addr *)netif->hwaddr,
|
||||
netif_ip4_addr(netif),
|
||||
ðzero,
|
||||
ipaddr,
|
||||
ARP_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,10 +43,10 @@
|
||||
|
||||
#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/inet_chksum.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include <string.h>
|
||||
@ -65,7 +65,8 @@
|
||||
/* The amount of data from the original packet to return in a dest-unreachable */
|
||||
#define ICMP_DEST_UNREACH_DATASIZE 8
|
||||
|
||||
static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
|
||||
static void
|
||||
icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
|
||||
|
||||
/**
|
||||
* Processes ICMP input packets, called from ip_input().
|
||||
@ -94,11 +95,11 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
iphdr_in = ip4_current_header();
|
||||
hlen = IPH_HL_BYTES(iphdr_in);
|
||||
if (hlen < IP_HLEN) {
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%"S16_F" bytes) received\n", hlen));
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%" S16_F " bytes) received\n", hlen));
|
||||
goto lenerr;
|
||||
}
|
||||
if (p->len < sizeof(u16_t) * 2) {
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%" U16_F " bytes) received\n", p->tot_len));
|
||||
goto lenerr;
|
||||
}
|
||||
|
||||
@ -122,7 +123,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
#if LWIP_MULTICAST_PING
|
||||
/* For multicast, use address of receiving interface as source address */
|
||||
src = netif_ip4_addr(inp);
|
||||
#else /* LWIP_MULTICAST_PING */
|
||||
#else /* LWIP_MULTICAST_PING */
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n"));
|
||||
goto icmperr;
|
||||
#endif /* LWIP_MULTICAST_PING */
|
||||
@ -132,7 +133,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
#if LWIP_BROADCAST_PING
|
||||
/* For broadcast, use address of receiving interface as source address */
|
||||
src = netif_ip4_addr(inp);
|
||||
#else /* LWIP_BROADCAST_PING */
|
||||
#else /* LWIP_BROADCAST_PING */
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n"));
|
||||
goto icmperr;
|
||||
#endif /* LWIP_BROADCAST_PING */
|
||||
@ -143,7 +144,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
goto lenerr;
|
||||
}
|
||||
#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) {
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
|
||||
pbuf_free(p);
|
||||
@ -214,7 +216,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
ip4_addr_copy(iphdr->dest, *ip4_current_src_addr());
|
||||
ICMPH_TYPE_SET(iecho, ICMP_ER);
|
||||
#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 */
|
||||
if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
|
||||
iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS((u16_t)(ICMP_ECHO << 8)) + 1);
|
||||
@ -223,11 +226,9 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
}
|
||||
}
|
||||
#if LWIP_CHECKSUM_CTRL_PER_NETIF
|
||||
else {
|
||||
iecho->chksum = 0;
|
||||
}
|
||||
else { iecho->chksum = 0; }
|
||||
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
|
||||
#else /* CHECKSUM_GEN_ICMP */
|
||||
#else /* CHECKSUM_GEN_ICMP */
|
||||
iecho->chksum = 0;
|
||||
#endif /* CHECKSUM_GEN_ICMP */
|
||||
|
||||
@ -235,9 +236,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
IPH_TTL_SET(iphdr, ICMP_TTL);
|
||||
IPH_CHKSUM_SET(iphdr, 0);
|
||||
#if CHECKSUM_GEN_IP
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) {
|
||||
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen));
|
||||
}
|
||||
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen)); }
|
||||
#endif /* CHECKSUM_GEN_IP */
|
||||
|
||||
ICMP_STATS_INC(icmp.xmit);
|
||||
@ -247,8 +246,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
MIB2_STATS_INC(mib2.icmpoutechoreps);
|
||||
|
||||
/* send an ICMP packet */
|
||||
ret = ip4_output_if(p, src, LWIP_IP_HDRINCL,
|
||||
ICMP_TTL, 0, IP_PROTO_ICMP, inp);
|
||||
ret = ip4_output_if(p, src, LWIP_IP_HDRINCL, ICMP_TTL, 0, IP_PROTO_ICMP, inp);
|
||||
if (ret != ERR_OK) {
|
||||
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) {
|
||||
MIB2_STATS_INC(mib2.icmpinaddrmaskreps);
|
||||
}
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n",
|
||||
(s16_t)type, (s16_t)code));
|
||||
LWIP_DEBUGF(ICMP_DEBUG,
|
||||
("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.drop);
|
||||
}
|
||||
@ -350,8 +348,7 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
|
||||
MIB2_STATS_INC(mib2.icmpoutmsgs);
|
||||
|
||||
/* ICMP header + IP header + 8 bytes of data */
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
|
||||
PBUF_RAM);
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, PBUF_RAM);
|
||||
if (q == NULL) {
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
|
||||
MIB2_STATS_INC(mib2.icmpouterrors);
|
||||
@ -374,8 +371,7 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
|
||||
icmphdr->seqno = 0;
|
||||
|
||||
/* copy fields from original packet */
|
||||
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
|
||||
IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
|
||||
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
|
||||
|
||||
ip4_addr_copy(iphdr_src, iphdr->src);
|
||||
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
|
||||
@ -391,9 +387,7 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
|
||||
/* calculate checksum */
|
||||
icmphdr->chksum = 0;
|
||||
#if CHECKSUM_GEN_ICMP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) {
|
||||
icmphdr->chksum = inet_chksum(icmphdr, q->len);
|
||||
}
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) { icmphdr->chksum = inet_chksum(icmphdr, q->len); }
|
||||
#endif
|
||||
ICMP_STATS_INC(icmp.xmit);
|
||||
ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif);
|
||||
|
@ -39,7 +39,7 @@
|
||||
* The Swedish Institute of Computer Science and Adam Dunkels
|
||||
* are specifically granted permission to redistribute this
|
||||
* source code.
|
||||
*/
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------
|
||||
Note 1)
|
||||
@ -70,10 +70,9 @@ Steve Reynolds
|
||||
* RFC 988 - Host extensions for IP multicasting - V0
|
||||
* RFC 1054 - Host extensions for IP multicasting -
|
||||
* 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 3376 - Internet Group Management Protocol, Version 3 - V3
|
||||
* RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+
|
||||
* RFC 2113 - IP Router Alert Option -
|
||||
* RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's
|
||||
*the "de facto" standard) RFC 3376 - Internet Group Management Protocol, Version 3 - V3 RFC 4604 - Using
|
||||
*Internet Group Management Protocol Version 3... - V3+ RFC 2113 - IP Router Alert Option -
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
@ -84,28 +83,35 @@ Steve Reynolds
|
||||
|
||||
#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/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/prot/igmp.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static struct igmp_group *igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr);
|
||||
static err_t igmp_remove_group(struct netif *netif, struct igmp_group *group);
|
||||
static void igmp_timeout(struct netif *netif, struct igmp_group *group);
|
||||
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 struct igmp_group *
|
||||
igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr);
|
||||
static err_t
|
||||
igmp_remove_group(struct netif *netif, struct igmp_group *group);
|
||||
static void
|
||||
igmp_timeout(struct netif *netif, struct igmp_group *group);
|
||||
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 allrouters;
|
||||
static ip4_addr_t allsystems;
|
||||
static ip4_addr_t allrouters;
|
||||
|
||||
/**
|
||||
* Initialize the IGMP module
|
||||
@ -257,16 +263,15 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
|
||||
group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
|
||||
if (group != NULL) {
|
||||
ip4_addr_set(&(group->group_address), addr);
|
||||
group->timer = 0; /* Not running */
|
||||
group->group_state = IGMP_GROUP_NON_MEMBER;
|
||||
group->timer = 0; /* Not running */
|
||||
group->group_state = IGMP_GROUP_NON_MEMBER;
|
||||
group->last_reporter_flag = 0;
|
||||
group->use = 0;
|
||||
group->use = 0;
|
||||
|
||||
/* Ensure allsystems group is always first in list */
|
||||
if (list_head == NULL) {
|
||||
/* this is the first entry in linked list */
|
||||
LWIP_ASSERT("igmp_lookup_group: first group must be allsystems",
|
||||
(ip4_addr_cmp(addr, &allsystems) != 0));
|
||||
LWIP_ASSERT("igmp_lookup_group: first group must be allsystems", (ip4_addr_cmp(addr, &allsystems) != 0));
|
||||
group->next = NULL;
|
||||
netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group);
|
||||
} 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);
|
||||
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)ifp));
|
||||
|
||||
@ -322,7 +328,7 @@ igmp_remove_group(struct netif *netif, struct igmp_group *group)
|
||||
void
|
||||
igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
|
||||
{
|
||||
struct igmp_msg *igmp;
|
||||
struct igmp_msg *igmp;
|
||||
struct igmp_group *group;
|
||||
struct igmp_group *groupref;
|
||||
|
||||
@ -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 ? */
|
||||
if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) {
|
||||
/* 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) {
|
||||
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;
|
||||
} else {
|
||||
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);
|
||||
if (ip4_addr_cmp(dest, &allsystems)) {
|
||||
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 */
|
||||
ip4_addr_copy(groupaddr, igmp->igmp_group_address);
|
||||
group = igmp_lookfor_group(inp, &groupaddr);
|
||||
} 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) {
|
||||
@ -427,8 +439,12 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("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));
|
||||
LWIP_DEBUGF(IGMP_DEBUG,
|
||||
("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);
|
||||
break;
|
||||
}
|
||||
@ -455,10 +471,12 @@ igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
|
||||
|
||||
/* 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 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 */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
/* Should we join this interface ? */
|
||||
if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
|
||||
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();
|
||||
|
||||
/* 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("igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
|
||||
LWIP_ERROR(
|
||||
"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 */
|
||||
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 */
|
||||
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();
|
||||
|
||||
/* 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("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
|
||||
LWIP_ERROR(
|
||||
"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 */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
/* Should we leave this interface ? */
|
||||
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);
|
||||
@ -585,11 +610,15 @@ igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
|
||||
/* 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("igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
|
||||
LWIP_ERROR(
|
||||
"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 */
|
||||
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 */
|
||||
group = igmp_lookfor_group(netif, groupaddr);
|
||||
@ -642,7 +671,8 @@ igmp_tmr(void)
|
||||
{
|
||||
struct netif *netif;
|
||||
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
struct igmp_group *group = netif_igmp_data(netif);
|
||||
|
||||
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
|
||||
(unless it is the allsystems group) */
|
||||
if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
|
||||
(!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
|
||||
if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && (!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address "));
|
||||
ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address);
|
||||
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)netif));
|
||||
@ -693,7 +722,7 @@ igmp_start_timer(struct igmp_group *group, u8_t max_time)
|
||||
{
|
||||
#ifdef LWIP_RAND
|
||||
group->timer = (u16_t)(max_time > 2 ? (LWIP_RAND() % max_time) : 1);
|
||||
#else /* LWIP_RAND */
|
||||
#else /* LWIP_RAND */
|
||||
/* ATTENTION: use this only if absolutely necessary! */
|
||||
group->timer = max_time / 2;
|
||||
#endif /* LWIP_RAND */
|
||||
@ -713,14 +742,12 @@ static void
|
||||
igmp_delaying_member(struct igmp_group *group, u8_t maxresp)
|
||||
{
|
||||
if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) ||
|
||||
((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
|
||||
((group->timer == 0) || (maxresp < group->timer)))) {
|
||||
((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && ((group->timer == 0) || (maxresp < group->timer)))) {
|
||||
igmp_start_timer(group, maxresp);
|
||||
group->group_state = IGMP_GROUP_DELAYING_MEMBER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@ -757,18 +784,17 @@ igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
|
||||
static void
|
||||
igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
|
||||
{
|
||||
struct pbuf *p = NULL;
|
||||
struct pbuf *p = NULL;
|
||||
struct igmp_msg *igmp = NULL;
|
||||
ip4_addr_t src = *IP4_ADDR_ANY4;
|
||||
ip4_addr_t *dest = NULL;
|
||||
ip4_addr_t src = *IP4_ADDR_ANY4;
|
||||
ip4_addr_t *dest = NULL;
|
||||
|
||||
/* IP header + "router alert" option + IGMP header */
|
||||
p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM);
|
||||
|
||||
if (p) {
|
||||
igmp = (struct igmp_msg *)p->payload;
|
||||
LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg",
|
||||
(p->len >= sizeof(struct igmp_msg)));
|
||||
LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", (p->len >= sizeof(struct igmp_msg)));
|
||||
ip4_addr_copy(src, *netif_ip4_addr(netif));
|
||||
|
||||
if (type == IGMP_V2_MEMB_REPORT) {
|
||||
@ -783,8 +809,8 @@ igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
|
||||
}
|
||||
|
||||
if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) {
|
||||
igmp->igmp_msgtype = type;
|
||||
igmp->igmp_maxresp = 0;
|
||||
igmp->igmp_msgtype = type;
|
||||
igmp->igmp_maxresp = 0;
|
||||
igmp->igmp_checksum = 0;
|
||||
igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN);
|
||||
|
||||
|
@ -42,20 +42,20 @@
|
||||
|
||||
#if LWIP_IPV4
|
||||
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/autoip.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/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/udp.h"
|
||||
#include "lwip/priv/tcp_priv.h"
|
||||
#include "lwip/autoip.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/prot/iana.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/udp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -67,16 +67,16 @@
|
||||
* generate the IP checksum (in contrast to calculating it on-the-fly). */
|
||||
#ifndef LWIP_INLINE_IP_CHKSUM
|
||||
#if LWIP_CHECKSUM_CTRL_PER_NETIF
|
||||
#define LWIP_INLINE_IP_CHKSUM 0
|
||||
#define LWIP_INLINE_IP_CHKSUM 0
|
||||
#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
|
||||
#define LWIP_INLINE_IP_CHKSUM 1
|
||||
#define LWIP_INLINE_IP_CHKSUM 1
|
||||
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
|
||||
#endif
|
||||
|
||||
#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
|
||||
#define CHECKSUM_GEN_IP_INLINE 1
|
||||
#define CHECKSUM_GEN_IP_INLINE 1
|
||||
#else
|
||||
#define CHECKSUM_GEN_IP_INLINE 0
|
||||
#define CHECKSUM_GEN_IP_INLINE 0
|
||||
#endif
|
||||
|
||||
#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT)
|
||||
@ -89,8 +89,8 @@
|
||||
*/
|
||||
#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT)
|
||||
/* accept DHCP client port and custom port */
|
||||
#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(LWIP_IANA_PORT_DHCP_CLIENT)) \
|
||||
|| (LWIP_IP_ACCEPT_UDP_PORT(port)))
|
||||
#define IP_ACCEPT_LINK_LAYER_ADDRESSED_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) */
|
||||
/* accept custom port only */
|
||||
#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 */
|
||||
|
||||
/* iterate through netifs */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
/* 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))) {
|
||||
/* network mask matches? */
|
||||
@ -188,7 +189,8 @@ ip4_route(const ip4_addr_t *dest)
|
||||
return netif_default;
|
||||
}
|
||||
/* default netif is not up, just use any netif for loopback traffic */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
if (netif_is_up(netif)) {
|
||||
return netif;
|
||||
}
|
||||
@ -214,8 +216,12 @@ ip4_route(const ip4_addr_t *dest)
|
||||
ip4_addr_isany_val(*netif_ip4_addr(netif_default))) {
|
||||
/* No matching netif found and default netif is not usable.
|
||||
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",
|
||||
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("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);
|
||||
MIB2_STATS_INC(mib2.ipoutnoroutes);
|
||||
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 */
|
||||
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",
|
||||
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())));
|
||||
LWIP_DEBUGF(IP_DEBUG,
|
||||
("ip4_forward: not forwarding LLA %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n",
|
||||
ip4_addr1_16(ip4_current_dest_addr()),
|
||||
ip4_addr2_16(ip4_current_dest_addr()),
|
||||
ip4_addr3_16(ip4_current_dest_addr()),
|
||||
ip4_addr4_16(ip4_current_dest_addr())));
|
||||
goto return_noroute;
|
||||
}
|
||||
|
||||
/* Find network interface where to forward this IP packet to. */
|
||||
netif = ip4_route_src(ip4_current_src_addr(), ip4_current_dest_addr());
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
|
||||
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
|
||||
ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
|
||||
LWIP_DEBUGF(IP_DEBUG,
|
||||
("ip4_forward: no forwarding route for %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F " found\n",
|
||||
ip4_addr1_16(ip4_current_dest_addr()),
|
||||
ip4_addr2_16(ip4_current_dest_addr()),
|
||||
ip4_addr3_16(ip4_current_dest_addr()),
|
||||
ip4_addr4_16(ip4_current_dest_addr())));
|
||||
/* @todo: send ICMP_DUR_NET? */
|
||||
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)));
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
|
||||
ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
|
||||
ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
|
||||
LWIP_DEBUGF(IP_DEBUG,
|
||||
("ip4_forward: forwarding packet to %" U16_F ".%" U16_F ".%" U16_F ".%" U16_F "\n",
|
||||
ip4_addr1_16(ip4_current_dest_addr()),
|
||||
ip4_addr2_16(ip4_current_dest_addr()),
|
||||
ip4_addr3_16(ip4_current_dest_addr()),
|
||||
ip4_addr4_16(ip4_current_dest_addr())));
|
||||
|
||||
IP_STATS_INC(ip.fw);
|
||||
MIB2_STATS_INC(mib2.ipforwdatagrams);
|
||||
@ -347,7 +362,7 @@ ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||
if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
|
||||
#if IP_FRAG
|
||||
ip4_frag(p, netif, ip4_current_dest_addr());
|
||||
#else /* IP_FRAG */
|
||||
#else /* IP_FRAG */
|
||||
/* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */
|
||||
#endif /* IP_FRAG */
|
||||
} else {
|
||||
@ -370,11 +385,14 @@ return_noroute:
|
||||
static int
|
||||
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",
|
||||
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(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))));
|
||||
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",
|
||||
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(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
|
||||
ip4_addr_get_u32(ip4_current_dest_addr()) & ~ip4_addr_get_u32(netif_ip4_netmask(netif))));
|
||||
|
||||
/* interface is up and configured? */
|
||||
if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) {
|
||||
@ -385,9 +403,8 @@ ip4_input_accept(struct netif *netif)
|
||||
#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
|
||||
|| (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK))
|
||||
#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
|
||||
) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n",
|
||||
netif->name[0], netif->name[1]));
|
||||
) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n", netif->name[0], netif->name[1]));
|
||||
/* accept on this netif */
|
||||
return 1;
|
||||
}
|
||||
@ -395,8 +412,7 @@ ip4_input_accept(struct netif *netif)
|
||||
/* connections to link-local addresses must persist after changing
|
||||
the netif's address (RFC3927 ch. 1.9) */
|
||||
if (autoip_accept_packet(netif, ip4_current_dest_addr())) {
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n",
|
||||
netif->name[0], netif->name[1]));
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n", netif->name[0], netif->name[1]));
|
||||
/* accept on this netif */
|
||||
return 1;
|
||||
}
|
||||
@ -441,7 +457,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
/* identify the IP header */
|
||||
iphdr = (struct ip_hdr *)p->payload;
|
||||
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);
|
||||
pbuf_free(p);
|
||||
IP_STATS_INC(ip.err);
|
||||
@ -471,17 +488,18 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) {
|
||||
if (iphdr_hlen < IP_HLEN) {
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("ip4_input: short IP header (%"U16_F" bytes) received, IP packet dropped\n", iphdr_hlen));
|
||||
("ip4_input: short IP header (%" U16_F " bytes) received, IP packet dropped\n", iphdr_hlen));
|
||||
}
|
||||
if (iphdr_hlen > p->len) {
|
||||
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",
|
||||
iphdr_hlen, p->len));
|
||||
("IP header (len %" U16_F ") does not fit in first pbuf (len %" U16_F "), IP packet dropped.\n",
|
||||
iphdr_hlen,
|
||||
p->len));
|
||||
}
|
||||
if (iphdr_len > p->tot_len) {
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
|
||||
iphdr_len, p->tot_len));
|
||||
LWIP_DEBUGF(
|
||||
IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("IP (len %" U16_F ") is longer than pbuf (len %" U16_F "), IP packet dropped.\n", iphdr_len, p->tot_len));
|
||||
}
|
||||
/* free (drop) packet pbufs */
|
||||
pbuf_free(p);
|
||||
@ -493,11 +511,12 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
/* verify checksum */
|
||||
#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) {
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
|
||||
("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
|
||||
("Checksum (0x%" X16_F ") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
|
||||
ip4_debug_print(p);
|
||||
pbuf_free(p);
|
||||
IP_STATS_INC(ip.chkerr);
|
||||
@ -519,15 +538,14 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
/* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */
|
||||
ip4_addr_t allsystems;
|
||||
IP4_ADDR(&allsystems, 224, 0, 0, 1);
|
||||
if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) &&
|
||||
ip4_addr_isany(ip4_current_src_addr())) {
|
||||
if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) && ip4_addr_isany(ip4_current_src_addr())) {
|
||||
check_ip_src = 0;
|
||||
}
|
||||
netif = inp;
|
||||
} else {
|
||||
netif = NULL;
|
||||
}
|
||||
#else /* LWIP_IGMP */
|
||||
#else /* LWIP_IGMP */
|
||||
if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) {
|
||||
netif = inp;
|
||||
} else {
|
||||
@ -549,7 +567,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
|
||||
{
|
||||
#if !LWIP_SINGLE_NETIF
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
if (netif == inp) {
|
||||
/* we checked that before already */
|
||||
continue;
|
||||
@ -577,8 +596,8 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
/* remote port is DHCP server? */
|
||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
|
||||
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_ntohs(udphdr->dest)));
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE,
|
||||
("ip4_input: UDP packet to DHCP client port %" U16_F "\n", lwip_ntohs(udphdr->dest)));
|
||||
if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n"));
|
||||
netif = inp;
|
||||
@ -595,11 +614,10 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
/* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
|
||||
&& !ip4_addr_isany_val(*ip4_current_src_addr())
|
||||
#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
|
||||
)
|
||||
)
|
||||
#endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */
|
||||
{
|
||||
if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) ||
|
||||
(ip4_addr_ismulticast(ip4_current_src_addr()))) {
|
||||
if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) || (ip4_addr_ismulticast(ip4_current_src_addr()))) {
|
||||
/* packet source is not valid */
|
||||
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n"));
|
||||
/* free (drop) packet pbufs */
|
||||
@ -633,8 +651,14 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
/* packet consists of multiple fragments? */
|
||||
if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
|
||||
#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_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)));
|
||||
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_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*/
|
||||
p = ip4_reass(p);
|
||||
/* packet not fully reassembled yet? */
|
||||
@ -642,10 +666,11 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
return ERR_OK;
|
||||
}
|
||||
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);
|
||||
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_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))));
|
||||
IP_STATS_INC(ip.opterr);
|
||||
IP_STATS_INC(ip.drop);
|
||||
/* unsupported protocol feature */
|
||||
@ -658,11 +683,12 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
#if LWIP_IGMP
|
||||
/* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
|
||||
if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
|
||||
if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
|
||||
#else
|
||||
if (iphdr_hlen > IP_HLEN) {
|
||||
#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);
|
||||
IP_STATS_INC(ip.opterr);
|
||||
IP_STATS_INC(ip.drop);
|
||||
@ -675,7 +701,7 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
/* send to upper layers */
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n"));
|
||||
ip4_debug_print(p);
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %" U16_F " p->tot_len %" U16_F "\n", p->len, p->tot_len));
|
||||
|
||||
ip_data.current_netif = netif;
|
||||
ip_data.current_input_netif = inp;
|
||||
@ -726,14 +752,14 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
{
|
||||
#if LWIP_ICMP
|
||||
/* send ICMP destination protocol unreachable unless is was a broadcast */
|
||||
if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
|
||||
!ip4_addr_ismulticast(ip4_current_dest_addr())) {
|
||||
if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) && !ip4_addr_ismulticast(ip4_current_dest_addr())) {
|
||||
pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */
|
||||
icmp_dest_unreach(p, ICMP_DUR_PROTO);
|
||||
}
|
||||
#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.drop);
|
||||
@ -781,9 +807,13 @@ ip4_input(struct pbuf *p, struct netif *inp)
|
||||
* unique identifiers independent of destination"
|
||||
*/
|
||||
err_t
|
||||
ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
|
||||
u8_t ttl, u8_t tos,
|
||||
u8_t proto, struct netif *netif)
|
||||
ip4_output_if(struct pbuf *p,
|
||||
const ip4_addr_t *src,
|
||||
const ip4_addr_t *dest,
|
||||
u8_t ttl,
|
||||
u8_t tos,
|
||||
u8_t proto,
|
||||
struct netif *netif)
|
||||
{
|
||||
#if IP_OPTIONS_SEND
|
||||
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
|
||||
*/
|
||||
err_t
|
||||
ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
|
||||
u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
|
||||
ip4_output_if_opt(struct pbuf *p,
|
||||
const ip4_addr_t *src,
|
||||
const ip4_addr_t *dest,
|
||||
u8_t ttl,
|
||||
u8_t tos,
|
||||
u8_t proto,
|
||||
struct netif *netif,
|
||||
void *ip_options,
|
||||
u16_t optlen)
|
||||
{
|
||||
#endif /* IP_OPTIONS_SEND */
|
||||
@ -809,9 +845,8 @@ ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
|
||||
}
|
||||
|
||||
#if IP_OPTIONS_SEND
|
||||
return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif,
|
||||
ip_options, optlen);
|
||||
#else /* IP_OPTIONS_SEND */
|
||||
return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif, ip_options, optlen);
|
||||
#else /* IP_OPTIONS_SEND */
|
||||
return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif);
|
||||
#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'.
|
||||
*/
|
||||
err_t
|
||||
ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
|
||||
u8_t ttl, u8_t tos,
|
||||
u8_t proto, struct netif *netif)
|
||||
ip4_output_if_src(struct pbuf *p,
|
||||
const ip4_addr_t *src,
|
||||
const ip4_addr_t *dest,
|
||||
u8_t ttl,
|
||||
u8_t tos,
|
||||
u8_t proto,
|
||||
struct netif *netif)
|
||||
{
|
||||
#if IP_OPTIONS_SEND
|
||||
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'.
|
||||
*/
|
||||
err_t
|
||||
ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
|
||||
u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
|
||||
ip4_output_if_opt_src(struct pbuf *p,
|
||||
const ip4_addr_t *src,
|
||||
const ip4_addr_t *dest,
|
||||
u8_t ttl,
|
||||
u8_t tos,
|
||||
u8_t proto,
|
||||
struct netif *netif,
|
||||
void *ip_options,
|
||||
u16_t optlen)
|
||||
{
|
||||
#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;
|
||||
LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
|
||||
(p->len >= sizeof(struct ip_hdr)));
|
||||
LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", (p->len >= sizeof(struct ip_hdr)));
|
||||
|
||||
IPH_TTL_SET(iphdr, ttl);
|
||||
IPH_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;
|
||||
chk_sum = ~chk_sum;
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
|
||||
iphdr->_chksum = (u16_t)chk_sum; /* network order */
|
||||
}
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { iphdr->_chksum = (u16_t)chk_sum; /* network order */ }
|
||||
#if LWIP_CHECKSUM_CTRL_PER_NETIF
|
||||
else {
|
||||
IPH_CHKSUM_SET(iphdr, 0);
|
||||
}
|
||||
else { IPH_CHKSUM_SET(iphdr, 0); }
|
||||
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
|
||||
#else /* CHECKSUM_GEN_IP_INLINE */
|
||||
#else /* CHECKSUM_GEN_IP_INLINE */
|
||||
IPH_CHKSUM_SET(iphdr, 0);
|
||||
#if CHECKSUM_GEN_IP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
|
||||
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
|
||||
}
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); }
|
||||
#endif /* CHECKSUM_GEN_IP */
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
} else {
|
||||
@ -974,7 +1012,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
|
||||
|
||||
IP_STATS_INC(ip.xmit);
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
|
||||
LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%" U16_F "\n", netif->name[0], netif->name[1], (u16_t)netif->num));
|
||||
ip4_debug_print(p);
|
||||
|
||||
#if ENABLE_LOOPBACK
|
||||
@ -982,7 +1020,7 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
|
||||
#if !LWIP_HAVE_LOOPIF
|
||||
|| ip4_addr_isloopback(dest)
|
||||
#endif /* !LWIP_HAVE_LOOPIF */
|
||||
) {
|
||||
) {
|
||||
/* Packet to self, enqueue it for loopback */
|
||||
LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
|
||||
return netif_loop_output(netif, p);
|
||||
@ -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
|
||||
*/
|
||||
err_t
|
||||
ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
|
||||
u8_t ttl, u8_t tos, u8_t proto)
|
||||
ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto)
|
||||
{
|
||||
struct netif *netif;
|
||||
|
||||
LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);
|
||||
|
||||
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",
|
||||
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
|
||||
LWIP_DEBUGF(IP_DEBUG,
|
||||
("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);
|
||||
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
|
||||
*/
|
||||
err_t
|
||||
ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
|
||||
u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint)
|
||||
ip4_output_hinted(struct pbuf *p,
|
||||
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;
|
||||
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);
|
||||
|
||||
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",
|
||||
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
|
||||
LWIP_DEBUGF(IP_DEBUG,
|
||||
("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);
|
||||
return ERR_RTE;
|
||||
}
|
||||
@ -1093,35 +1143,40 @@ ip4_debug_print(struct pbuf *p)
|
||||
|
||||
LWIP_DEBUGF(IP_DEBUG, ("IP header:\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",
|
||||
(u16_t)IPH_V(iphdr),
|
||||
(u16_t)IPH_HL(iphdr),
|
||||
(u16_t)IPH_TOS(iphdr),
|
||||
lwip_ntohs(IPH_LEN(iphdr))));
|
||||
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_HL(iphdr),
|
||||
(u16_t)IPH_TOS(iphdr),
|
||||
lwip_ntohs(IPH_LEN(iphdr))));
|
||||
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_ntohs(IPH_ID(iphdr)),
|
||||
(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)) >> 13 & 1),
|
||||
(u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
|
||||
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)),
|
||||
(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)) >> 13 & 1),
|
||||
(u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
|
||||
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\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_PROTO(iphdr),
|
||||
lwip_ntohs(IPH_CHKSUM(iphdr))));
|
||||
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_PROTO(iphdr),
|
||||
lwip_ntohs(IPH_CHKSUM(iphdr))));
|
||||
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\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_addr2_16_val(iphdr->src),
|
||||
ip4_addr3_16_val(iphdr->src),
|
||||
ip4_addr4_16_val(iphdr->src)));
|
||||
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_addr2_16_val(iphdr->src),
|
||||
ip4_addr3_16_val(iphdr->src),
|
||||
ip4_addr4_16_val(iphdr->src)));
|
||||
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\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_addr2_16_val(iphdr->dest),
|
||||
ip4_addr3_16_val(iphdr->dest),
|
||||
ip4_addr4_16_val(iphdr->dest)));
|
||||
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_addr2_16_val(iphdr->dest),
|
||||
ip4_addr3_16_val(iphdr->dest),
|
||||
ip4_addr4_16_val(iphdr->dest)));
|
||||
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
|
||||
}
|
||||
#endif /* IP_DEBUG */
|
||||
|
@ -61,8 +61,7 @@ ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif)
|
||||
ip4_addr_set_u32(&ipaddr, addr);
|
||||
|
||||
/* all ones (broadcast) or all zeroes (old skool broadcast) */
|
||||
if ((~addr == IPADDR_ANY) ||
|
||||
(addr == IPADDR_ANY)) {
|
||||
if ((~addr == IPADDR_ANY) || (addr == IPADDR_ANY)) {
|
||||
return 1;
|
||||
/* no broadcast support on this network interface? */
|
||||
} else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
|
||||
@ -96,7 +95,7 @@ ip4_addr_netmask_valid(u32_t netmask)
|
||||
u32_t nm_hostorder = lwip_htonl(netmask);
|
||||
|
||||
/* first, check for the first zero */
|
||||
for (mask = 1UL << 31 ; mask != 0; mask >>= 1) {
|
||||
for (mask = 1UL << 31; mask != 0; mask >>= 1) {
|
||||
if ((nm_hostorder & mask) == 0) {
|
||||
break;
|
||||
}
|
||||
@ -211,12 +210,12 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
|
||||
switch (pp - parts + 1) {
|
||||
|
||||
case 0:
|
||||
return 0; /* initial nondigit */
|
||||
return 0; /* initial nondigit */
|
||||
|
||||
case 1: /* a -- 32 bits */
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffffUL) {
|
||||
return 0;
|
||||
}
|
||||
@ -226,7 +225,7 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffff) {
|
||||
return 0;
|
||||
}
|
||||
@ -236,7 +235,7 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xff) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -42,12 +42,12 @@
|
||||
|
||||
#if LWIP_IPV4
|
||||
|
||||
#include "lwip/ip4_frag.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/icmp.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/ip4_frag.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/icmp.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -79,9 +79,9 @@
|
||||
|
||||
#define IP_REASS_FLAG_LASTFRAG 0x01
|
||||
|
||||
#define IP_REASS_VALIDATE_TELEGRAM_FINISHED 1
|
||||
#define IP_REASS_VALIDATE_PBUF_QUEUED 0
|
||||
#define IP_REASS_VALIDATE_PBUF_DROPPED -1
|
||||
#define IP_REASS_VALIDATE_TELEGRAM_FINISHED 1
|
||||
#define IP_REASS_VALIDATE_PBUF_QUEUED 0
|
||||
#define IP_REASS_VALIDATE_PBUF_DROPPED -1
|
||||
|
||||
/** This is a helper struct which holds the starting
|
||||
* offset and the ending offset of this fragment to
|
||||
@ -92,31 +92,35 @@
|
||||
* this struct doesn't need packing, too.)
|
||||
*/
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct ip_reass_helper {
|
||||
struct ip_reass_helper
|
||||
{
|
||||
PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
|
||||
PACK_STRUCT_FIELD(u16_t start);
|
||||
PACK_STRUCT_FIELD(u16_t end);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \
|
||||
(ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \
|
||||
ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \
|
||||
IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0
|
||||
#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \
|
||||
(ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \
|
||||
IPH_ID(iphdrA) == IPH_ID(iphdrB)) \
|
||||
? 1 \
|
||||
: 0
|
||||
|
||||
/* global variables */
|
||||
static struct ip_reassdata *reassdatagrams;
|
||||
static u16_t ip_reass_pbufcount;
|
||||
|
||||
/* function prototypes */
|
||||
static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
|
||||
static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
|
||||
static void
|
||||
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
|
||||
@ -135,7 +139,7 @@ ip_reass_tmr(void)
|
||||
* clean up the incomplete fragment assembly */
|
||||
if (r->timer > 0) {
|
||||
r->timer--;
|
||||
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n", (u16_t)r->timer));
|
||||
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %" U16_F "\n", (u16_t)r->timer));
|
||||
prev = r;
|
||||
r = r->next;
|
||||
} else {
|
||||
@ -278,7 +282,7 @@ static struct ip_reassdata *
|
||||
ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen)
|
||||
{
|
||||
struct ip_reassdata *ipr;
|
||||
#if ! IP_REASS_FREE_OLDEST
|
||||
#if !IP_REASS_FREE_OLDEST
|
||||
LWIP_UNUSED_ARG(clen);
|
||||
#endif
|
||||
|
||||
@ -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,
|
||||
* and setup the embedded helper structure. */
|
||||
/* make sure the struct ip_reass_helper fits into the IP header */
|
||||
LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN",
|
||||
sizeof(struct ip_reass_helper) <= IP_HLEN);
|
||||
LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", sizeof(struct ip_reass_helper) <= IP_HLEN);
|
||||
iprh = (struct ip_reass_helper *)new_p->payload;
|
||||
iprh->next_pbuf = NULL;
|
||||
iprh->start = offset;
|
||||
@ -443,8 +446,7 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
|
||||
}
|
||||
} else {
|
||||
#if IP_REASS_CHECK_OVERLAP
|
||||
LWIP_ASSERT("no previous fragment, this must be the first fragment!",
|
||||
ipr->p == NULL);
|
||||
LWIP_ASSERT("no previous fragment, this must be the first fragment!", ipr->p == NULL);
|
||||
#endif /* IP_REASS_CHECK_OVERLAP */
|
||||
/* this is the first fragment we ever received for this ip datagram */
|
||||
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 */
|
||||
if (valid) {
|
||||
LWIP_ASSERT("sanity check", ipr->p != NULL);
|
||||
LWIP_ASSERT("sanity check",
|
||||
((struct ip_reass_helper *)ipr->p->payload) != iprh);
|
||||
LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
|
||||
iprh->next_pbuf == NULL);
|
||||
LWIP_ASSERT("sanity check", ((struct ip_reass_helper *)ipr->p->payload) != iprh);
|
||||
LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", iprh->next_pbuf == NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -535,13 +535,13 @@ ip4_reass(struct pbuf *p)
|
||||
clen = pbuf_clen(p);
|
||||
if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
|
||||
#if IP_REASS_FREE_OLDEST
|
||||
if (!ip_reass_remove_oldest_datagram(fraghdr, clen) ||
|
||||
((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
|
||||
if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
|
||||
#endif /* IP_REASS_FREE_OLDEST */
|
||||
{
|
||||
/* 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",
|
||||
ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
|
||||
LWIP_DEBUGF(
|
||||
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);
|
||||
/* @todo: send ICMP time exceeded here? */
|
||||
/* drop this pbuf */
|
||||
@ -556,8 +556,8 @@ ip4_reass(struct pbuf *p)
|
||||
in the reassembly buffer. If so, we proceed with copying the
|
||||
fragment into the buffer. */
|
||||
if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
|
||||
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n",
|
||||
lwip_ntohs(IPH_ID(fraghdr))));
|
||||
LWIP_DEBUGF(IP_REASS_DEBUG,
|
||||
("ip4_reass: matching previous fragment ID=%" X16_F "\n", lwip_ntohs(IPH_ID(fraghdr))));
|
||||
IPFRAG_STATS_INC(ip_frag.cachehit);
|
||||
break;
|
||||
}
|
||||
@ -609,9 +609,7 @@ ip4_reass(struct pbuf *p)
|
||||
u16_t datagram_len = (u16_t)(offset + len);
|
||||
ipr->datagram_len = datagram_len;
|
||||
ipr->flags |= IP_REASS_FLAG_LASTFRAG;
|
||||
LWIP_DEBUGF(IP_REASS_DEBUG,
|
||||
("ip4_reass: last fragment seen, total len %"S16_F"\n",
|
||||
ipr->datagram_len));
|
||||
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: last fragment seen, total len %" S16_F "\n", ipr->datagram_len));
|
||||
}
|
||||
|
||||
if (valid == IP_REASS_VALIDATE_TELEGRAM_FINISHED) {
|
||||
@ -631,7 +629,8 @@ ip4_reass(struct pbuf *p)
|
||||
IPH_CHKSUM_SET(fraghdr, 0);
|
||||
/* @todo: do we need to set/calculate the correct checksum? */
|
||||
#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));
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_IP */
|
||||
@ -780,8 +779,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
|
||||
if (rambuf == NULL) {
|
||||
goto memerr;
|
||||
}
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!",
|
||||
(rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
|
||||
poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff);
|
||||
/* make room for the IP header */
|
||||
if (pbuf_add_header(rambuf, IP_HLEN)) {
|
||||
@ -791,7 +789,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
|
||||
/* fill in the IP header */
|
||||
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
|
||||
iphdr = (struct ip_hdr *)rambuf->payload;
|
||||
#else /* LWIP_NETIF_TX_SINGLE_PBUF */
|
||||
#else /* LWIP_NETIF_TX_SINGLE_PBUF */
|
||||
/* When not using a static buffer, create a chain of pbufs.
|
||||
* The first will be a PBUF_RAM holding the link and IP header.
|
||||
* The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
|
||||
@ -801,8 +799,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
|
||||
if (rambuf == NULL) {
|
||||
goto memerr;
|
||||
}
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!",
|
||||
(rambuf->len >= (IP_HLEN)));
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len >= (IP_HLEN)));
|
||||
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
|
||||
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;
|
||||
}
|
||||
/* Mirror this pbuf, although we might not need all of it. */
|
||||
newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc,
|
||||
(u8_t *)p->payload + poff, newpbuflen);
|
||||
newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, (u8_t *)p->payload + poff, newpbuflen);
|
||||
if (newpbuf == NULL) {
|
||||
ip_frag_free_pbuf_custom_ref(pcr);
|
||||
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_CHKSUM_SET(iphdr, 0);
|
||||
#if CHECKSUM_GEN_IP
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
|
||||
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
|
||||
}
|
||||
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); }
|
||||
#endif /* CHECKSUM_GEN_IP */
|
||||
|
||||
/* No need for separate header pbuf - we allowed room for it in rambuf
|
||||
|
@ -59,11 +59,11 @@
|
||||
|
||||
#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/udp.h"
|
||||
#include "lwip/dhcp6.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "lwip/prot/dhcp6.h"
|
||||
#include "lwip/udp.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)
|
||||
#endif
|
||||
#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
|
||||
|
||||
#if LWIP_DNS && LWIP_DHCP6_MAX_DNS_SERVERS
|
||||
@ -87,13 +90,13 @@
|
||||
#define LWIP_DHCP6_PROVIDE_DNS_SERVERS 0
|
||||
#endif
|
||||
|
||||
|
||||
/** Option handling: options are parsed in dhcp6_parse_reply
|
||||
* and saved in an array where other functions can load them from.
|
||||
* This might be moved into the struct dhcp6 (not necessarily since
|
||||
* lwIP is single-threaded and the array is only used while in recv
|
||||
* callback). */
|
||||
enum dhcp6_option_idx {
|
||||
enum dhcp6_option_idx
|
||||
{
|
||||
DHCP6_OPTION_IDX_CLI_ID = 0,
|
||||
DHCP6_OPTION_IDX_SERVER_ID,
|
||||
#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
|
||||
@ -106,7 +109,8 @@ enum dhcp6_option_idx {
|
||||
DHCP6_OPTION_IDX_MAX
|
||||
};
|
||||
|
||||
struct dhcp6_option_info {
|
||||
struct dhcp6_option_info
|
||||
{
|
||||
u8_t option_given;
|
||||
u16_t val_start;
|
||||
u16_t val_length;
|
||||
@ -115,14 +119,17 @@ struct dhcp6_option_info {
|
||||
/** Holds the decoded option info, only valid while in dhcp6_recv. */
|
||||
struct dhcp6_option_info dhcp6_rx_options[DHCP6_OPTION_IDX_MAX];
|
||||
|
||||
#define dhcp6_option_given(dhcp6, idx) (dhcp6_rx_options[idx].option_given != 0)
|
||||
#define dhcp6_got_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 1)
|
||||
#define dhcp6_clear_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 0)
|
||||
#define dhcp6_clear_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_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_option_given(dhcp6, idx) (dhcp6_rx_options[idx].option_given != 0)
|
||||
#define dhcp6_got_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 1)
|
||||
#define dhcp6_clear_option(dhcp6, idx) (dhcp6_rx_options[idx].option_given = 0)
|
||||
#define dhcp6_clear_all_options(dhcp6) (memset(dhcp6_rx_options, 0, sizeof(dhcp6_rx_options)))
|
||||
#define dhcp6_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_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_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 u8_t dhcp6_pcb_refcount;
|
||||
|
||||
|
||||
/* 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 */
|
||||
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
|
||||
*/
|
||||
void dhcp6_cleanup(struct netif *netif)
|
||||
void
|
||||
dhcp6_cleanup(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", netif != NULL);
|
||||
|
||||
@ -213,7 +221,7 @@ void dhcp6_cleanup(struct netif *netif)
|
||||
}
|
||||
}
|
||||
|
||||
static struct dhcp6*
|
||||
static struct dhcp6 *
|
||||
dhcp6_get_struct(struct netif *netif, const char *dbg_requester)
|
||||
{
|
||||
struct dhcp6 *dhcp6 = netif_dhcp6_data(netif);
|
||||
@ -253,8 +261,8 @@ dhcp6_get_struct(struct netif *netif, const char *dbg_requester)
|
||||
static void
|
||||
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",
|
||||
dhcp6->state, new_state, dbg_caller));
|
||||
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
|
||||
("DHCPv6 state: %d -> %d (%s)\n", dhcp6->state, new_state, dbg_caller));
|
||||
if (new_state != dhcp6->state) {
|
||||
dhcp6->state = new_state;
|
||||
dhcp6->tries = 0;
|
||||
@ -265,8 +273,7 @@ dhcp6_set_state(struct dhcp6 *dhcp6, u8_t new_state, const char *dbg_caller)
|
||||
static int
|
||||
dhcp6_stateless_enabled(struct dhcp6 *dhcp6)
|
||||
{
|
||||
if ((dhcp6->state == DHCP6_STATE_STATELESS_IDLE) ||
|
||||
(dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG)) {
|
||||
if ((dhcp6->state == DHCP6_STATE_STATELESS_IDLE) || (dhcp6->state == DHCP6_STATE_REQUESTING_CONFIG)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -317,7 +324,12 @@ dhcp6_enable_stateless(struct netif *netif)
|
||||
{
|
||||
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()");
|
||||
if (dhcp6 == NULL) {
|
||||
@ -347,13 +359,16 @@ dhcp6_disable(struct netif *netif)
|
||||
{
|
||||
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);
|
||||
if (dhcp6 != NULL) {
|
||||
if (dhcp6->state != DHCP6_STATE_OFF) {
|
||||
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("dhcp6_disable(): DHCPv6 disabled (old state: %s)\n",
|
||||
(dhcp6_stateless_enabled(dhcp6) ? "stateless" : "stateful")));
|
||||
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE,
|
||||
("dhcp6_disable(): DHCPv6 disabled (old state: %s)\n",
|
||||
(dhcp6_stateless_enabled(dhcp6) ? "stateless" : "stateful")));
|
||||
dhcp6_set_state(dhcp6, DHCP6_STATE_OFF, "dhcp6_disable");
|
||||
if (dhcp6->pcb_allocated != 0) {
|
||||
dhcp6_dec_pcb_refcount(); /* free DHCPv6 PCB if not needed any more */
|
||||
@ -374,8 +389,11 @@ dhcp6_disable(struct netif *netif)
|
||||
* @return a pbuf for the message
|
||||
*/
|
||||
static struct pbuf *
|
||||
dhcp6_create_msg(struct netif *netif, struct dhcp6 *dhcp6, u8_t message_type,
|
||||
u16_t opt_len_alloc, u16_t *options_out_len)
|
||||
dhcp6_create_msg(struct netif *netif,
|
||||
struct dhcp6 *dhcp6,
|
||||
u8_t message_type,
|
||||
u16_t opt_len_alloc,
|
||||
u16_t *options_out_len)
|
||||
{
|
||||
struct pbuf *p_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;
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE,
|
||||
("transaction id xid(%"X32_F")\n", dhcp6->xid));
|
||||
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("transaction id xid(%" X32_F ")\n", dhcp6->xid));
|
||||
|
||||
msg_out = (struct dhcp6_msg *)p_out->payload;
|
||||
memset(msg_out, 0, sizeof(struct dhcp6_msg) + opt_len_alloc);
|
||||
@ -415,19 +432,22 @@ static u16_t
|
||||
dhcp6_option_short(u16_t options_out_len, u8_t *options, u16_t value)
|
||||
{
|
||||
options[options_out_len++] = (u8_t)((value & 0xff00U) >> 8);
|
||||
options[options_out_len++] = (u8_t) (value & 0x00ffU);
|
||||
options[options_out_len++] = (u8_t)(value & 0x00ffU);
|
||||
return options_out_len;
|
||||
}
|
||||
|
||||
static u16_t
|
||||
dhcp6_option_optionrequest(u16_t options_out_len, u8_t *options, const u16_t *req_options,
|
||||
u16_t num_req_options, u16_t max_len)
|
||||
dhcp6_option_optionrequest(u16_t options_out_len,
|
||||
u8_t *options,
|
||||
const u16_t *req_options,
|
||||
u16_t num_req_options,
|
||||
u16_t max_len)
|
||||
{
|
||||
size_t i;
|
||||
u16_t ret;
|
||||
|
||||
LWIP_ASSERT("dhcp6_option_optionrequest: options_out_len + sizeof(struct dhcp6_msg) + addlen <= max_len",
|
||||
sizeof(struct dhcp6_msg) + options_out_len + 4U + (2U * num_req_options) <= max_len);
|
||||
sizeof(struct dhcp6_msg) + options_out_len + 4U + (2U * num_req_options) <= max_len);
|
||||
LWIP_UNUSED_ARG(max_len);
|
||||
|
||||
ret = dhcp6_option_short(options_out_len, options, DHCP6_OPTION_ORO);
|
||||
@ -446,12 +466,11 @@ 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));
|
||||
}
|
||||
|
||||
|
||||
#if LWIP_IPV6_DHCP6_STATELESS
|
||||
static void
|
||||
dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)
|
||||
{
|
||||
const u16_t requested_options[] = {DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_SNTP_SERVERS};
|
||||
const u16_t requested_options[] = { DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_SNTP_SERVERS };
|
||||
u16_t msecs;
|
||||
struct pbuf *p_out;
|
||||
u16_t options_out_len;
|
||||
@ -464,18 +483,20 @@ dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)
|
||||
u8_t *options = (u8_t *)(msg_out + 1);
|
||||
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,
|
||||
LWIP_ARRAYSIZE(requested_options), p_out->len);
|
||||
LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, DHCP6_STATE_REQUESTING_CONFIG, msg_out,
|
||||
DHCP6_INFOREQUEST, options_out_len, p_out->len);
|
||||
options_out_len = dhcp6_option_optionrequest(
|
||||
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, DHCP6_INFOREQUEST, options_out_len, p_out->len);
|
||||
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);
|
||||
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);
|
||||
} 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");
|
||||
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);
|
||||
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
|
||||
@ -676,9 +698,9 @@ dhcp6_parse_reply(struct pbuf *p, struct dhcp6 *dhcp6)
|
||||
break;
|
||||
#endif /* LWIP_DHCP6_GET_NTP_SRV*/
|
||||
default:
|
||||
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,
|
||||
msg_in->msgtype, op, len, q, val_offset);
|
||||
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, msg_in->msgtype, op, len, q, val_offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -703,10 +725,10 @@ dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr
|
||||
|
||||
LWIP_ERROR("invalid server address type", IP_IS_V6(addr), goto free_pbuf_and_return;);
|
||||
|
||||
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE, ("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->tot_len = %"U16_F"\n", p->tot_len));
|
||||
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE,
|
||||
("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->tot_len = %" U16_F "\n", p->tot_len));
|
||||
/* prevent warnings about unused arguments */
|
||||
LWIP_UNUSED_ARG(pcb);
|
||||
LWIP_UNUSED_ARG(addr);
|
||||
@ -723,7 +745,7 @@ dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr
|
||||
xid |= reply_msg->transaction_id[2];
|
||||
if (xid != dhcp6->xid) {
|
||||
LWIP_DEBUGF(DHCP6_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
|
||||
("transaction id mismatch reply_msg->xid(%"X32_F")!= dhcp6->xid(%"X32_F")\n", xid, dhcp6->xid));
|
||||
("transaction id mismatch reply_msg->xid(%" X32_F ")!= dhcp6->xid(%" X32_F ")\n", xid, dhcp6->xid));
|
||||
goto free_pbuf_and_return;
|
||||
}
|
||||
/* option fields could be unfold? */
|
||||
@ -791,7 +813,8 @@ dhcp6_tmr(void)
|
||||
{
|
||||
struct netif *netif;
|
||||
/* loop through netif's */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
struct dhcp6 *dhcp6 = netif_dhcp6_data(netif);
|
||||
/* only act on DHCPv6 configured interfaces */
|
||||
if (dhcp6 != NULL) {
|
||||
|
@ -44,13 +44,13 @@
|
||||
#if LWIP_IPV6 && LWIP_ETHERNET
|
||||
|
||||
#include "lwip/ethip6.h"
|
||||
#include "lwip/nd6.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/icmp6.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/ip6.h"
|
||||
#include "lwip/ip6_addr.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/nd6.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/icmp6.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/prot/ethernet.h"
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
@ -98,7 +98,7 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
|
||||
dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3];
|
||||
|
||||
/* Send out. */
|
||||
return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
|
||||
return ethernet_output(netif, q, (const struct eth_addr *)(netif->hwaddr), &dest, ETHTYPE_IPV6);
|
||||
}
|
||||
|
||||
/* We have a unicast destination IP address */
|
||||
@ -117,7 +117,7 @@ ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
|
||||
|
||||
/* Send out the packet using the returned hardware address. */
|
||||
SMEMCPY(dest.addr, hwaddr, 6);
|
||||
return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6);
|
||||
return ethernet_output(netif, q, (const struct eth_addr *)(netif->hwaddr), &dest, ETHTYPE_IPV6);
|
||||
}
|
||||
|
||||
#endif /* LWIP_IPV6 && LWIP_ETHERNET */
|
||||
|
@ -44,31 +44,42 @@
|
||||
#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.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_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/ip.h"
|
||||
#include "lwip/nd6.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/prot/icmp6.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if LWIP_ICMP6_DATASIZE == 0
|
||||
#undef LWIP_ICMP6_DATASIZE
|
||||
#define LWIP_ICMP6_DATASIZE 8
|
||||
#define LWIP_ICMP6_DATASIZE 8
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type);
|
||||
static void icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data,
|
||||
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);
|
||||
|
||||
static void
|
||||
icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type);
|
||||
static void
|
||||
icmp6_send_response_with_addrs(struct pbuf *p,
|
||||
u8_t code,
|
||||
u32_t data,
|
||||
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.
|
||||
@ -100,9 +111,9 @@ icmp6_input(struct pbuf *p, struct netif *inp)
|
||||
icmp6hdr = (struct icmp6_hdr *)p->payload;
|
||||
|
||||
#if 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__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) {
|
||||
/* Checksum failed */
|
||||
pbuf_free(p);
|
||||
ICMP6_STATS_INC(icmp6.chkerr);
|
||||
@ -113,99 +124,97 @@ icmp6_input(struct pbuf *p, struct netif *inp)
|
||||
#endif /* CHECKSUM_CHECK_ICMP6 */
|
||||
|
||||
switch (icmp6hdr->type) {
|
||||
case ICMP6_TYPE_NA: /* Neighbor advertisement */
|
||||
case ICMP6_TYPE_NS: /* Neighbor solicitation */
|
||||
case ICMP6_TYPE_RA: /* Router advertisement */
|
||||
case ICMP6_TYPE_RD: /* Redirect */
|
||||
case ICMP6_TYPE_PTB: /* Packet too big */
|
||||
nd6_input(p, inp);
|
||||
return;
|
||||
case ICMP6_TYPE_RS:
|
||||
#if LWIP_IPV6_FORWARD
|
||||
/* @todo implement router functionality */
|
||||
#endif
|
||||
break;
|
||||
#if LWIP_IPV6_MLD
|
||||
case ICMP6_TYPE_MLQ:
|
||||
case ICMP6_TYPE_MLR:
|
||||
case ICMP6_TYPE_MLD:
|
||||
mld6_input(p, inp);
|
||||
return;
|
||||
#endif
|
||||
case ICMP6_TYPE_EREQ:
|
||||
#if !LWIP_MULTICAST_PING
|
||||
/* multicast destination address? */
|
||||
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
|
||||
/* drop */
|
||||
pbuf_free(p);
|
||||
ICMP6_STATS_INC(icmp6.drop);
|
||||
case ICMP6_TYPE_NA: /* Neighbor advertisement */
|
||||
case ICMP6_TYPE_NS: /* Neighbor solicitation */
|
||||
case ICMP6_TYPE_RA: /* Router advertisement */
|
||||
case ICMP6_TYPE_RD: /* Redirect */
|
||||
case ICMP6_TYPE_PTB: /* Packet too big */
|
||||
nd6_input(p, inp);
|
||||
return;
|
||||
}
|
||||
case ICMP6_TYPE_RS:
|
||||
#if LWIP_IPV6_FORWARD
|
||||
/* @todo implement router functionality */
|
||||
#endif
|
||||
break;
|
||||
#if LWIP_IPV6_MLD
|
||||
case ICMP6_TYPE_MLQ:
|
||||
case ICMP6_TYPE_MLR:
|
||||
case ICMP6_TYPE_MLD:
|
||||
mld6_input(p, inp);
|
||||
return;
|
||||
#endif
|
||||
case ICMP6_TYPE_EREQ:
|
||||
#if !LWIP_MULTICAST_PING
|
||||
/* multicast destination address? */
|
||||
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
|
||||
/* drop */
|
||||
pbuf_free(p);
|
||||
ICMP6_STATS_INC(icmp6.drop);
|
||||
return;
|
||||
}
|
||||
#endif /* LWIP_MULTICAST_PING */
|
||||
|
||||
/* Allocate reply. */
|
||||
r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM);
|
||||
if (r == NULL) {
|
||||
/* drop */
|
||||
pbuf_free(p);
|
||||
ICMP6_STATS_INC(icmp6.memerr);
|
||||
return;
|
||||
}
|
||||
/* Allocate reply. */
|
||||
r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM);
|
||||
if (r == NULL) {
|
||||
/* drop */
|
||||
pbuf_free(p);
|
||||
ICMP6_STATS_INC(icmp6.memerr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy echo request. */
|
||||
if (pbuf_copy(r, p) != ERR_OK) {
|
||||
/* drop */
|
||||
pbuf_free(p);
|
||||
pbuf_free(r);
|
||||
ICMP6_STATS_INC(icmp6.err);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Determine reply source IPv6 address. */
|
||||
#if LWIP_MULTICAST_PING
|
||||
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
|
||||
reply_src = ip_2_ip6(ip6_select_source_address(inp, ip6_current_src_addr()));
|
||||
if (reply_src == NULL) {
|
||||
/* Copy echo request. */
|
||||
if (pbuf_copy(r, p) != ERR_OK) {
|
||||
/* drop */
|
||||
pbuf_free(p);
|
||||
pbuf_free(r);
|
||||
ICMP6_STATS_INC(icmp6.rterr);
|
||||
ICMP6_STATS_INC(icmp6.err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* LWIP_MULTICAST_PING */
|
||||
{
|
||||
reply_src = ip6_current_dest_addr();
|
||||
}
|
||||
|
||||
/* Set fields in reply. */
|
||||
((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP;
|
||||
((struct icmp6_echo_hdr *)(r->payload))->chksum = 0;
|
||||
/* Determine reply source IPv6 address. */
|
||||
#if LWIP_MULTICAST_PING
|
||||
if (ip6_addr_ismulticast(ip6_current_dest_addr())) {
|
||||
reply_src = ip_2_ip6(ip6_select_source_address(inp, ip6_current_src_addr()));
|
||||
if (reply_src == NULL) {
|
||||
/* drop */
|
||||
pbuf_free(p);
|
||||
pbuf_free(r);
|
||||
ICMP6_STATS_INC(icmp6.rterr);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
#endif /* LWIP_MULTICAST_PING */
|
||||
{
|
||||
reply_src = ip6_current_dest_addr();
|
||||
}
|
||||
|
||||
/* Set fields in reply. */
|
||||
((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP;
|
||||
((struct icmp6_echo_hdr *)(r->payload))->chksum = 0;
|
||||
#if 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());
|
||||
}
|
||||
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());
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_ICMP6 */
|
||||
|
||||
/* Send reply. */
|
||||
ICMP6_STATS_INC(icmp6.xmit);
|
||||
ip6_output_if(r, reply_src, ip6_current_src_addr(),
|
||||
LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp);
|
||||
pbuf_free(r);
|
||||
/* Send reply. */
|
||||
ICMP6_STATS_INC(icmp6.xmit);
|
||||
ip6_output_if(r, reply_src, ip6_current_src_addr(), LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp);
|
||||
pbuf_free(r);
|
||||
|
||||
break;
|
||||
default:
|
||||
ICMP6_STATS_INC(icmp6.proterr);
|
||||
ICMP6_STATS_INC(icmp6.drop);
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
ICMP6_STATS_INC(icmp6.proterr);
|
||||
ICMP6_STATS_INC(icmp6.drop);
|
||||
break;
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send an icmpv6 'destination unreachable' packet.
|
||||
*
|
||||
@ -270,8 +279,10 @@ icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c)
|
||||
* information
|
||||
*/
|
||||
void
|
||||
icmp6_time_exceeded_with_addrs(struct pbuf *p, enum icmp6_te_code c,
|
||||
const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr)
|
||||
icmp6_time_exceeded_with_addrs(struct pbuf *p,
|
||||
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);
|
||||
}
|
||||
@ -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
|
||||
*/
|
||||
static void
|
||||
icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, u8_t type,
|
||||
const ip6_addr_t *src_addr, const ip6_addr_t *dest_addr)
|
||||
icmp6_send_response_with_addrs(struct pbuf *p,
|
||||
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;
|
||||
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);
|
||||
return;
|
||||
}
|
||||
icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src,
|
||||
reply_dest, netif);
|
||||
icmp6_send_response_with_addrs_and_netif(p, code, data, type, reply_src, reply_dest, netif);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -382,22 +396,26 @@ icmp6_send_response_with_addrs(struct pbuf *p, u8_t code, u32_t data, u8_t type,
|
||||
* @param netif netif to send the packet
|
||||
*/
|
||||
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 *reply_src, const ip6_addr_t *reply_dest, struct netif *netif)
|
||||
icmp6_send_response_with_addrs_and_netif(struct pbuf *p,
|
||||
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 icmp6_hdr *icmp6hdr;
|
||||
|
||||
/* ICMPv6 header + IPv6 header + data */
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE,
|
||||
PBUF_RAM);
|
||||
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE, PBUF_RAM);
|
||||
if (q == NULL) {
|
||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n"));
|
||||
ICMP6_STATS_INC(icmp6.memerr);
|
||||
return;
|
||||
}
|
||||
LWIP_ASSERT("check that first pbuf can hold icmp 6message",
|
||||
(q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));
|
||||
(q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));
|
||||
|
||||
icmp6hdr = (struct icmp6_hdr *)q->payload;
|
||||
icmp6hdr->type = type;
|
||||
@ -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);
|
||||
|
||||
/* copy fields from original packet */
|
||||
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload,
|
||||
IP6_HLEN + LWIP_ICMP6_DATASIZE);
|
||||
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload, IP6_HLEN + LWIP_ICMP6_DATASIZE);
|
||||
|
||||
/* calculate checksum */
|
||||
icmp6hdr->chksum = 0;
|
||||
#if 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);
|
||||
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);
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_ICMP6 */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,21 +42,21 @@
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
|
||||
#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/ip_addr.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/ip_addr.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if LWIP_IPV4
|
||||
#include "lwip/ip4_addr.h" /* for ip6addr_aton to handle IPv4-mapped addresses */
|
||||
#endif /* LWIP_IPV4 */
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
/* used by IP6_ADDR_ANY(6) in ip6_addr.h */
|
||||
const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul);
|
||||
|
||||
#define lwip_xchar(i) ((char)((i) < 10 ? '0' + (i) : 'A' + (i) - 10))
|
||||
#define lwip_xchar(i) ((char)((i) < 10 ? '0' + (i) : 'A' + (i)-10))
|
||||
|
||||
/**
|
||||
* Check whether "cp" is a valid ascii representation
|
||||
@ -84,7 +84,7 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
|
||||
zero_blocks--;
|
||||
#if LWIP_IPV4
|
||||
} else if (*s == '.') {
|
||||
if ((zero_blocks == 5) ||(zero_blocks == 2)) {
|
||||
if ((zero_blocks == 5) || (zero_blocks == 2)) {
|
||||
check_ipv4_mapped = 1;
|
||||
/* last block could be the start of an IPv4 address */
|
||||
zero_blocks--;
|
||||
@ -108,8 +108,7 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
|
||||
if (addr) {
|
||||
if (current_block_index & 0x1) {
|
||||
addr->addr[addr_index++] |= current_block_value;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
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)) {
|
||||
/* add current digit */
|
||||
current_block_value = (current_block_value << 4) +
|
||||
(lwip_isdigit(*s) ? (u32_t)(*s - '0') :
|
||||
(u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A')));
|
||||
current_block_value =
|
||||
(current_block_value << 4) +
|
||||
(lwip_isdigit(*s) ? (u32_t)(*s - '0') : (u32_t)(10 + (lwip_islower(*s) ? *s - 'a' : *s - 'A')));
|
||||
} else {
|
||||
/* unexpected digit, space? CRLF? */
|
||||
break;
|
||||
@ -172,12 +171,11 @@ ip6addr_aton(const char *cp, ip6_addr_t *addr)
|
||||
if (addr) {
|
||||
if (current_block_index & 0x1) {
|
||||
addr->addr[addr_index++] |= current_block_value;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
addr->addr[addr_index] = current_block_value << 16;
|
||||
}
|
||||
#if LWIP_IPV4
|
||||
fix_byte_order_and_return:
|
||||
fix_byte_order_and_return:
|
||||
#endif
|
||||
/* convert to network byte order. */
|
||||
for (addr_index = 0; addr_index < 4; addr_index++) {
|
||||
@ -271,7 +269,7 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
|
||||
* according to current formatting suggestions RFC 5952. */
|
||||
next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]);
|
||||
if ((current_block_index & 0x1) == 0x01) {
|
||||
next_block_value = next_block_value >> 16;
|
||||
next_block_value = next_block_value >> 16;
|
||||
}
|
||||
next_block_value &= 0xffff;
|
||||
if (next_block_value == 0) {
|
||||
@ -320,8 +318,7 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
|
||||
|
||||
if (((current_block_value & 0xf0) == 0) && (zero_flag)) {
|
||||
/* do nothing */
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
buf[i++] = lwip_xchar(((current_block_value & 0xf0) >> 4));
|
||||
zero_flag = 0;
|
||||
if (i >= buflen) {
|
||||
|
@ -39,21 +39,20 @@
|
||||
* <delamer@inicotech.com>
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/ip6_frag.h"
|
||||
#include "lwip/ip6.h"
|
||||
#include "lwip/icmp6.h"
|
||||
#include "lwip/nd6.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/ip6.h"
|
||||
#include "lwip/nd6.h"
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.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
|
||||
* regions. The code gets a little smaller. Only use this if you know that
|
||||
@ -86,17 +85,18 @@
|
||||
* track of the various fragments.
|
||||
*/
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/bpstruct.h"
|
||||
#include "arch/bpstruct.h"
|
||||
#endif
|
||||
PACK_STRUCT_BEGIN
|
||||
struct ip6_reass_helper {
|
||||
struct ip6_reass_helper
|
||||
{
|
||||
PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
|
||||
PACK_STRUCT_FIELD(u16_t start);
|
||||
PACK_STRUCT_FIELD(u16_t end);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
# include "arch/epstruct.h"
|
||||
#include "arch/epstruct.h"
|
||||
#endif
|
||||
|
||||
/* static variables */
|
||||
@ -104,9 +104,11 @@ static struct ip6_reassdata *reassdatagrams;
|
||||
static u16_t ip6_reass_pbufcount;
|
||||
|
||||
/* 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
|
||||
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 */
|
||||
|
||||
void
|
||||
@ -116,7 +118,7 @@ ip6_reass_tmr(void)
|
||||
|
||||
#if !IPV6_FRAG_COPYHEADER
|
||||
LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
|
||||
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
|
||||
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
|
||||
#endif /* !IPV6_FRAG_COPYHEADER */
|
||||
|
||||
r = reassdatagrams;
|
||||
@ -133,8 +135,8 @@ ip6_reass_tmr(void)
|
||||
r = r->next;
|
||||
/* free the helper struct and all enqueued pbufs */
|
||||
ip6_reass_free_complete_datagram(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,10 +167,9 @@ ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr)
|
||||
MEMCPY(p->payload, ipr->orig_hdr, sizeof(iprh));
|
||||
/* Then, move back to the original ipv6 header (we are now pointing to Fragment header).
|
||||
This cannot fail since we already checked when receiving this fragment. */
|
||||
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);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* Reconstruct the zoned source and destination addresses, so that we do
|
||||
* not end up sending the ICMP response over the wrong link. */
|
||||
ip6_addr_t src_addr, dest_addr;
|
||||
@ -272,7 +273,7 @@ struct pbuf *
|
||||
ip6_reass(struct pbuf *p)
|
||||
{
|
||||
struct ip6_reassdata *ipr, *ipr_prev;
|
||||
struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
|
||||
struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev = NULL;
|
||||
struct ip6_frag_hdr *frag_hdr;
|
||||
u16_t offset, len, start, end;
|
||||
ptrdiff_t hdrdiff;
|
||||
@ -283,10 +284,9 @@ ip6_reass(struct pbuf *p)
|
||||
IP6_FRAG_STATS_INC(ip6_frag.recv);
|
||||
|
||||
/* ip6_frag_hdr must be in the first pbuf, not chained. Checked by caller. */
|
||||
LWIP_ASSERT("IPv6 fragment header does not fit in first pbuf",
|
||||
p->len >= sizeof(struct ip6_frag_hdr));
|
||||
LWIP_ASSERT("IPv6 fragment header does not fit in first pbuf", p->len >= sizeof(struct ip6_frag_hdr));
|
||||
|
||||
frag_hdr = (struct ip6_frag_hdr *) p->payload;
|
||||
frag_hdr = (struct ip6_frag_hdr *)p->payload;
|
||||
|
||||
clen = pbuf_clen(p);
|
||||
|
||||
@ -296,7 +296,7 @@ ip6_reass(struct pbuf *p)
|
||||
* Adjust for headers before Fragment Header.
|
||||
* And finally adjust by Fragment Header length. */
|
||||
len = lwip_ntohs(ip6_current_header()->_plen);
|
||||
hdrdiff = (u8_t*)p->payload - (const u8_t*)ip6_current_header();
|
||||
hdrdiff = (u8_t *)p->payload - (const u8_t *)ip6_current_header();
|
||||
LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff <= 0xFFFF);
|
||||
LWIP_ASSERT("not a valid pbuf (ip6_input check missing?)", hdrdiff >= IP6_HLEN);
|
||||
hdrdiff -= IP6_HLEN;
|
||||
@ -329,7 +329,7 @@ ip6_reass(struct pbuf *p)
|
||||
}
|
||||
|
||||
if (ipr == NULL) {
|
||||
/* Enqueue a new datagram into the datagram queue */
|
||||
/* Enqueue a new datagram into the datagram queue */
|
||||
ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA);
|
||||
if (ipr == NULL) {
|
||||
#if IP_REASS_FREE_OLDEST
|
||||
@ -414,9 +414,9 @@ ip6_reass(struct pbuf *p)
|
||||
LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */
|
||||
LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0);
|
||||
}
|
||||
#else /* IPV6_FRAG_COPYHEADER */
|
||||
#else /* IPV6_FRAG_COPYHEADER */
|
||||
LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1",
|
||||
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
|
||||
sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN);
|
||||
#endif /* IPV6_FRAG_COPYHEADER */
|
||||
|
||||
/* Prepare the pointer to the helper structure, and its initial values.
|
||||
@ -431,7 +431,7 @@ ip6_reass(struct pbuf *p)
|
||||
/* Iterate through until we either get to the end of the list (append),
|
||||
* or we find on with a larger offset (insert). */
|
||||
for (q = ipr->p; q != NULL;) {
|
||||
iprh_tmp = (struct ip6_reass_helper*)q->payload;
|
||||
iprh_tmp = (struct ip6_reass_helper *)q->payload;
|
||||
if (start < iprh_tmp->start) {
|
||||
#if IP_REASS_CHECK_OVERLAP
|
||||
if (end > iprh_tmp->start) {
|
||||
@ -494,8 +494,7 @@ ip6_reass(struct pbuf *p)
|
||||
}
|
||||
} else {
|
||||
#if IP_REASS_CHECK_OVERLAP
|
||||
LWIP_ASSERT("no previous fragment, this must be the first fragment!",
|
||||
ipr->p == NULL);
|
||||
LWIP_ASSERT("no previous fragment, this must be the first fragment!", ipr->p == NULL);
|
||||
#endif /* IP_REASS_CHECK_OVERLAP */
|
||||
/* this is the first fragment we ever received for this ip datagram */
|
||||
ipr->p = p;
|
||||
@ -528,7 +527,7 @@ ip6_reass(struct pbuf *p)
|
||||
}
|
||||
|
||||
/* Additional validity tests: we have received first and last fragment. */
|
||||
iprh_tmp = (struct ip6_reass_helper*)ipr->p->payload;
|
||||
iprh_tmp = (struct ip6_reass_helper *)ipr->p->payload;
|
||||
if (iprh_tmp->start != 0) {
|
||||
valid = 0;
|
||||
}
|
||||
@ -540,7 +539,7 @@ ip6_reass(struct pbuf *p)
|
||||
iprh_prev = iprh;
|
||||
q = iprh->next_pbuf;
|
||||
while ((q != NULL) && valid) {
|
||||
iprh = (struct ip6_reass_helper*)q->payload;
|
||||
iprh = (struct ip6_reass_helper *)q->payload;
|
||||
if (iprh_prev->end != iprh->start) {
|
||||
valid = 0;
|
||||
break;
|
||||
@ -551,15 +550,15 @@ ip6_reass(struct pbuf *p)
|
||||
|
||||
if (valid) {
|
||||
/* All fragments have been received */
|
||||
struct ip6_hdr* iphdr_ptr;
|
||||
struct ip6_hdr *iphdr_ptr;
|
||||
|
||||
/* chain together the pbufs contained within the ip6_reassdata list. */
|
||||
iprh = (struct ip6_reass_helper*) ipr->p->payload;
|
||||
iprh = (struct ip6_reass_helper *)ipr->p->payload;
|
||||
while (iprh != NULL) {
|
||||
next_pbuf = iprh->next_pbuf;
|
||||
if (next_pbuf != NULL) {
|
||||
/* Save next helper struct (will be hidden in next step). */
|
||||
iprh_tmp = (struct ip6_reass_helper*)next_pbuf->payload;
|
||||
iprh_tmp = (struct ip6_reass_helper *)next_pbuf->payload;
|
||||
|
||||
/* hide the fragment header for every succeeding fragment */
|
||||
pbuf_remove_header(next_pbuf, IP6_FRAG_HLEN);
|
||||
@ -572,8 +571,7 @@ ip6_reass(struct pbuf *p)
|
||||
}
|
||||
#endif
|
||||
pbuf_cat(ipr->p, next_pbuf);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
iprh_tmp = NULL;
|
||||
}
|
||||
|
||||
@ -606,16 +604,14 @@ ip6_reass(struct pbuf *p)
|
||||
* accordingly. This works because all these headers are in the first pbuf
|
||||
* of the chain, and because the caller adjusts all its pointers on
|
||||
* successful reassembly. */
|
||||
MEMMOVE((u8_t*)ipr->iphdr + sizeof(struct ip6_frag_hdr), ipr->iphdr,
|
||||
(size_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr));
|
||||
MEMMOVE(
|
||||
(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. */
|
||||
iphdr_ptr = (struct ip6_hdr*)((u8_t*)ipr->iphdr +
|
||||
sizeof(struct ip6_frag_hdr));
|
||||
iphdr_ptr = (struct ip6_hdr *)((u8_t *)ipr->iphdr + sizeof(struct ip6_frag_hdr));
|
||||
|
||||
/* Adjust datagram length by adding header lengths. */
|
||||
ipr->datagram_len = (u16_t)(ipr->datagram_len + ((u8_t*)p->payload - (u8_t*)iphdr_ptr)
|
||||
- IP6_HLEN);
|
||||
ipr->datagram_len = (u16_t)(ipr->datagram_len + ((u8_t *)p->payload - (u8_t *)iphdr_ptr) - IP6_HLEN);
|
||||
|
||||
/* Set payload length in ip header. */
|
||||
iphdr_ptr->_plen = lwip_htons(ipr->datagram_len);
|
||||
@ -651,7 +647,7 @@ ip6_reass(struct pbuf *p)
|
||||
ip6_reass_pbufcount = (u16_t)(ip6_reass_pbufcount - clen);
|
||||
|
||||
/* Move pbuf back to IPv6 header. This should never fail. */
|
||||
if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)iphdr_ptr))) {
|
||||
if (pbuf_header_force(p, (s16_t)((u8_t *)p->payload - (u8_t *)iphdr_ptr))) {
|
||||
LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0);
|
||||
pbuf_free(p);
|
||||
return NULL;
|
||||
@ -675,15 +671,15 @@ nullreturn:
|
||||
|
||||
#if !LWIP_NETIF_TX_SINGLE_PBUF
|
||||
/** Allocate a new struct pbuf_custom_ref */
|
||||
static struct pbuf_custom_ref*
|
||||
static struct pbuf_custom_ref *
|
||||
ip6_frag_alloc_pbuf_custom_ref(void)
|
||||
{
|
||||
return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF);
|
||||
return (struct pbuf_custom_ref *)memp_malloc(MEMP_FRAG_PBUF);
|
||||
}
|
||||
|
||||
/** Free a struct pbuf_custom_ref */
|
||||
static void
|
||||
ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p)
|
||||
ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref *p)
|
||||
{
|
||||
LWIP_ASSERT("p != NULL", p != NULL);
|
||||
memp_free(MEMP_FRAG_PBUF, p);
|
||||
@ -694,9 +690,9 @@ ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p)
|
||||
static void
|
||||
ip6_frag_free_pbuf_custom(struct pbuf *p)
|
||||
{
|
||||
struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p;
|
||||
struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref *)p;
|
||||
LWIP_ASSERT("pcr != NULL", pcr != NULL);
|
||||
LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p);
|
||||
LWIP_ASSERT("pcr == p", (void *)pcr == (void *)p);
|
||||
if (pcr->original != NULL) {
|
||||
pbuf_free(pcr->original);
|
||||
}
|
||||
@ -756,9 +752,8 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
|
||||
IP6_FRAG_STATS_INC(ip6_frag.memerr);
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!",
|
||||
(rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
|
||||
poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff);
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!", (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
|
||||
poff += pbuf_copy_partial(p, (u8_t *)rambuf->payload + IP6_FRAG_HLEN, cop, poff);
|
||||
/* make room for the IP header */
|
||||
if (pbuf_add_header(rambuf, IP6_HLEN)) {
|
||||
pbuf_free(rambuf);
|
||||
@ -768,7 +763,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
|
||||
/* fill in the IP header */
|
||||
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
|
||||
ip6hdr = (struct ip6_hdr *)rambuf->payload;
|
||||
frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
|
||||
frag_hdr = (struct ip6_frag_hdr *)((u8_t *)rambuf->payload + IP6_HLEN);
|
||||
#else
|
||||
/* When not using a static buffer, create a chain of pbufs.
|
||||
* The first will be a PBUF_RAM holding the link, IPv6, and Fragment header.
|
||||
@ -780,11 +775,10 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
|
||||
IP6_FRAG_STATS_INC(ip6_frag.memerr);
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!",
|
||||
(p->len >= (IP6_HLEN)));
|
||||
LWIP_ASSERT("this needs a pbuf in one piece!", (p->len >= (IP6_HLEN)));
|
||||
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
|
||||
ip6hdr = (struct ip6_hdr *)rambuf->payload;
|
||||
frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);
|
||||
frag_hdr = (struct ip6_frag_hdr *)((u8_t *)rambuf->payload + IP6_HLEN);
|
||||
|
||||
/* Can just adjust p directly for needed offset. */
|
||||
p->payload = (u8_t *)p->payload + poff;
|
||||
@ -833,7 +827,8 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
|
||||
/* Set headers */
|
||||
frag_hdr->_nexth = original_ip6hdr->_nexth;
|
||||
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);
|
||||
|
||||
IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT);
|
||||
|
@ -6,7 +6,7 @@
|
||||
* @ingroup ip6
|
||||
* Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710.
|
||||
* No support for MLDv2.\n
|
||||
* Note: The allnodes (ff01::1, ff02::1) group is assumed be received by your
|
||||
* Note: The allnodes (ff01::1, ff02::1) group is assumed be received by your
|
||||
* netif since it must always be received for correct IPv6 operation (e.g. SLAAC).
|
||||
* Ensure the netif filters are configured accordingly!\n
|
||||
* The netif flags also need NETIF_FLAG_MLD6 flag set to enable MLD6 on a
|
||||
@ -53,39 +53,41 @@
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD /* don't build if not configured for use in lwipopts.h */
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/mld6.h"
|
||||
#include "lwip/prot/mld6.h"
|
||||
#include "lwip/icmp6.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/ip6.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/mld6.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/prot/mld6.h"
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* MLD constants
|
||||
*/
|
||||
#define MLD6_HL 1
|
||||
#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500)
|
||||
#define MLD6_HL 1
|
||||
#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500)
|
||||
|
||||
#define MLD6_GROUP_NON_MEMBER 0
|
||||
#define MLD6_GROUP_DELAYING_MEMBER 1
|
||||
#define MLD6_GROUP_IDLE_MEMBER 2
|
||||
#define MLD6_GROUP_NON_MEMBER 0
|
||||
#define MLD6_GROUP_DELAYING_MEMBER 1
|
||||
#define MLD6_GROUP_IDLE_MEMBER 2
|
||||
|
||||
/* Forward declarations. */
|
||||
static struct mld_group *mld6_new_group(struct netif *ifp, const ip6_addr_t *addr);
|
||||
static err_t mld6_remove_group(struct netif *netif, struct mld_group *group);
|
||||
static 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);
|
||||
|
||||
static struct mld_group *
|
||||
mld6_new_group(struct netif *ifp, const ip6_addr_t *addr);
|
||||
static err_t
|
||||
mld6_remove_group(struct netif *netif, struct mld_group *group);
|
||||
static 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
|
||||
@ -155,7 +157,6 @@ mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a new group
|
||||
*
|
||||
@ -172,11 +173,11 @@ mld6_new_group(struct netif *ifp, const ip6_addr_t *addr)
|
||||
group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP);
|
||||
if (group != NULL) {
|
||||
ip6_addr_set(&(group->group_address), addr);
|
||||
group->timer = 0; /* Not running */
|
||||
group->group_state = MLD6_GROUP_IDLE_MEMBER;
|
||||
group->timer = 0; /* Not running */
|
||||
group->group_state = MLD6_GROUP_IDLE_MEMBER;
|
||||
group->last_reporter_flag = 0;
|
||||
group->use = 0;
|
||||
group->next = netif_mld6_data(ifp);
|
||||
group->use = 0;
|
||||
group->next = netif_mld6_data(ifp);
|
||||
|
||||
netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group);
|
||||
}
|
||||
@ -216,7 +217,6 @@ mld6_remove_group(struct netif *netif, struct mld_group *group)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process an input MLD message. Called by icmp6_input.
|
||||
*
|
||||
@ -243,54 +243,53 @@ mld6_input(struct pbuf *p, struct netif *inp)
|
||||
mld_hdr = (struct mld_header *)p->payload;
|
||||
|
||||
switch (mld_hdr->type) {
|
||||
case ICMP6_TYPE_MLQ: /* Multicast listener query. */
|
||||
/* Is it a general query? */
|
||||
if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) &&
|
||||
ip6_addr_isany(&(mld_hdr->multicast_address))) {
|
||||
MLD6_STATS_INC(mld6.rx_general);
|
||||
/* Report all groups, except all nodes group, and if-local groups. */
|
||||
group = netif_mld6_data(inp);
|
||||
while (group != NULL) {
|
||||
if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
|
||||
(!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
|
||||
case ICMP6_TYPE_MLQ: /* Multicast listener query. */
|
||||
/* Is it a general query? */
|
||||
if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && ip6_addr_isany(&(mld_hdr->multicast_address))) {
|
||||
MLD6_STATS_INC(mld6.rx_general);
|
||||
/* Report all groups, except all nodes group, and if-local groups. */
|
||||
group = netif_mld6_data(inp);
|
||||
while (group != NULL) {
|
||||
if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
|
||||
(!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
|
||||
mld6_delayed_report(group, mld_hdr->max_resp_delay);
|
||||
}
|
||||
group = group->next;
|
||||
}
|
||||
} else {
|
||||
/* Have we joined this group?
|
||||
* We use IP6 destination address to have a memory aligned copy.
|
||||
* mld_hdr->multicast_address should be the same. */
|
||||
MLD6_STATS_INC(mld6.rx_group);
|
||||
group = mld6_lookfor_group(inp, ip6_current_dest_addr());
|
||||
if (group != NULL) {
|
||||
/* Schedule a report. */
|
||||
mld6_delayed_report(group, mld_hdr->max_resp_delay);
|
||||
}
|
||||
group = group->next;
|
||||
}
|
||||
} else {
|
||||
break; /* ICMP6_TYPE_MLQ */
|
||||
case ICMP6_TYPE_MLR: /* Multicast listener report. */
|
||||
/* Have we joined this group?
|
||||
* We use IP6 destination address to have a memory aligned copy.
|
||||
* mld_hdr->multicast_address should be the same. */
|
||||
MLD6_STATS_INC(mld6.rx_group);
|
||||
MLD6_STATS_INC(mld6.rx_report);
|
||||
group = mld6_lookfor_group(inp, ip6_current_dest_addr());
|
||||
if (group != NULL) {
|
||||
/* Schedule a report. */
|
||||
mld6_delayed_report(group, mld_hdr->max_resp_delay);
|
||||
/* If we are waiting to report, cancel it. */
|
||||
if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
|
||||
group->timer = 0; /* stopped */
|
||||
group->group_state = MLD6_GROUP_IDLE_MEMBER;
|
||||
group->last_reporter_flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break; /* ICMP6_TYPE_MLQ */
|
||||
case ICMP6_TYPE_MLR: /* Multicast listener report. */
|
||||
/* Have we joined this group?
|
||||
* We use IP6 destination address to have a memory aligned copy.
|
||||
* mld_hdr->multicast_address should be the same. */
|
||||
MLD6_STATS_INC(mld6.rx_report);
|
||||
group = mld6_lookfor_group(inp, ip6_current_dest_addr());
|
||||
if (group != NULL) {
|
||||
/* If we are waiting to report, cancel it. */
|
||||
if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
|
||||
group->timer = 0; /* stopped */
|
||||
group->group_state = MLD6_GROUP_IDLE_MEMBER;
|
||||
group->last_reporter_flag = 0;
|
||||
}
|
||||
}
|
||||
break; /* ICMP6_TYPE_MLR */
|
||||
case ICMP6_TYPE_MLD: /* Multicast listener done. */
|
||||
/* Do nothing, router will query us. */
|
||||
break; /* ICMP6_TYPE_MLD */
|
||||
default:
|
||||
MLD6_STATS_INC(mld6.proterr);
|
||||
MLD6_STATS_INC(mld6.drop);
|
||||
break;
|
||||
break; /* ICMP6_TYPE_MLR */
|
||||
case ICMP6_TYPE_MLD: /* Multicast listener done. */
|
||||
/* Do nothing, router will query us. */
|
||||
break; /* ICMP6_TYPE_MLD */
|
||||
default:
|
||||
MLD6_STATS_INC(mld6.proterr);
|
||||
MLD6_STATS_INC(mld6.drop);
|
||||
break;
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
@ -314,16 +313,16 @@ mld6_input(struct pbuf *p, struct netif *inp)
|
||||
err_t
|
||||
mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
|
||||
{
|
||||
err_t err = ERR_VAL; /* no matching interface */
|
||||
err_t err = ERR_VAL; /* no matching interface */
|
||||
struct netif *netif;
|
||||
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
|
||||
/* loop through netif's */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
/* Should we join this interface ? */
|
||||
if (ip6_addr_isany(srcaddr) ||
|
||||
netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
|
||||
if (ip6_addr_isany(srcaddr) || netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
|
||||
err = mld6_joingroup_netif(netif, groupaddr);
|
||||
if (err != ERR_OK) {
|
||||
return err;
|
||||
@ -403,16 +402,16 @@ mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
|
||||
err_t
|
||||
mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr)
|
||||
{
|
||||
err_t err = ERR_VAL; /* no matching interface */
|
||||
err_t err = ERR_VAL; /* no matching interface */
|
||||
struct netif *netif;
|
||||
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
|
||||
/* loop through netif's */
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
/* Should we leave this interface ? */
|
||||
if (ip6_addr_isany(srcaddr) ||
|
||||
netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
|
||||
if (ip6_addr_isany(srcaddr) || netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
|
||||
err_t res = mld6_leavegroup_netif(netif, groupaddr);
|
||||
if (err != ERR_OK) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Periodic timer for mld processing. Must be called every
|
||||
* MLD6_TMR_INTERVAL milliseconds (100).
|
||||
@ -497,7 +495,8 @@ mld6_tmr(void)
|
||||
{
|
||||
struct netif *netif;
|
||||
|
||||
NETIF_FOREACH(netif) {
|
||||
NETIF_FOREACH(netif)
|
||||
{
|
||||
struct mld_group *group = netif_mld6_data(netif);
|
||||
|
||||
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. */
|
||||
if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) ||
|
||||
((group->group_state == MLD6_GROUP_DELAYING_MEMBER) &&
|
||||
((group->timer == 0) || (maxresp < group->timer)))) {
|
||||
((group->group_state == MLD6_GROUP_DELAYING_MEMBER) && ((group->timer == 0) || (maxresp < group->timer)))) {
|
||||
group->timer = maxresp;
|
||||
group->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);
|
||||
|
||||
#if 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));
|
||||
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));
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_ICMP6 */
|
||||
|
||||
@ -618,8 +616,8 @@ mld6_send(struct netif *netif, struct mld_group *group, u8_t type)
|
||||
|
||||
/* Send the packet out. */
|
||||
MLD6_STATS_INC(mld6.xmit);
|
||||
ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address),
|
||||
MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif);
|
||||
ip6_output_if(
|
||||
p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif);
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
|
1413
src/core/ipv6/nd6.c
1413
src/core/ipv6/nd6.c
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user