IDF release/v4.0 08219f3cf

This commit is contained in:
me-no-dev
2020-01-25 14:51:58 +00:00
parent 8c723be135
commit 41ba143063
858 changed files with 37940 additions and 49396 deletions

View File

@ -1,3 +0,0 @@
#pragma once
#warning "This header file is deprecated, please include esp_sntp.h instead."
#include "esp_sntp.h"

View File

@ -41,7 +41,9 @@
#include "arch/sys_arch.h"
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif // BYTE_ORDER
typedef uint8_t u8_t;
typedef int8_t s8_t;
@ -50,7 +52,7 @@ typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
typedef unsigned long mem_ptr_t;
typedef int sys_prot_t;
#define S16_F "d"

View File

@ -80,7 +80,7 @@ typedef struct sys_mbox_s {
* However, if the sys_mbox_set_invalid() is not called after sys_mbox_free(), e.g. in netconn_alloc(),
* we need to initialize the mbox to invalid explicitly since sys_mbox_set_invalid() now is empty.
*/
#define sys_mbox_set_invalid( x )
#define sys_mbox_set_invalid( x ) *x = NULL
#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define sys_sem_set_invalid( x ) ( ( *x ) = NULL )

View File

@ -41,7 +41,9 @@
#include "arch/sys_arch.h"
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif // BYTE_ORDER
typedef uint8_t u8_t;
typedef int8_t s8_t;
@ -50,7 +52,7 @@ typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
typedef unsigned long mem_ptr_t;
typedef int sys_prot_t;
#define S16_F "d"

View File

@ -0,0 +1,36 @@
/**
* @file
* This file is a posix wrapper for lwip/if_api.h.
*/
/*
* Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#include "lwip/if_api.h"

View File

@ -31,10 +31,3 @@
*/
#include "lwip/netdb.h"
#ifdef ESP_PLATFORM
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
char *host, socklen_t hostlen,
char *serv, socklen_t servlen, int flags);
#endif

View File

@ -0,0 +1,33 @@
/**
* @file
* This file is a posix wrapper for lwip/sockets.h.
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#include "lwip/sockets.h"

View File

@ -1,6 +1,6 @@
/**
* @file
* This file is a posix wrapper for lwip/errno.h.
* This file is a posix/stdc wrapper for lwip/errno.h.
*/
/*

View File

@ -24,7 +24,7 @@ extern "C" {
// gen_esp_err_to_name.py: include this as "esp_ping.h" because "components/lwip/include/apps/" is in the compiler path
// and not "components/lwip/include"
#define ESP_ERR_PING_BASE 0x6000
#define ESP_ERR_PING_BASE 0xa000
#define ESP_ERR_PING_INVALID_PARAMS ESP_ERR_PING_BASE + 0x01
#define ESP_ERR_PING_NO_MEM ESP_ERR_PING_BASE + 0x02

View File

@ -0,0 +1,206 @@
/**
* @file
* Application layered TCP connection API (to be used from TCPIP thread)\n
*
* This file contains the generic API.
* For more details see @ref altcp_api.
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_H
#define LWIP_HDR_ALTCP_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/tcpbase.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
struct altcp_pcb;
struct altcp_functions;
typedef err_t (*altcp_accept_fn)(void *arg, struct altcp_pcb *new_conn, err_t err);
typedef err_t (*altcp_connected_fn)(void *arg, struct altcp_pcb *conn, err_t err);
typedef err_t (*altcp_recv_fn)(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err);
typedef err_t (*altcp_sent_fn)(void *arg, struct altcp_pcb *conn, u16_t len);
typedef err_t (*altcp_poll_fn)(void *arg, struct altcp_pcb *conn);
typedef void (*altcp_err_fn)(void *arg, err_t err);
typedef struct altcp_pcb* (*altcp_new_fn)(void *arg, u8_t ip_type);
struct altcp_pcb {
const struct altcp_functions *fns;
struct altcp_pcb *inner_conn;
void *arg;
void *state;
/* application callbacks */
altcp_accept_fn accept;
altcp_connected_fn connected;
altcp_recv_fn recv;
altcp_sent_fn sent;
altcp_poll_fn poll;
altcp_err_fn err;
u8_t pollinterval;
};
/** @ingroup altcp */
typedef struct altcp_allocator_s {
/** Allocator function */
altcp_new_fn alloc;
/** Argument to allocator function */
void *arg;
} altcp_allocator_t;
struct altcp_pcb *altcp_new(altcp_allocator_t *allocator);
struct altcp_pcb *altcp_new_ip6(altcp_allocator_t *allocator);
struct altcp_pcb *altcp_new_ip_type(altcp_allocator_t *allocator, u8_t ip_type);
void altcp_arg(struct altcp_pcb *conn, void *arg);
void altcp_accept(struct altcp_pcb *conn, altcp_accept_fn accept);
void altcp_recv(struct altcp_pcb *conn, altcp_recv_fn recv);
void altcp_sent(struct altcp_pcb *conn, altcp_sent_fn sent);
void altcp_poll(struct altcp_pcb *conn, altcp_poll_fn poll, u8_t interval);
void altcp_err(struct altcp_pcb *conn, altcp_err_fn err);
void altcp_recved(struct altcp_pcb *conn, u16_t len);
err_t altcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port);
err_t altcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected);
/* return conn for source code compatibility to tcp callback API only */
struct altcp_pcb *altcp_listen_with_backlog_and_err(struct altcp_pcb *conn, u8_t backlog, err_t *err);
#define altcp_listen_with_backlog(conn, backlog) altcp_listen_with_backlog_and_err(conn, backlog, NULL)
/** @ingroup altcp */
#define altcp_listen(conn) altcp_listen_with_backlog_and_err(conn, TCP_DEFAULT_LISTEN_BACKLOG, NULL)
void altcp_abort(struct altcp_pcb *conn);
err_t altcp_close(struct altcp_pcb *conn);
err_t altcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx);
err_t altcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags);
err_t altcp_output(struct altcp_pcb *conn);
u16_t altcp_mss(struct altcp_pcb *conn);
u16_t altcp_sndbuf(struct altcp_pcb *conn);
u16_t altcp_sndqueuelen(struct altcp_pcb *conn);
void altcp_nagle_disable(struct altcp_pcb *conn);
void altcp_nagle_enable(struct altcp_pcb *conn);
int altcp_nagle_disabled(struct altcp_pcb *conn);
void altcp_setprio(struct altcp_pcb *conn, u8_t prio);
err_t altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
ip_addr_t *altcp_get_ip(struct altcp_pcb *conn, int local);
u16_t altcp_get_port(struct altcp_pcb *conn, int local);
#if LWIP_TCP_KEEPALIVE
void altcp_keepalive_disable(struct altcp_pcb *conn);
void altcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
#endif
#ifdef LWIP_DEBUG
enum tcp_state altcp_dbg_get_tcp_state(struct altcp_pcb *conn);
#endif
#ifdef __cplusplus
}
#endif
#else /* LWIP_ALTCP */
/* ALTCP disabled, define everything to link against tcp callback API (e.g. to get a small non-ssl httpd) */
#include "lwip/tcp.h"
#define altcp_accept_fn tcp_accept_fn
#define altcp_connected_fn tcp_connected_fn
#define altcp_recv_fn tcp_recv_fn
#define altcp_sent_fn tcp_sent_fn
#define altcp_poll_fn tcp_poll_fn
#define altcp_err_fn tcp_err_fn
#define altcp_pcb tcp_pcb
#define altcp_tcp_new_ip_type tcp_new_ip_type
#define altcp_tcp_new tcp_new
#define altcp_tcp_new_ip6 tcp_new_ip6
#define altcp_new(allocator) tcp_new()
#define altcp_new_ip6(allocator) tcp_new_ip6()
#define altcp_new_ip_type(allocator, ip_type) tcp_new_ip_type(ip_type)
#define altcp_arg tcp_arg
#define altcp_accept tcp_accept
#define altcp_recv tcp_recv
#define altcp_sent tcp_sent
#define altcp_poll tcp_poll
#define altcp_err tcp_err
#define altcp_recved tcp_recved
#define altcp_bind tcp_bind
#define altcp_connect tcp_connect
#define altcp_listen_with_backlog_and_err tcp_listen_with_backlog_and_err
#define altcp_listen_with_backlog tcp_listen_with_backlog
#define altcp_listen tcp_listen
#define altcp_abort tcp_abort
#define altcp_close tcp_close
#define altcp_shutdown tcp_shutdown
#define altcp_write tcp_write
#define altcp_output tcp_output
#define altcp_mss tcp_mss
#define altcp_sndbuf tcp_sndbuf
#define altcp_sndqueuelen tcp_sndqueuelen
#define altcp_nagle_disable tcp_nagle_disable
#define altcp_nagle_enable tcp_nagle_enable
#define altcp_nagle_disabled tcp_nagle_disabled
#define altcp_setprio tcp_setprio
#define altcp_get_tcp_addrinfo tcp_get_tcp_addrinfo
#define altcp_get_ip(pcb, local) ((local) ? (&(pcb)->local_ip) : (&(pcb)->remote_ip))
#ifdef LWIP_DEBUG
#define altcp_dbg_get_tcp_state tcp_dbg_get_tcp_state
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_H */

View File

@ -0,0 +1,72 @@
/**
* @file
* Application layered TCP connection API (to be used from TCPIP thread)\n
* This interface mimics the tcp callback API to the application while preventing
* direct linking (much like virtual functions).
* This way, an application can make use of other application layer protocols
* on top of TCP without knowing the details (e.g. TLS, proxy connection).
*
* This file contains the base implementation calling into tcp.
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_TCP_H
#define LWIP_HDR_ALTCP_TCP_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/altcp.h"
#ifdef __cplusplus
extern "C" {
#endif
struct altcp_pcb *altcp_tcp_new_ip_type(u8_t ip_type);
#define altcp_tcp_new() altcp_tcp_new_ip_type(IPADDR_TYPE_V4)
#define altcp_tcp_new_ip6() altcp_tcp_new_ip_type(IPADDR_TYPE_V6)
struct altcp_pcb *altcp_tcp_alloc(void *arg, u8_t ip_type);
struct tcp_pcb;
struct altcp_pcb *altcp_tcp_wrap(struct tcp_pcb *tpcb);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_TCP_H */

View File

@ -0,0 +1,143 @@
/**
* @file
* Application layered TCP/TLS connection API (to be used from TCPIP thread)
*
* @defgroup altcp_tls TLS layer
* @ingroup altcp
* This file contains function prototypes for a TLS layer.
* A port to ARM mbedtls is provided in the apps/ tree
* (LWIP_ALTCP_TLS_MBEDTLS option).
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_TLS_H
#define LWIP_HDR_ALTCP_TLS_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#if LWIP_ALTCP_TLS
#include "lwip/altcp.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @ingroup altcp_tls
* ALTCP_TLS configuration handle, content depends on port (e.g. mbedtls)
*/
struct altcp_tls_config;
/** @ingroup altcp_tls
* Create an ALTCP_TLS server configuration handle prepared for multiple certificates
*/
struct altcp_tls_config *altcp_tls_create_config_server(uint8_t cert_count);
/** @ingroup altcp_tls
* Add a certificate to an ALTCP_TLS server configuration handle
*/
err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config,
const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Create an ALTCP_TLS server configuration handle with one certificate
* (short version of calling @ref altcp_tls_create_config_server and
* @ref altcp_tls_config_server_add_privkey_cert)
*/
struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Create an ALTCP_TLS client configuration handle
*/
struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Create an ALTCP_TLS client configuration handle with two-way server/client authentication
*/
struct altcp_tls_config *altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Free an ALTCP_TLS configuration handle
*/
void altcp_tls_free_config(struct altcp_tls_config *conf);
/** @ingroup altcp_tls
* Free an ALTCP_TLS global entropy instance.
* All ALTCP_TLS configuration are linked to one altcp_tls_entropy_rng structure
* that handle an unique system entropy & ctr_drbg instance.
* This function allow application to free this altcp_tls_entropy_rng structure
* when all configuration referencing it were destroyed.
* This function does nothing if some ALTCP_TLS configuration handle are still
* active.
*/
void altcp_tls_free_entropy(void);
/** @ingroup altcp_tls
* Create new ALTCP_TLS layer wrapping an existing pcb as inner connection (e.g. TLS over TCP)
*/
struct altcp_pcb *altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb);
/** @ingroup altcp_tls
* Create new ALTCP_TLS pcb and its inner tcp pcb
*/
struct altcp_pcb *altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type);
/** @ingroup altcp_tls
* Create new ALTCP_TLS layer pcb and its inner tcp pcb.
* Same as @ref altcp_tls_new but this allocator function fits to
* @ref altcp_allocator_t / @ref altcp_new.\n
'arg' must contain a struct altcp_tls_config *.
*/
struct altcp_pcb *altcp_tls_alloc(void *arg, u8_t ip_type);
/** @ingroup altcp_tls
* Return pointer to internal TLS context so application can tweak it.
* Real type depends on port (e.g. mbedtls)
*/
void *altcp_tls_context(struct altcp_pcb *conn);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ALTCP_TLS */
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_TLS_H */

View File

@ -58,22 +58,25 @@ extern "C" {
*/
/* Flags for netconn_write (u8_t) */
#define NETCONN_NOFLAG 0x00
#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */
#define NETCONN_COPY 0x01
#define NETCONN_MORE 0x02
#define NETCONN_DONTBLOCK 0x04
#define NETCONN_NOFLAG 0x00
#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */
#define NETCONN_COPY 0x01
#define NETCONN_MORE 0x02
#define NETCONN_DONTBLOCK 0x04
#define NETCONN_NOAUTORCVD 0x08 /* prevent netconn_recv_data_tcp() from updating the tcp window - must be done manually via netconn_tcp_recvd() */
#define NETCONN_NOFIN 0x10 /* upper layer already received data, leave FIN in queue until called again */
/* Flags for struct netconn.flags (u8_t) */
/** This netconn had an error, don't block on recvmbox/acceptmbox any more */
#define NETCONN_FLAG_MBOXCLOSED 0x01
/** Should this netconn avoid blocking? */
#define NETCONN_FLAG_NON_BLOCKING 0x02
/** Was the last connect action a non-blocking one? */
#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04
#if ESP_AUTO_RECV
/** If this is set, a TCP netconn must call netconn_recved() to update
the TCP receive window (done automatically if not set). */
#define NETCONN_FLAG_NO_AUTO_RECVED 0x08
#endif
#if LWIP_NETCONN_FULLDUPLEX
/** The mbox of this netconn is being deallocated, don't use it anymore */
#define NETCONN_FLAG_MBOXINVALID 0x08
#endif /* LWIP_NETCONN_FULLDUPLEX */
/** If a nonblocking write has been rejected before, poll_tcp needs to
check if the netconn is writable again */
#define NETCONN_FLAG_CHECK_WRITESPACE 0x10
@ -83,7 +86,12 @@ extern "C" {
dual-stack usage by default. */
#define NETCONN_FLAG_IPV6_V6ONLY 0x20
#endif /* LWIP_IPV6 */
#if LWIP_NETBUF_RECVINFO
/** Received packet info will be recorded for this netconn */
#define NETCONN_FLAG_PKTINFO 0x40
#endif /* LWIP_NETBUF_RECVINFO */
/** A FIN has been received but not passed to the application yet */
#define NETCONN_FIN_RX_PENDING 0x80
/* Helpers to process several netconn_types by the same code */
#define NETCONNTYPE_GROUP(t) ((t)&0xF0)
@ -219,8 +227,8 @@ struct netconn {
struct udp_pcb *udp;
struct raw_pcb *raw;
} pcb;
/** the last error this netconn had */
err_t last_err;
/** the last asynchronous unreported error this netconn had */
err_t pending_err;
#if !LWIP_NETCONN_SEM_PER_THREAD
/** sem that is used to synchronously execute functions in the core context */
sys_sem_t op_completed;
@ -233,6 +241,11 @@ struct netconn {
by the application thread */
sys_mbox_t acceptmbox;
#endif /* LWIP_TCP */
#if LWIP_NETCONN_FULLDUPLEX
/** number of threads waiting on an mbox. This is required to unblock
all threads when closing while threads are waiting. */
int mbox_threads_waiting;
#endif
/** only used for socket layer */
#if LWIP_SOCKET
int socket;
@ -245,7 +258,7 @@ struct netconn {
#if LWIP_SO_RCVTIMEO
/** timeout in milliseconds to wait for new data to be received
(or connections to arrive for listening netconns) */
int recv_timeout;
u32_t recv_timeout;
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVBUF
/** maximum amount of bytes queued in recvmbox
@ -263,9 +276,6 @@ struct netconn {
/** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
u8_t flags;
#if LWIP_TCP
/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
this temporarily stores how much is already sent. */
size_t write_offset;
/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
this temporarily stores the message.
Also used during connect and close. */
@ -275,21 +285,23 @@ struct netconn {
netconn_callback callback;
};
/** This vector type is passed to @ref netconn_write_vectors_partly to send
* multiple buffers at once.
* ATTENTION: This type has to directly map struct iovec since one is casted
* into the other!
*/
struct netvector {
/** pointer to the application buffer that contains the data to send */
const void *ptr;
/** size of the application data to send */
size_t len;
};
/** Register an Network connection event */
#define API_EVENT(c,e,l) if (c->callback) { \
(*c->callback)(c, e, l); \
}
/** Set conn->last_err to err but don't overwrite fatal errors */
#define NETCONN_SET_SAFE_ERR(conn, err) do { if ((conn) != NULL) { \
SYS_ARCH_DECL_PROTECT(netconn_set_safe_err_lev); \
SYS_ARCH_PROTECT(netconn_set_safe_err_lev); \
if (!ERR_IS_FATAL((conn)->last_err)) { \
(conn)->last_err = err; \
} \
SYS_ARCH_UNPROTECT(netconn_set_safe_err_lev); \
}} while(0);
/* Network connection functions: */
/** @ingroup netconn_common
@ -299,6 +311,7 @@ struct netconn {
#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c)
struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto,
netconn_callback callback);
err_t netconn_prepare_delete(struct netconn *conn);
err_t netconn_delete(struct netconn *conn);
/** Get the type of a netconn (as enum netconn_type). */
#define netconn_type(conn) (conn->type)
@ -311,6 +324,7 @@ err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr,
#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1)
err_t netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port);
err_t netconn_bind_if(struct netconn *conn, u8_t if_idx);
err_t netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port);
err_t netconn_disconnect (struct netconn *conn);
err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
@ -318,15 +332,18 @@ err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG)
err_t netconn_accept(struct netconn *conn, struct netconn **new_conn);
err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf);
err_t 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);
err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf);
#if ESP_AUTO_RECV
void netconn_recved(struct netconn *conn, u32_t length);
#endif
err_t netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags);
err_t netconn_tcp_recvd(struct netconn *conn, size_t len);
err_t netconn_sendto(struct netconn *conn, struct netbuf *buf,
const ip_addr_t *addr, u16_t port);
err_t netconn_send(struct netconn *conn, struct netbuf *buf);
err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
u8_t apiflags, size_t *bytes_written);
err_t netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt,
u8_t apiflags, size_t *bytes_written);
/** @ingroup netconn_tcp */
#define netconn_write(conn, dataptr, size, apiflags) \
netconn_write_partly(conn, dataptr, size, apiflags, NULL)
@ -336,6 +353,8 @@ err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx);
#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
err_t netconn_join_leave_group(struct netconn *conn, const ip_addr_t *multiaddr,
const ip_addr_t *netif_addr, enum netconn_igmp join_or_leave);
err_t netconn_join_leave_group_netif(struct netconn *conn, const ip_addr_t *multiaddr,
u8_t if_idx, enum netconn_igmp join_or_leave);
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
#if LWIP_DNS
#if LWIP_IPV4 && LWIP_IPV6
@ -347,35 +366,29 @@ err_t netconn_gethostbyname(const char *name, ip_addr_t *addr);
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#endif /* LWIP_DNS */
#define netconn_err(conn) ((conn)->last_err)
err_t netconn_err(struct netconn *conn);
#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize)
#define netconn_set_flags(conn, set_flags) do { (conn)->flags = (u8_t)((conn)->flags | (set_flags)); } while(0)
#define netconn_clear_flags(conn, clr_flags) do { (conn)->flags = (u8_t)((conn)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
#define netconn_is_flag_set(conn, flag) (((conn)->flags & (flag)) != 0)
/** Set the blocking status of netconn calls (@todo: write/send is missing) */
#define netconn_set_nonblocking(conn, val) do { if(val) { \
(conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \
netconn_set_flags(conn, NETCONN_FLAG_NON_BLOCKING); \
} else { \
(conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0)
netconn_clear_flags(conn, NETCONN_FLAG_NON_BLOCKING); }} while(0)
/** Get the blocking status of netconn calls (@todo: write/send is missing) */
#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0)
#if ESP_AUTO_RECV
/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */
#define netconn_set_noautorecved(conn, val) do { if(val) { \
(conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \
} else { \
(conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0)
/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */
#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0)
#endif
#if LWIP_IPV6
/** @ingroup netconn_common
* TCP: Set the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY)
*/
#define netconn_set_ipv6only(conn, val) do { if(val) { \
(conn)->flags |= NETCONN_FLAG_IPV6_V6ONLY; \
netconn_set_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); \
} else { \
(conn)->flags &= ~ NETCONN_FLAG_IPV6_V6ONLY; }} while(0)
netconn_clear_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); }} while(0)
/** @ingroup netconn_common
* TCP: Get the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY)
*/

View File

@ -0,0 +1,79 @@
/**
* @file
* Application layered TCP connection API that executes a proxy-connect.
*
* This file provides a starting layer that executes a proxy-connect e.g. to
* set up TLS connections through a http proxy.
*/
/*
* Copyright (c) 2018 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H
#define LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
struct altcp_proxyconnect_config {
ip_addr_t proxy_addr;
u16_t proxy_port;
};
struct altcp_pcb *altcp_proxyconnect_new(struct altcp_proxyconnect_config *config, struct altcp_pcb *inner_pcb);
struct altcp_pcb *altcp_proxyconnect_new_tcp(struct altcp_proxyconnect_config *config, u8_t ip_type);
struct altcp_pcb *altcp_proxyconnect_alloc(void *arg, u8_t ip_type);
#if LWIP_ALTCP_TLS
struct altcp_proxyconnect_tls_config {
struct altcp_proxyconnect_config proxy;
struct altcp_tls_config *tls_config;
};
struct altcp_pcb *altcp_proxyconnect_tls_alloc(void *arg, u8_t ip_type);
#endif /* LWIP_ALTCP_TLS */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H */

View File

@ -0,0 +1,105 @@
/**
* @file
* Application layered TCP/TLS connection API (to be used from TCPIP thread)
*
* This file contains options for an mbedtls port of the TLS layer.
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_TLS_OPTS_H
#define LWIP_HDR_ALTCP_TLS_OPTS_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
/** LWIP_ALTCP_TLS_MBEDTLS==1: use mbedTLS for TLS support for altcp API
* mbedtls include directory must be reachable via include search path
*/
#ifndef LWIP_ALTCP_TLS_MBEDTLS
#define LWIP_ALTCP_TLS_MBEDTLS 0
#endif
/** Configure debug level of this file */
#ifndef ALTCP_MBEDTLS_DEBUG
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_OFF
#endif
/** Configure lwIP debug level of the mbedTLS library */
#ifndef ALTCP_MBEDTLS_LIB_DEBUG
#define ALTCP_MBEDTLS_LIB_DEBUG LWIP_DBG_OFF
#endif
/** Configure minimum internal debug level of the mbedTLS library */
#ifndef ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN
#define ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN 0
#endif
/** Enable the basic session cache
* ATTENTION: Using a session cache can lower security by reusing keys!
*/
#ifndef ALTCP_MBEDTLS_USE_SESSION_CACHE
#define ALTCP_MBEDTLS_USE_SESSION_CACHE 0
#endif
/** Maximum cache size of the basic session cache */
#ifndef ALTCP_MBEDTLS_SESSION_CACHE_SIZE
#define ALTCP_MBEDTLS_SESSION_CACHE_SIZE 30
#endif
/** Set a session timeout in seconds for the basic session cache */
#ifndef ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS (60 * 60)
#endif
/** Use session tickets to speed up connection setup (needs
* MBEDTLS_SSL_SESSION_TICKETS enabled in mbedTLS config).
* ATTENTION: Using session tickets can lower security by reusing keys!
*/
#ifndef ALTCP_MBEDTLS_USE_SESSION_TICKETS
#define ALTCP_MBEDTLS_USE_SESSION_TICKETS 0
#endif
/** Session ticket cipher */
#ifndef ALTCP_MBEDTLS_SESSION_TICKET_CIPHER
#define ALTCP_MBEDTLS_SESSION_TICKET_CIPHER MBEDTLS_CIPHER_AES_256_GCM
#endif
/** Maximum timeout for session tickets */
#ifndef ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS
#define ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS (60 * 60 * 24)
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_TLS_OPTS_H */

View File

@ -52,12 +52,23 @@ struct fsdata_chksum {
#define FS_FILE_FLAGS_HEADER_INCLUDED 0x01
#define FS_FILE_FLAGS_HEADER_PERSISTENT 0x02
#define FS_FILE_FLAGS_HEADER_HTTPVER_1_1 0x04
#define FS_FILE_FLAGS_SSI 0x08
/** Define FS_FILE_EXTENSION_T_DEFINED if you have typedef'ed to your private
* pointer type (defaults to 'void' so the default usage is 'void*')
*/
#ifndef FS_FILE_EXTENSION_T_DEFINED
typedef void fs_file_extension;
#endif
struct fs_file {
const char *data;
int len;
int index;
void *pextension;
/* pextension is free for implementations to hold private (extensional)
arbitrary data, e.g. holding some file state or file system handle */
fs_file_extension *pextension;
#if HTTPD_PRECALCULATED_CHECKSUM
const struct fsdata_chksum *chksum;
u16_t chksum_count;
@ -96,6 +107,18 @@ void *fs_state_init(struct fs_file *file, const char *name);
void fs_state_free(struct fs_file *file, void *state);
#endif /* #if LWIP_HTTPD_FILE_STATE */
struct fsdata_file {
const struct fsdata_file *next;
const unsigned char *name;
const unsigned char *data;
int len;
u8_t flags;
#if HTTPD_PRECALCULATED_CHECKSUM
u16_t chksum_count;
const struct fsdata_chksum *chksum;
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
};
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,160 @@
/**
* @file
* HTTP client
*/
/*
* Copyright (c) 2018 Simon Goldschmidt <goldsimon@gmx.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_APPS_HTTP_CLIENT_H
#define LWIP_HDR_APPS_HTTP_CLIENT_H
#include "lwip/opt.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#include "lwip/altcp.h"
#include "lwip/prot/iana.h"
#include "lwip/pbuf.h"
#if LWIP_TCP && LWIP_CALLBACK_API
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup httpc
* HTTPC_HAVE_FILE_IO: define this to 1 to have functions dowloading directly
* to disk via fopen/fwrite.
* These functions are example implementations of the interface only.
*/
#ifndef LWIP_HTTPC_HAVE_FILE_IO
#define LWIP_HTTPC_HAVE_FILE_IO 0
#endif
/**
* @ingroup httpc
* The default TCP port used for HTTP
*/
#define HTTP_DEFAULT_PORT LWIP_IANA_PORT_HTTP
/**
* @ingroup httpc
* HTTP client result codes
*/
typedef enum ehttpc_result {
/** File successfully received */
HTTPC_RESULT_OK = 0,
/** Unknown error */
HTTPC_RESULT_ERR_UNKNOWN = 1,
/** Connection to server failed */
HTTPC_RESULT_ERR_CONNECT = 2,
/** Failed to resolve server hostname */
HTTPC_RESULT_ERR_HOSTNAME = 3,
/** Connection unexpectedly closed by remote server */
HTTPC_RESULT_ERR_CLOSED = 4,
/** Connection timed out (server didn't respond in time) */
HTTPC_RESULT_ERR_TIMEOUT = 5,
/** Server responded with an error code */
HTTPC_RESULT_ERR_SVR_RESP = 6,
/** Local memory error */
HTTPC_RESULT_ERR_MEM = 7,
/** Local abort */
HTTPC_RESULT_LOCAL_ABORT = 8,
/** Content length mismatch */
HTTPC_RESULT_ERR_CONTENT_LEN = 9
} httpc_result_t;
typedef struct _httpc_state httpc_state_t;
/**
* @ingroup httpc
* Prototype of a http client callback function
*
* @param arg argument specified when initiating the request
* @param httpc_result result of the http transfer (see enum httpc_result_t)
* @param rx_content_len number of bytes received (without headers)
* @param srv_res this contains the http status code received (if any)
* @param err an error returned by internal lwip functions, can help to specify
* the source of the error but must not necessarily be != ERR_OK
*/
typedef void (*httpc_result_fn)(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err);
/**
* @ingroup httpc
* Prototype of http client callback: called when the headers are received
*
* @param connection http client connection
* @param arg argument specified when initiating the request
* @param hdr header pbuf(s) (may contain data also)
* @param hdr_len length of the heders in 'hdr'
* @param content_len content length as received in the headers (-1 if not received)
* @return if != ERR_OK is returned, the connection is aborted
*/
typedef err_t (*httpc_headers_done_fn)(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len);
typedef struct _httpc_connection {
ip_addr_t proxy_addr;
u16_t proxy_port;
u8_t use_proxy;
/* @todo: add username:pass? */
#if LWIP_ALTCP
altcp_allocator_t *altcp_allocator;
#endif
/* this callback is called when the transfer is finished (or aborted) */
httpc_result_fn result_fn;
/* this callback is called after receiving the http headers
It can abort the connection by returning != ERR_OK */
httpc_headers_done_fn headers_done_fn;
} httpc_connection_t;
err_t httpc_get_file(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings,
altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection);
err_t httpc_get_file_dns(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings,
altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection);
#if LWIP_HTTPC_HAVE_FILE_IO
err_t httpc_get_file_to_disk(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings,
void* callback_arg, const char* local_file_name, httpc_state_t **connection);
err_t httpc_get_file_dns_to_disk(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings,
void* callback_arg, const char* local_file_name, httpc_state_t **connection);
#endif /* LWIP_HTTPC_HAVE_FILE_IO */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_TCP && LWIP_CALLBACK_API */
#endif /* LWIP_HDR_APPS_HTTP_CLIENT_H */

View File

@ -51,13 +51,14 @@ extern "C" {
#if LWIP_HTTPD_CGI
/*
/**
* @ingroup httpd
* Function pointer for a CGI script handler.
*
* This function is called each time the HTTPD server is asked for a file
* whose name was previously registered as a CGI function using a call to
* http_set_cgi_handler. The iIndex parameter provides the index of the
* CGI within the ppcURLs array passed to http_set_cgi_handler. Parameters
* http_set_cgi_handlers. The iIndex parameter provides the index of the
* CGI within the cgis array passed to http_set_cgi_handlers. Parameters
* pcParam and pcValue provide access to the parameters provided along with
* the URI. iNumParams provides a count of the entries in the pcParam and
* pcValue arrays. Each entry in the pcParam array contains the name of a
@ -71,8 +72,8 @@ extern "C" {
* browser, for example "/thanks.htm" or "/response/error.ssi".
*
* The maximum number of parameters that will be passed to this function via
* iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in the incoming
* HTTP request above this number will be discarded.
* iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in
* the incoming HTTP request above this number will be discarded.
*
* Requests intended for use by this CGI mechanism must be sent using the GET
* method (which encodes all parameters within the URI rather than in a block
@ -83,7 +84,8 @@ extern "C" {
typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[],
char *pcValue[]);
/*
/**
* @ingroup httpd
* Structure defining the base filename (URL) of a CGI and the associated
* function which is to be called when that URL is requested.
*/
@ -100,11 +102,17 @@ void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers);
#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI
#if LWIP_HTTPD_CGI_SSI
/* we have to prototype this struct here to make it available for the handler */
struct fs_file;
/** Define this generic CGI handler in your application.
* It is called once for every URI with parameters.
* The parameters can be stored to
* The parameters can be stored to the object passed as connection_state, which
* is allocated to file->state via fs_state_init() from fs_open() or fs_open_custom().
* Content creation via SSI or complete dynamic files can retrieve the CGI params from there.
*/
extern void httpd_cgi_handler(const char* uri, int iNumParams, char **pcParam, char **pcValue
extern void httpd_cgi_handler(struct fs_file *file, const char* uri, int iNumParams,
char **pcParam, char **pcValue
#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
, void *connection_state
#endif /* LWIP_HTTPD_FILE_STATE */
@ -115,34 +123,35 @@ extern void httpd_cgi_handler(const char* uri, int iNumParams, char **pcParam, c
#if LWIP_HTTPD_SSI
/*
/**
* @ingroup httpd
* Function pointer for the SSI tag handler callback.
*
* This function will be called each time the HTTPD server detects a tag of the
* form <!--#name--> in a .shtml, .ssi or .shtm file where "name" appears as
* one of the tags supplied to http_set_ssi_handler in the ppcTags array. The
* form <!--#name--> in files with extensions mentioned in the g_pcSSIExtensions
* array (currently .shtml, .shtm, .ssi, .xml, .json) where "name" appears as
* one of the tags supplied to http_set_ssi_handler in the tags array. The
* returned insert string, which will be appended after the the string
* "<!--#name-->" in file sent back to the client,should be written to pointer
* pcInsert. iInsertLen contains the size of the buffer pointed to by
* pcInsert. The iIndex parameter provides the zero-based index of the tag as
* found in the ppcTags array and identifies the tag that is to be processed.
* "<!--#name-->" in file sent back to the client, should be written to pointer
* pcInsert. iInsertLen contains the size of the buffer pointed to by
* pcInsert. The iIndex parameter provides the zero-based index of the tag as
* found in the tags array and identifies the tag that is to be processed.
*
* The handler returns the number of characters written to pcInsert excluding
* any terminating NULL or a negative number to indicate a failure (tag not
* recognized, for example).
* any terminating NULL or HTTPD_SSI_TAG_UNKNOWN when tag is not recognized.
*
* Note that the behavior of this SSI mechanism is somewhat different from the
* "normal" SSI processing as found in, for example, the Apache web server. In
* this case, the inserted text is appended following the SSI tag rather than
* replacing the tag entirely. This allows for an implementation that does not
* require significant additional buffering of output data yet which will still
* offer usable SSI functionality. One downside to this approach is when
* offer usable SSI functionality. One downside to this approach is when
* attempting to use SSI within JavaScript. The SSI tag is structured to
* resemble an HTML comment but this syntax does not constitute a comment
* within JavaScript and, hence, leaving the tag in place will result in
* problems in these cases. To work around this, any SSI tag which needs to
* output JavaScript code must do so in an encapsulated way, sending the whole
* HTML <script>...</script> section as a single include.
* problems in these cases. In order to avoid these problems, define
* LWIP_HTTPD_SSI_INCLUDE_TAG as zero in your lwip options file, or use JavaScript
* style block comments in the form / * # name * / (without the spaces).
*/
typedef u16_t (*tSSIHandler)(
#if LWIP_HTTPD_SSI_RAW
@ -177,7 +186,9 @@ void http_set_ssi_handler(tSSIHandler pfnSSIHandler,
/* These functions must be implemented by the application */
/** Called when a POST request has been received. The application can decide
/**
* @ingroup httpd
* Called when a POST request has been received. The application can decide
* whether to accept it or not.
*
* @param connection Unique connection identifier, valid until httpd_post_end
@ -199,7 +210,9 @@ err_t httpd_post_begin(void *connection, const char *uri, const char *http_reque
u16_t http_request_len, int content_len, char *response_uri,
u16_t response_uri_len, u8_t *post_auto_wnd);
/** Called for each pbuf of data that has been received for a POST.
/**
* @ingroup httpd
* Called for each pbuf of data that has been received for a POST.
* ATTENTION: The application is responsible for freeing the pbufs passed in!
*
* @param connection Unique connection identifier.
@ -209,7 +222,9 @@ err_t httpd_post_begin(void *connection, const char *uri, const char *http_reque
*/
err_t httpd_post_receive_data(void *connection, struct pbuf *p);
/** Called when all data is received or when the connection is closed.
/**
* @ingroup httpd
* Called when all data is received or when the connection is closed.
* The application must return the filename/URI of a file to send in response
* to this POST request. If the response_uri buffer is untouched, a 404
* response is returned.
@ -228,9 +243,13 @@ void httpd_post_data_recved(void *connection, u16_t recved_len);
void httpd_init(void);
#if HTTPD_ENABLE_HTTPS
struct altcp_tls_config;
void httpd_inits(struct altcp_tls_config *conf);
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HTTPD_H */
#endif /* LWIP_HDR_APPS_HTTPD_H */

View File

@ -42,6 +42,7 @@
#define LWIP_HDR_APPS_HTTPD_OPTS_H
#include "lwip/opt.h"
#include "lwip/prot/iana.h"
/**
* @defgroup httpd_opts Options
@ -49,27 +50,77 @@
* @{
*/
/** Set this to 1 to support CGI (old style) */
/** Set this to 1 to support CGI (old style).
*
* This old style CGI support works by registering an array of URLs and
* associated CGI handler functions (@ref http_set_cgi_handlers).
* This list is scanned just before fs_open is called from request handling.
* The handler can return a new URL that is used internally by the httpd to
* load the returned page (passed to fs_open).
*
* Use this CGI type e.g. to execute specific actions and return a page that
* does not depend on the CGI parameters.
*/
#if !defined LWIP_HTTPD_CGI || defined __DOXYGEN__
#define LWIP_HTTPD_CGI 0
#endif
/** Set this to 1 to support CGI (new style) */
/** Set this to 1 to support CGI (new style).
*
* This new style CGI support works by calling a global function
* (@ref tCGIHandler) for all URLs that are found. fs_open is called first
* and the URL can not be written by the CGI handler. Instead, this handler gets
* passed the http file state, an object where it can store information derived
* from the CGI URL or parameters. This file state is later passed to SSI, so
* the SSI code can return data depending on CGI input.
*
* Use this CGI handler if you want CGI information passed on to SSI.
*/
#if !defined LWIP_HTTPD_CGI_SSI || defined __DOXYGEN__
#define LWIP_HTTPD_CGI_SSI 0
#endif
/** Set this to 1 to support SSI (Server-Side-Includes) */
/** Set this to 1 to support SSI (Server-Side-Includes)
*
* In contrast to other http servers, this only calls a preregistered callback
* function (@see http_set_ssi_handler) for each tag (in the format of
* <!--#tag-->) encountered in SSI-enabled pages.
* SSI-enabled pages must have one of the predefined SSI-enabled file extensions.
* All files with one of these extensions are parsed when sent.
*
* A downside of the current SSI implementation is that persistent connections
* don't work, as the file length is not known in advance (and httpd currently
* relies on the Content-Length header for persistent connections).
*
* To save memory, the maximum tag length is limited (@see LWIP_HTTPD_MAX_TAG_NAME_LEN).
* To save memory, the maximum insertion string length is limited (@see
* LWIP_HTTPD_MAX_TAG_INSERT_LEN). If this is not enought, @ref LWIP_HTTPD_SSI_MULTIPART
* can be used.
*/
#if !defined LWIP_HTTPD_SSI || defined __DOXYGEN__
#define LWIP_HTTPD_SSI 0
#endif
/** Set this to 1 to implement an SSI tag handler callback that gets a const char*
* to the tag (instead of an index into a pre-registered array of known tags) */
* to the tag (instead of an index into a pre-registered array of known tags)
* If this is 0, the SSI handler callback function is only called pre-registered tags.
*/
#if !defined LWIP_HTTPD_SSI_RAW || defined __DOXYGEN__
#define LWIP_HTTPD_SSI_RAW 0
#endif
/** Set this to 0 to prevent parsing the file extension at runtime to decide
* if a file should be scanned for SSI tags or not.
* Default is 1 (file extensions are checked using the g_pcSSIExtensions array)
* Set to 2 to override this runtime test function.
*
* This is enabled by default, but if you only use a newer version of makefsdata
* supporting the "-ssi" option, this info is already present in
*/
#if !defined LWIP_HTTPD_SSI_BY_FILE_EXTENSION || defined __DOXYGEN__
#define LWIP_HTTPD_SSI_BY_FILE_EXTENSION 1
#endif
/** Set this to 1 to support HTTP POST */
#if !defined LWIP_HTTPD_SUPPORT_POST || defined __DOXYGEN__
#define LWIP_HTTPD_SUPPORT_POST 0
@ -88,12 +139,16 @@
#define LWIP_HTTPD_SSI_MULTIPART 0
#endif
/* The maximum length of the string comprising the tag name */
/* The maximum length of the string comprising the SSI tag name
* ATTENTION: tags longer than this are ignored, not truncated!
*/
#if !defined LWIP_HTTPD_MAX_TAG_NAME_LEN || defined __DOXYGEN__
#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8
#endif
/* The maximum length of string that can be returned to replace any given tag */
/* The maximum length of string that can be returned to replace any given tag
* If this buffer is not long enough, use LWIP_HTTPD_SSI_MULTIPART.
*/
#if !defined LWIP_HTTPD_MAX_TAG_INSERT_LEN || defined __DOXYGEN__
#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192
#endif
@ -122,6 +177,9 @@
/** Set this to 1 to use a memp pool for allocating
* struct http_state instead of the heap.
* If enabled, you'll need to define MEMP_NUM_PARALLEL_HTTPD_CONNS
* (and MEMP_NUM_PARALLEL_HTTPD_SSI_CONNS for SSI) to set the size of
* the pool(s).
*/
#if !defined HTTPD_USE_MEM_POOL || defined __DOXYGEN__
#define HTTPD_USE_MEM_POOL 0
@ -129,7 +187,17 @@
/** The server port for HTTPD to use */
#if !defined HTTPD_SERVER_PORT || defined __DOXYGEN__
#define HTTPD_SERVER_PORT 80
#define HTTPD_SERVER_PORT LWIP_IANA_PORT_HTTP
#endif
/** The https server port for HTTPD to use */
#if !defined HTTPD_SERVER_PORT_HTTPS || defined __DOXYGEN__
#define HTTPD_SERVER_PORT_HTTPS LWIP_IANA_PORT_HTTPS
#endif
/** Enable https support? */
#if !defined HTTPD_ENABLE_HTTPS || defined __DOXYGEN__
#define HTTPD_ENABLE_HTTPS 0
#endif
/** Maximum retries before the connection is aborted/closed.
@ -261,10 +329,11 @@
#endif
/* Define this to a function that returns the maximum amount of data to enqueue.
The function have this signature: u16_t fn(struct tcp_pcb* pcb); */
The function have this signature: u16_t fn(struct altcp_pcb* pcb);
The best place to define this is the hooks file (@see LWIP_HOOK_FILENAME) */
#if !defined HTTPD_MAX_WRITE_LEN || defined __DOXYGEN__
#if HTTPD_LIMIT_SENDING_TO_2MSS
#define HTTPD_MAX_WRITE_LEN(pcb) (2 * tcp_mss(pcb))
#define HTTPD_MAX_WRITE_LEN(pcb) ((u16_t)(2 * altcp_mss(pcb)))
#endif
#endif
@ -310,10 +379,14 @@
#define LWIP_HTTPD_FS_ASYNC_READ 0
#endif
/** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the
* file system (to prevent changing the file included in CVS) */
#if !defined HTTPD_USE_CUSTOM_FSDATA || defined __DOXYGEN__
#define HTTPD_USE_CUSTOM_FSDATA 0
/** Filename (including path) to use as FS data file */
#if !defined HTTPD_FSDATA_FILE || defined __DOXYGEN__
/* HTTPD_USE_CUSTOM_FSDATA: Compatibility with deprecated lwIP option */
#if defined(HTTPD_USE_CUSTOM_FSDATA) && (HTTPD_USE_CUSTOM_FSDATA != 0)
#define HTTPD_FSDATA_FILE "fsdata_custom.c"
#else
#define HTTPD_FSDATA_FILE "fsdata.c"
#endif
#endif
/**

View File

@ -63,6 +63,17 @@ enum lwiperf_report_type
LWIPERF_TCP_ABORTED_REMOTE
};
/** Control */
enum lwiperf_client_type
{
/** Unidirectional tx only test */
LWIPERF_CLIENT,
/** Do a bidirectional test simultaneously */
LWIPERF_DUAL,
/** Do a bidirectional test individually */
LWIPERF_TRADEOFF
};
/** Prototype of a report function that is called when a session is finished.
This report function can show the test results.
@param report_type contains the test result */
@ -70,10 +81,15 @@ typedef void (*lwiperf_report_fn)(void *arg, enum lwiperf_report_type report_typ
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec);
void* lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port,
lwiperf_report_fn report_fn, void* report_arg);
void* lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg);
void* lwiperf_start_tcp_client(const ip_addr_t* remote_addr, u16_t remote_port,
enum lwiperf_client_type type,
lwiperf_report_fn report_fn, void* report_arg);
void* lwiperf_start_tcp_client_default(const ip_addr_t* remote_addr,
lwiperf_report_fn report_fn, void* report_arg);
void lwiperf_abort(void* lwiperf_session);

View File

@ -34,12 +34,17 @@
* Author: Erik Ekman <erik@kryo.se>
*
*/
#ifndef LWIP_HDR_MDNS_H
#define LWIP_HDR_MDNS_H
#ifndef LWIP_HDR_APPS_MDNS_H
#define LWIP_HDR_APPS_MDNS_H
#include "lwip/apps/mdns_opts.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_MDNS_RESPONDER
enum mdns_sd_proto {
@ -47,6 +52,9 @@ enum mdns_sd_proto {
DNSSD_PROTO_TCP = 1
};
#define MDNS_PROBING_CONFLICT 0
#define MDNS_PROBING_SUCCESSFUL 1
#define MDNS_LABEL_MAXLEN 63
struct mdns_host;
@ -55,15 +63,43 @@ struct mdns_service;
/** Callback function to add text to a reply, called when generating the reply */
typedef void (*service_get_txt_fn_t)(struct mdns_service *service, void *txt_userdata);
/** Callback function to let application know the result of probing network for name
* uniqueness, called with result MDNS_PROBING_SUCCESSFUL if no other node claimed
* use for the name for the netif or a service and is safe to use, or MDNS_PROBING_CONFLICT
* if another node is already using it and mdns is disabled on this interface */
typedef void (*mdns_name_result_cb_t)(struct netif* netif, u8_t result);
void mdns_resp_init(void);
void mdns_resp_register_name_result_cb(mdns_name_result_cb_t cb);
err_t mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl);
err_t mdns_resp_remove_netif(struct netif *netif);
err_t mdns_resp_rename_netif(struct netif *netif, const char *hostname);
s8_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_userdata);
err_t mdns_resp_del_service(struct netif *netif, s8_t slot);
err_t mdns_resp_rename_service(struct netif *netif, s8_t slot, const char *name);
err_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_userdata);
err_t mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len);
void mdns_resp_netif_settings_changed(struct netif *netif);
void mdns_resp_restart(struct netif *netif);
void mdns_resp_announce(struct netif *netif);
/**
* @ingroup mdns
* Announce IP settings have changed on netif.
* Call this in your callback registered by netif_set_status_callback().
* No need to call this function when LWIP_NETIF_EXT_STATUS_CALLBACK==1,
* this handled automatically for you.
* @param netif The network interface where settings have changed.
*/
#define mdns_resp_netif_settings_changed(netif) mdns_resp_announce(netif)
#endif /* LWIP_MDNS_RESPONDER */
#endif /* LWIP_HDR_MDNS_H */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_MDNS_H */

View File

@ -59,6 +59,13 @@
#define MDNS_MAX_SERVICES 1
#endif
/** MDNS_RESP_USENETIF_EXTCALLBACK==1: register an ext_callback on the netif
* to automatically restart probing/announcing on status or address change.
*/
#ifndef MDNS_RESP_USENETIF_EXTCALLBACK
#define MDNS_RESP_USENETIF_EXTCALLBACK LWIP_NETIF_EXT_STATUS_CALLBACK
#endif
/**
* MDNS_DEBUG: Enable debugging for multicast DNS.
*/

View File

@ -40,6 +40,10 @@
#include "lwip/apps/mdns_opts.h"
#include "lwip/pbuf.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_MDNS_RESPONDER
/* Domain struct and methods - visible for unit tests */
@ -63,4 +67,8 @@ u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain
#endif /* LWIP_MDNS_RESPONDER */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_MDNS_PRIV_H */

View File

@ -40,16 +40,24 @@
#include "lwip/apps/mqtt_opts.h"
#include "lwip/err.h"
#include "lwip/ip_addr.h"
#include "lwip/prot/iana.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct mqtt_client_t mqtt_client_t;
typedef struct mqtt_client_s mqtt_client_t;
#if LWIP_ALTCP && LWIP_ALTCP_TLS
struct altcp_tls_config;
#endif
/** @ingroup mqtt
* Default MQTT port */
#define MQTT_PORT 1883
* Default MQTT port (non-TLS) */
#define MQTT_PORT LWIP_IANA_PORT_MQTT
/** @ingroup mqtt
* Default MQTT TLS port */
#define MQTT_TLS_PORT LWIP_IANA_PORT_SECURE_MQTT
/*---------------------------------------------------------------------------------------------- */
/* Connection with server */
@ -60,17 +68,25 @@ typedef struct mqtt_client_t mqtt_client_t;
struct mqtt_connect_client_info_t {
/** Client identifier, must be set by caller */
const char *client_id;
/** User name and password, set to NULL if not used */
/** User name, set to NULL if not used */
const char* client_user;
/** Password, set to NULL if not used */
const char* client_pass;
/** keep alive time in seconds, 0 to disable keep alive functionality*/
u16_t keep_alive;
/** will topic, set to NULL if will is not to be used,
will_msg, will_qos and will retain are then ignored */
const char* will_topic;
/** will_msg, see will_topic */
const char* will_msg;
/** will_qos, see will_topic */
u8_t will_qos;
/** will_retain, see will_topic */
u8_t will_retain;
#if LWIP_ALTCP && LWIP_ALTCP_TLS
/** TLS configuration for secure connections */
struct altcp_tls_config *tls_config;
#endif
};
/**
@ -78,13 +94,21 @@ struct mqtt_connect_client_info_t {
* Connection status codes */
typedef enum
{
/** Accepted */
MQTT_CONNECT_ACCEPTED = 0,
/** Refused protocol version */
MQTT_CONNECT_REFUSED_PROTOCOL_VERSION = 1,
/** Refused identifier */
MQTT_CONNECT_REFUSED_IDENTIFIER = 2,
/** Refused server */
MQTT_CONNECT_REFUSED_SERVER = 3,
/** Refused user credentials */
MQTT_CONNECT_REFUSED_USERNAME_PASS = 4,
/** Refused not authorized */
MQTT_CONNECT_REFUSED_NOT_AUTHORIZED_ = 5,
/** Disconnected */
MQTT_CONNECT_DISCONNECTED = 256,
/** Timeout */
MQTT_CONNECT_TIMEOUT = 257
} mqtt_connection_status_t;
@ -92,7 +116,7 @@ typedef enum
* @ingroup mqtt
* Function prototype for mqtt connection status callback. Called when
* client has connected to the server after initiating a mqtt connection attempt by
* calling mqtt_connect() or when connection is closed by server or an error
* calling mqtt_client_connect() or when connection is closed by server or an error
*
* @param client MQTT client itself
* @param arg Additional argument to pass to the callback function
@ -149,80 +173,19 @@ typedef void (*mqtt_incoming_publish_cb_t)(void *arg, const char *topic, u32_t t
typedef void (*mqtt_request_cb_t)(void *arg, err_t err);
/**
* Pending request item, binds application callback to pending server requests
*/
struct mqtt_request_t
{
/** Next item in list, NULL means this is the last in chain,
next pointing at itself means request is unallocated */
struct mqtt_request_t *next;
/** Callback to upper layer */
mqtt_request_cb_t cb;
void *arg;
/** MQTT packet identifier */
u16_t pkt_id;
/** Expire time relative to element before this */
u16_t timeout_diff;
};
/** Ring buffer */
struct mqtt_ringbuf_t {
u16_t put;
u16_t get;
u8_t buf[MQTT_OUTPUT_RINGBUF_SIZE];
};
/** MQTT client */
struct mqtt_client_t
{
/** Timers and timeouts */
u16_t cyclic_tick;
u16_t keep_alive;
u16_t server_watchdog;
/** Packet identifier generator*/
u16_t pkt_id_seq;
/** Packet identifier of pending incoming publish */
u16_t inpub_pkt_id;
/** Connection state */
u8_t conn_state;
struct tcp_pcb *conn;
/** Connection callback */
void *connect_arg;
mqtt_connection_cb_t connect_cb;
/** Pending requests to server */
struct mqtt_request_t *pend_req_queue;
struct mqtt_request_t req_list[MQTT_REQ_MAX_IN_FLIGHT];
void *inpub_arg;
/** Incoming data callback */
mqtt_incoming_data_cb_t data_cb;
mqtt_incoming_publish_cb_t pub_cb;
/** Input */
u32_t msg_idx;
u8_t rx_buffer[MQTT_VAR_HEADER_BUFFER_LEN];
/** Output ring-buffer */
struct mqtt_ringbuf_t output;
};
/** Connect to server */
err_t mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ipaddr, u16_t port, mqtt_connection_cb_t cb, void *arg,
const struct mqtt_connect_client_info_t *client_info);
/** Disconnect from server */
void mqtt_disconnect(mqtt_client_t *client);
/** Create new client */
mqtt_client_t *mqtt_client_new(void);
void mqtt_client_free(mqtt_client_t* client);
/** Check connection status */
u8_t mqtt_client_is_connected(mqtt_client_t *client);
/** Set callback to call for incoming publish */
void mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t,
mqtt_incoming_data_cb_t data_cb, void *arg);
/** Common function for subscribe and unsubscribe */
err_t mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub);
/** @ingroup mqtt
@ -232,8 +195,6 @@ err_t mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_re
* Unsubscribe to topic */
#define mqtt_unsubscribe(client, topic, cb, arg) mqtt_sub_unsub(client, topic, 0, cb, arg, 0)
/** Publish data to topic */
err_t mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain,
mqtt_request_cb_t cb, void *arg);

View File

@ -39,7 +39,7 @@
#include "lwip/opt.h"
#ifdef __cplusplus
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -0,0 +1,104 @@
/**
* @file
* MQTT client (private interface)
*/
/*
* Copyright (c) 2016 Erik Andersson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Erik Andersson
*
*/
#ifndef LWIP_HDR_APPS_MQTT_PRIV_H
#define LWIP_HDR_APPS_MQTT_PRIV_H
#include "lwip/apps/mqtt.h"
#include "lwip/altcp.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Pending request item, binds application callback to pending server requests */
struct mqtt_request_t
{
/** Next item in list, NULL means this is the last in chain,
next pointing at itself means request is unallocated */
struct mqtt_request_t *next;
/** Callback to upper layer */
mqtt_request_cb_t cb;
void *arg;
/** MQTT packet identifier */
u16_t pkt_id;
/** Expire time relative to element before this */
u16_t timeout_diff;
};
/** Ring buffer */
struct mqtt_ringbuf_t {
u16_t put;
u16_t get;
u8_t buf[MQTT_OUTPUT_RINGBUF_SIZE];
};
/** MQTT client */
struct mqtt_client_s
{
/** Timers and timeouts */
u16_t cyclic_tick;
u16_t keep_alive;
u16_t server_watchdog;
/** Packet identifier generator*/
u16_t pkt_id_seq;
/** Packet identifier of pending incoming publish */
u16_t inpub_pkt_id;
/** Connection state */
u8_t conn_state;
struct altcp_pcb *conn;
/** Connection callback */
void *connect_arg;
mqtt_connection_cb_t connect_cb;
/** Pending requests to server */
struct mqtt_request_t *pend_req_queue;
struct mqtt_request_t req_list[MQTT_REQ_MAX_IN_FLIGHT];
void *inpub_arg;
/** Incoming data callback */
mqtt_incoming_data_cb_t data_cb;
mqtt_incoming_publish_cb_t pub_cb;
/** Input */
u32_t msg_idx;
u8_t rx_buffer[MQTT_VAR_HEADER_BUFFER_LEN];
/** Output ring-buffer */
struct mqtt_ringbuf_t output;
};
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_MQTT_PRIV_H */

View File

@ -34,10 +34,18 @@
#include "lwip/apps/netbiosns_opts.h"
#ifdef __cplusplus
extern "C" {
#endif
void netbiosns_init(void);
#ifndef NETBIOS_LWIP_NAME
void netbiosns_set_name(const char* hostname);
#endif
void netbiosns_stop(void);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_NETBIOS_H */

View File

@ -52,6 +52,13 @@
#define NETBIOS_LWIP_NAME "NETBIOSLWIPDEV"
#endif
/** Respond to NetBIOS name queries
* Default is disabled
*/
#if !defined LWIP_NETBIOS_RESPOND_NAME_QUERY || defined __DOXYGEN__
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 0
#endif
/**
* @}
*/

View File

@ -0,0 +1,128 @@
#ifndef LWIP_HDR_APPS_SMTP_H
#define LWIP_HDR_APPS_SMTP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "lwip/apps/smtp_opts.h"
#include "lwip/err.h"
#include "lwip/prot/iana.h"
/** The default TCP port used for SMTP */
#define SMTP_DEFAULT_PORT LWIP_IANA_PORT_SMTP
/** The default TCP port used for SMTPS */
#define SMTPS_DEFAULT_PORT LWIP_IANA_PORT_SMTPS
/** Email successfully sent */
#define SMTP_RESULT_OK 0
/** Unknown error */
#define SMTP_RESULT_ERR_UNKNOWN 1
/** Connection to server failed */
#define SMTP_RESULT_ERR_CONNECT 2
/** Failed to resolve server hostname */
#define SMTP_RESULT_ERR_HOSTNAME 3
/** Connection unexpectedly closed by remote server */
#define SMTP_RESULT_ERR_CLOSED 4
/** Connection timed out (server didn't respond in time) */
#define SMTP_RESULT_ERR_TIMEOUT 5
/** Server responded with an unknown response code */
#define SMTP_RESULT_ERR_SVR_RESP 6
/** Out of resources locally */
#define SMTP_RESULT_ERR_MEM 7
/** Prototype of an smtp callback function
*
* @param arg argument specified when initiating the email
* @param smtp_result result of the mail transfer (see defines SMTP_RESULT_*)
* @param srv_err if aborted by the server, this contains the error code received
* @param err an error returned by internal lwip functions, can help to specify
* the source of the error but must not necessarily be != ERR_OK
*/
typedef void (*smtp_result_fn)(void *arg, u8_t smtp_result, u16_t srv_err, err_t err);
/** This structure is used as argument for smtp_send_mail_int(),
* which in turn can be used with tcpip_callback() to send mail
* from interrupt context, e.g. like this:
* struct smtp_send_request *req; (to be filled)
* tcpip_try_callback(smtp_send_mail_int, (void*)req);
*
* For member description, see parameter description of smtp_send_mail().
* When using with tcpip_callback, this structure has to stay allocated
* (e.g. using mem_malloc/mem_free) until its 'callback_fn' is called.
*/
struct smtp_send_request {
const char *from;
const char* to;
const char* subject;
const char* body;
smtp_result_fn callback_fn;
void* callback_arg;
/** If this is != 0, data is *not* copied into an extra buffer
* but used from the pointers supplied in this struct.
* This means less memory usage, but data must stay untouched until
* the callback function is called. */
u8_t static_data;
};
#if SMTP_BODYDH
#ifndef SMTP_BODYDH_BUFFER_SIZE
#define SMTP_BODYDH_BUFFER_SIZE 256
#endif /* SMTP_BODYDH_BUFFER_SIZE */
struct smtp_bodydh {
u16_t state;
u16_t length; /* Length of content in buffer */
char buffer[SMTP_BODYDH_BUFFER_SIZE]; /* buffer for generated content */
#ifdef SMTP_BODYDH_USER_SIZE
u8_t user[SMTP_BODYDH_USER_SIZE];
#endif /* SMTP_BODYDH_USER_SIZE */
};
enum bdh_retvals_e {
BDH_DONE = 0,
BDH_WORKING
};
/** Prototype of an smtp body callback function
* It receives a struct smtp_bodydh, and a buffer to write data,
* must return BDH_WORKING to be called again and BDH_DONE when
* it has finished processing. This one tries to fill one TCP buffer with
* data, your function will be repeatedly called until that happens; so if you
* know you'll be taking too long to serve your request, pause once in a while
* by writing length=0 to avoid hogging system resources
*
* @param arg argument specified when initiating the email
* @param smtp_bodydh state handling + buffer structure
*/
typedef int (*smtp_bodycback_fn)(void *arg, struct smtp_bodydh *bodydh);
err_t smtp_send_mail_bodycback(const char *from, const char* to, const char* subject,
smtp_bodycback_fn bodycback_fn, smtp_result_fn callback_fn, void* callback_arg);
#endif /* SMTP_BODYDH */
err_t smtp_set_server_addr(const char* server);
void smtp_set_server_port(u16_t port);
#if LWIP_ALTCP && LWIP_ALTCP_TLS
struct altcp_tls_config;
void smtp_set_tls_config(struct altcp_tls_config *tls_config);
#endif
err_t smtp_set_auth(const char* username, const char* pass);
err_t smtp_send_mail(const char *from, const char* to, const char* subject, const char* body,
smtp_result_fn callback_fn, void* callback_arg);
err_t smtp_send_mail_static(const char *from, const char* to, const char* subject, const char* body,
smtp_result_fn callback_fn, void* callback_arg);
void smtp_send_mail_int(void *arg);
#ifdef LWIP_DEBUG
const char* smtp_result_str(u8_t smtp_result);
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SMTP_H */

View File

@ -0,0 +1,81 @@
#ifndef LWIP_HDR_APPS_SMTP_OPTS_H
#define LWIP_HDR_APPS_SMTP_OPTS_H
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup smtp_opts Options
* @ingroup smtp
*
* @{
*/
/** Set this to 1 to enable data handler callback on BODY */
#ifndef SMTP_BODYDH
#define SMTP_BODYDH 0
#endif
/** SMTP_DEBUG: Enable debugging for SNTP. */
#ifndef SMTP_DEBUG
#define SMTP_DEBUG LWIP_DBG_OFF
#endif
/** Maximum length reserved for server name including terminating 0 byte */
#ifndef SMTP_MAX_SERVERNAME_LEN
#define SMTP_MAX_SERVERNAME_LEN 256
#endif
/** Maximum length reserved for username */
#ifndef SMTP_MAX_USERNAME_LEN
#define SMTP_MAX_USERNAME_LEN 32
#endif
/** Maximum length reserved for password */
#ifndef SMTP_MAX_PASS_LEN
#define SMTP_MAX_PASS_LEN 32
#endif
/** Set this to 0 if you know the authentication data will not change
* during the smtp session, which saves some heap space. */
#ifndef SMTP_COPY_AUTHDATA
#define SMTP_COPY_AUTHDATA 1
#endif
/** Set this to 0 to save some code space if you know for sure that all data
* passed to this module conforms to the requirements in the SMTP RFC.
* WARNING: use this with care!
*/
#ifndef SMTP_CHECK_DATA
#define SMTP_CHECK_DATA 1
#endif
/** Set this to 1 to enable AUTH PLAIN support */
#ifndef SMTP_SUPPORT_AUTH_PLAIN
#define SMTP_SUPPORT_AUTH_PLAIN 1
#endif
/** Set this to 1 to enable AUTH LOGIN support */
#ifndef SMTP_SUPPORT_AUTH_LOGIN
#define SMTP_SUPPORT_AUTH_LOGIN 1
#endif
/* Memory allocation/deallocation can be overridden... */
#ifndef SMTP_STATE_MALLOC
#define SMTP_STATE_MALLOC(size) mem_malloc(size)
#define SMTP_STATE_FREE(ptr) mem_free(ptr)
#endif
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* SMTP_OPTS_H */

View File

@ -106,6 +106,13 @@ err_t snmp_send_trap(const struct snmp_obj_id* oid, s32_t generic_trap, s32_t sp
void snmp_set_auth_traps_enabled(u8_t enable);
u8_t snmp_get_auth_traps_enabled(void);
u8_t snmp_v1_enabled(void);
u8_t snmp_v2c_enabled(void);
u8_t snmp_v3_enabled(void);
void snmp_v1_enable(u8_t enable);
void snmp_v2c_enable(u8_t enable);
void snmp_v3_enable(u8_t enable);
const char * snmp_get_community(void);
const char * snmp_get_community_write(void);
const char * snmp_get_community_trap(void);

View File

@ -91,7 +91,9 @@ extern "C" {
#define SNMP_ASN1_TYPE_UNSIGNED32 SNMP_ASN1_TYPE_GAUGE
#define SNMP_ASN1_TYPE_TIMETICKS (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_TIMETICKS)
#define SNMP_ASN1_TYPE_OPAQUE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_OPAQUE)
#if LWIP_HAVE_INT64
#define SNMP_ASN1_TYPE_COUNTER64 (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER64)
#endif
#define SNMP_VARBIND_EXCEPTION_OFFSET 0xF0
#define SNMP_VARBIND_EXCEPTION_MASK 0x0F
@ -144,6 +146,9 @@ union snmp_variant_value
const void* const_ptr;
u32_t u32;
s32_t s32;
#if LWIP_HAVE_INT64
u64_t u64;
#endif
};
@ -186,7 +191,7 @@ typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*,
typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*);
typedef void (*node_instance_release_method)(struct snmp_node_instance*);
#define SNMP_GET_VALUE_RAW_DATA 0x8000
#define SNMP_GET_VALUE_RAW_DATA 0x4000 /* do not use 0x8000 because return value of node_instance_get_value_method is signed16 and 0x8000 would be the signed bit */
/** SNMP node instance */
struct snmp_node_instance
@ -286,8 +291,8 @@ struct snmp_next_oid_state
void snmp_next_oid_init(struct snmp_next_oid_state *state,
const u32_t *start_oid, u8_t start_oid_len,
u32_t *next_oid_buf, u8_t next_oid_max_len);
u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len);
u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len, void* reference);
u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len);
u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len, void* reference);
void snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
void snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
@ -351,6 +356,14 @@ struct snmp_statistics
u32_t outsetrequests;
u32_t outgetresponses;
u32_t outtraps;
#if LWIP_SNMP_V3
u32_t unsupportedseclevels;
u32_t notintimewindows;
u32_t unknownusernames;
u32_t unknownengineids;
u32_t wrongdigests;
u32_t decryptionerrors;
#endif
};
extern struct snmp_statistics snmp_stats;

View File

@ -133,11 +133,11 @@
#if !defined SNMP_MAX_VALUE_SIZE || defined __DOXYGEN__
/**
* The maximum size of a value.
* The minimum size of a value.
*/
#define SNMP_MIN_VALUE_SIZE (2 * sizeof(u32_t*)) /* size required to store the basic types (8 bytes for counter64) */
/**
* The minimum size of a value.
* The maximum size of a value.
*/
#define SNMP_MAX_VALUE_SIZE LWIP_MAX(LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN), sizeof(u32_t)*(SNMP_MAX_OBJ_ID_LEN)), SNMP_MIN_VALUE_SIZE)
#endif
@ -282,12 +282,16 @@
#define LWIP_SNMP_V3 0
#endif
#ifndef LWIP_SNMP_V3_CRYPTO
#define LWIP_SNMP_V3_CRYPTO LWIP_SNMP_V3
#endif
#ifndef LWIP_SNMP_V3_MBEDTLS
#define LWIP_SNMP_V3_MBEDTLS LWIP_SNMP_V3
#endif
#ifndef LWIP_SNMP_V3_CRYPTO
#define LWIP_SNMP_V3_CRYPTO LWIP_SNMP_V3_MBEDTLS
#endif
#ifndef LWIP_SNMP_CONFIGURE_VERSIONS
#define LWIP_SNMP_CONFIGURE_VERSIONS 0
#endif
#endif /* LWIP_HDR_SNMP_OPTS_H */

View File

@ -0,0 +1,32 @@
/*
Generated by LwipMibCompiler
*/
#ifndef LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H
#define LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H
#include "lwip/apps/snmp_opts.h"
#if LWIP_SNMP
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "lwip/apps/snmp_core.h"
extern const struct snmp_obj_id usmNoAuthProtocol;
extern const struct snmp_obj_id usmHMACMD5AuthProtocol;
extern const struct snmp_obj_id usmHMACSHAAuthProtocol;
extern const struct snmp_obj_id usmNoPrivProtocol;
extern const struct snmp_obj_id usmDESPrivProtocol;
extern const struct snmp_obj_id usmAESPrivProtocol;
extern const struct snmp_mib snmpframeworkmib;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LWIP_SNMP */
#endif /* LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H */

View File

@ -0,0 +1,24 @@
/*
Generated by LwipMibCompiler
*/
#ifndef LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H
#define LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H
#include "lwip/apps/snmp_opts.h"
#if LWIP_SNMP
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "lwip/apps/snmp_core.h"
extern const struct snmp_mib snmpusmmib;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LWIP_SNMP */
#endif /* LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H */

View File

@ -38,18 +38,34 @@
#include "lwip/apps/snmp_opts.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_SNMP && LWIP_SNMP_V3
#define SNMP_V3_AUTH_ALGO_INVAL 0
#define SNMP_V3_AUTH_ALGO_MD5 1
#define SNMP_V3_AUTH_ALGO_SHA 2
typedef enum
{
SNMP_V3_AUTH_ALGO_INVAL = 0,
SNMP_V3_AUTH_ALGO_MD5 = 1,
SNMP_V3_AUTH_ALGO_SHA = 2
} snmpv3_auth_algo_t;
#define SNMP_V3_PRIV_ALGO_INVAL 0
#define SNMP_V3_PRIV_ALGO_DES 1
#define SNMP_V3_PRIV_ALGO_AES 2
typedef enum
{
SNMP_V3_PRIV_ALGO_INVAL = 0,
SNMP_V3_PRIV_ALGO_DES = 1,
SNMP_V3_PRIV_ALGO_AES = 2
} snmpv3_priv_algo_t;
#define SNMP_V3_PRIV_MODE_DECRYPT 0
#define SNMP_V3_PRIV_MODE_ENCRYPT 1
typedef enum
{
SNMP_V3_USER_STORAGETYPE_OTHER = 1,
SNMP_V3_USER_STORAGETYPE_VOLATILE = 2,
SNMP_V3_USER_STORAGETYPE_NONVOLATILE = 3,
SNMP_V3_USER_STORAGETYPE_PERMANENT = 4,
SNMP_V3_USER_STORAGETYPE_READONLY = 5
} snmpv3_user_storagetype_t;
/*
* The following callback functions must be implemented by the application.
@ -65,26 +81,34 @@ void snmpv3_set_engine_boots(u32_t boots);
u32_t snmpv3_get_engine_time(void);
void snmpv3_reset_engine_time(void);
err_t snmpv3_get_user(const char* username, u8_t *auth_algo, u8_t *auth_key, u8_t *priv_algo, u8_t *priv_key);
err_t snmpv3_get_user(const char* username, snmpv3_auth_algo_t *auth_algo, u8_t *auth_key, snmpv3_priv_algo_t *priv_algo, u8_t *priv_key);
u8_t snmpv3_get_amount_of_users(void);
err_t snmpv3_get_user_storagetype(const char *username, snmpv3_user_storagetype_t *storagetype);
err_t snmpv3_get_username(char *username, u8_t index);
/* The following functions are provided by the SNMPv3 agent */
void snmpv3_engine_id_changed(void);
s32_t snmpv3_get_engine_time_internal(void);
void snmpv3_password_to_key_md5(
const u8_t *password, /* IN */
u8_t passwordlen, /* IN */
size_t passwordlen, /* IN */
const u8_t *engineID, /* IN - pointer to snmpEngineID */
u8_t engineLength, /* IN - length of snmpEngineID */
u8_t *key); /* OUT - pointer to caller 16-octet buffer */
void snmpv3_password_to_key_sha(
const u8_t *password, /* IN */
u8_t passwordlen, /* IN */
size_t passwordlen, /* IN */
const u8_t *engineID, /* IN - pointer to snmpEngineID */
u8_t engineLength, /* IN - length of snmpEngineID */
u8_t *key); /* OUT - pointer to caller 20-octet buffer */
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNMP_V3_H */

View File

@ -58,16 +58,20 @@ u8_t sntp_enabled(void);
void sntp_setserver(u8_t idx, const ip_addr_t *addr);
const ip_addr_t* sntp_getserver(u8_t idx);
#if SNTP_MONITOR_SERVER_REACHABILITY
u8_t sntp_getreachability(u8_t idx);
#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
#if SNTP_SERVER_DNS
void sntp_setservername(u8_t idx, char *server);
char *sntp_getservername(u8_t idx);
void sntp_setservername(u8_t idx, const char *server);
const char *sntp_getservername(u8_t idx);
#endif /* SNTP_SERVER_DNS */
#if SNTP_GET_SERVERS_FROM_DHCP
#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
void sntp_servermode_dhcp(int set_servers_from_dhcp);
#else /* SNTP_GET_SERVERS_FROM_DHCP */
#else /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
#define sntp_servermode_dhcp(x)
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
#ifdef __cplusplus
}

View File

@ -38,6 +38,7 @@
#define LWIP_HDR_APPS_SNTP_OPTS_H
#include "lwip/opt.h"
#include "lwip/prot/iana.h"
/**
* @defgroup sntp_opts Options
@ -46,8 +47,10 @@
*/
/** SNTP macro to change system time in seconds
* Define SNTP_SET_SYSTEM_TIME_US(sec, us) to set the time in microseconds instead of this one
* if you need the additional precision.
* Define SNTP_SET_SYSTEM_TIME_US(sec, us) to set the time in microseconds
* instead of this one if you need the additional precision. Alternatively,
* define SNTP_SET_SYSTEM_TIME_NTP(sec, frac) in order to work with native
* NTP timestamps instead.
*/
#if !defined SNTP_SET_SYSTEM_TIME || defined __DOXYGEN__
#define SNTP_SET_SYSTEM_TIME(sec) LWIP_UNUSED_ARG(sec)
@ -64,12 +67,18 @@
#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV
#endif
/** Set this to 1 to implement the callback function called by dhcpv6 when
* NTP servers are received. */
#if !defined SNTP_GET_SERVERS_FROM_DHCPV6 || defined __DOXYGEN__
#define SNTP_GET_SERVERS_FROM_DHCPV6 LWIP_DHCP6_GET_NTP_SRV
#endif
/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers
* One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
* \#define SNTP_SERVER_ADDRESS "pool.ntp.org"
*/
#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__
#define SNTP_SERVER_DNS 1
#define SNTP_SERVER_DNS 0
#endif
/**
@ -81,12 +90,7 @@
/** SNTP server port */
#if !defined SNTP_PORT || defined __DOXYGEN__
#define SNTP_PORT 123
#endif
/** Set this to 1 to allow config of SNTP server(s) by DNS name */
#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__
#define SNTP_SERVER_DNS 0
#define SNTP_PORT LWIP_IANA_PORT_SNTP
#endif
/** Sanity check:
@ -96,7 +100,7 @@
* response comes from the server we sent the request to.
* - >= 2 to check returned Originate Timestamp against Transmit Timestamp
* sent to the server (to ensure response to older request).
* - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp
* - >= 3 @todo: discard reply if any of the VN, Stratum, or Transmit Timestamp
* fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast).
* - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each
* greater than or equal to 0 and less than infinity, where infinity is
@ -107,6 +111,30 @@
#define SNTP_CHECK_RESPONSE 0
#endif
/** Enable round-trip delay compensation.
* Compensate for the round-trip delay by calculating the clock offset from
* the originate, receive, transmit and destination timestamps, as per RFC.
*
* The calculation requires compiler support for 64-bit integers. Also, either
* SNTP_SET_SYSTEM_TIME_US or SNTP_SET_SYSTEM_TIME_NTP has to be implemented
* for setting the system clock with sub-second precision. Likewise, either
* SNTP_GET_SYSTEM_TIME or SNTP_GET_SYSTEM_TIME_NTP needs to be implemented
* with sub-second precision.
*
* Although not strictly required, it makes sense to combine this option with
* SNTP_CHECK_RESPONSE >= 2 for sanity-checking of the received timestamps.
* Also, in order for the round-trip calculation to work, the difference
* between the local clock and the NTP server clock must not be larger than
* about 34 years. If that limit is exceeded, the implementation will fall back
* to setting the clock without compensation. In order to ensure that the local
* clock is always within the permitted range for compensation, even at first
* try, it may be necessary to store at least the current year in non-volatile
* memory.
*/
#if !defined SNTP_COMP_ROUNDTRIP || defined __DOXYGEN__
#define SNTP_COMP_ROUNDTRIP 0
#endif
/** According to the RFC, this shall be a random delay
* between 1 and 5 minutes (in milliseconds) to prevent load peaks.
* This can be defined to a random generation function,
@ -114,33 +142,40 @@
* Turned off by default.
*/
#if !defined SNTP_STARTUP_DELAY || defined __DOXYGEN__
#ifdef LWIP_RAND
#define SNTP_STARTUP_DELAY 1
#else
#define SNTP_STARTUP_DELAY 0
#endif
#endif
/** If you want the startup delay to be a function, define this
* to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1.
*/
#if !defined SNTP_STARTUP_DELAY_FUNC || defined __DOXYGEN__
#define SNTP_STARTUP_DELAY_FUNC SNTP_STARTUP_DELAY
#define SNTP_STARTUP_DELAY_FUNC (LWIP_RAND() % 5000)
#endif
/** SNTP receive timeout - in milliseconds
* Also used as retry timeout - this shouldn't be too low.
* Default is 3 seconds.
* Default is 15 seconds. Must not be beolw 15 seconds by specification (i.e. 15000)
*/
#if !defined SNTP_RECV_TIMEOUT || defined __DOXYGEN__
#define SNTP_RECV_TIMEOUT 3000
#define SNTP_RECV_TIMEOUT 15000
#endif
/** SNTP update delay - in milliseconds
* Default is 1 hour. Must not be beolw 15 seconds by specification (i.e. 15000)
* Default is 1 hour. Must not be beolw 60 seconds by specification (i.e. 60000)
*/
#if !defined SNTP_UPDATE_DELAY || defined __DOXYGEN__
#define SNTP_UPDATE_DELAY 3600000
#endif
/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2
* to send in request and compare in response.
* to send in request and compare in response. Also used for round-trip
* delay compensation if SNTP_COMP_ROUNDTRIP != 0.
* Alternatively, define SNTP_GET_SYSTEM_TIME_NTP(sec, frac) in order to
* work with native NTP timestamps instead.
*/
#if !defined SNTP_GET_SYSTEM_TIME || defined __DOXYGEN__
#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0)
@ -166,6 +201,13 @@
#define SNTP_RETRY_TIMEOUT_EXP 1
#endif
/** Keep a reachability shift register per server
* Default is on to conform to RFC.
*/
#if !defined SNTP_MONITOR_SERVER_REACHABILITY || defined __DOXYGEN__
#define SNTP_MONITOR_SERVER_REACHABILITY 1
#endif
/**
* @}
*/

View File

@ -1,4 +1,4 @@
/****************************************************************//**
/**
*
* @file tftp_opts.h
*
@ -9,7 +9,7 @@
* Copyright (c) Deltatee Enterprises Ltd. 2013
* All rights reserved.
*
********************************************************************/
*/
/*
* Redistribution and use in source and binary forms, with or without
@ -42,6 +42,7 @@
#define LWIP_HDR_APPS_TFTP_OPTS_H
#include "lwip/opt.h"
#include "lwip/prot/iana.h"
/**
* @defgroup tftp_opts Options
@ -53,14 +54,14 @@
* Enable TFTP debug messages
*/
#if !defined TFTP_DEBUG || defined __DOXYGEN__
#define TFTP_DEBUG LWIP_DBG_ON
#define TFTP_DEBUG LWIP_DBG_OFF
#endif
/**
* TFTP server port
*/
#if !defined TFTP_PORT || defined __DOXYGEN__
#define TFTP_PORT 69
#define TFTP_PORT LWIP_IANA_PORT_TFTP
#endif
/**
@ -81,7 +82,7 @@
* TFTP timer cyclic interval
*/
#if !defined TFTP_TIMER_MSECS || defined __DOXYGEN__
#define TFTP_TIMER_MSECS 50
#define TFTP_TIMER_MSECS (TFTP_TIMEOUT_MSECS / 10)
#endif
/**

View File

@ -1,4 +1,4 @@
/****************************************************************//**
/**
*
* @file tftp_server.h
*
@ -9,7 +9,7 @@
* Copyright (c) Deltatee Enterprises Ltd. 2013
* All rights reserved.
*
********************************************************************/
*/
/*
* Redistribution and use in source and binary forms, with or without
@ -86,6 +86,7 @@ struct tftp_context {
};
err_t tftp_init(const struct tftp_context* ctx);
void tftp_cleanup(void);
#ifdef __cplusplus
}

View File

@ -52,6 +52,8 @@
* @ingroup sys_layer
* All defines related to this section must not be placed in lwipopts.h,
* but in arch/cc.h!
* If the compiler does not provide memset() this file must include a
* definition of it, or include a file which defines it.
* These options cannot be \#defined in lwipopts.h since they are not options
* of lwIP itself, but options of the lwIP port to your system.
* @{
@ -116,12 +118,21 @@
/* Define generic types used in lwIP */
#if !LWIP_NO_STDINT_H
#include <stdint.h>
/* stdint.h is C99 which should also provide support for 64-bit integers */
#if !defined(LWIP_HAVE_INT64) && defined(UINT64_MAX)
#define LWIP_HAVE_INT64 1
#endif
typedef uint8_t u8_t;
typedef int8_t s8_t;
typedef uint16_t u16_t;
typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
#if LWIP_HAVE_INT64
typedef uint64_t u64_t;
typedef int64_t s64_t;
#endif
typedef uintptr_t mem_ptr_t;
#endif
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
@ -163,7 +174,7 @@ typedef int32_t s32_t;
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
* the limits.h header. You need to define the type limits yourself in this case
* (e.g. INT_MAX).
* (e.g. INT_MAX, SSIZE_MAX).
*/
#ifndef LWIP_NO_LIMITS_H
#define LWIP_NO_LIMITS_H 0
@ -174,6 +185,56 @@ typedef int32_t s32_t;
#include <limits.h>
#endif
/* Do we need to define ssize_t? This is a compatibility hack:
* Unfortunately, this type seems to be unavailable on some systems (even if
* sys/types or unistd.h are available).
* Being like that, we define it to 'int' if SSIZE_MAX is not defined.
*/
#ifdef SSIZE_MAX
/* If SSIZE_MAX is defined, unistd.h should provide the type as well */
#ifndef LWIP_NO_UNISTD_H
#define LWIP_NO_UNISTD_H 0
#endif
#if !LWIP_NO_UNISTD_H
#include <unistd.h>
#endif
#else /* SSIZE_MAX */
typedef int ssize_t;
#define SSIZE_MAX INT_MAX
#endif /* SSIZE_MAX */
/* some maximum values needed in lwip code */
#define LWIP_UINT32_MAX 0xffffffff
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
* the ctype.h header. If ctype.h is available, a few character functions
* are mapped to the appropriate functions (lwip_islower, lwip_isdigit...), if
* not, a private implementation is provided.
*/
#ifndef LWIP_NO_CTYPE_H
#define LWIP_NO_CTYPE_H 0
#endif
#if LWIP_NO_CTYPE_H
#define lwip_in_range(c, lo, up) ((u8_t)(c) >= (lo) && (u8_t)(c) <= (up))
#define lwip_isdigit(c) lwip_in_range((c), '0', '9')
#define lwip_isxdigit(c) (lwip_isdigit(c) || lwip_in_range((c), 'a', 'f') || lwip_in_range((c), 'A', 'F'))
#define lwip_islower(c) lwip_in_range((c), 'a', 'z')
#define lwip_isspace(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\v')
#define lwip_isupper(c) lwip_in_range((c), 'A', 'Z')
#define lwip_tolower(c) (lwip_isupper(c) ? (c) - 'A' + 'a' : c)
#define lwip_toupper(c) (lwip_islower(c) ? (c) - 'a' + 'A' : c)
#else
#include <ctype.h>
#define lwip_isdigit(c) isdigit((unsigned char)(c))
#define lwip_isxdigit(c) isxdigit((unsigned char)(c))
#define lwip_islower(c) islower((unsigned char)(c))
#define lwip_isspace(c) isspace((unsigned char)(c))
#define lwip_isupper(c) isupper((unsigned char)(c))
#define lwip_tolower(c) tolower((unsigned char)(c))
#define lwip_toupper(c) toupper((unsigned char)(c))
#endif
/** C++ const_cast<target_type>(val) equivalent to remove constness from a value (GCC -Wcast-qual) */
#ifndef LWIP_CONST_CAST
#define LWIP_CONST_CAST(target_type, val) ((target_type)((ptrdiff_t)val))
@ -191,6 +252,11 @@ typedef int32_t s32_t;
#define LWIP_PTR_NUMERIC_CAST(target_type, val) LWIP_CONST_CAST(target_type, val)
#endif
/** Avoid warnings/errors related to implicitly casting away packed attributes by doing a explicit cast */
#ifndef LWIP_PACKED_CAST
#define LWIP_PACKED_CAST(target_type, val) LWIP_CONST_CAST(target_type, val)
#endif
/** Allocates a memory buffer of specified size that is of sufficient size to align
* its start address using LWIP_MEM_ALIGN.
* You can declare your own version here e.g. to enforce alignment without adding
@ -290,7 +356,7 @@ extern "C" {
#define PACK_STRUCT_FLD_S(x) PACK_STRUCT_FIELD(x)
#endif /* PACK_STRUCT_FLD_S */
/** Packed structs support using \#include files before and after struct to be packed.\n
/** PACK_STRUCT_USE_INCLUDES==1: Packed structs support using \#include files before and after struct to be packed.\n
* The file included BEFORE the struct is "arch/bpstruct.h".\n
* The file included AFTER the struct is "arch/epstruct.h".\n
* This can be used to implement struct packing on MS Visual C compilers, see
@ -307,6 +373,15 @@ extern "C" {
#define LWIP_UNUSED_ARG(x) (void)x
#endif /* LWIP_UNUSED_ARG */
/** LWIP_PROVIDE_ERRNO==1: Let lwIP provide ERRNO values and the 'errno' variable.
* If this is disabled, cc.h must either define 'errno', include <errno.h>,
* define LWIP_ERRNO_STDINCLUDE to get <errno.h> included or
* define LWIP_ERRNO_INCLUDE to <errno.h> or equivalent.
*/
#if defined __DOXYGEN__
#define LWIP_PROVIDE_ERRNO
#endif
/**
* @}
*/

View File

@ -115,17 +115,12 @@
#ifndef LWIP_NOASSERT
#define LWIP_ASSERT(message, assertion) do { if (!(assertion)) { \
LWIP_PLATFORM_ASSERT(message); }} while(0)
#ifndef LWIP_PLATFORM_ASSERT
#error "If you want to use LWIP_ASSERT, LWIP_PLATFORM_ASSERT(message) needs to be defined in your arch/cc.h"
#endif
#else /* LWIP_NOASSERT */
#define LWIP_ASSERT(message, assertion)
#endif /* LWIP_NOASSERT */
#ifndef LWIP_ERROR
#ifndef LWIP_NOASSERT
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message)
#elif defined LWIP_DEBUG
#ifdef LWIP_DEBUG
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message))
#else
#define LWIP_PLATFORM_ERROR(message)
@ -145,9 +140,6 @@
#endif
#ifdef LWIP_DEBUG
#ifndef LWIP_PLATFORM_DIAG
#error "If you want to use LWIP_DEBUG, LWIP_PLATFORM_DIAG(message) needs to be defined in your arch/cc.h"
#endif
#define LWIP_DEBUGF(debug, message) do { \
if ( \
((debug) & LWIP_DBG_ON) && \

View File

@ -34,6 +34,17 @@
* Author: Adam Dunkels <adam@sics.se>
*
*/
/**
* @defgroup perf Performance measurement
* @ingroup sys_layer
* All defines related to this section must not be placed in lwipopts.h,
* but in arch/perf.h!
* Measurement calls made throughout lwip, these can be defined to nothing.
* - PERF_START: start measuring something.
* - PERF_STOP(x): stop measuring something, and record the result.
*/
#ifndef LWIP_HDR_DEF_H
#define LWIP_HDR_DEF_H
@ -72,14 +83,14 @@ extern "C" {
#endif
#if BYTE_ORDER == BIG_ENDIAN
#define lwip_htons(x) (x)
#define lwip_ntohs(x) (x)
#define lwip_htonl(x) (x)
#define lwip_ntohl(x) (x)
#define PP_HTONS(x) (x)
#define PP_NTOHS(x) (x)
#define PP_HTONL(x) (x)
#define PP_NTOHL(x) (x)
#define lwip_htons(x) ((u16_t)(x))
#define lwip_ntohs(x) ((u16_t)(x))
#define lwip_htonl(x) ((u32_t)(x))
#define lwip_ntohl(x) ((u32_t)(x))
#define PP_HTONS(x) ((u16_t)(x))
#define PP_NTOHS(x) ((u16_t)(x))
#define PP_HTONL(x) ((u32_t)(x))
#define PP_NTOHL(x) ((u32_t)(x))
#else /* BYTE_ORDER != BIG_ENDIAN */
#ifndef lwip_htons
u16_t lwip_htons(u16_t x);
@ -94,12 +105,12 @@ u32_t lwip_htonl(u32_t x);
/* These macros should be calculated by the preprocessor and are used
with compile-time constants only (so that there is no little-endian
overhead at runtime). */
#define PP_HTONS(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
#define PP_HTONS(x) ((u16_t)((((x) & (u16_t)0x00ffU) << 8) | (((x) & (u16_t)0xff00U) >> 8)))
#define PP_NTOHS(x) PP_HTONS(x)
#define PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
(((x) & 0x0000ff00UL) << 8) | \
(((x) & 0x00ff0000UL) >> 8) | \
(((x) & 0xff000000UL) >> 24))
#define PP_HTONL(x) ((((x) & (u32_t)0x000000ffUL) << 24) | \
(((x) & (u32_t)0x0000ff00UL) << 8) | \
(((x) & (u32_t)0x00ff0000UL) >> 8) | \
(((x) & (u32_t)0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#endif /* BYTE_ORDER == BIG_ENDIAN */

View File

@ -72,8 +72,6 @@ struct dhcp
{
/** transaction identifier of last sent request */
u32_t xid;
/** incoming msg */
struct dhcp_msg *msg_in;
/** track PCB allocation state */
u8_t pcb_allocated;
/** current DHCP state machine state */
@ -85,11 +83,8 @@ struct dhcp
#endif
u8_t subnet_mask_given;
struct pbuf *p_out; /* pbuf of outcoming msg */
struct dhcp_msg *msg_out; /* outgoing msg */
u16_t options_out_len; /* outgoing msg options length */
u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
#if ESP_DHCP_TIMER
#if ESP_DHCP
u32_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
u32_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
u32_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */
@ -135,6 +130,7 @@ err_t dhcp_start(struct netif *netif);
err_t dhcp_renew(struct netif *netif);
err_t dhcp_release(struct netif *netif);
void dhcp_stop(struct netif *netif);
void dhcp_release_and_stop(struct netif *netif);
void dhcp_inform(struct netif *netif);
void dhcp_network_changed(struct netif *netif);

View File

@ -1,11 +1,13 @@
/**
* @file
*
* IPv6 address autoconfiguration as per RFC 4862.
* DHCPv6 client: IPv6 address autoconfiguration as per
* RFC 3315 (stateful DHCPv6) and
* RFC 3736 (stateless DHCPv6).
*/
/*
* Copyright (c) 2010 Inico Technologies Ltd.
* Copyright (c) 2018 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@ -32,12 +34,7 @@
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Ivan Delamer <delamer@inicotech.com>
*
* IPv6 address autoconfiguration as per RFC 4862.
*
* Please coordinate changes and requests with Ivan Delamer
* <delamer@inicotech.com>
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*/
#ifndef LWIP_HDR_IP6_DHCP6_H
@ -47,12 +44,61 @@
#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/err.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/** period (in milliseconds) of the application calling dhcp6_tmr() */
#define DHCP6_TIMER_MSECS 500
struct dhcp6
{
/*@todo: implement DHCP6*/
/** transaction identifier of last sent request */
u32_t xid;
/** track PCB allocation state */
u8_t pcb_allocated;
/** current DHCPv6 state machine state */
u8_t state;
/** retries of current request */
u8_t tries;
/** if request config is triggered while another action is active, this keeps track of it */
u8_t request_config_pending;
/** #ticks with period DHCP6_TIMER_MSECS for request timeout */
u16_t request_timeout;
#if LWIP_IPV6_DHCP6_STATEFUL
/* @todo: add more members here to keep track of stateful DHCPv6 data, like lease times */
#endif /* LWIP_IPV6_DHCP6_STATEFUL */
};
void dhcp6_set_struct(struct netif *netif, struct dhcp6 *dhcp6);
/** Remove a struct dhcp6 previously set to the netif using dhcp6_set_struct() */
#define dhcp6_remove_struct(netif) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6, NULL)
void dhcp6_cleanup(struct netif *netif);
err_t dhcp6_enable_stateful(struct netif *netif);
err_t dhcp6_enable_stateless(struct netif *netif);
void dhcp6_disable(struct netif *netif);
void dhcp6_tmr(void);
void dhcp6_nd6_ra_trigger(struct netif *netif, u8_t managed_addr_config, u8_t other_config);
#if LWIP_DHCP6_GET_NTP_SRV
/** This function must exist, in other to add offered NTP servers to
* the NTP (or SNTP) engine.
* See LWIP_DHCP6_MAX_NTP_SERVERS */
extern void dhcp6_set_ntp_servers(u8_t num_ntp_servers, const ip_addr_t* ntp_server_addrs);
#endif /* LWIP_DHCP6_GET_NTP_SRV */
#define netif_dhcp6_data(netif) ((struct dhcp6*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6))
#ifdef __cplusplus
}
#endif
#endif /* LWIP_IPV6_DHCP6 */
#endif /* LWIP_HDR_IP6_DHCP6_H */

View File

@ -105,11 +105,7 @@ typedef void (*dns_found_callback)(const char *name, const ip_addr_t *ipaddr, vo
void dns_init(void);
void dns_tmr(void);
void dns_setserver(u8_t numdns, const ip_addr_t *dnsserver);
#if ESP_DNS
ip_addr_t dns_getserver(u8_t numdns);
#else
const ip_addr_t* dns_getserver(u8_t numdns);
#endif
err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr,
dns_found_callback found, void *callback_arg);
err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr,
@ -119,7 +115,6 @@ err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *add
void dns_clear_servers(bool keep_fallback);
#endif
#if DNS_LOCAL_HOSTLIST
size_t dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg);
err_t dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype);

View File

@ -49,14 +49,6 @@ extern "C" {
* @{
*/
/** Define LWIP_ERR_T in cc.h if you want to use
* a different type for your platform (must be signed). */
#ifdef LWIP_ERR_T
typedef LWIP_ERR_T err_t;
#else /* LWIP_ERR_T */
typedef s8_t err_t;
#endif /* LWIP_ERR_T*/
/** Definitions for error constants. */
typedef enum {
/** No error, everything OK. */
@ -96,7 +88,13 @@ typedef enum {
ERR_ARG = -16
} err_enum_t;
#define ERR_IS_FATAL(e) ((e) <= ERR_ABRT)
/** Define LWIP_ERR_T in cc.h if you want to use
* a different type for your platform (must be signed). */
#ifdef LWIP_ERR_T
typedef LWIP_ERR_T err_t;
#else /* LWIP_ERR_T */
typedef s8_t err_t;
#endif /* LWIP_ERR_T*/
/**
* @}

View File

@ -179,10 +179,15 @@ extern int errno;
#else /* LWIP_PROVIDE_ERRNO */
/* Define LWIP_ERRNO_INCLUDE to <errno.h> to include the error defines here */
/* Define LWIP_ERRNO_STDINCLUDE if you want to include <errno.h> here */
#ifdef LWIP_ERRNO_STDINCLUDE
#include <errno.h>
#else /* LWIP_ERRNO_STDINCLUDE */
/* Define LWIP_ERRNO_INCLUDE to an equivalent of <errno.h> to include the error defines here */
#ifdef LWIP_ERRNO_INCLUDE
#include LWIP_ERRNO_INCLUDE
#endif /* LWIP_ERRNO_INCLUDE */
#endif /* LWIP_ERRNO_STDINCLUDE */
#endif /* LWIP_PROVIDE_ERRNO */

View File

@ -52,14 +52,14 @@
#include "lwip/ip4.h"
#include "lwip/prot/ethernet.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */
#include "lwip/prot/etharp.h"
#ifdef __cplusplus
extern "C" {
#endif
/** 1 seconds period */
#define ARP_TMR_INTERVAL 1000
@ -85,9 +85,9 @@ void garp_tmr(void);
#define etharp_init() /* Compatibility define, no init needed. */
void etharp_tmr(void);
s8_t etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr,
ssize_t etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr,
struct eth_addr **eth_ret, const ip4_addr_t **ip_ret);
u8_t etharp_get_entry(u8_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret);
int etharp_get_entry(size_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret);
err_t etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr);
err_t etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q);
err_t etharp_request(struct netif *netif, const ip4_addr_t *ipaddr);
@ -103,14 +103,13 @@ err_t etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr
err_t etharp_remove_static_entry(const ip4_addr_t *ipaddr);
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
#endif /* LWIP_IPV4 && LWIP_ARP */
void etharp_input(struct pbuf *p, struct netif *netif);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_IPV4 && LWIP_ARP */
#endif /* LWIP_ARP || LWIP_ETHERNET */
#endif /* LWIP_HDR_NETIF_ETHARP_H */

View File

@ -57,7 +57,9 @@ void icmp6_input(struct pbuf *p, struct netif *inp);
void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c);
void icmp6_packet_too_big(struct pbuf *p, u32_t mtu);
void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c);
void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer);
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);
void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, const void *pointer);
#endif /* LWIP_ICMP6 && LWIP_IPV6 */

View File

@ -0,0 +1,68 @@
/**
* @file
* Interface Identification APIs from:
* RFC 3493: Basic Socket Interface Extensions for IPv6
* Section 4: Interface Identification
*/
/*
* Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Joel Cunningham <joel.cunningham@me.com>
*
*/
#ifndef LWIP_HDR_IF_H
#define LWIP_HDR_IF_H
#include "lwip/opt.h"
#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
#define IF_NAMESIZE NETIF_NAMESIZE
char * lwip_if_indextoname(unsigned int ifindex, char *ifname);
unsigned int lwip_if_nametoindex(const char *ifname);
#if LWIP_COMPAT_SOCKETS
#define if_indextoname(ifindex, ifname) lwip_if_indextoname(ifindex,ifname)
#define if_nametoindex(ifname) lwip_if_nametoindex(ifname)
#endif /* LWIP_COMPAT_SOCKETS */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_SOCKET */
#endif /* LWIP_HDR_IF_H */

View File

@ -134,8 +134,6 @@ extern const struct in6_addr in6addr_any;
#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
/* ATTENTION: the next define only works because both s_addr and ip4_addr_t are an u32_t effectively! */
#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr) ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
/* directly map this to the lwip internal functions */
#define inet_addr(cp) ipaddr_addr(cp)
@ -153,9 +151,8 @@ extern const struct in6_addr in6addr_any;
#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
(target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
(target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
(target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];}
/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */
#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
(target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3]; \
ip6_addr_clear_zone(target_ip6addr);}
/* directly map this to the lwip internal functions */
#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr)

View File

@ -49,7 +49,7 @@
/** Split an u32_t in two u16_ts and add them up */
#ifndef FOLD_U32T
#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL))
#define FOLD_U32T(u) ((u32_t)(((u) >> 16) + ((u) & 0x0000ffffUL)))
#endif
#if LWIP_CHECKSUM_ON_COPY

View File

@ -52,13 +52,13 @@ extern "C" {
/** X.x.x: Major version of the stack */
#define LWIP_VERSION_MAJOR 2
/** x.X.x: Minor version of the stack */
#define LWIP_VERSION_MINOR 0
#define LWIP_VERSION_MINOR 1
/** x.x.X: Revision of the stack */
#define LWIP_VERSION_REVISION 3
/** For release candidates, this is set to 1..254
* For official releases, this is set to 255 (LWIP_RC_RELEASE)
* For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */
#define LWIP_VERSION_RC LWIP_RC_RELEASE
#define LWIP_VERSION_RC LWIP_RC_DEVELOPMENT
/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */
#define LWIP_RC_RELEASE 255
@ -81,8 +81,8 @@ extern "C" {
#endif
/** Provides the version of the stack */
#define LWIP_VERSION (((u32_t)LWIP_VERSION_MAJOR) << 24 | ((u32_t)LWIP_VERSION_MINOR) << 16 | \
((u32_t)LWIP_VERSION_REVISION) << 8 | ((u32_t)LWIP_VERSION_RC))
#define LWIP_VERSION ((LWIP_VERSION_MAJOR) << 24 | (LWIP_VERSION_MINOR) << 16 | \
(LWIP_VERSION_REVISION) << 8 | (LWIP_VERSION_RC))
/** Provides the version of the stack as string */
#define LWIP_VERSION_STRING LWIP_VERSTR(LWIP_VERSION_MAJOR) "." LWIP_VERSTR(LWIP_VERSION_MINOR) "." LWIP_VERSTR(LWIP_VERSION_REVISION) LWIP_VERSION_STRING_SUFFIX

View File

@ -63,31 +63,33 @@ extern "C" {
#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p) LWIP_ASSERT("p->ref == 1", (p)->ref == 1)
#endif
#if LWIP_NETIF_HWADDRHINT
#define IP_PCB_ADDRHINT ;u8_t addr_hint
#else
#define IP_PCB_ADDRHINT
#endif /* LWIP_NETIF_HWADDRHINT */
#if LWIP_NETIF_USE_HINTS
#define IP_PCB_NETIFHINT ;struct netif_hint netif_hints
#else /* LWIP_NETIF_USE_HINTS */
#define IP_PCB_NETIFHINT
#endif /* LWIP_NETIF_USE_HINTS */
/** This is the common part of all PCB types. It needs to be at the
beginning of a PCB type definition. It is located here so that
changes to this common part are made in one location instead of
having to change all PCB structs. */
#define IP_PCB \
#define IP_PCB \
/* ip addresses in network byte order */ \
ip_addr_t local_ip; \
ip_addr_t remote_ip; \
/* Socket options */ \
u8_t so_options; \
/* Type Of Service */ \
u8_t tos; \
/* Time To Live */ \
u8_t ttl \
ip_addr_t local_ip; \
ip_addr_t remote_ip; \
/* Bound netif index */ \
u8_t netif_idx; \
/* Socket options */ \
u8_t so_options; \
/* Type Of Service */ \
u8_t tos; \
/* Time To Live */ \
u8_t ttl \
/* link layer address resolution hint */ \
IP_PCB_ADDRHINT
IP_PCB_NETIFHINT
struct ip_pcb {
/* Common members of all PCB types */
/* Common members of all PCB types */
IP_PCB;
};
@ -110,7 +112,7 @@ struct ip_globals
struct netif *current_input_netif;
#if LWIP_IPV4
/** Header of the input packet currently being processed. */
struct ip_hdr *current_ip4_header;
const struct ip_hdr *current_ip4_header;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
/** Header of the input IPv6 packet currently being processed. */
@ -146,7 +148,7 @@ extern struct ip_globals ip_data;
/** Get the IPv4 header of the current packet.
* This function must only be called from a receive callback (udp_recv,
* raw_recv, tcp_accept). It will return NULL otherwise. */
#define ip4_current_header() ((const struct ip_hdr*)(ip_data.current_ip4_header))
#define ip4_current_header() ip_data.current_ip4_header
/** Get the IPv6 header of the current packet.
* This function must only be called from a receive callback (udp_recv,
* raw_recv, tcp_accept). It will return NULL otherwise. */
@ -175,7 +177,7 @@ extern struct ip_globals ip_data;
/** Get the IPv4 header of the current packet.
* This function must only be called from a receive callback (udp_recv,
* raw_recv, tcp_accept). It will return NULL otherwise. */
#define ip4_current_header() ((const struct ip_hdr*)(ip_data.current_ip4_header))
#define ip4_current_header() ip_data.current_ip4_header
/** Always returns FALSE when only supporting IPv4 only */
#define ip_current_is_v6() 0
/** Get the transport layer protocol */
@ -198,7 +200,7 @@ extern struct ip_globals ip_data;
/** Get the transport layer protocol */
#define ip_current_header_proto() IP6H_NEXTH(ip6_current_header())
/** Get the transport layer header */
#define ip_next_header_ptr() ((const void*)((const u8_t*)ip6_current_header()))
#define ip_next_header_ptr() ((const void*)(((const u8_t*)ip6_current_header()) + ip_current_header_tot_len()))
/** Source IP6 address of current_header */
#define ip6_current_src_addr() (&ip_data.current_iphdr_src)
/** Destination IP6 address of current_header */
@ -214,9 +216,9 @@ extern struct ip_globals ip_data;
/** Gets an IP pcb option (SOF_* flags) */
#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt))
/** Sets an IP pcb option (SOF_* flags) */
#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
#define ip_set_option(pcb, opt) ((pcb)->so_options = (u8_t)((pcb)->so_options | (opt)))
/** Resets an IP pcb option (SOF_* flags) */
#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt))
#define ip_reset_option(pcb, opt) ((pcb)->so_options = (u8_t)((pcb)->so_options & ~(opt)))
#if LWIP_IPV4 && LWIP_IPV6
/**
@ -243,11 +245,16 @@ extern struct ip_globals ip_data;
(IP_IS_V6(dest) ? \
ip6_output_if_src(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \
ip4_output_if_src(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif))
/** Output IP packet with addr_hint */
#define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \
/** Output IP packet that already includes an IP header. */
#define ip_output_if_hdrincl(p, src, dest, netif) \
(IP_IS_V6(dest) ? \
ip6_output_hinted(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, addr_hint) : \
ip4_output_hinted(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, addr_hint))
ip6_output_if(p, ip_2_ip6(src), LWIP_IP_HDRINCL, 0, 0, 0, netif) : \
ip4_output_if(p, ip_2_ip4(src), LWIP_IP_HDRINCL, 0, 0, 0, netif))
/** Output IP packet with netif_hint */
#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \
(IP_IS_V6(dest) ? \
ip6_output_hinted(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif_hint) : \
ip4_output_hinted(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif_hint))
/**
* @ingroup ip
* Get netif for address combination. See \ref ip6_route and \ref ip4_route
@ -255,7 +262,7 @@ extern struct ip_globals ip_data;
#define ip_route(src, dest) \
(IP_IS_V6(dest) ? \
ip6_route(ip_2_ip6(src), ip_2_ip6(dest)) : \
ip4_route_src(ip_2_ip4(dest), ip_2_ip4(src)))
ip4_route_src(ip_2_ip4(src), ip_2_ip4(dest)))
/**
* @ingroup ip
* Get netif for IP.
@ -275,10 +282,12 @@ err_t ip_input(struct pbuf *p, struct netif *inp);
ip4_output_if(p, src, dest, ttl, tos, proto, netif)
#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \
ip4_output_if_src(p, src, dest, ttl, tos, proto, netif)
#define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \
ip4_output_hinted(p, src, dest, ttl, tos, proto, addr_hint)
#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \
ip4_output_hinted(p, src, dest, ttl, tos, proto, netif_hint)
#define ip_output_if_hdrincl(p, src, dest, netif) \
ip4_output_if(p, src, LWIP_IP_HDRINCL, 0, 0, 0, netif)
#define ip_route(src, dest) \
ip4_route_src(dest, src)
ip4_route_src(src, dest)
#define ip_netif_get_local_ip(netif, dest) \
ip4_netif_get_local_ip(netif)
#define ip_debug_print(is_ipv6, p) ip4_debug_print(p)
@ -293,8 +302,10 @@ err_t ip_input(struct pbuf *p, struct netif *inp);
ip6_output_if(p, src, dest, ttl, tos, proto, netif)
#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \
ip6_output_if_src(p, src, dest, ttl, tos, proto, netif)
#define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \
ip6_output_hinted(p, src, dest, ttl, tos, proto, addr_hint)
#define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \
ip6_output_hinted(p, src, dest, ttl, tos, proto, netif_hint)
#define ip_output_if_hdrincl(p, src, dest, netif) \
ip6_output_if(p, src, LWIP_IP_HDRINCL, 0, 0, 0, netif)
#define ip_route(src, dest) \
ip6_route(src, dest)
#define ip_netif_get_local_ip(netif, dest) \

View File

@ -64,9 +64,9 @@ extern "C" {
#define ip_init() /* Compatibility define, no init needed. */
struct netif *ip4_route(const ip4_addr_t *dest);
#if LWIP_IPV4_SRC_ROUTING
struct netif *ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src);
struct netif *ip4_route_src(const ip4_addr_t *src, const ip4_addr_t *dest);
#else /* LWIP_IPV4_SRC_ROUTING */
#define ip4_route_src(dest, src) ip4_route(dest)
#define ip4_route_src(src, dest) ip4_route(dest)
#endif /* LWIP_IPV4_SRC_ROUTING */
err_t ip4_input(struct pbuf *p, struct netif *inp);
err_t ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
@ -75,10 +75,10 @@ err_t ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *des
u8_t ttl, u8_t tos, u8_t proto, struct netif *netif);
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);
#if LWIP_NETIF_HWADDRHINT
#if LWIP_NETIF_USE_HINTS
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, u8_t *addr_hint);
#endif /* LWIP_NETIF_HWADDRHINT */
u8_t ttl, u8_t tos, u8_t proto, struct netif_hint *netif_hint);
#endif /* LWIP_NETIF_USE_HINTS */
#if IP_OPTIONS_SEND
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,

View File

@ -56,22 +56,6 @@ struct ip4_addr {
* operate both on ip4_addr_t as well as on ip4_addr_p_t. */
typedef struct ip4_addr ip4_addr_t;
/**
* struct ipaddr2 is used in the definition of the ARP packet format in
* order to support compilers that don't have structure packing.
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip4_addr2 {
PACK_STRUCT_FIELD(u16_t addrw[2]);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/* Forward declaration to not include netif.h */
struct netif;
@ -119,13 +103,6 @@ struct netif;
/** Set an IP address given by the four byte-parts */
#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
/** MEMCPY-like copying of IP addresses where addresses are known to be
* 16-bit-aligned if the port is correctly configured (so a port could define
* this to copying 2 u16_t's) - no NULL-pointer-checking needed. */
#ifndef IPADDR2_COPY
#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t))
#endif
/** Copy IP address - faster than ip4_addr_set: no NULL check */
#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr)
/** Safely copy one IP address to another (src may be NULL) */
@ -190,22 +167,34 @@ u8_t ip4_addr_netmask_valid(u32_t netmask);
(u16_t)((ipaddr) != NULL ? ip4_addr4_16(ipaddr) : 0))
#define ip4_addr_debug_print_val(debug, ipaddr) \
ip4_addr_debug_print_parts(debug, \
ip4_addr1_16(&(ipaddr)), \
ip4_addr2_16(&(ipaddr)), \
ip4_addr3_16(&(ipaddr)), \
ip4_addr4_16(&(ipaddr)))
ip4_addr1_16_val(ipaddr), \
ip4_addr2_16_val(ipaddr), \
ip4_addr3_16_val(ipaddr), \
ip4_addr4_16_val(ipaddr))
/* Get one byte from the 4-byte address */
#define ip4_addr1(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[0])
#define ip4_addr2(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[1])
#define ip4_addr3(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[2])
#define ip4_addr4(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[3])
#define ip4_addr_get_byte(ipaddr, idx) (((const u8_t*)(&(ipaddr)->addr))[idx])
#define ip4_addr1(ipaddr) ip4_addr_get_byte(ipaddr, 0)
#define ip4_addr2(ipaddr) ip4_addr_get_byte(ipaddr, 1)
#define ip4_addr3(ipaddr) ip4_addr_get_byte(ipaddr, 2)
#define ip4_addr4(ipaddr) ip4_addr_get_byte(ipaddr, 3)
/* Get one byte from the 4-byte address, but argument is 'ip4_addr_t',
* not a pointer */
#define ip4_addr_get_byte_val(ipaddr, idx) ((u8_t)(((ipaddr).addr >> (idx * 8)) & 0xff))
#define ip4_addr1_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 0)
#define ip4_addr2_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 1)
#define ip4_addr3_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 2)
#define ip4_addr4_val(ipaddr) ip4_addr_get_byte_val(ipaddr, 3)
/* These are cast to u16_t, with the intent that they are often arguments
* to printf using the U16_F format from cc.h. */
#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr))
#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr))
#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
#define ip4_addr1_16_val(ipaddr) ((u16_t)ip4_addr1_val(ipaddr))
#define ip4_addr2_16_val(ipaddr) ((u16_t)ip4_addr2_val(ipaddr))
#define ip4_addr3_16_val(ipaddr) ((u16_t)ip4_addr3_val(ipaddr))
#define ip4_addr4_16_val(ipaddr) ((u16_t)ip4_addr4_val(ipaddr))
#define IP4ADDR_STRLEN_MAX 16

View File

@ -66,10 +66,10 @@ err_t ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_add
u8_t hl, u8_t tc, u8_t nexth, struct netif *netif);
err_t ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
u8_t hl, u8_t tc, u8_t nexth, struct netif *netif);
#if LWIP_NETIF_HWADDRHINT
#if LWIP_NETIF_USE_HINTS
err_t ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint);
#endif /* LWIP_NETIF_HWADDRHINT */
u8_t hl, u8_t tc, u8_t nexth, struct netif_hint *netif_hint);
#endif /* LWIP_NETIF_USE_HINTS */
#if LWIP_IPV6_MLD
err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value);
#endif /* LWIP_IPV6_MLD */

View File

@ -47,6 +47,7 @@
#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
#include "lwip/ip6_zone.h"
#ifdef __cplusplus
extern "C" {
@ -57,6 +58,9 @@ extern "C" {
used as local variable, on the stack, etc. */
struct ip6_addr {
u32_t addr[4];
#if LWIP_IPV6_SCOPES
u8_t zone;
#endif /* LWIP_IPV6_SCOPES */
};
/** IPv6 address */
@ -72,7 +76,8 @@ typedef struct ip6_addr ip6_addr_t;
(ip6addr)->addr[0] = idx0; \
(ip6addr)->addr[1] = idx1; \
(ip6addr)->addr[2] = idx2; \
(ip6addr)->addr[3] = idx3; } while(0)
(ip6addr)->addr[3] = idx3; \
ip6_addr_clear_zone(ip6addr); } while(0)
/** Access address in 16-bit block */
#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xffff))
@ -95,18 +100,34 @@ typedef struct ip6_addr ip6_addr_t;
#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \
(dest).addr[1] = (src).addr[1]; \
(dest).addr[2] = (src).addr[2]; \
(dest).addr[3] = (src).addr[3];}while(0)
(dest).addr[3] = (src).addr[3]; \
ip6_addr_copy_zone((dest), (src)); }while(0)
/** Safely copy one IPv6 address to another (src may be NULL) */
#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \
(dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \
(dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \
(dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0)
(dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3]; \
ip6_addr_set_zone((dest), (src) == NULL ? IP6_NO_ZONE : ip6_addr_zone(src)); }while(0)
/** Copy packed IPv6 address to unpacked IPv6 address; zone is not set */
#define ip6_addr_copy_from_packed(dest, src) do{(dest).addr[0] = (src).addr[0]; \
(dest).addr[1] = (src).addr[1]; \
(dest).addr[2] = (src).addr[2]; \
(dest).addr[3] = (src).addr[3]; \
ip6_addr_clear_zone(&dest); }while(0)
/** Copy unpacked IPv6 address to packed IPv6 address; zone is lost */
#define ip6_addr_copy_to_packed(dest, src) do{(dest).addr[0] = (src).addr[0]; \
(dest).addr[1] = (src).addr[1]; \
(dest).addr[2] = (src).addr[2]; \
(dest).addr[3] = (src).addr[3]; }while(0)
/** Set complete address to zero */
#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[2] = 0; \
(ip6addr)->addr[3] = 0;}while(0)
(ip6addr)->addr[3] = 0; \
ip6_addr_clear_zone(ip6addr);}while(0)
/** Set address to ipv6 'any' (no need for lwip_htonl()) */
#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr)
@ -114,29 +135,57 @@ typedef struct ip6_addr ip6_addr_t;
#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[2] = 0; \
(ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0)
(ip6addr)->addr[3] = PP_HTONL(0x00000001UL); \
ip6_addr_clear_zone(ip6addr);}while(0)
/** Safely copy one IPv6 address to another and change byte order
* from host- to network-order. */
#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : lwip_htonl((src)->addr[0]); \
(dest)->addr[1] = (src) == NULL ? 0 : lwip_htonl((src)->addr[1]); \
(dest)->addr[2] = (src) == NULL ? 0 : lwip_htonl((src)->addr[2]); \
(dest)->addr[3] = (src) == NULL ? 0 : lwip_htonl((src)->addr[3]);}while(0)
(dest)->addr[3] = (src) == NULL ? 0 : lwip_htonl((src)->addr[3]); \
ip6_addr_set_zone((dest), (src) == NULL ? IP6_NO_ZONE : ip6_addr_zone(src));}while(0)
/** Compare IPv6 networks, ignoring zone information. To be used sparingly! */
#define ip6_addr_netcmp_zoneless(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
((addr1)->addr[1] == (addr2)->addr[1]))
/**
* Determine if two IPv6 address are on the same network.
*
* @arg addr1 IPv6 address 1
* @arg addr2 IPv6 address 2
* @return !0 if the network identifiers of both address match
* @param addr1 IPv6 address 1
* @param addr2 IPv6 address 2
* @return 1 if the network identifiers of both address match, 0 if not
*/
#define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
((addr1)->addr[1] == (addr2)->addr[1]))
#define ip6_addr_netcmp(addr1, addr2) (ip6_addr_netcmp_zoneless((addr1), (addr2)) && \
ip6_addr_cmp_zone((addr1), (addr2)))
#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
/* Exact-host comparison *after* ip6_addr_netcmp() succeeded, for efficiency. */
#define ip6_addr_nethostcmp(addr1, addr2) (((addr1)->addr[2] == (addr2)->addr[2]) && \
((addr1)->addr[3] == (addr2)->addr[3]))
/** Compare IPv6 addresses, ignoring zone information. To be used sparingly! */
#define ip6_addr_cmp_zoneless(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
((addr1)->addr[1] == (addr2)->addr[1]) && \
((addr1)->addr[2] == (addr2)->addr[2]) && \
((addr1)->addr[3] == (addr2)->addr[3]))
/**
* Determine if two IPv6 addresses are the same. In particular, the address
* part of both must be the same, and the zone must be compatible.
*
* @param addr1 IPv6 address 1
* @param addr2 IPv6 address 2
* @return 1 if the addresses are considered equal, 0 if not
*/
#define ip6_addr_cmp(addr1, addr2) (ip6_addr_cmp_zoneless((addr1), (addr2)) && \
ip6_addr_cmp_zone((addr1), (addr2)))
/** Compare IPv6 address to packed address and zone */
#define ip6_addr_cmp_packed(ip6addr, paddr, zone_idx) (((ip6addr)->addr[0] == (paddr)->addr[0]) && \
((ip6addr)->addr[1] == (paddr)->addr[1]) && \
((ip6addr)->addr[2] == (paddr)->addr[2]) && \
((ip6addr)->addr[3] == (paddr)->addr[3]) && \
ip6_addr_equals_zone((ip6addr), (zone_idx)))
#define ip6_get_subnet_id(ip6addr) (lwip_htonl((ip6addr)->addr[2]) & 0x0000ffffUL)
@ -183,7 +232,13 @@ typedef struct ip6_addr ip6_addr_t;
#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff080000UL))
#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff0e0000UL))
/* @todo define get/set for well-know multicast addresses, e.g. ff02::1 */
/* Scoping note: while interface-local and link-local multicast addresses do
* have a scope (i.e., they are meaningful only in the context of a particular
* interface), the following functions are not assigning or comparing zone
* indices. The reason for this is backward compatibility. Any call site that
* produces a non-global multicast address must assign a multicast address as
* appropriate itself. */
#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \
((ip6addr)->addr[1] == 0UL) && \
((ip6addr)->addr[2] == 0UL) && \
@ -196,7 +251,8 @@ typedef struct ip6_addr ip6_addr_t;
#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[2] = 0; \
(ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0)
(ip6addr)->addr[3] = PP_HTONL(0x00000001UL); \
ip6_addr_clear_zone(ip6addr); }while(0)
#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
((ip6addr)->addr[1] == 0UL) && \
@ -205,7 +261,8 @@ typedef struct ip6_addr ip6_addr_t;
#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[2] = 0; \
(ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0)
(ip6addr)->addr[3] = PP_HTONL(0x00000002UL); \
ip6_addr_clear_zone(ip6addr); }while(0)
#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \
@ -214,7 +271,8 @@ typedef struct ip6_addr ip6_addr_t;
#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \
(ip6addr)->addr[3] = (PP_HTONL(0xff000000UL) | (if_id));}while(0)
(ip6addr)->addr[3] = (PP_HTONL(0xff000000UL) | (if_id)); \
ip6_addr_clear_zone(ip6addr); }while(0)
#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
((ip6addr)->addr[1] == 0) && \
@ -234,6 +292,7 @@ typedef struct ip6_addr ip6_addr_t;
#define IP6_ADDR_VALID 0x10 /* This bit marks an address as valid (preferred or deprecated) */
#define IP6_ADDR_PREFERRED 0x30
#define IP6_ADDR_DEPRECATED 0x10 /* Same as VALID (valid but not preferred) */
#define IP6_ADDR_DUPLICATED 0x40 /* Failed DAD test, not valid */
#define IP6_ADDR_TENTATIVE_COUNT_MASK 0x07 /* 1-7 probes sent */
@ -242,6 +301,14 @@ typedef struct ip6_addr ip6_addr_t;
#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */
#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED)
#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED)
#define ip6_addr_isduplicated(addr_state) (addr_state == IP6_ADDR_DUPLICATED)
#if LWIP_IPV6_ADDRESS_LIFETIMES
#define IP6_ADDR_LIFE_STATIC (0)
#define IP6_ADDR_LIFE_INFINITE (0xffffffffUL)
#define ip6_addr_life_isstatic(addr_life) ((addr_life) == IP6_ADDR_LIFE_STATIC)
#define ip6_addr_life_isinfinite(addr_life) ((addr_life) == IP6_ADDR_LIFE_INFINITE)
#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
#define ip6_addr_debug_print_parts(debug, a, b, c, d, e, f, g, h) \
LWIP_DEBUGF(debug, ("%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F, \

View File

@ -54,24 +54,34 @@ extern "C" {
#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */
/** IP6_FRAG_COPYHEADER==1: for platforms where sizeof(void*) > 4, this needs to
* be enabled (to not overwrite part of the data). When enabled, the IPv6 header
* is copied instead of referencing it, which gives more room for struct ip6_reass_helper */
/** The IPv6 reassembly timer interval in milliseconds. */
#define IP6_REASS_TMR_INTERVAL 1000
/** IP6_FRAG_COPYHEADER==1: for platforms where sizeof(void*) > 4, "struct
* ip6_reass_helper" is too large to be stored in the IPv6 fragment header, and
* will bleed into the header before it, which may be the IPv6 header or an
* extension header. This means that for each first fragment packet, we need to
* 1) make a copy of some IPv6 header fields (src+dest) that we need later on,
* just in case we do overwrite part of the IPv6 header, and 2) make a copy of
* the header data that we overwrote, so that we can restore it before either
* completing reassembly or sending an ICMPv6 reply. The last part is true even
* if this setting is disabled, but if it is enabled, we need to save a bit
* more data (up to the size of a pointer) because we overwrite more. */
#ifndef IPV6_FRAG_COPYHEADER
#define IPV6_FRAG_COPYHEADER 0
#endif
/** The IPv6 reassembly timer interval in milliseconds. */
#define IP6_REASS_TMR_INTERVAL 1000
/* Copy the complete header of the first fragment to struct ip6_reassdata
or just point to its original location in the first pbuf? */
/* With IPV6_FRAG_COPYHEADER==1, a helper structure may (or, depending on the
* presence of extensions, may not) overwrite part of the IP header. Therefore,
* we copy the fields that we need from the IP header for as long as the helper
* structure may still be in place. This is easier than temporarily restoring
* those fields in the IP header each time we need to perform checks on them. */
#if IPV6_FRAG_COPYHEADER
#define IPV6_FRAG_HDRPTR
#define IPV6_FRAG_HDRREF(hdr) (&(hdr))
#define IPV6_FRAG_SRC(ipr) ((ipr)->src)
#define IPV6_FRAG_DEST(ipr) ((ipr)->dest)
#else /* IPV6_FRAG_COPYHEADER */
#define IPV6_FRAG_HDRPTR *
#define IPV6_FRAG_HDRREF(hdr) (hdr)
#define IPV6_FRAG_SRC(ipr) ((ipr)->iphdr->src)
#define IPV6_FRAG_DEST(ipr) ((ipr)->iphdr->dest)
#endif /* IPV6_FRAG_COPYHEADER */
/** IPv6 reassembly helper struct.
@ -80,11 +90,25 @@ extern "C" {
struct ip6_reassdata {
struct ip6_reassdata *next;
struct pbuf *p;
struct ip6_hdr IPV6_FRAG_HDRPTR iphdr;
struct ip6_hdr *iphdr; /* pointer to the first (original) IPv6 header */
#if IPV6_FRAG_COPYHEADER
ip6_addr_p_t src; /* copy of the source address in the IP header */
ip6_addr_p_t dest; /* copy of the destination address in the IP header */
/* This buffer (for the part of the original header that we overwrite) will
* be slightly oversized, but we cannot compute the exact size from here. */
u8_t orig_hdr[sizeof(struct ip6_frag_hdr) + sizeof(void*)];
#else /* IPV6_FRAG_COPYHEADER */
/* In this case we still need the buffer, for sending ICMPv6 replies. */
u8_t orig_hdr[sizeof(struct ip6_frag_hdr)];
#endif /* IPV6_FRAG_COPYHEADER */
u32_t identification;
u16_t datagram_len;
u8_t nexth;
u8_t timer;
#if LWIP_IPV6_SCOPES
u8_t src_zone; /* zone of original packet's source address */
u8_t dest_zone; /* zone of original packet's destination address */
#endif /* LWIP_IPV6_SCOPES */
};
#define ip6_reass_init() /* Compatibility define */

View File

@ -0,0 +1,304 @@
/**
* @file
*
* IPv6 address scopes, zones, and scoping policy.
*
* This header provides the means to implement support for IPv6 address scopes,
* as per RFC 4007. An address scope can be either global or more constrained.
* In lwIP, we say that an address "has a scope" or "is scoped" when its scope
* is constrained, in which case the address is meaningful only in a specific
* "zone." For unicast addresses, only link-local addresses have a scope; in
* that case, the scope is the link. For multicast addresses, there are various
* scopes defined by RFC 4007 and others. For any constrained scope, a system
* must establish a (potentially one-to-many) mapping between zones and local
* interfaces. For example, a link-local address is valid on only one link (its
* zone). That link may be attached to one or more local interfaces. The
* decisions on which scopes are constrained and the mapping between zones and
* interfaces is together what we refer to as the "scoping policy" - more on
* this in a bit.
*
* In lwIP, each IPv6 address has an associated zone index. This zone index may
* be set to "no zone" (IP6_NO_ZONE, 0) or an actual zone. We say that an
* address "has a zone" or "is zoned" when its zone index is *not* set to "no
* zone." In lwIP, in principle, each address should be "properly zoned," which
* means that if the address has a zone if and only if has a scope. As such, it
* is a rule that an unscoped (e.g., global) address must never have a zone.
* Even though one could argue that there is always one zone even for global
* scopes, this rule exists for implementation simplicity. Violation of the
* rule will trigger assertions or otherwise result in undesired behavior.
*
* Backward compatibility prevents us from requiring that applications always
* provide properly zoned addresses. We do enforce the rule that the in the
* lwIP link layer (everything below netif->output_ip6() and in particular ND6)
* *all* addresses are properly zoned. Thus, on the output paths down the
* stack, various places deal with the case of addresses that lack a zone.
* Some of them are best-effort for efficiency (e.g. the PCB bind and connect
* API calls' attempts to add missing zones); ultimately the IPv6 output
* handler (@ref ip6_output_if_src) will set a zone if necessary.
*
* Aside from dealing with scoped addresses lacking a zone, a proper IPv6
* implementation must also ensure that a packet with a scoped source and/or
* destination address does not leave its zone. This is currently implemented
* in the input and forward functions. However, for output, these checks are
* deliberately omitted in order to keep the implementation lightweight. The
* routing algorithm in @ref ip6_route will take decisions such that it will
* not cause zone violations unless the application sets bad addresses, though.
*
* In terms of scoping policy, lwIP implements the default policy from RFC 4007
* using macros in this file. This policy considers link-local unicast
* addresses and (only) interface-local and link-local multicast addresses as
* having a scope. For all these addresses, the zone is equal to the interface.
* As shown below in this file, it is possible to implement a custom policy.
*/
/*
* Copyright (c) 2017 The MINIX 3 Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: David van Moolenbroek <david@minix3.org>
*
*/
#ifndef LWIP_HDR_IP6_ZONE_H
#define LWIP_HDR_IP6_ZONE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup ip6_zones IPv6 Zones
* @ingroup ip6
* @{
*/
#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
/** Identifier for "no zone". */
#define IP6_NO_ZONE 0
#if LWIP_IPV6_SCOPES
/** Zone initializer for static IPv6 address initialization, including comma. */
#define IPADDR6_ZONE_INIT , IP6_NO_ZONE
/** Return the zone index of the given IPv6 address; possibly "no zone". */
#define ip6_addr_zone(ip6addr) ((ip6addr)->zone)
/** Does the given IPv6 address have a zone set? (0/1) */
#define ip6_addr_has_zone(ip6addr) (ip6_addr_zone(ip6addr) != IP6_NO_ZONE)
/** Set the zone field of an IPv6 address to a particular value. */
#define ip6_addr_set_zone(ip6addr, zone_idx) ((ip6addr)->zone = (zone_idx))
/** Clear the zone field of an IPv6 address, setting it to "no zone". */
#define ip6_addr_clear_zone(ip6addr) ((ip6addr)->zone = IP6_NO_ZONE)
/** Copy the zone field from the second IPv6 address to the first one. */
#define ip6_addr_copy_zone(ip6addr1, ip6addr2) ((ip6addr1).zone = (ip6addr2).zone)
/** Is the zone field of the given IPv6 address equal to the given zone index? (0/1) */
#define ip6_addr_equals_zone(ip6addr, zone_idx) ((ip6addr)->zone == (zone_idx))
/** Are the zone fields of the given IPv6 addresses equal? (0/1)
* This macro must only be used on IPv6 addresses of the same scope. */
#define ip6_addr_cmp_zone(ip6addr1, ip6addr2) ((ip6addr1)->zone == (ip6addr2)->zone)
/** Symbolic constants for the 'type' parameters in some of the macros.
* These exist for efficiency only, allowing the macros to avoid certain tests
* when the address is known not to be of a certain type. Dead code elimination
* will do the rest. IP6_MULTICAST is supported but currently not optimized.
* @see ip6_addr_has_scope, ip6_addr_assign_zone, ip6_addr_lacks_zone.
*/
enum lwip_ipv6_scope_type
{
/** Unknown */
IP6_UNKNOWN = 0,
/** Unicast */
IP6_UNICAST = 1,
/** Multicast */
IP6_MULTICAST = 2
};
/** IPV6_CUSTOM_SCOPES: together, the following three macro definitions,
* @ref ip6_addr_has_scope, @ref ip6_addr_assign_zone, and
* @ref ip6_addr_test_zone, completely define the lwIP scoping policy.
* The definitions below implement the default policy from RFC 4007 Sec. 6.
* Should an implementation desire to implement a different policy, it can
* define IPV6_CUSTOM_SCOPES to 1 and supply its own definitions for the three
* macros instead.
*/
#ifndef IPV6_CUSTOM_SCOPES
#define IPV6_CUSTOM_SCOPES 0
#endif /* !IPV6_CUSTOM_SCOPES */
#if !IPV6_CUSTOM_SCOPES
/**
* Determine whether an IPv6 address has a constrained scope, and as such is
* meaningful only if accompanied by a zone index to identify the scope's zone.
* The given address type may be used to eliminate at compile time certain
* checks that will evaluate to false at run time anyway.
*
* This default implementation follows the default model of RFC 4007, where
* only interface-local and link-local scopes are defined.
*
* Even though the unicast loopback address does have an implied link-local
* scope, in this implementation it does not have an explicitly assigned zone
* index. As such it should not be tested for in this macro.
*
* @param ip6addr the IPv6 address (const); only its address part is examined.
* @param type address type; see @ref lwip_ipv6_scope_type.
* @return 1 if the address has a constrained scope, 0 if it does not.
*/
#define ip6_addr_has_scope(ip6addr, type) \
(ip6_addr_islinklocal(ip6addr) || (((type) != IP6_UNICAST) && \
(ip6_addr_ismulticast_iflocal(ip6addr) || \
ip6_addr_ismulticast_linklocal(ip6addr))))
/**
* Assign a zone index to an IPv6 address, based on a network interface. If the
* given address has a scope, the assigned zone index is that scope's zone of
* the given netif; otherwise, the assigned zone index is "no zone".
*
* This default implementation follows the default model of RFC 4007, where
* only interface-local and link-local scopes are defined, and the zone index
* of both of those scopes always equals the index of the network interface.
* As such, this default implementation need not distinguish between different
* constrained scopes when assigning the zone.
*
* @param ip6addr the IPv6 address; its address part is examined, and its zone
* index is assigned.
* @param type address type; see @ref lwip_ipv6_scope_type.
* @param netif the network interface (const).
*/
#define ip6_addr_assign_zone(ip6addr, type, netif) \
(ip6_addr_set_zone((ip6addr), \
ip6_addr_has_scope((ip6addr), (type)) ? netif_get_index(netif) : 0))
/**
* Test whether an IPv6 address is "zone-compatible" with a network interface.
* That is, test whether the network interface is part of the zone associated
* with the address. For efficiency, this macro is only ever called if the
* given address is either scoped or zoned, and thus, it need not test this.
* If an address is scoped but not zoned, or zoned and not scoped, it is
* considered not zone-compatible with any netif.
*
* This default implementation follows the default model of RFC 4007, where
* only interface-local and link-local scopes are defined, and the zone index
* of both of those scopes always equals the index of the network interface.
* As such, there is always only one matching netif for a specific zone index,
* but all call sites of this macro currently support multiple matching netifs
* as well (at no additional expense in the common case).
*
* @param ip6addr the IPv6 address (const).
* @param netif the network interface (const).
* @return 1 if the address is scope-compatible with the netif, 0 if not.
*/
#define ip6_addr_test_zone(ip6addr, netif) \
(ip6_addr_equals_zone((ip6addr), netif_get_index(netif)))
#endif /* !IPV6_CUSTOM_SCOPES */
/** Does the given IPv6 address have a scope, and as such should also have a
* zone to be meaningful, but does not actually have a zone? (0/1) */
#define ip6_addr_lacks_zone(ip6addr, type) \
(!ip6_addr_has_zone(ip6addr) && ip6_addr_has_scope((ip6addr), (type)))
/**
* Try to select a zone for a scoped address that does not yet have a zone.
* Called from PCB bind and connect routines, for two reasons: 1) to save on
* this (relatively expensive) selection for every individual packet route
* operation and 2) to allow the application to obtain the selected zone from
* the PCB as is customary for e.g. getsockname/getpeername BSD socket calls.
*
* Ideally, callers would always supply a properly zoned address, in which case
* this function would not be needed. It exists both for compatibility with the
* BSD socket API (which accepts zoneless destination addresses) and for
* backward compatibility with pre-scoping lwIP code.
*
* It may be impossible to select a zone, e.g. if there are no netifs. In that
* case, the address's zone field will be left as is.
*
* @param dest the IPv6 address for which to select and set a zone.
* @param src source IPv6 address (const); may be equal to dest.
*/
#define ip6_addr_select_zone(dest, src) do { struct netif *selected_netif; \
selected_netif = ip6_route((src), (dest)); \
if (selected_netif != NULL) { \
ip6_addr_assign_zone((dest), IP6_UNKNOWN, selected_netif); \
} } while (0)
/**
* @}
*/
#else /* LWIP_IPV6_SCOPES */
#define IPADDR6_ZONE_INIT
#define ip6_addr_zone(ip6addr) (IP6_NO_ZONE)
#define ip6_addr_has_zone(ip6addr) (0)
#define ip6_addr_set_zone(ip6addr, zone_idx)
#define ip6_addr_clear_zone(ip6addr)
#define ip6_addr_copy_zone(ip6addr1, ip6addr2)
#define ip6_addr_equals_zone(ip6addr, zone_idx) (1)
#define ip6_addr_cmp_zone(ip6addr1, ip6addr2) (1)
#define IPV6_CUSTOM_SCOPES 0
#define ip6_addr_has_scope(ip6addr, type) (0)
#define ip6_addr_assign_zone(ip6addr, type, netif)
#define ip6_addr_test_zone(ip6addr, netif) (1)
#define ip6_addr_lacks_zone(ip6addr, type) (0)
#define ip6_addr_select_zone(ip6addr, src)
#endif /* LWIP_IPV6_SCOPES */
#if LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG
/** Verify that the given IPv6 address is properly zoned. */
#define IP6_ADDR_ZONECHECK(ip6addr) LWIP_ASSERT("IPv6 zone check failed", \
ip6_addr_has_scope(ip6addr, IP6_UNKNOWN) == ip6_addr_has_zone(ip6addr))
/** Verify that the given IPv6 address is properly zoned for the given netif. */
#define IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif) LWIP_ASSERT("IPv6 netif zone check failed", \
ip6_addr_has_scope(ip6addr, IP6_UNKNOWN) ? \
(ip6_addr_has_zone(ip6addr) && \
(((netif) == NULL) || ip6_addr_test_zone((ip6addr), (netif)))) : \
!ip6_addr_has_zone(ip6addr))
#else /* LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG */
#define IP6_ADDR_ZONECHECK(ip6addr)
#define IP6_ADDR_ZONECHECK_NETIF(ip6addr, netif)
#endif /* LWIP_IPV6_SCOPES && LWIP_IPV6_SCOPES_DEBUG */
#endif /* LWIP_IPV6 */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_IP6_ZONE_H */

View File

@ -78,18 +78,19 @@ typedef struct ip_addr {
extern const ip_addr_t ip_addr_any_type;
/** @ingroup ip4addr */
#define IPADDR4_INIT(u32val) { { { { u32val, 0ul, 0ul, 0ul } } }, IPADDR_TYPE_V4 }
#define IPADDR4_INIT(u32val) { { { { u32val, 0ul, 0ul, 0ul } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V4 }
/** @ingroup ip4addr */
#define IPADDR4_INIT_BYTES(a,b,c,d) IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d)))
/** @ingroup ip6addr */
#define IPADDR6_INIT(a, b, c, d) { { { { a, b, c, d } } }, IPADDR_TYPE_V6 }
#define IPADDR6_INIT(a, b, c, d) { { { { a, b, c, d } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V6 }
/** @ingroup ip6addr */
#define IPADDR6_INIT_HOST(a, b, c, d) { { { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } } }, IPADDR_TYPE_V6 }
#define IPADDR6_INIT_HOST(a, b, c, d) { { { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_V6 }
/** @ingroup ipaddr */
#define IP_IS_ANY_TYPE_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_ANY)
/** @ingroup ipaddr */
#define IPADDR_ANY_TYPE_INIT { { { { 0ul, 0ul, 0ul, 0ul } } }, IPADDR_TYPE_ANY }
#define IPADDR_ANY_TYPE_INIT { { { { 0ul, 0ul, 0ul, 0ul } IPADDR6_ZONE_INIT } }, IPADDR_TYPE_ANY }
/** @ingroup ip4addr */
#define IP_IS_V4_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4)
@ -100,15 +101,12 @@ extern const ip_addr_t ip_addr_any_type;
/** @ingroup ip6addr */
#define IP_IS_V6(ipaddr) (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr)))
#if ESP_LWIP
#define IP_V6_EQ_PART(ipaddr, WORD, VAL) (ip_2_ip6(ipaddr)->addr[WORD] == htonl(VAL))
#define IP_IS_V4MAPPEDV6(ipaddr) (IP_IS_V6(ipaddr) && IP_V6_EQ_PART(ipaddr, 0, 0) && IP_V6_EQ_PART(ipaddr, 1, 0) && IP_V6_EQ_PART(ipaddr, 2, 0x0000FFFF))
#endif
#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0)
#define IP_SET_TYPE(ipaddr, iptype) do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0)
#define IP_GET_TYPE(ipaddr) ((ipaddr)->type)
#define IP_ADDR_RAW_SIZE(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4 ? sizeof(ip4_addr_t) : sizeof(ip6_addr_t))
#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) (IP_GET_TYPE(&pcb->local_ip) == IP_GET_TYPE(ipaddr))
#define IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr) (IP_IS_ANY_TYPE_VAL(pcb->local_ip) || IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr))
@ -130,26 +128,42 @@ extern const ip_addr_t ip_addr_any_type;
/** @ingroup ip6addr */
#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3) IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3))
#define ip_clear_no4(ipaddr) do { ip_2_ip6(ipaddr)->addr[1] = \
ip_2_ip6(ipaddr)->addr[2] = \
ip_2_ip6(ipaddr)->addr[3] = 0; \
ip6_addr_clear_zone(ip_2_ip6(ipaddr)); }while(0)
#if ESP_IPV6
#define IP_V6_EQ_PART(ipaddr, WORD, VAL) (ip_2_ip6(ipaddr)->addr[WORD] == htonl(VAL))
#define IP_IS_V4MAPPEDV6(ipaddr) (IP_IS_V6(ipaddr) && IP_V6_EQ_PART(ipaddr, 0, 0) && IP_V6_EQ_PART(ipaddr, 1, 0) && IP_V6_EQ_PART(ipaddr, 2, 0x0000FFFF))
#endif
/** @ingroup ipaddr */
#define ip_addr_copy(dest, src) do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \
ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \
ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); }}while(0)
ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); ip_clear_no4(&dest); }}while(0)
/** @ingroup ip6addr */
#define ip_addr_copy_from_ip6(dest, src) do{ \
ip6_addr_copy(*ip_2_ip6(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V6); }while(0)
/** @ingroup ip6addr */
#define ip_addr_copy_from_ip6_packed(dest, src) do{ \
ip6_addr_copy_from_packed(*ip_2_ip6(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V6); }while(0)
/** @ingroup ip4addr */
#define ip_addr_copy_from_ip4(dest, src) do{ \
ip4_addr_copy(*ip_2_ip4(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V4); }while(0)
ip4_addr_copy(*ip_2_ip4(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V4); ip_clear_no4(&dest); }while(0)
/** @ingroup ip4addr */
#define ip_addr_set_ip4_u32(ipaddr, val) do{if(ipaddr){ip4_addr_set_u32(ip_2_ip4(ipaddr), val); \
IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0)
/** @ingroup ip4addr */
#define ip_addr_set_ip4_u32_val(ipaddr, val) do{ ip4_addr_set_u32(ip_2_ip4(&(ipaddr)), val); \
IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }while(0)
/** @ingroup ip4addr */
#define ip_addr_get_ip4_u32(ipaddr) (((ipaddr) && IP_IS_V4(ipaddr)) ? \
ip4_addr_get_u32(ip_2_ip4(ipaddr)) : 0)
/** @ingroup ipaddr */
#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, IP_GET_TYPE(src)); if(IP_IS_V6(src)){ \
ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \
ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); }}while(0)
ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); ip_clear_no4(dest); }}while(0)
/** @ingroup ipaddr */
#define ip_addr_set_ipaddr(dest, src) ip_addr_set(dest, src)
/** @ingroup ipaddr */
@ -164,15 +178,23 @@ extern const ip_addr_t ip_addr_any_type;
/** @ingroup ipaddr */
#define ip_addr_set_any(is_ipv6, ipaddr) do{if(is_ipv6){ \
ip6_addr_set_any(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \
ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0)
/** @ingroup ipaddr */
#define ip_addr_set_any_val(is_ipv6, ipaddr) do{if(is_ipv6){ \
ip6_addr_set_any(ip_2_ip6(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V6); }else{ \
ip4_addr_set_any(ip_2_ip4(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }}while(0)
/** @ingroup ipaddr */
#define ip_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \
ip6_addr_set_loopback(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \
ip4_addr_set_loopback(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
ip4_addr_set_loopback(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0)
/** @ingroup ipaddr */
#define ip_addr_set_loopback_val(is_ipv6, ipaddr) do{if(is_ipv6){ \
ip6_addr_set_loopback(ip_2_ip6(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V6); }else{ \
ip4_addr_set_loopback(ip_2_ip4(&(ipaddr))); IP_SET_TYPE_VAL(ipaddr, IPADDR_TYPE_V4); ip_clear_no4(&ipaddr); }}while(0)
/** @ingroup ipaddr */
#define ip_addr_set_hton(dest, src) do{if(IP_IS_V6(src)){ \
ip6_addr_set_hton(ip_2_ip6(ipaddr), (src)); IP_SET_TYPE(dest, IPADDR_TYPE_V6); }else{ \
ip4_addr_set_hton(ip_2_ip4(ipaddr), (src)); IP_SET_TYPE(dest, IPADDR_TYPE_V4); }}while(0)
ip6_addr_set_hton(ip_2_ip6(dest), ip_2_ip6(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V6); }else{ \
ip4_addr_set_hton(ip_2_ip4(dest), ip_2_ip4(src)); IP_SET_TYPE(dest, IPADDR_TYPE_V4); ip_clear_no4(ipaddr); }}while(0)
/** @ingroup ipaddr */
#define ip_addr_get_network(target, host, netmask) do{if(IP_IS_V6(host)){ \
ip4_addr_set_zero(ip_2_ip4(target)); IP_SET_TYPE(target, IPADDR_TYPE_V6); } else { \
@ -186,9 +208,13 @@ extern const ip_addr_t ip_addr_any_type;
ip6_addr_cmp(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \
ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2))))
/** @ingroup ipaddr */
#define ip_addr_isany(ipaddr) ((IP_IS_V6(ipaddr)) ? \
#define ip_addr_cmp_zoneless(addr1, addr2) ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \
ip6_addr_cmp_zoneless(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \
ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2))))
/** @ingroup ipaddr */
#define ip_addr_isany(ipaddr) (((ipaddr) == NULL) ? 1 : ((IP_IS_V6(ipaddr)) ? \
ip6_addr_isany(ip_2_ip6(ipaddr)) : \
ip4_addr_isany(ip_2_ip4(ipaddr)))
ip4_addr_isany(ip_2_ip4(ipaddr))))
/** @ingroup ipaddr */
#define ip_addr_isany_val(ipaddr) ((IP_IS_V6_VAL(ipaddr)) ? \
ip6_addr_isany_val(*ip_2_ip6(&(ipaddr))) : \
@ -215,12 +241,8 @@ extern const ip_addr_t ip_addr_any_type;
#define ip_addr_debug_print_val(debug, ipaddr) do { if(IP_IS_V6_VAL(ipaddr)) { \
ip6_addr_debug_print_val(debug, *ip_2_ip6(&(ipaddr))); } else { \
ip4_addr_debug_print_val(debug, *ip_2_ip4(&(ipaddr))); }}while(0)
/** @ingroup ipaddr */
#define ipaddr_ntoa(addr) (((addr) == NULL) ? "NULL" : \
((IP_IS_V6(addr)) ? ip6addr_ntoa(ip_2_ip6(addr)) : ip4addr_ntoa(ip_2_ip4(addr))))
/** @ingroup ipaddr */
#define ipaddr_ntoa_r(addr, buf, buflen) (((addr) == NULL) ? "NULL" : \
((IP_IS_V6(addr)) ? ip6addr_ntoa_r(ip_2_ip6(addr), buf, buflen) : ip4addr_ntoa_r(ip_2_ip4(addr), buf, buflen)))
char *ipaddr_ntoa(const ip_addr_t *addr);
char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen);
int ipaddr_aton(const char *cp, ip_addr_t *addr);
/** @ingroup ipaddr */
@ -231,7 +253,8 @@ int ipaddr_aton(const char *cp, ip_addr_t *addr);
(ip6addr)->addr[3] = (ip4addr)->addr; \
(ip6addr)->addr[2] = PP_HTONL(0x0000FFFFUL); \
(ip6addr)->addr[1] = 0; \
(ip6addr)->addr[0] = 0; } while(0);
(ip6addr)->addr[0] = 0; \
ip6_addr_clear_zone(ip6addr); } while(0);
/** @ingroup ipaddr */
#define unmap_ipv4_mapped_ipv6(ip4addr, ip6addr) \
@ -241,8 +264,11 @@ int ipaddr_aton(const char *cp, ip_addr_t *addr);
#else /* LWIP_IPV4 && LWIP_IPV6 */
#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb) 1
#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) 1
#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb) 1
#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) 1
#define ip_addr_set_any_val(is_ipv6, ipaddr) ip_addr_set_any(is_ipv6, &(ipaddr))
#define ip_addr_set_loopback_val(is_ipv6, ipaddr) ip_addr_set_loopback(is_ipv6, &(ipaddr))
#if LWIP_IPV4
@ -257,12 +283,14 @@ typedef ip4_addr_t ip_addr_t;
#define IP_SET_TYPE_VAL(ipaddr, iptype)
#define IP_SET_TYPE(ipaddr, iptype)
#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V4
#define IP_ADDR_RAW_SIZE(ipaddr) sizeof(ip4_addr_t)
#define ip_2_ip4(ipaddr) (ipaddr)
#define IP_ADDR4(ipaddr,a,b,c,d) IP4_ADDR(ipaddr,a,b,c,d)
#define ip_addr_copy(dest, src) ip4_addr_copy(dest, src)
#define ip_addr_copy_from_ip4(dest, src) ip4_addr_copy(dest, src)
#define ip_addr_set_ip4_u32(ipaddr, val) ip4_addr_set_u32(ip_2_ip4(ipaddr), val)
#define ip_addr_set_ip4_u32_val(ipaddr, val) ip_addr_set_ip4_u32(&(ipaddr), val)
#define ip_addr_get_ip4_u32(ipaddr) ip4_addr_get_u32(ip_2_ip4(ipaddr))
#define ip_addr_set(dest, src) ip4_addr_set(dest, src)
#define ip_addr_set_ipaddr(dest, src) ip4_addr_set(dest, src)
@ -293,8 +321,8 @@ typedef ip4_addr_t ip_addr_t;
#else /* LWIP_IPV4 */
typedef ip6_addr_t ip_addr_t;
#define IPADDR6_INIT(a, b, c, d) { { a, b, c, d } }
#define IPADDR6_INIT_HOST(a, b, c, d) { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } }
#define IPADDR6_INIT(a, b, c, d) { { a, b, c, d } IPADDR6_ZONE_INIT }
#define IPADDR6_INIT_HOST(a, b, c, d) { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } IPADDR6_ZONE_INIT }
#define IP_IS_V4_VAL(ipaddr) 0
#define IP_IS_V6_VAL(ipaddr) 1
#define IP_IS_V4(ipaddr) 0
@ -303,12 +331,14 @@ typedef ip6_addr_t ip_addr_t;
#define IP_SET_TYPE_VAL(ipaddr, iptype)
#define IP_SET_TYPE(ipaddr, iptype)
#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V6
#define IP_ADDR_RAW_SIZE(ipaddr) sizeof(ip6_addr_t)
#define ip_2_ip6(ipaddr) (ipaddr)
#define IP_ADDR6(ipaddr,i0,i1,i2,i3) IP6_ADDR(ipaddr,i0,i1,i2,i3)
#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3) IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3))
#define ip_addr_copy(dest, src) ip6_addr_copy(dest, src)
#define ip_addr_copy_from_ip6(dest, src) ip6_addr_copy(dest, src)
#define ip_addr_copy_from_ip6_packed(dest, src) ip6_addr_copy_from_packed(dest, src)
#define ip_addr_set(dest, src) ip6_addr_set(dest, src)
#define ip_addr_set_ipaddr(dest, src) ip6_addr_set(dest, src)
#define ip_addr_set_zero(ipaddr) ip6_addr_set_zero(ipaddr)
@ -319,6 +349,7 @@ typedef ip6_addr_t ip_addr_t;
#define ip_addr_get_network(target, host, mask) ip6_addr_set_zero(target)
#define ip_addr_netcmp(addr1, addr2, mask) 0
#define ip_addr_cmp(addr1, addr2) ip6_addr_cmp(addr1, addr2)
#define ip_addr_cmp_zoneless(addr1, addr2) ip6_addr_cmp_zoneless(addr1, addr2)
#define ip_addr_isany(ipaddr) ip6_addr_isany(ipaddr)
#define ip_addr_isany_val(ipaddr) ip6_addr_isany_val(ipaddr)
#define ip_addr_isloopback(ipaddr) ip6_addr_isloopback(ipaddr)

View File

@ -90,7 +90,7 @@ extern const struct memp_desc* const memp_pools[MEMP_MAX];
* - free: LWIP_MEMPOOL_FREE(my_private_pool, my_new_mem);
*
* To relocate a pool, declare it as extern in cc.h. Example for GCC:
* extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_my_private_pool[];
* extern u8_t \_\_attribute\_\_((section(".onchip_mem"))) memp_memory_my_private_pool_base[];
*/
#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \
LWIP_DECLARE_MEMORY_ALIGNED(memp_memory_ ## name ## _base, ((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))); \

View File

@ -58,6 +58,11 @@ extern "C" {
/** 1 second period */
#define ND6_TMR_INTERVAL 1000
/** Router solicitations are sent in 4 second intervals (see RFC 4861, ch. 6.3.7) */
#ifndef ND6_RTR_SOLICITATION_INTERVAL
#define ND6_RTR_SOLICITATION_INTERVAL 4000
#endif
struct pbuf;
struct netif;
@ -74,8 +79,9 @@ void nd6_cleanup_netif(struct netif *netif);
#if LWIP_IPV6_MLD
void nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state);
#endif /* LWIP_IPV6_MLD */
void nd6_restart_netif(struct netif *netif);
#if ESP_LWIP
#if ESP_IPV6
/** set nd6 callback when ipv6 addr state pref*/
void nd6_set_cb(struct netif *netif, void (*cb)(struct netif *netif, u8_t ip_index));
#endif

View File

@ -62,9 +62,7 @@ struct netbuf {
ip_addr_t addr;
u16_t port;
#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY
#if LWIP_CHECKSUM_ON_COPY
u8_t flags;
#endif /* LWIP_CHECKSUM_ON_COPY */
u16_t toport_chksum;
#if LWIP_NETBUF_RECVINFO
ip_addr_t toaddr;

View File

@ -129,7 +129,7 @@ int lwip_getaddrinfo(const char *nodename,
struct addrinfo **res);
#if LWIP_COMPAT_SOCKETS
#if ESP_LWIP
#if ESP_SOCKET
#if LWIP_COMPAT_SOCKET_ADDR == 1
/* Some libraries have problems with inet_... being macros, so please use this define
to declare normal functions */
@ -156,7 +156,7 @@ static inline int getaddrinfo(const char *nodename, const char *servname, const
lwip_getaddrinfo(nodname, servname, hints, res)
#endif /* LWIP_COMPAT_SOCKET_ADDR == 1 */
#else /* ESP_LWIP */
#else /* ESP_SOCKET */
/** @ingroup netdbapi */
#define gethostbyname(name) lwip_gethostbyname(name)
@ -169,7 +169,7 @@ static inline int getaddrinfo(const char *nodename, const char *servname, const
#define getaddrinfo(nodname, servname, hints, res) \
lwip_getaddrinfo(nodname, servname, hints, res)
#endif /* ESP_LWIP */
#endif /* ESP_SOCKET */
#endif /* LWIP_COMPAT_SOCKETS */
#ifdef __cplusplus

View File

@ -63,6 +63,12 @@ extern "C" {
#define NETIF_MAX_HWADDR_LEN 6U
#endif
/** The size of a fully constructed netif name which the
* netif can be identified by in APIs. Composed of
* 2 chars, 3 (max) digits, and 1 \0
*/
#define NETIF_NAMESIZE 6
/**
* @defgroup netif_flags Flags
* @ingroup netif
@ -111,6 +117,7 @@ extern "C" {
enum lwip_internal_netif_client_data_index
{
#if LWIP_IPV4
#if LWIP_DHCP
LWIP_NETIF_CLIENT_DATA_INDEX_DHCP,
#endif
@ -120,9 +127,15 @@ enum lwip_internal_netif_client_data_index
#if LWIP_IGMP
LWIP_NETIF_CLIENT_DATA_INDEX_IGMP,
#endif
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
#if LWIP_IPV6_DHCP6
LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6,
#endif
#if LWIP_IPV6_MLD
LWIP_NETIF_CLIENT_DATA_INDEX_MLD6,
#endif
#endif /* LWIP_IPV6 */
LWIP_NETIF_CLIENT_DATA_INDEX_MAX
};
@ -163,6 +176,9 @@ typedef err_t (*netif_init_fn)(struct netif *netif);
*
* @param p The received packet, copied into a pbuf
* @param inp The netif which received the packet
* @return ERR_OK if the packet was handled
* != ERR_OK is the packet was NOT handled, in this case, the caller has
* to free the pbuf
*/
typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp);
@ -212,8 +228,10 @@ typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif,
const ip6_addr_t *group, enum netif_mac_filter_action action);
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
#if LWIP_DHCP || LWIP_AUTOIP || LWIP_IGMP || LWIP_IPV6_MLD || (LWIP_NUM_NETIF_CLIENT_DATA > 0)
#if LWIP_DHCP || LWIP_AUTOIP || LWIP_IGMP || LWIP_IPV6_MLD || LWIP_IPV6_DHCP6 || (LWIP_NUM_NETIF_CLIENT_DATA > 0)
#if LWIP_NUM_NETIF_CLIENT_DATA > 0
u8_t netif_alloc_client_data_id(void);
#endif
/** @ingroup netif_cd
* Set client data. Obtain ID from netif_alloc_client_data_id().
*/
@ -222,7 +240,24 @@ u8_t netif_alloc_client_data_id(void);
* Get client data. Obtain ID from netif_alloc_client_data_id().
*/
#define netif_get_client_data(netif, id) (netif)->client_data[(id)]
#endif /* LWIP_DHCP || LWIP_AUTOIP || (LWIP_NUM_NETIF_CLIENT_DATA > 0) */
#endif
#if (LWIP_IPV4 && LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) || (LWIP_IPV6 && (LWIP_ND6_NUM_DESTINATIONS > 0x7f))
typedef u16_t netif_addr_idx_t;
#define NETIF_ADDR_IDX_MAX 0x7FFF
#else
typedef u8_t netif_addr_idx_t;
#define NETIF_ADDR_IDX_MAX 0x7F
#endif
#if LWIP_NETIF_HWADDRHINT
#define LWIP_NETIF_USE_HINTS 1
struct netif_hint {
netif_addr_idx_t addr_hint;
};
#else /* LWIP_NETIF_HWADDRHINT */
#define LWIP_NETIF_USE_HINTS 0
#endif /* LWIP_NETIF_HWADDRHINT */
#if ESP_DHCP
/*add DHCP event processing by LiuHan*/
@ -233,8 +268,10 @@ typedef void (*dhcp_event_fn)(void);
* The following fields should be filled in by the initialization
* function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
struct netif {
#if !LWIP_SINGLE_NETIF
/** pointer to next in linked list */
struct netif *next;
#endif
#if LWIP_IPV4
/** IP address configuration in network byte order */
@ -248,10 +285,16 @@ struct netif {
/** The state of each IPv6 address (Tentative, Preferred, etc).
* @see ip6_addr.h */
u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES];
#if LWIP_IPV6_ADDRESS_LIFETIMES
/** Remaining valid and preferred lifetime of each IPv6 address, in seconds.
* For valid lifetimes, the special value of IP6_ADDR_LIFE_STATIC (0)
* indicates the address is static and has no lifetimes. */
u32_t ip6_addr_valid_life[LWIP_IPV6_NUM_ADDRESSES];
u32_t ip6_addr_pref_life[LWIP_IPV6_NUM_ADDRESSES];
#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
#if ESP_LWIP
void (*ipv6_addr_cb)(struct netif* netif, u8_t ip_idex); /* callback for ipv6 addr states changed */
#endif
#endif /* LWIP_IPV6 */
/** This function is called by the network device driver
* to pass a packet up the TCP/IP stack. */
@ -300,14 +343,6 @@ struct netif {
dhcp_event_fn dhcp_event;
#endif
#if LWIP_IPV6_AUTOCONFIG
/** is this netif enabled for IPv6 autoconfiguration */
u8_t ip6_autoconfig_enabled;
#endif /* LWIP_IPV6_AUTOCONFIG */
#if LWIP_IPV6_SEND_ROUTER_SOLICIT
/** Number of Router Solicitation messages that remain to be sent. */
u8_t rs_count;
#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
#if LWIP_NETIF_HOSTNAME
/* the hostname for this netif, NULL is a valid value */
const char* hostname;
@ -317,16 +352,29 @@ struct netif {
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
/** maximum transfer unit (in bytes) */
u16_t mtu;
/** number of bytes used in hwaddr */
u8_t hwaddr_len;
#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
/** maximum transfer unit (in bytes), updated by RA */
u16_t mtu6;
#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
/** link level hardware address of this interface */
u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
/** number of bytes used in hwaddr */
u8_t hwaddr_len;
/** flags (@see @ref netif_flags) */
u8_t flags;
/** descriptive abbreviation */
char name[2];
/** number of this interface */
/** number of this interface. Used for @ref if_api and @ref netifapi_netif,
* as well as for IPv6 zones */
u8_t num;
#if LWIP_IPV6_AUTOCONFIG
/** is this netif enabled for IPv6 autoconfiguration */
u8_t ip6_autoconfig_enabled;
#endif /* LWIP_IPV6_AUTOCONFIG */
#if LWIP_IPV6_SEND_ROUTER_SOLICIT
/** Number of Router Solicitation messages that remain to be sent. */
u8_t rs_count;
#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
#if MIB2_STATS
/** link type (from "snmp_ifType" enum from snmp_mib2.h) */
u8_t link_type;
@ -347,9 +395,9 @@ struct netif {
filter table of the ethernet MAC. */
netif_mld_mac_filter_fn mld_mac_filter;
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
#if LWIP_NETIF_HWADDRHINT
u8_t *addr_hint;
#endif /* LWIP_NETIF_HWADDRHINT */
#if LWIP_NETIF_USE_HINTS
struct netif_hint *hints;
#endif /* LWIP_NETIF_USE_HINTS */
#if ENABLE_LOOPBACK
/* List of packets to be queued for ourselves. */
struct pbuf *loop_first;
@ -358,13 +406,11 @@ struct netif {
u16_t loop_cnt_current;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
#endif /* ENABLE_LOOPBACK */
#if ESP_LWIP
void (*l2_buffer_free_notify)(void *user_buf); /* Allows LWIP to notify driver when a L2-supplied pbuf can be freed */
#if ESP_PBUF
void (*l2_buffer_free_notify)(struct netif *lwip_netif, void *user_buf); /* Allows LWIP to notify driver when a L2-supplied pbuf can be freed */
ip_addr_t last_ip_addr; /* Store last non-zero ip address */
#endif
};
#if LWIP_CHECKSUM_CTRL_PER_NETIF
#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) do { \
(netif)->chksum_flags = chksumflags; } while(0)
@ -374,21 +420,28 @@ struct netif {
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#if LWIP_SINGLE_NETIF
#define NETIF_FOREACH(netif) if (((netif) = netif_default) != NULL)
#else /* LWIP_SINGLE_NETIF */
/** The list of network interfaces. */
extern struct netif *netif_list;
#define NETIF_FOREACH(netif) for ((netif) = netif_list; (netif) != NULL; (netif) = (netif)->next)
#endif /* LWIP_SINGLE_NETIF */
/** The default network interface. */
extern struct netif *netif_default;
void netif_init(void);
struct netif *netif_add_noaddr(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input);
#if LWIP_IPV4
struct netif *netif_add(struct netif *netif,
#if LWIP_IPV4
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);
#if LWIP_IPV4
const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
void *state, netif_init_fn init, netif_input_fn input);
void netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask,
const ip4_addr_t *gw);
#else /* LWIP_IPV4 */
struct netif *netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input);
#endif /* LWIP_IPV4 */
#if ESP_GRATUITOUS_ARP
@ -423,16 +476,16 @@ void netif_set_gw(struct netif *netif, const ip4_addr_t *gw);
#define netif_ip_gw4(netif) ((const ip_addr_t*)&((netif)->gw))
#endif /* LWIP_IPV4 */
#define netif_set_flags(netif, set_flags) do { (netif)->flags = (u8_t)((netif)->flags | (set_flags)); } while(0)
#define netif_clear_flags(netif, clr_flags) do { (netif)->flags = (u8_t)((netif)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
#define netif_is_flag_set(nefif, flag) (((netif)->flags & (flag)) != 0)
void netif_set_up(struct netif *netif);
void netif_set_down(struct netif *netif);
/** @ingroup netif
* Ask if an interface is up
*/
#if ESP_LWIP
#define netif_is_up(netif) ( ((netif) && ((netif)->flags & NETIF_FLAG_UP)) ? (u8_t)1 : (u8_t)0)
#else
#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0)
#endif
#if LWIP_NETIF_STATUS_CALLBACK
void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback);
@ -493,13 +546,148 @@ s8_t netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr);
void netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit);
err_t netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx);
#define netif_set_ip6_autoconfig_enabled(netif, action) do { if(netif) { (netif)->ip6_autoconfig_enabled = (action); }}while(0)
#if LWIP_IPV6_ADDRESS_LIFETIMES
#define netif_ip6_addr_valid_life(netif, i) \
(((netif) != NULL) ? ((netif)->ip6_addr_valid_life[i]) : IP6_ADDR_LIFE_STATIC)
#define netif_ip6_addr_set_valid_life(netif, i, secs) \
do { if (netif != NULL) { (netif)->ip6_addr_valid_life[i] = (secs); }} while (0)
#define netif_ip6_addr_pref_life(netif, i) \
(((netif) != NULL) ? ((netif)->ip6_addr_pref_life[i]) : IP6_ADDR_LIFE_STATIC)
#define netif_ip6_addr_set_pref_life(netif, i, secs) \
do { if (netif != NULL) { (netif)->ip6_addr_pref_life[i] = (secs); }} while (0)
#define netif_ip6_addr_isstatic(netif, i) \
(netif_ip6_addr_valid_life((netif), (i)) == IP6_ADDR_LIFE_STATIC)
#else /* !LWIP_IPV6_ADDRESS_LIFETIMES */
#define netif_ip6_addr_isstatic(netif, i) (1) /* all addresses are static */
#endif /* !LWIP_IPV6_ADDRESS_LIFETIMES */
#if LWIP_ND6_ALLOW_RA_UPDATES
#define netif_mtu6(netif) ((netif)->mtu6)
#else /* LWIP_ND6_ALLOW_RA_UPDATES */
#define netif_mtu6(netif) ((netif)->mtu)
#endif /* LWIP_ND6_ALLOW_RA_UPDATES */
#endif /* LWIP_IPV6 */
#if LWIP_NETIF_HWADDRHINT
#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint))
#else /* LWIP_NETIF_HWADDRHINT */
#define NETIF_SET_HWADDRHINT(netif, hint)
#endif /* LWIP_NETIF_HWADDRHINT */
#if LWIP_NETIF_USE_HINTS
#define NETIF_SET_HINTS(netif, netifhint) (netif)->hints = (netifhint)
#define NETIF_RESET_HINTS(netif) (netif)->hints = NULL
#else /* LWIP_NETIF_USE_HINTS */
#define NETIF_SET_HINTS(netif, netifhint)
#define NETIF_RESET_HINTS(netif)
#endif /* LWIP_NETIF_USE_HINTS */
u8_t netif_name_to_index(const char *name);
char * netif_index_to_name(u8_t idx, char *name);
struct netif* netif_get_by_index(u8_t idx);
/* Interface indexes always start at 1 per RFC 3493, section 4, num starts at 0 (internal index is 0..254)*/
#define netif_get_index(netif) ((u8_t)((netif)->num + 1))
#define NETIF_NO_INDEX (0)
/**
* @ingroup netif
* Extended netif status callback (NSC) reasons flags.
* May be extended in the future!
*/
typedef u16_t netif_nsc_reason_t;
/* used for initialization only */
#define LWIP_NSC_NONE 0x0000
/** netif was added. arg: NULL. Called AFTER netif was added. */
#define LWIP_NSC_NETIF_ADDED 0x0001
/** netif was removed. arg: NULL. Called BEFORE netif is removed. */
#define LWIP_NSC_NETIF_REMOVED 0x0002
/** link changed */
#define LWIP_NSC_LINK_CHANGED 0x0004
/** netif administrative status changed.\n
* up is called AFTER netif is set up.\n
* down is called BEFORE the netif is actually set down. */
#define LWIP_NSC_STATUS_CHANGED 0x0008
/** IPv4 address has changed */
#define LWIP_NSC_IPV4_ADDRESS_CHANGED 0x0010
/** IPv4 gateway has changed */
#define LWIP_NSC_IPV4_GATEWAY_CHANGED 0x0020
/** IPv4 netmask has changed */
#define LWIP_NSC_IPV4_NETMASK_CHANGED 0x0040
/** called AFTER IPv4 address/gateway/netmask changes have been applied */
#define LWIP_NSC_IPV4_SETTINGS_CHANGED 0x0080
/** IPv6 address was added */
#define LWIP_NSC_IPV6_SET 0x0100
/** IPv6 address state has changed */
#define LWIP_NSC_IPV6_ADDR_STATE_CHANGED 0x0200
/** @ingroup netif
* Argument supplied to netif_ext_callback_fn.
*/
typedef union
{
/** Args to LWIP_NSC_LINK_CHANGED callback */
struct link_changed_s
{
/** 1: up; 0: down */
u8_t state;
} link_changed;
/** Args to LWIP_NSC_STATUS_CHANGED callback */
struct status_changed_s
{
/** 1: up; 0: down */
u8_t state;
} status_changed;
/** Args to LWIP_NSC_IPV4_ADDRESS_CHANGED|LWIP_NSC_IPV4_GATEWAY_CHANGED|LWIP_NSC_IPV4_NETMASK_CHANGED|LWIP_NSC_IPV4_SETTINGS_CHANGED callback */
struct ipv4_changed_s
{
/** Old IPv4 address */
const ip_addr_t* old_address;
const ip_addr_t* old_netmask;
const ip_addr_t* old_gw;
} ipv4_changed;
/** Args to LWIP_NSC_IPV6_SET callback */
struct ipv6_set_s
{
/** Index of changed IPv6 address */
s8_t addr_index;
/** Old IPv6 address */
const ip_addr_t* old_address;
} ipv6_set;
/** Args to LWIP_NSC_IPV6_ADDR_STATE_CHANGED callback */
struct ipv6_addr_state_changed_s
{
/** Index of affected IPv6 address */
s8_t addr_index;
/** Old IPv6 address state */
u8_t old_state;
/** Affected IPv6 address */
const ip_addr_t* address;
} ipv6_addr_state_changed;
} netif_ext_callback_args_t;
/**
* @ingroup netif
* Function used for extended netif status callbacks
* Note: When parsing reason argument, keep in mind that more reasons may be added in the future!
* @param netif netif that is affected by change
* @param reason change reason
* @param args depends on reason, see reason description
*/
typedef void (*netif_ext_callback_fn)(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args);
#if LWIP_NETIF_EXT_STATUS_CALLBACK
struct netif_ext_callback;
typedef struct netif_ext_callback
{
netif_ext_callback_fn callback_fn;
struct netif_ext_callback* next;
} netif_ext_callback_t;
#define NETIF_DECLARE_EXT_CALLBACK(name) static netif_ext_callback_t name;
void netif_add_ext_callback(netif_ext_callback_t* callback, netif_ext_callback_fn fn);
void netif_remove_ext_callback(netif_ext_callback_t* callback);
void netif_invoke_ext_callback(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args);
#else
#define NETIF_DECLARE_EXT_CALLBACK(name)
#define netif_add_ext_callback(callback, fn)
#define netif_remove_ext_callback(callback)
#define netif_invoke_ext_callback(netif, reason, args)
#endif
#ifdef __cplusplus
}

View File

@ -41,43 +41,27 @@
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/priv/api_msg.h"
#include "lwip/prot/ethernet.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_MPU_COMPATIBLE
#define NETIFAPI_IPADDR_DEF(type, m) type m
#else /* LWIP_MPU_COMPATIBLE */
#define NETIFAPI_IPADDR_DEF(type, m) const type * m
#endif /* LWIP_MPU_COMPATIBLE */
typedef void (*netifapi_void_fn)(struct netif *netif);
typedef err_t (*netifapi_errt_fn)(struct netif *netif);
struct netifapi_msg {
struct tcpip_api_call_data call;
struct netif *netif;
union {
struct {
#if LWIP_IPV4
NETIFAPI_IPADDR_DEF(ip4_addr_t, ipaddr);
NETIFAPI_IPADDR_DEF(ip4_addr_t, netmask);
NETIFAPI_IPADDR_DEF(ip4_addr_t, gw);
#endif /* LWIP_IPV4 */
void *state;
netif_init_fn init;
netif_input_fn input;
} add;
struct {
netifapi_void_fn voidfunc;
netifapi_errt_fn errtfunc;
} common;
} msg;
/* API for application */
#if LWIP_ARP && LWIP_IPV4
/* Used for netfiapi_arp_* APIs */
enum netifapi_arp_entry {
NETIFAPI_ARP_PERM /* Permanent entry */
/* Other entry types can be added here */
};
/** @ingroup netifapi_arp */
err_t netifapi_arp_add(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, enum netifapi_arp_entry type);
/** @ingroup netifapi_arp */
err_t netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type);
#endif /* LWIP_ARP && LWIP_IPV4 */
/* API for application */
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,
@ -93,16 +77,33 @@ err_t netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
netifapi_errt_fn errtfunc);
/** @ingroup netifapi_netif */
err_t netifapi_netif_name_to_index(const char *name, u8_t *index);
/** @ingroup netifapi_netif */
err_t netifapi_netif_index_to_name(u8_t index, char *name);
/** @ingroup netifapi_netif
* @see netif_remove()
*/
#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL)
/** @ingroup netifapi_netif */
/** @ingroup netifapi_netif
* @see netif_set_up()
*/
#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL)
/** @ingroup netifapi_netif */
/** @ingroup netifapi_netif
* @see netif_set_down()
*/
#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL)
/** @ingroup netifapi_netif */
/** @ingroup netifapi_netif
* @see netif_set_default()
*/
#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL)
/** @ingroup netifapi_netif */
/** @ingroup netifapi_netif
* @see netif_set_link_up()
*/
#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL)
/** @ingroup netifapi_netif */
/** @ingroup netifapi_netif
* @see netif_set_link_down()
*/
#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL)
/**
@ -110,25 +111,45 @@ err_t netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
* @ingroup netifapi
* To be called from non-TCPIP threads
*/
/** @ingroup netifapi_dhcp4 */
#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start)
/** @ingroup netifapi_dhcp4 */
#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL)
/** @ingroup netifapi_dhcp4 */
#define netifapi_dhcp_inform(n) netifapi_netif_common(n, dhcp_inform, NULL)
/** @ingroup netifapi_dhcp4 */
#define netifapi_dhcp_renew(n) netifapi_netif_common(n, NULL, dhcp_renew)
/** @ingroup netifapi_dhcp4 */
#define netifapi_dhcp_release(n) netifapi_netif_common(n, NULL, dhcp_release)
/** @ingroup netifapi_dhcp4
* @see dhcp_start()
*/
#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start)
/**
* @ingroup netifapi_dhcp4
* @deprecated Use netifapi_dhcp_release_and_stop() instead.
*/
#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL)
/** @ingroup netifapi_dhcp4
* @see dhcp_inform()
*/
#define netifapi_dhcp_inform(n) netifapi_netif_common(n, dhcp_inform, NULL)
/** @ingroup netifapi_dhcp4
* @see dhcp_renew()
*/
#define netifapi_dhcp_renew(n) netifapi_netif_common(n, NULL, dhcp_renew)
/**
* @ingroup netifapi_dhcp4
* @deprecated Use netifapi_dhcp_release_and_stop() instead.
*/
#define netifapi_dhcp_release(n) netifapi_netif_common(n, NULL, dhcp_release)
/** @ingroup netifapi_dhcp4
* @see dhcp_release_and_stop()
*/
#define netifapi_dhcp_release_and_stop(n) netifapi_netif_common(n, dhcp_release_and_stop, NULL)
/**
* @defgroup netifapi_autoip AUTOIP
* @ingroup netifapi
* To be called from non-TCPIP threads
*/
/** @ingroup netifapi_autoip */
/** @ingroup netifapi_autoip
* @see autoip_start()
*/
#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start)
/** @ingroup netifapi_autoip */
/** @ingroup netifapi_autoip
* @see autoip_stop()
*/
#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop)
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,23 @@ extern "C" {
#define LWIP_SUPPORT_CUSTOM_PBUF ((IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF) || (LWIP_IPV6 && LWIP_IPV6_FRAG))
#endif
/** @ingroup pbuf
* PBUF_NEEDS_COPY(p): return a boolean value indicating whether the given
* pbuf needs to be copied in order to be kept around beyond the current call
* stack without risking being corrupted. The default setting provides safety:
* it will make a copy iof any pbuf chain that does not consist entirely of
* PBUF_ROM type pbufs. For setups with zero-copy support, it may be redefined
* to evaluate to true in all cases, for example. However, doing so also has an
* effect on the application side: any buffers that are *not* copied must also
* *not* be reused by the application after passing them to lwIP. For example,
* when setting PBUF_NEEDS_COPY to (0), after using udp_send() with a PBUF_RAM
* pbuf, the application must free the pbuf immediately, rather than reusing it
* for other purposes. For more background information on this, see tasks #6735
* and #7896, and bugs #11400 and #49914. */
#ifndef PBUF_NEEDS_COPY
#define PBUF_NEEDS_COPY(p) ((p)->type_internal & PBUF_TYPE_FLAG_DATA_VOLATILE)
#endif /* PBUF_NEEDS_COPY */
/* @todo: We need a mechanism to prevent wasting memory in every pbuf
(TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */
@ -73,27 +90,54 @@ typedef enum {
/** Includes spare room for transport layer header, e.g. UDP header.
* Use this if you intend to pass the pbuf to functions like udp_send().
*/
PBUF_TRANSPORT,
PBUF_TRANSPORT = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN,
/** Includes spare room for IP header.
* Use this if you intend to pass the pbuf to functions like raw_send().
*/
PBUF_IP,
PBUF_IP = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN,
/** Includes spare room for link layer header (ethernet header).
* Use this if you intend to pass the pbuf to functions like ethernet_output().
* @see PBUF_LINK_HLEN
*/
PBUF_LINK,
PBUF_LINK = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN,
/** Includes spare room for additional encapsulation header before ethernet
* headers (e.g. 802.11).
* Use this if you intend to pass the pbuf to functions like netif->linkoutput().
* @see PBUF_LINK_ENCAPSULATION_HLEN
*/
PBUF_RAW_TX,
PBUF_RAW_TX = PBUF_LINK_ENCAPSULATION_HLEN,
/** Use this for input packets in a netif driver when calling netif->input()
* in the most common case - ethernet-layer netif driver. */
PBUF_RAW
PBUF_RAW = 0
} pbuf_layer;
/* Base flags for pbuf_type definitions: */
/** Indicates that the payload directly follows the struct pbuf.
* This makes @ref pbuf_header work in both directions. */
#define PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS 0x80
/** Indicates the data stored in this pbuf can change. If this pbuf needs
* to be queued, it must be copied/duplicated. */
#define PBUF_TYPE_FLAG_DATA_VOLATILE 0x40
/** 4 bits are reserved for 16 allocation sources (e.g. heap, pool1, pool2, etc)
* Internally, we use: 0=heap, 1=MEMP_PBUF, 2=MEMP_PBUF_POOL -> 13 types free*/
#define PBUF_TYPE_ALLOC_SRC_MASK 0x0F
/** Indicates this pbuf is used for RX (if not set, indicates use for TX).
* This information can be used to keep some spare RX buffers e.g. for
* receiving TCP ACKs to unblock a connection) */
#define PBUF_ALLOC_FLAG_RX 0x0100
/** Indicates the application needs the pbuf payload to be in one piece */
#define PBUF_ALLOC_FLAG_DATA_CONTIGUOUS 0x0200
#define PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP 0x00
#define PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF 0x01
#define PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL 0x02
/** First pbuf allocation type for applications */
#define PBUF_TYPE_ALLOC_SRC_MASK_APP_MIN 0x03
/** Last pbuf allocation type for applications */
#define PBUF_TYPE_ALLOC_SRC_MASK_APP_MAX PBUF_TYPE_ALLOC_SRC_MASK
/**
* @ingroup pbuf
* Enumeration of pbuf types
@ -105,22 +149,22 @@ typedef enum {
pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might
change in future versions).
This should be used for all OUTGOING packets (TX).*/
PBUF_RAM,
PBUF_RAM = (PBUF_ALLOC_FLAG_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP),
/** pbuf data is stored in ROM, i.e. struct pbuf and its payload are located in
totally different memory areas. Since it points to ROM, payload does not
have to be copied when queued for transmission. */
PBUF_ROM,
PBUF_ROM = PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF,
/** pbuf comes from the pbuf pool. Much like PBUF_ROM but payload might change
so it has to be duplicated when queued before transmitting, depending on
who has a 'ref' to it. */
PBUF_REF,
PBUF_REF = (PBUF_TYPE_FLAG_DATA_VOLATILE | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF),
/** pbuf payload refers to RAM. This one comes from a pool and should be used
for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct
pbuf and its payload are allocated in one piece of contiguous memory (so
the first payload byte can be calculated from struct pbuf).
Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing,
you are unable to receive TCP acks! */
PBUF_POOL
PBUF_POOL = (PBUF_ALLOC_FLAG_RX | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL)
} pbuf_type;
@ -158,8 +202,10 @@ struct pbuf {
/** length of this buffer */
u16_t len;
/** pbuf_type as u8_t instead of enum to save space */
u8_t /*pbuf_type*/ type;
/** a bit field indicating pbuf type and allocation sources
(see PBUF_TYPE_FLAG_*, PBUF_ALLOC_FLAG_* and PBUF_TYPE_ALLOC_SRC_MASK)
*/
u8_t type_internal;
/** misc flags */
u8_t flags;
@ -169,9 +215,14 @@ struct pbuf {
* that refer to this pbuf. This can be pointers from an application,
* the stack itself, or pbuf->next pointers from a chain.
*/
u16_t ref;
LWIP_PBUF_REF_T ref;
#if ESP_LWIP
/** For incoming packets, this contains the input netif's index */
u8_t if_idx;
/** In case the user needs to store data custom data on a pbuf */
LWIP_PBUF_CUSTOM_DATA
#if ESP_PBUF
struct netif *l2_owner;
void *l2_buf;
#endif
@ -226,14 +277,22 @@ void pbuf_free_ooseq(void);
#define pbuf_init()
struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type);
struct pbuf *pbuf_alloc_reference(void *payload, u16_t length, pbuf_type type);
#if LWIP_SUPPORT_CUSTOM_PBUF
struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type,
struct pbuf_custom *p, void *payload_mem,
u16_t payload_mem_len);
#endif /* LWIP_SUPPORT_CUSTOM_PBUF */
void pbuf_realloc(struct pbuf *p, u16_t size);
#define pbuf_get_allocsrc(p) ((p)->type_internal & PBUF_TYPE_ALLOC_SRC_MASK)
#define pbuf_match_allocsrc(p, type) (pbuf_get_allocsrc(p) == ((type) & PBUF_TYPE_ALLOC_SRC_MASK))
#define pbuf_match_type(p, type) pbuf_match_allocsrc(p, type)
u8_t pbuf_header(struct pbuf *p, s16_t header_size);
u8_t pbuf_header_force(struct pbuf *p, s16_t header_size);
u8_t pbuf_add_header(struct pbuf *p, size_t header_size_increment);
u8_t pbuf_add_header_force(struct pbuf *p, size_t header_size_increment);
u8_t pbuf_remove_header(struct pbuf *p, size_t header_size);
struct pbuf *pbuf_free_header(struct pbuf *q, u16_t size);
void pbuf_ref(struct pbuf *p);
u8_t pbuf_free(struct pbuf *p);
u16_t pbuf_clen(const struct pbuf *p);
@ -242,10 +301,12 @@ void pbuf_chain(struct pbuf *head, struct pbuf *tail);
struct pbuf *pbuf_dechain(struct pbuf *p);
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from);
u16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
void *pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset);
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len);
err_t pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset);
struct pbuf *pbuf_skip(struct pbuf* in, u16_t in_offset, u16_t* out_offset);
struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer);
struct pbuf *pbuf_clone(pbuf_layer l, pbuf_type type, struct pbuf *p);
#if LWIP_CHECKSUM_ON_COPY
err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr,
u16_t len, u16_t *chksum);

View File

@ -0,0 +1,159 @@
/**
* @file
* Application layered TCP connection API (to be used from TCPIP thread)\n
* This interface mimics the tcp callback API to the application while preventing
* direct linking (much like virtual functions).
* This way, an application can make use of other application layer protocols
* on top of TCP without knowing the details (e.g. TLS, proxy connection).
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_PRIV_H
#define LWIP_HDR_ALTCP_PRIV_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/altcp.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
struct altcp_pcb *altcp_alloc(void);
void altcp_free(struct altcp_pcb *conn);
/* Function prototypes for application layers */
typedef void (*altcp_set_poll_fn)(struct altcp_pcb *conn, u8_t interval);
typedef void (*altcp_recved_fn)(struct altcp_pcb *conn, u16_t len);
typedef err_t (*altcp_bind_fn)(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port);
typedef err_t (*altcp_connect_fn)(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected);
typedef struct altcp_pcb *(*altcp_listen_fn)(struct altcp_pcb *conn, u8_t backlog, err_t *err);
typedef void (*altcp_abort_fn)(struct altcp_pcb *conn);
typedef err_t (*altcp_close_fn)(struct altcp_pcb *conn);
typedef err_t (*altcp_shutdown_fn)(struct altcp_pcb *conn, int shut_rx, int shut_tx);
typedef err_t (*altcp_write_fn)(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags);
typedef err_t (*altcp_output_fn)(struct altcp_pcb *conn);
typedef u16_t (*altcp_mss_fn)(struct altcp_pcb *conn);
typedef u16_t (*altcp_sndbuf_fn)(struct altcp_pcb *conn);
typedef u16_t (*altcp_sndqueuelen_fn)(struct altcp_pcb *conn);
typedef void (*altcp_nagle_disable_fn)(struct altcp_pcb *conn);
typedef void (*altcp_nagle_enable_fn)(struct altcp_pcb *conn);
typedef int (*altcp_nagle_disabled_fn)(struct altcp_pcb *conn);
typedef void (*altcp_setprio_fn)(struct altcp_pcb *conn, u8_t prio);
typedef void (*altcp_dealloc_fn)(struct altcp_pcb *conn);
typedef err_t (*altcp_get_tcp_addrinfo_fn)(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
typedef ip_addr_t *(*altcp_get_ip_fn)(struct altcp_pcb *conn, int local);
typedef u16_t (*altcp_get_port_fn)(struct altcp_pcb *conn, int local);
#if LWIP_TCP_KEEPALIVE
typedef void (*altcp_keepalive_disable_fn)(struct altcp_pcb *conn);
typedef void (*altcp_keepalive_enable_fn)(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
#endif
#ifdef LWIP_DEBUG
typedef enum tcp_state (*altcp_dbg_get_tcp_state_fn)(struct altcp_pcb *conn);
#endif
struct altcp_functions {
altcp_set_poll_fn set_poll;
altcp_recved_fn recved;
altcp_bind_fn bind;
altcp_connect_fn connect;
altcp_listen_fn listen;
altcp_abort_fn abort;
altcp_close_fn close;
altcp_shutdown_fn shutdown;
altcp_write_fn write;
altcp_output_fn output;
altcp_mss_fn mss;
altcp_sndbuf_fn sndbuf;
altcp_sndqueuelen_fn sndqueuelen;
altcp_nagle_disable_fn nagle_disable;
altcp_nagle_enable_fn nagle_enable;
altcp_nagle_disabled_fn nagle_disabled;
altcp_setprio_fn setprio;
altcp_dealloc_fn dealloc;
altcp_get_tcp_addrinfo_fn addrinfo;
altcp_get_ip_fn getip;
altcp_get_port_fn getport;
#if LWIP_TCP_KEEPALIVE
altcp_keepalive_disable_fn keepalive_disable;
altcp_keepalive_enable_fn keepalive_enable;
#endif
#ifdef LWIP_DEBUG
altcp_dbg_get_tcp_state_fn dbg_get_tcp_state;
#endif
};
void altcp_default_set_poll(struct altcp_pcb *conn, u8_t interval);
void altcp_default_recved(struct altcp_pcb *conn, u16_t len);
err_t altcp_default_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port);
err_t altcp_default_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx);
err_t altcp_default_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags);
err_t altcp_default_output(struct altcp_pcb *conn);
u16_t altcp_default_mss(struct altcp_pcb *conn);
u16_t altcp_default_sndbuf(struct altcp_pcb *conn);
u16_t altcp_default_sndqueuelen(struct altcp_pcb *conn);
void altcp_default_nagle_disable(struct altcp_pcb *conn);
void altcp_default_nagle_enable(struct altcp_pcb *conn);
int altcp_default_nagle_disabled(struct altcp_pcb *conn);
void altcp_default_setprio(struct altcp_pcb *conn, u8_t prio);
void altcp_default_dealloc(struct altcp_pcb *conn);
err_t altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
ip_addr_t *altcp_default_get_ip(struct altcp_pcb *conn, int local);
u16_t altcp_default_get_port(struct altcp_pcb *conn, int local);
#if LWIP_TCP_KEEPALIVE
void altcp_default_keepalive_disable(struct altcp_pcb *conn);
void altcp_default_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
#endif
#ifdef LWIP_DEBUG
enum tcp_state altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn);
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_PRIV_H */

View File

@ -39,10 +39,6 @@
#include "lwip/opt.h"
#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
/* Note: Netconn API is always available when sockets are enabled -
* sockets are implemented on top of them */
#include "lwip/arch.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
@ -55,6 +51,10 @@
extern "C" {
#endif
#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
/* Note: Netconn API is always available when sockets are enabled -
* sockets are implemented on top of them */
#if LWIP_MPU_COMPATIBLE
#if LWIP_NETCONN_SEM_PER_THREAD
#define API_MSG_M_DEF_SEM(m) *m
@ -94,6 +94,7 @@ struct api_msg {
struct {
API_MSG_M_DEF_C(ip_addr_t, ipaddr);
u16_t port;
u8_t if_idx;
} bc;
/** used for lwip_netconn_do_getaddr */
struct {
@ -103,8 +104,16 @@ struct api_msg {
} ad;
/** used for lwip_netconn_do_write */
struct {
const void *dataptr;
/** current vector to write */
const struct netvector *vector;
/** number of unwritten vectors */
u16_t vector_cnt;
/** offset into current vector */
size_t vector_off;
/** total length across vectors */
size_t len;
/** offset into total length/output of bytes written when err == ERR_OK */
size_t offset;
u8_t apiflags;
#if LWIP_SO_SNDTIMEO
u32_t time_started;
@ -112,7 +121,7 @@ struct api_msg {
} w;
/** used for lwip_netconn_do_recv */
struct {
u32_t len;
size_t len;
} r;
#if LWIP_TCP
/** used for lwip_netconn_do_close (/shutdown) */
@ -130,6 +139,7 @@ struct api_msg {
struct {
API_MSG_M_DEF_C(ip_addr_t, multiaddr);
API_MSG_M_DEF_C(ip_addr_t, netif_addr);
u8_t if_idx;
enum netconn_igmp join_or_leave;
} jl;
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
@ -185,13 +195,15 @@ struct dns_api_msg {
#endif
#endif
#if LWIP_TCP
extern u8_t netconn_aborted;
#endif /* LWIP_TCP */
#if LWIP_NETCONN_FULLDUPLEX
int lwip_netconn_is_deallocated_msg(void *msg);
#endif
int lwip_netconn_is_err_msg(void *msg, err_t *err);
void lwip_netconn_do_newconn (void *m);
void lwip_netconn_do_delconn (void *m);
void lwip_netconn_do_bind (void *m);
void lwip_netconn_do_bind_if (void *m);
void lwip_netconn_do_connect (void *m);
void lwip_netconn_do_disconnect (void *m);
void lwip_netconn_do_listen (void *m);
@ -206,6 +218,7 @@ void lwip_netconn_do_close (void *m);
void lwip_netconn_do_shutdown (void *m);
#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
void lwip_netconn_do_join_leave_group(void *m);
void lwip_netconn_do_join_leave_group_netif(void *m);
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
#if LWIP_DNS
@ -215,10 +228,54 @@ void lwip_netconn_do_gethostbyname(void *arg);
struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback);
void netconn_free(struct netconn *conn);
#endif /* LWIP_NETCONN || LWIP_SOCKET */
#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
/* netifapi related lwIP internal definitions */
#if LWIP_MPU_COMPATIBLE
#define NETIFAPI_IPADDR_DEF(type, m) type m
#else /* LWIP_MPU_COMPATIBLE */
#define NETIFAPI_IPADDR_DEF(type, m) const type * m
#endif /* LWIP_MPU_COMPATIBLE */
typedef void (*netifapi_void_fn)(struct netif *netif);
typedef err_t (*netifapi_errt_fn)(struct netif *netif);
struct netifapi_msg {
struct tcpip_api_call_data call;
struct netif *netif;
union {
struct {
#if LWIP_IPV4
NETIFAPI_IPADDR_DEF(ip4_addr_t, ipaddr);
NETIFAPI_IPADDR_DEF(ip4_addr_t, netmask);
NETIFAPI_IPADDR_DEF(ip4_addr_t, gw);
#endif /* LWIP_IPV4 */
void *state;
netif_init_fn init;
netif_input_fn input;
} add;
struct {
netifapi_void_fn voidfunc;
netifapi_errt_fn errtfunc;
} common;
struct {
#if LWIP_MPU_COMPATIBLE
char name[NETIF_NAMESIZE];
#else /* LWIP_MPU_COMPATIBLE */
char *name;
#endif /* LWIP_MPU_COMPATIBLE */
u8_t index;
} ifs;
} msg;
};
#endif /* LWIP_NETIF_API */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_NETCONN || LWIP_SOCKET */
#endif /* LWIP_HDR_API_MSG_H */

View File

@ -0,0 +1,84 @@
/**
* @file
* lwIP internal memory implementations (do not use in application code)
*/
/*
* Copyright (c) 2018 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_MEM_PRIV_H
#define LWIP_HDR_MEM_PRIV_H
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "lwip/mem.h"
#if MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK
/* if MEM_OVERFLOW_CHECK or MEMP_OVERFLOW_CHECK is turned on, we reserve some
* bytes at the beginning and at the end of each element, initialize them as
* 0xcd and check them later.
* If MEM(P)_OVERFLOW_CHECK is >= 2, on every call to mem(p)_malloc or mem(p)_free,
* every single element in each pool/heap is checked!
* This is VERY SLOW but also very helpful.
* MEM_SANITY_REGION_BEFORE and MEM_SANITY_REGION_AFTER can be overridden in
* lwipopts.h to change the amount reserved for checking. */
#ifndef MEM_SANITY_REGION_BEFORE
#define MEM_SANITY_REGION_BEFORE 16
#endif /* MEM_SANITY_REGION_BEFORE*/
#if MEM_SANITY_REGION_BEFORE > 0
#define MEM_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SANITY_REGION_BEFORE)
#else
#define MEM_SANITY_REGION_BEFORE_ALIGNED 0
#endif /* MEM_SANITY_REGION_BEFORE*/
#ifndef MEM_SANITY_REGION_AFTER
#define MEM_SANITY_REGION_AFTER 16
#endif /* MEM_SANITY_REGION_AFTER*/
#if MEM_SANITY_REGION_AFTER > 0
#define MEM_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SANITY_REGION_AFTER)
#else
#define MEM_SANITY_REGION_AFTER_ALIGNED 0
#endif /* MEM_SANITY_REGION_AFTER*/
void mem_overflow_init_raw(void *p, size_t size);
void mem_overflow_check_raw(void *p, size_t size, const char *descr1, const char *descr2);
#endif /* MEM_OVERFLOW_CHECK || MEMP_OVERFLOW_CHECK */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_MEMP_PRIV_H */

View File

@ -45,36 +45,14 @@ extern "C" {
#endif
#include "lwip/mem.h"
#include "lwip/priv/mem_priv.h"
#if MEMP_OVERFLOW_CHECK
/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning
* and at the end of each element, initialize them as 0xcd and check
* them later. */
/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free,
* every single element in each pool is checked!
* This is VERY SLOW but also very helpful. */
/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in
* lwipopts.h to change the amount reserved for checking. */
#ifndef MEMP_SANITY_REGION_BEFORE
#define MEMP_SANITY_REGION_BEFORE 16
#endif /* MEMP_SANITY_REGION_BEFORE*/
#if MEMP_SANITY_REGION_BEFORE > 0
#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE)
#else
#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0
#endif /* MEMP_SANITY_REGION_BEFORE*/
#ifndef MEMP_SANITY_REGION_AFTER
#define MEMP_SANITY_REGION_AFTER 16
#endif /* MEMP_SANITY_REGION_AFTER*/
#if MEMP_SANITY_REGION_AFTER > 0
#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER)
#else
#define MEMP_SANITY_REGION_AFTER_ALIGNED 0
#endif /* MEMP_SANITY_REGION_AFTER*/
/* MEMP_SIZE: save space for struct memp and for sanity check */
#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED)
#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED)
#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEM_SANITY_REGION_BEFORE_ALIGNED)
#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEM_SANITY_REGION_AFTER_ALIGNED)
#else /* MEMP_OVERFLOW_CHECK */

View File

@ -28,7 +28,7 @@
#ifndef LWIP_PBUF_MEMPOOL
/* This treats "pbuf pools" just like any other pool.
* Allocates buffers for a pbuf struct AND a payload size */
#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc)
#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) + LWIP_MEM_ALIGN_SIZE(payload)), desc)
#endif /* LWIP_PBUF_MEMPOOL */
@ -52,6 +52,10 @@ LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_lis
LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG")
#endif /* LWIP_TCP */
#if LWIP_ALTCP && LWIP_TCP
LWIP_MEMPOOL(ALTCP_PCB, MEMP_NUM_ALTCP_PCB, sizeof(struct altcp_pcb), "ALTCP_PCB")
#endif /* LWIP_ALTCP && LWIP_TCP */
#if LWIP_IPV4 && IP_REASSEMBLY
LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA")
#endif /* LWIP_IPV4 && IP_REASSEMBLY */
@ -74,6 +78,9 @@ LWIP_MEMPOOL(DNS_API_MSG, MEMP_NUM_DNS_API_MSG, sizeof(struct dns_api_msg
#if LWIP_SOCKET && !LWIP_TCPIP_CORE_LOCKING
LWIP_MEMPOOL(SOCKET_SETGETSOCKOPT_DATA, MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA, sizeof(struct lwip_setgetsockopt_data), "SOCKET_SETGETSOCKOPT_DATA")
#endif
#if LWIP_SOCKET && (LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL)
LWIP_MEMPOOL(SELECT_CB, MEMP_NUM_SELECT_CB, sizeof(struct lwip_select_cb), "SELECT_CB")
#endif /* LWIP_SOCKET && (LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL) */
#if LWIP_NETIF_API
LWIP_MEMPOOL(NETIFAPI_MSG, MEMP_NUM_NETIFAPI_MSG, sizeof(struct netifapi_msg), "NETIFAPI_MSG")
#endif
@ -103,15 +110,15 @@ LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE,
#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
#if LWIP_IPV6 && LWIP_ND6_QUEUEING
LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE")
LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE")
#endif /* LWIP_IPV6 && LWIP_ND6_QUEUEING */
#if LWIP_IPV6 && LWIP_IPV6_REASS
LWIP_MEMPOOL(IP6_REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip6_reassdata), "IP6_REASSDATA")
LWIP_MEMPOOL(IP6_REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip6_reassdata), "IP6_REASSDATA")
#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */
#if LWIP_IPV6 && LWIP_IPV6_MLD
LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group), "MLD6_GROUP")
LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group), "MLD6_GROUP")
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
@ -123,7 +130,7 @@ LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group),
* This allocates enough space for the pbuf struct and a payload.
* (Example: pbuf_payload_size=0 allocates only size for the struct)
*/
LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM")
LWIP_MEMPOOL(PBUF, MEMP_NUM_PBUF, sizeof(struct pbuf), "PBUF_REF/ROM")
LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL")

View File

@ -83,7 +83,7 @@ struct nd6_neighbor_cache_entry {
u8_t state;
u8_t isrouter;
union {
u32_t reachable_time; /* in ms since value may originate from network packet */
u32_t reachable_time; /* in seconds */
u32_t delay_time; /* ticks (ND6_TMR_INTERVAL) */
u32_t probes_sent;
u32_t stale_time; /* ticks (ND6_TMR_INTERVAL) */
@ -100,18 +100,12 @@ struct nd6_destination_cache_entry {
struct nd6_prefix_list_entry {
ip6_addr_t prefix;
struct netif *netif;
u32_t invalidation_timer; /* in ms since value may originate from network packet */
#if LWIP_IPV6_AUTOCONFIG
u8_t flags;
#define ND6_PREFIX_AUTOCONFIG_AUTONOMOUS 0x01
#define ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED 0x02
#define ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE 0x04
#endif /* LWIP_IPV6_AUTOCONFIG */
u32_t invalidation_timer; /* in seconds */
};
struct nd6_router_list_entry {
struct nd6_neighbor_cache_entry *neighbor_entry;
u32_t invalidation_timer; /* in ms since value may originate from network packet */
u32_t invalidation_timer; /* in seconds */
u8_t flags;
};
@ -124,6 +118,10 @@ enum nd6_neighbor_cache_entry_state {
ND6_PROBE
};
#define ND6_HOPLIM 255 /* maximum hop limit, required in all ND packets */
#define ND6_2HRS 7200 /* two hours, expressed in number of seconds */
/* Router tables. */
/* @todo make these static? and entries accessible through API? */
extern struct nd6_neighbor_cache_entry neighbor_cache[];

View File

@ -0,0 +1,69 @@
/**
* @file
* raw API internal implementations (do not use in application code)
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_RAW_PRIV_H
#define LWIP_HDR_RAW_PRIV_H
#include "lwip/opt.h"
#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
#include "lwip/raw.h"
#ifdef __cplusplus
extern "C" {
#endif
/** return codes for raw_input */
typedef enum raw_input_state
{
RAW_INPUT_NONE = 0, /* pbuf did not match any pcbs */
RAW_INPUT_EATEN, /* pbuf handed off and delivered to pcb */
RAW_INPUT_DELIVERED /* pbuf only delivered to pcb (pbuf can still be referenced) */
} raw_input_state_t;
/* The following functions are the lower layer interface to RAW. */
raw_input_state_t raw_input(struct pbuf *p, struct netif *inp);
void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_RAW */
#endif /* LWIP_HDR_RAW_PRIV_H */

View File

@ -0,0 +1,180 @@
/**
* @file
* Sockets API internal implementations (do not use in application code)
*/
/*
* Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Joel Cunningham <joel.cunningham@me.com>
*
*/
#ifndef LWIP_HDR_SOCKETS_PRIV_H
#define LWIP_HDR_SOCKETS_PRIV_H
#include "lwip/opt.h"
#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NUM_SOCKETS MEMP_NUM_NETCONN
/** This is overridable for the rare case where more than 255 threads
* select on the same socket...
*/
#ifndef SELWAIT_T
#define SELWAIT_T u8_t
#endif
union lwip_sock_lastdata {
struct netbuf *netbuf;
struct pbuf *pbuf;
};
/** Contains all internal pointers and states used for a socket */
struct lwip_sock {
/** sockets currently are built on netconns, each socket has one netconn */
struct netconn *conn;
/** data that was left from the previous read */
union lwip_sock_lastdata lastdata;
#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
/** number of times data was received, set by event_callback(),
tested by the receive and select functions */
s16_t rcvevent;
/** number of times data was ACKed (free send buffer), set by event_callback(),
tested by select */
u16_t sendevent;
/** error happened for this socket, set by event_callback(), tested by select */
u16_t errevent;
/** counter of how many threads are waiting for this socket using select */
SELWAIT_T select_waiting;
#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
#if LWIP_NETCONN_FULLDUPLEX
/* counter of how many threads are using a struct lwip_sock (not the 'int') */
u8_t fd_used;
/* status of pending close/delete actions */
u8_t fd_free_pending;
#define LWIP_SOCK_FD_FREE_TCP 1
#define LWIP_SOCK_FD_FREE_FREE 2
#endif
#if ESP_LWIP_LOCK
sys_mutex_t lock;
#endif
};
#ifndef set_errno
#define set_errno(err) do { if (err) { errno = (err); } } while(0)
#endif
#if !LWIP_TCPIP_CORE_LOCKING
/** Maximum optlen used by setsockopt/getsockopt */
#define LWIP_SETGETSOCKOPT_MAXOPTLEN LWIP_MAX(16, sizeof(struct ifreq))
/** This struct is used to pass data to the set/getsockopt_internal
* functions running in tcpip_thread context (only a void* is allowed) */
struct lwip_setgetsockopt_data {
/** socket index for which to change options */
int s;
/** level of the option to process */
int level;
/** name of the option to process */
int optname;
/** set: value to set the option to
* get: value of the option is stored here */
#if LWIP_MPU_COMPATIBLE
u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
#else
union {
void *p;
const void *pc;
} optval;
#endif
/** size of *optval */
socklen_t optlen;
/** if an error occurs, it is temporarily stored here */
int err;
/** semaphore to wake up the calling task */
void* completed_sem;
};
#endif /* !LWIP_TCPIP_CORE_LOCKING */
#ifdef __cplusplus
}
#endif
struct lwip_sock* lwip_socket_dbg_get_socket(int fd);
#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
#if LWIP_NETCONN_SEM_PER_THREAD
#define SELECT_SEM_T sys_sem_t*
#define SELECT_SEM_PTR(sem) (sem)
#else /* LWIP_NETCONN_SEM_PER_THREAD */
#define SELECT_SEM_T sys_sem_t
#define SELECT_SEM_PTR(sem) (&(sem))
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
/** Description for a task waiting in select */
struct lwip_select_cb {
/** Pointer to the next waiting task */
struct lwip_select_cb *next;
/** Pointer to the previous waiting task */
struct lwip_select_cb *prev;
#if LWIP_SOCKET_SELECT
/** readset passed to select */
fd_set *readset;
/** writeset passed to select */
fd_set *writeset;
/** unimplemented: exceptset passed to select */
fd_set *exceptset;
#endif /* LWIP_SOCKET_SELECT */
#if LWIP_SOCKET_POLL
/** fds passed to poll; NULL if select */
struct pollfd *poll_fds;
/** nfds passed to poll; 0 if select */
nfds_t poll_nfds;
#endif /* LWIP_SOCKET_POLL */
/** don't signal the same semaphore twice: set to 1 when signalled */
int sem_signalled;
/** semaphore to wake up a task waiting for select */
SELECT_SEM_T sem;
};
#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
#endif /* LWIP_SOCKET */
#endif /* LWIP_HDR_SOCKETS_PRIV_H */

View File

@ -77,9 +77,12 @@ void tcp_txnow (void);
void tcp_input (struct pbuf *p, struct netif *inp);
/* Used within the TCP code only: */
struct tcp_pcb * tcp_alloc (u8_t prio);
void tcp_free (struct tcp_pcb *pcb);
void tcp_abandon (struct tcp_pcb *pcb, int reset);
err_t tcp_send_empty_ack(struct tcp_pcb *pcb);
void tcp_rexmit (struct tcp_pcb *pcb);
err_t tcp_rexmit (struct tcp_pcb *pcb);
err_t tcp_rexmit_rto_prepare(struct tcp_pcb *pcb);
void tcp_rexmit_rto_commit(struct tcp_pcb *pcb);
void tcp_rexmit_rto (struct tcp_pcb *pcb);
void tcp_rexmit_fast (struct tcp_pcb *pcb);
u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
@ -174,6 +177,8 @@ err_t tcp_process_refused_data(struct tcp_pcb *pcb);
ret = lwip_tcp_event((pcb)->callback_arg, (pcb), LWIP_EVENT_POLL, NULL, 0, ERR_OK); \
} else { \
ret = ERR_ARG; } } while(0)
/* For event API, last state SYN_RCVD must be excluded here: the application
has not seen this pcb, yet! */
#define TCP_EVENT_ERR(last_state,errf,arg,err) do { if (last_state != SYN_RCVD) { \
lwip_tcp_event((arg), NULL, LWIP_EVENT_ERR, NULL, 0, (err)); } } while(0)
@ -259,11 +264,12 @@ struct tcp_seg {
u8_t chksum_swapped;
#endif /* TCP_CHECKSUM_ON_COPY */
u8_t flags;
#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */
#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option (only used in SYN segments) */
#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */
#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is
checksummed into 'chksum' */
#define TF_SEG_OPTS_WND_SCALE (u8_t)0x08U /* Include WND SCALE option */
#define TF_SEG_OPTS_WND_SCALE (u8_t)0x08U /* Include WND SCALE option (only used in SYN segments) */
#define TF_SEG_OPTS_SACK_PERM (u8_t)0x10U /* Include SACK Permitted option (only used in SYN segments) */
struct tcp_hdr *tcphdr; /* the TCP header */
};
@ -271,6 +277,7 @@ struct tcp_seg {
#define LWIP_TCP_OPT_NOP 1
#define LWIP_TCP_OPT_MSS 2
#define LWIP_TCP_OPT_WS 3
#define LWIP_TCP_OPT_SACK_PERM 4
#define LWIP_TCP_OPT_TS 8
#define LWIP_TCP_OPT_LEN_MSS 4
@ -287,10 +294,18 @@ struct tcp_seg {
#define LWIP_TCP_OPT_LEN_WS_OUT 0
#endif
#if LWIP_TCP_SACK_OUT
#define LWIP_TCP_OPT_LEN_SACK_PERM 2
#define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 4 /* aligned for output (includes NOP padding) */
#else
#define LWIP_TCP_OPT_LEN_SACK_PERM_OUT 0
#endif
#define LWIP_TCP_OPT_LENGTH(flags) \
(flags & TF_SEG_OPTS_MSS ? LWIP_TCP_OPT_LEN_MSS : 0) + \
(flags & TF_SEG_OPTS_TS ? LWIP_TCP_OPT_LEN_TS_OUT : 0) + \
(flags & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT : 0)
((flags) & TF_SEG_OPTS_MSS ? LWIP_TCP_OPT_LEN_MSS : 0) + \
((flags) & TF_SEG_OPTS_TS ? LWIP_TCP_OPT_LEN_TS_OUT : 0) + \
((flags) & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT : 0) + \
((flags) & TF_SEG_OPTS_SACK_PERM ? LWIP_TCP_OPT_LEN_SACK_PERM_OUT : 0)
/** This returns a TCP header option for MSS in an u32_t */
#define TCP_BUILD_MSS_OPTION(mss) lwip_htonl(0x02040000 | ((mss) & 0xFFFF))
@ -342,7 +357,7 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
#if TCP_DEBUG_PCB_LISTS
#define TCP_REG(pcbs, npcb) do {\
struct tcp_pcb *tcp_tmp_pcb; \
LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \
LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %"U16_F"\n", (void *)(npcb), (npcb)->local_port)); \
for (tcp_tmp_pcb = *(pcbs); \
tcp_tmp_pcb != NULL; \
tcp_tmp_pcb = tcp_tmp_pcb->next) { \
@ -352,13 +367,13 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
(npcb)->next = *(pcbs); \
LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \
*(pcbs) = (npcb); \
LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
LWIP_ASSERT("TCP_REG: tcp_pcbs sane", tcp_pcbs_sane()); \
tcp_timer_needed(); \
} while(0)
#define TCP_RMV(pcbs, npcb) do { \
struct tcp_pcb *tcp_tmp_pcb; \
LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \
LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \
LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \
if(*(pcbs) == (npcb)) { \
*(pcbs) = (*pcbs)->next; \
} else for (tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
@ -369,7 +384,7 @@ extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS];
} \
(npcb)->next = NULL; \
LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \
LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \
LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (void *)(npcb), (void *)(*(pcbs)))); \
} while(0)
#else /* LWIP_DEBUG */
@ -433,45 +448,38 @@ struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
#define tcp_ack(pcb) \
do { \
if((pcb)->flags & TF_ACK_DELAY) { \
(pcb)->flags &= ~TF_ACK_DELAY; \
(pcb)->flags |= TF_ACK_NOW; \
tcp_clear_flags(pcb, TF_ACK_DELAY); \
tcp_ack_now(pcb); \
} \
else { \
(pcb)->flags |= TF_ACK_DELAY; \
tcp_set_flags(pcb, TF_ACK_DELAY); \
} \
} while (0)
#define tcp_ack_now(pcb) \
do { \
(pcb)->flags |= TF_ACK_NOW; \
} while (0)
tcp_set_flags(pcb, TF_ACK_NOW)
err_t tcp_send_fin(struct tcp_pcb *pcb);
err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags);
void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);
void tcp_rst(u32_t seqno, u32_t ackno,
void tcp_rst(const struct tcp_pcb* pcb, u32_t seqno, u32_t ackno,
const ip_addr_t *local_ip, const ip_addr_t *remote_ip,
u16_t local_port, u16_t remote_port);
u32_t tcp_next_iss(struct tcp_pcb *pcb);
err_t tcp_keepalive(struct tcp_pcb *pcb);
err_t tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split);
err_t tcp_zero_window_probe(struct tcp_pcb *pcb);
void tcp_trigger_input_pcb_close(void);
#if TCP_CALCULATE_EFF_SEND_MSS
u16_t tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest
#if LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING
, const ip_addr_t *src
#endif /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */
);
#if LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING
#define tcp_eff_send_mss(sendmss, src, dest) tcp_eff_send_mss_impl(sendmss, dest, src)
#else /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */
#define tcp_eff_send_mss(sendmss, src, dest) tcp_eff_send_mss_impl(sendmss, dest)
#endif /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */
u16_t tcp_eff_send_mss_netif(u16_t sendmss, struct netif *outif,
const ip_addr_t *dest);
#define tcp_eff_send_mss(sendmss, src, dest) \
tcp_eff_send_mss_netif(sendmss, ip_route(src, dest), dest)
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
#if LWIP_CALLBACK_API
@ -498,6 +506,14 @@ void tcp_timer_needed(void);
void tcp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
#if TCP_QUEUE_OOSEQ
void tcp_free_ooseq(struct tcp_pcb *pcb);
#endif
#if LWIP_TCP_PCB_NUM_EXT_ARGS
err_t tcp_ext_arg_invoke_callbacks_passive_open(struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -55,12 +55,13 @@ struct netif;
#if LWIP_MPU_COMPATIBLE
#define API_VAR_REF(name) (*(name))
#define API_VAR_DECLARE(type, name) type * name
#define API_VAR_ALLOC(type, pool, name, errorval) do { \
#define API_VAR_ALLOC_EXT(type, pool, name, errorblock) do { \
name = (type *)memp_malloc(pool); \
if (name == NULL) { \
return errorval; \
errorblock; \
} \
} while(0)
#define API_VAR_ALLOC(type, pool, name, errorval) API_VAR_ALLOC_EXT(type, pool, name, return errorval)
#define API_VAR_ALLOC_POOL(type, pool, name, errorval) do { \
name = (type *)LWIP_MEMPOOL_ALLOC(pool); \
if (name == NULL) { \
@ -81,6 +82,7 @@ struct netif;
#else /* LWIP_MPU_COMPATIBLE */
#define API_VAR_REF(name) name
#define API_VAR_DECLARE(type, name) type name
#define API_VAR_ALLOC_EXT(type, pool, name, errorblock)
#define API_VAR_ALLOC(type, pool, name, errorval)
#define API_VAR_ALLOC_POOL(type, pool, name, errorval)
#define API_VAR_FREE(pool, name)
@ -109,9 +111,13 @@ typedef err_t (*tcpip_api_call_fn)(struct tcpip_api_call_data* call);
err_t tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call);
enum tcpip_msg_type {
#if !LWIP_TCPIP_CORE_LOCKING
TCPIP_MSG_API,
TCPIP_MSG_API_CALL,
#endif /* !LWIP_TCPIP_CORE_LOCKING */
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
TCPIP_MSG_INPKT,
#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
TCPIP_MSG_TIMEOUT,
TCPIP_MSG_UNTIMEOUT,
@ -123,6 +129,7 @@ enum tcpip_msg_type {
struct tcpip_msg {
enum tcpip_msg_type type;
union {
#if !LWIP_TCPIP_CORE_LOCKING
struct {
tcpip_callback_fn function;
void* msg;
@ -132,11 +139,14 @@ struct tcpip_msg {
struct tcpip_api_call_data *arg;
sys_sem_t *sem;
} api_call;
#endif /* LWIP_TCPIP_CORE_LOCKING */
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
struct {
struct pbuf *p;
struct netif *netif;
netif_input_fn input_fn;
} inp;
#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
struct {
tcpip_callback_fn function;
void *ctx;

View File

@ -39,15 +39,13 @@
#define LWIP_HDR_PROT_DHCP_H
#include "lwip/opt.h"
#include "lwip/arch.h"
#include "lwip/prot/ip4.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DHCP_CLIENT_PORT 68
#define DHCP_SERVER_PORT 67
/* DHCP message item offsets and length */
#define DHCP_CHADDR_LEN 16U
#define DHCP_SNAME_OFS 44U
@ -128,9 +126,6 @@ typedef enum {
#define DHCP_RELEASE 7
#define DHCP_INFORM 8
/** DHCP hardware type, currently only ethernet is supported */
#define DHCP_HTYPE_ETH 1
#define DHCP_MAGIC_COOKIE 0x63825363UL
/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */
@ -148,18 +143,6 @@ typedef enum {
#define DHCP_OPTION_NTP 42
#define DHCP_OPTION_END 255
#if ESP_LWIP
/**add options for support more router by liuHan**/
#define DHCP_OPTION_DOMAIN_NAME 15
#define DHCP_OPTION_PRD 31
#define DHCP_OPTION_STATIC_ROUTER 33
#define DHCP_OPTION_VSN 43
#define DHCP_OPTION_NB_TINS 44
#define DHCP_OPTION_NB_TINT 46
#define DHCP_OPTION_NB_TIS 47
#define DHCP_OPTION_CLASSLESS_STATIC_ROUTER 121
#endif
/* DHCP options */
#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */
#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
@ -192,4 +175,4 @@ typedef enum {
}
#endif
#endif /*LWIP_HDR_PROT_DHCP_H*/
#endif /* LWIP_HDR_PROT_DHCP_H */

View File

@ -0,0 +1,138 @@
/**
* @file
* DHCPv6 protocol definitions
*/
/*
* Copyright (c) 2017 Simon Goldschmidt <goldsimon@gmx.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_PROT_DHCP6_H
#define LWIP_HDR_PROT_DHCP6_H
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DHCP6_CLIENT_PORT 546
#define DHCP6_SERVER_PORT 547
/* DHCPv6 message item offsets and length */
#define DHCP6_TRANSACTION_ID_LEN 3
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** minimum set of fields of any DHCPv6 message */
struct dhcp6_msg
{
PACK_STRUCT_FLD_8(u8_t msgtype);
PACK_STRUCT_FLD_8(u8_t transaction_id[DHCP6_TRANSACTION_ID_LEN]);
/* options follow */
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/* DHCP6 client states */
typedef enum {
DHCP6_STATE_OFF = 0,
DHCP6_STATE_STATELESS_IDLE = 1,
DHCP6_STATE_REQUESTING_CONFIG = 2
} dhcp6_state_enum_t;
/* DHCPv6 message types */
#define DHCP6_SOLICIT 1
#define DHCP6_ADVERTISE 2
#define DHCP6_REQUEST 3
#define DHCP6_CONFIRM 4
#define DHCP6_RENEW 5
#define DHCP6_REBIND 6
#define DHCP6_REPLY 7
#define DHCP6_RELEASE 8
#define DHCP6_DECLINE 9
#define DHCP6_RECONFIGURE 10
#define DHCP6_INFOREQUEST 11
#define DHCP6_RELAYFORW 12
#define DHCP6_RELAYREPL 13
/* More message types see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */
/** DHCPv6 status codes */
#define DHCP6_STATUS_SUCCESS 0 /* Success. */
#define DHCP6_STATUS_UNSPECFAIL 1 /* Failure, reason unspecified; this status code is sent by either a client or a server to indicate a failure not explicitly specified in this document. */
#define DHCP6_STATUS_NOADDRSAVAIL 2 /* Server has no addresses available to assign to the IA(s). */
#define DHCP6_STATUS_NOBINDING 3 /* Client record (binding) unavailable. */
#define DHCP6_STATUS_NOTONLINK 4 /* The prefix for the address is not appropriate for the link to which the client is attached. */
#define DHCP6_STATUS_USEMULTICAST 5 /* Sent by a server to a client to force the client to send messages to the server using the All_DHCP_Relay_Agents_and_Servers address. */
/* More status codes see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */
/** DHCPv6 DUID types */
#define DHCP6_DUID_LLT 1 /* LLT: Link-layer Address Plus Time */
#define DHCP6_DUID_EN 2 /* EN: Enterprise number */
#define DHCP6_DUID_LL 3 /* LL: Link-layer Address */
#define DHCP6_DUID_UUID 4 /* UUID (RFC 6355) */
/* DHCPv6 options */
#define DHCP6_OPTION_CLIENTID 1
#define DHCP6_OPTION_SERVERID 2
#define DHCP6_OPTION_IA_NA 3
#define DHCP6_OPTION_IA_TA 4
#define DHCP6_OPTION_IAADDR 5
#define DHCP6_OPTION_ORO 6
#define DHCP6_OPTION_PREFERENCE 7
#define DHCP6_OPTION_ELAPSED_TIME 8
#define DHCP6_OPTION_RELAY_MSG 9
#define DHCP6_OPTION_AUTH 11
#define DHCP6_OPTION_UNICAST 12
#define DHCP6_OPTION_STATUS_CODE 13
#define DHCP6_OPTION_RAPID_COMMIT 14
#define DHCP6_OPTION_USER_CLASS 15
#define DHCP6_OPTION_VENDOR_CLASS 16
#define DHCP6_OPTION_VENDOR_OPTS 17
#define DHCP6_OPTION_INTERFACE_ID 18
#define DHCP6_OPTION_RECONF_MSG 19
#define DHCP6_OPTION_RECONF_ACCEPT 20
/* More options see https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml */
#define DHCP6_OPTION_DNS_SERVERS 23 /* RFC 3646 */
#define DHCP6_OPTION_DOMAIN_LIST 24 /* RFC 3646 */
#define DHCP6_OPTION_SNTP_SERVERS 31 /* RFC 4075 */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_PROT_DHCP6_H */

View File

@ -39,7 +39,6 @@
#include "lwip/arch.h"
#include "lwip/prot/ethernet.h"
#include "lwip/ip4_addr.h"
#ifdef __cplusplus
extern "C" {
@ -49,6 +48,36 @@ extern "C" {
#define ETHARP_HWADDR_LEN ETH_HWADDR_LEN
#endif
/**
* struct ip4_addr_wordaligned is used in the definition of the ARP packet format in
* order to support compilers that don't have structure packing.
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip4_addr_wordaligned {
PACK_STRUCT_FIELD(u16_t addrw[2]);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/** MEMCPY-like copying of IP addresses where addresses are known to be
* 16-bit-aligned if the port is correctly configured (so a port could define
* this to copying 2 u16_t's) - no NULL-pointer-checking needed. */
#ifndef IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T
#define IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t))
#endif
/** MEMCPY-like copying of IP addresses where addresses are known to be
* 16-bit-aligned if the port is correctly configured (so a port could define
* this to copying 2 u16_t's) - no NULL-pointer-checking needed. */
#ifndef IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T
#define IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t))
#endif
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
@ -61,9 +90,9 @@ struct etharp_hdr {
PACK_STRUCT_FLD_8(u8_t protolen);
PACK_STRUCT_FIELD(u16_t opcode);
PACK_STRUCT_FLD_S(struct eth_addr shwaddr);
PACK_STRUCT_FLD_S(struct ip4_addr2 sipaddr);
PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned sipaddr);
PACK_STRUCT_FLD_S(struct eth_addr dhwaddr);
PACK_STRUCT_FLD_S(struct ip4_addr2 dipaddr);
PACK_STRUCT_FLD_S(struct ip4_addr_wordaligned dipaddr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
@ -72,12 +101,6 @@ PACK_STRUCT_END
#define SIZEOF_ETHARP_HDR 28
/* ARP hwtype values */
enum etharp_hwtype {
HWTYPE_ETHERNET = 1
/* others not used */
};
/* ARP message types (opcodes) */
enum etharp_opcode {
ARP_REQUEST = 1,

View File

@ -38,6 +38,7 @@
#define LWIP_HDR_PROT_ETHERNET_H
#include "lwip/arch.h"
#include "lwip/prot/ieee.h"
#ifdef __cplusplus
extern "C" {
@ -55,6 +56,7 @@ extern "C" {
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** An Ethernet MAC address */
struct eth_addr {
PACK_STRUCT_FLD_8(u8_t addr[ETH_HWADDR_LEN]);
} PACK_STRUCT_STRUCT;
@ -63,6 +65,9 @@ PACK_STRUCT_END
# include "arch/epstruct.h"
#endif
/** Initialize a struct eth_addr with its 6 bytes (takes care of correct braces) */
#define ETH_ADDR(b0, b1, b2, b3, b4, b5) {{b0, b1, b2, b3, b4, b5}}
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
@ -102,44 +107,6 @@ PACK_STRUCT_END
#define SIZEOF_VLAN_HDR 4
#define VLAN_ID(vlan_hdr) (lwip_htons((vlan_hdr)->prio_vid) & 0xFFF)
/**
* @ingroup ethernet
* A list of often ethtypes (although lwIP does not use all of them): */
enum eth_type {
/** Internet protocol v4 */
ETHTYPE_IP = 0x0800U,
/** Address resolution protocol */
ETHTYPE_ARP = 0x0806U,
/** Wake on lan */
ETHTYPE_WOL = 0x0842U,
/** RARP */
ETHTYPE_RARP = 0x8035U,
/** Virtual local area network */
ETHTYPE_VLAN = 0x8100U,
/** Internet protocol v6 */
ETHTYPE_IPV6 = 0x86DDU,
/** PPP Over Ethernet Discovery Stage */
ETHTYPE_PPPOEDISC = 0x8863U,
/** PPP Over Ethernet Session Stage */
ETHTYPE_PPPOE = 0x8864U,
/** Jumbo Frames */
ETHTYPE_JUMBO = 0x8870U,
/** Process field network */
ETHTYPE_PROFINET = 0x8892U,
/** Ethernet for control automation technology */
ETHTYPE_ETHERCAT = 0x88A4U,
/** Link layer discovery protocol */
ETHTYPE_LLDP = 0x88CCU,
/** Serial real-time communication system */
ETHTYPE_SERCOS = 0x88CDU,
/** Media redundancy protocol */
ETHTYPE_MRP = 0x88E3U,
/** Precision time protocol */
ETHTYPE_PTP = 0x88F7U,
/** Q-in-Q, 802.1ad */
ETHTYPE_QINQ = 0x9100U
};
/** The 24-bit IANA IPv4-multicast OUI is 01-00-5e: */
#define LL_IP4_MULTICAST_ADDR_0 0x01
#define LL_IP4_MULTICAST_ADDR_1 0x00
@ -149,18 +116,6 @@ enum eth_type {
#define LL_IP6_MULTICAST_ADDR_0 0x33
#define LL_IP6_MULTICAST_ADDR_1 0x33
/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables
* or known to be 32-bit aligned within the protocol header. */
#ifndef ETHADDR32_COPY
#define ETHADDR32_COPY(dst, src) SMEMCPY(dst, src, ETH_HWADDR_LEN)
#endif
/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local
* variables and known to be 16-bit aligned within the protocol header. */
#ifndef ETHADDR16_COPY
#define ETHADDR16_COPY(dst, src) SMEMCPY(dst, src, ETH_HWADDR_LEN)
#endif
#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETH_HWADDR_LEN) == 0)
#ifdef __cplusplus

View File

@ -0,0 +1,97 @@
/**
* @file
* IANA assigned numbers (RFC 1700 and successors)
*
* @defgroup iana IANA assigned numbers
* @ingroup infrastructure
*/
/*
* Copyright (c) 2017 Dirk Ziegelmeier.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
*
*/
#ifndef LWIP_HDR_PROT_IANA_H
#define LWIP_HDR_PROT_IANA_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup iana
* Hardware types
*/
enum lwip_iana_hwtype {
/** Ethernet */
LWIP_IANA_HWTYPE_ETHERNET = 1
};
/**
* @ingroup iana
* Port numbers
* https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
*/
enum lwip_iana_port_number {
/** SMTP */
LWIP_IANA_PORT_SMTP = 25,
/** DHCP server */
LWIP_IANA_PORT_DHCP_SERVER = 67,
/** DHCP client */
LWIP_IANA_PORT_DHCP_CLIENT = 68,
/** TFTP */
LWIP_IANA_PORT_TFTP = 69,
/** HTTP */
LWIP_IANA_PORT_HTTP = 80,
/** SNTP */
LWIP_IANA_PORT_SNTP = 123,
/** NETBIOS */
LWIP_IANA_PORT_NETBIOS = 137,
/** SNMP */
LWIP_IANA_PORT_SNMP = 161,
/** SNMP traps */
LWIP_IANA_PORT_SNMP_TRAP = 162,
/** HTTPS */
LWIP_IANA_PORT_HTTPS = 443,
/** SMTPS */
LWIP_IANA_PORT_SMTPS = 465,
/** MQTT */
LWIP_IANA_PORT_MQTT = 1883,
/** MDNS */
LWIP_IANA_PORT_MDNS = 5353,
/** Secure MQTT */
LWIP_IANA_PORT_SECURE_MQTT = 8883
};
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_PROT_IANA_H */

View File

@ -0,0 +1,91 @@
/**
* @file
* IEEE assigned numbers
*
* @defgroup ieee IEEE assigned numbers
* @ingroup infrastructure
*/
/*
* Copyright (c) 2017 Dirk Ziegelmeier.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
*
*/
#ifndef LWIP_HDR_PROT_IEEE_H
#define LWIP_HDR_PROT_IEEE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup ieee
* A list of often ethtypes (although lwIP does not use all of them).
*/
enum lwip_ieee_eth_type {
/** Internet protocol v4 */
ETHTYPE_IP = 0x0800U,
/** Address resolution protocol */
ETHTYPE_ARP = 0x0806U,
/** Wake on lan */
ETHTYPE_WOL = 0x0842U,
/** RARP */
ETHTYPE_RARP = 0x8035U,
/** Virtual local area network */
ETHTYPE_VLAN = 0x8100U,
/** Internet protocol v6 */
ETHTYPE_IPV6 = 0x86DDU,
/** PPP Over Ethernet Discovery Stage */
ETHTYPE_PPPOEDISC = 0x8863U,
/** PPP Over Ethernet Session Stage */
ETHTYPE_PPPOE = 0x8864U,
/** Jumbo Frames */
ETHTYPE_JUMBO = 0x8870U,
/** Process field network */
ETHTYPE_PROFINET = 0x8892U,
/** Ethernet for control automation technology */
ETHTYPE_ETHERCAT = 0x88A4U,
/** Link layer discovery protocol */
ETHTYPE_LLDP = 0x88CCU,
/** Serial real-time communication system */
ETHTYPE_SERCOS = 0x88CDU,
/** Media redundancy protocol */
ETHTYPE_MRP = 0x88E3U,
/** Precision time protocol */
ETHTYPE_PTP = 0x88F7U,
/** Q-in-Q, 802.1ad */
ETHTYPE_QINQ = 0x9100U
};
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_PROT_IEEE_H */

View File

@ -38,7 +38,7 @@
#define LWIP_HDR_PROT_IGMP_H
#include "lwip/arch.h"
#include "lwip/ip4_addr.h"
#include "lwip/prot/ip4.h"
#ifdef __cplusplus
extern "C" {

View File

@ -39,6 +39,10 @@
#include "lwip/arch.h"
#ifdef __cplusplus
extern "C" {
#endif
#define IP_PROTO_ICMP 1
#define IP_PROTO_IGMP 2
#define IP_PROTO_UDP 17
@ -48,4 +52,8 @@
/** This operates on a void* by loading the first byte */
#define IP_HDR_GET_VERSION(ptr) ((*(u8_t*)(ptr)) >> 4)
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_PROT_IP_H */

View File

@ -62,6 +62,8 @@ typedef struct ip4_addr_packed ip4_addr_p_t;
/* Size of the IPv4 header. Same as 'sizeof(struct ip_hdr)'. */
#define IP_HLEN 20
/* Maximum size of the IPv4 header with options. */
#define IP_HLEN_MAX 60
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
@ -101,10 +103,12 @@ PACK_STRUCT_END
/* Macros to get struct ip_hdr fields: */
#define IPH_V(hdr) ((hdr)->_v_hl >> 4)
#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f)
#define IPH_HL_BYTES(hdr) ((u8_t)(IPH_HL(hdr) * 4))
#define IPH_TOS(hdr) ((hdr)->_tos)
#define IPH_LEN(hdr) ((hdr)->_len)
#define IPH_ID(hdr) ((hdr)->_id)
#define IPH_OFFSET(hdr) ((hdr)->_offset)
#define IPH_OFFSET_BYTES(hdr) ((u16_t)((lwip_ntohs(IPH_OFFSET(hdr)) & IP_OFFMASK) * 8U))
#define IPH_TTL(hdr) ((hdr)->_ttl)
#define IPH_PROTO(hdr) ((hdr)->_proto)
#define IPH_CHKSUM(hdr) ((hdr)->_chksum)

View File

@ -43,7 +43,7 @@
#ifdef __cplusplus
extern "C" {
#endif
/** This is the packed version of ip6_addr_t,
used in network headers that are itself packed */
#ifdef PACK_STRUCT_USE_INCLUDES
@ -94,13 +94,50 @@ PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define IP6H_V(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f)
#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff)
#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff)
#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen))
#define IP6H_NEXTH(hdr) ((hdr)->_nexth)
#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6)
#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim)
#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl)))
#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen)
#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth)
#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl)
/* ipv6 extended options header */
#define IP6_PAD1_OPTION 0
#define IP6_PADN_OPTION 1
#define IP6_ROUTER_ALERT_OPTION 5
#define IP6_JUMBO_OPTION 194
#define IP6_HOME_ADDRESS_OPTION 201
#define IP6_ROUTER_ALERT_DLEN 2
#define IP6_ROUTER_ALERT_VALUE_MLD 0
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip6_opt_hdr {
/* router alert option type */
PACK_STRUCT_FLD_8(u8_t _opt_type);
/* router alert option data len */
PACK_STRUCT_FLD_8(u8_t _opt_dlen);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define IP6_OPT_HLEN 2
#define IP6_OPT_TYPE_ACTION(hdr) ((((hdr)->_opt_type) >> 6) & 0x3)
#define IP6_OPT_TYPE_CHANGE(hdr) ((((hdr)->_opt_type) >> 5) & 0x1)
#define IP6_OPT_TYPE(hdr) ((hdr)->_opt_type)
#define IP6_OPT_DLEN(hdr) ((hdr)->_opt_dlen)
/* Hop-by-Hop header. */
#define IP6_HBH_HLEN 2
/* Hop-by-hop router alert option. */
#define IP6_HBH_HLEN 8
#define IP6_PAD1_OPTION 0
#define IP6_PADN_ALERT_OPTION 1
#define IP6_ROUTER_ALERT_OPTION 5
#define IP6_ROUTER_ALERT_VALUE_MLD 0
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
@ -108,28 +145,65 @@ PACK_STRUCT_BEGIN
struct ip6_hbh_hdr {
/* next header */
PACK_STRUCT_FLD_8(u8_t _nexth);
/* header length */
/* header length in 8-octet units */
PACK_STRUCT_FLD_8(u8_t _hlen);
/* router alert option type */
PACK_STRUCT_FLD_8(u8_t _ra_opt_type);
/* router alert option data len */
PACK_STRUCT_FLD_8(u8_t _ra_opt_dlen);
/* router alert option data */
PACK_STRUCT_FIELD(u16_t _ra_opt_data);
/* PadN option type */
PACK_STRUCT_FLD_8(u8_t _padn_opt_type);
/* PadN option data len */
PACK_STRUCT_FLD_8(u8_t _padn_opt_dlen);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define IP6_HBH_NEXTH(hdr) ((hdr)->_nexth)
/* Destination header. */
#define IP6_DEST_HLEN 2
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip6_dest_hdr {
/* next header */
PACK_STRUCT_FLD_8(u8_t _nexth);
/* header length in 8-octet units */
PACK_STRUCT_FLD_8(u8_t _hlen);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define IP6_DEST_NEXTH(hdr) ((hdr)->_nexth)
/* Routing header */
#define IP6_ROUT_TYPE2 2
#define IP6_ROUT_RPL 3
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip6_rout_hdr {
/* next header */
PACK_STRUCT_FLD_8(u8_t _nexth);
/* reserved */
PACK_STRUCT_FLD_8(u8_t _hlen);
/* fragment offset */
PACK_STRUCT_FIELD(u8_t _routing_type);
/* fragmented packet identification */
PACK_STRUCT_FIELD(u8_t _segments_left);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define IP6_ROUT_NEXTH(hdr) ((hdr)->_nexth)
#define IP6_ROUT_TYPE(hdr) ((hdr)->_routing_type)
#define IP6_ROUT_SEG_LEFT(hdr) ((hdr)->_segments_left)
/* Fragment header. */
#define IP6_FRAG_HLEN 8
#define IP6_FRAG_OFFSET_MASK 0xfff8
#define IP6_FRAG_MORE_FLAG 0x0001
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
@ -148,19 +222,9 @@ PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define IP6H_V(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f)
#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff)
#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff)
#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen))
#define IP6H_NEXTH(hdr) ((hdr)->_nexth)
#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6)
#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim)
#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl)))
#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen)
#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth)
#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl)
#define IP6_FRAG_NEXTH(hdr) ((hdr)->_nexth)
#define IP6_FRAG_MBIT(hdr) (lwip_ntohs((hdr)->_fragment_offset) & 0x1)
#define IP6_FRAG_ID(hdr) (lwip_ntohl((hdr)->_identification))
#ifdef __cplusplus
}

View File

@ -44,6 +44,7 @@
extern "C" {
#endif
#define MLD6_HBH_HLEN 8
/** Multicast listener report/query/done message header. */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"

View File

@ -248,11 +248,6 @@ PACK_STRUCT_END
#endif
/** Recursive DNS Server Option. */
#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS
#define LWIP_RDNSS_OPTION_MAX_SERVERS LWIP_ND6_RDNSS_MAX_DNS_SERVERS
#else
#define LWIP_RDNSS_OPTION_MAX_SERVERS 1
#endif
#define ND6_OPTION_TYPE_RDNSS (25)
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
@ -263,13 +258,15 @@ struct rdnss_option {
PACK_STRUCT_FLD_8(u8_t length);
PACK_STRUCT_FIELD(u16_t reserved);
PACK_STRUCT_FIELD(u32_t lifetime);
PACK_STRUCT_FLD_S(ip6_addr_p_t rdnss_address[LWIP_RDNSS_OPTION_MAX_SERVERS]);
PACK_STRUCT_FLD_S(ip6_addr_p_t rdnss_address[1]);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_RDNSS_OPTION_BASE 8 /* size without addresses */
#ifdef __cplusplus
}
#endif

View File

@ -80,8 +80,11 @@ PACK_STRUCT_END
/* Valid TCP header flags */
#define TCP_FLAGS 0x3fU
#define TCP_MAX_OPTION_BYTES 40
#define TCPH_HDRLEN(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) >> 12))
#define TCPH_FLAGS(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS))
#define TCPH_HDRLEN_BYTES(phdr) ((u8_t)(TCPH_HDRLEN(phdr) << 2))
#define TCPH_FLAGS(phdr) ((u8_t)((lwip_ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)))
#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = lwip_htons(((len) << 12) | TCPH_FLAGS(phdr))
#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS(~TCP_FLAGS)) | lwip_htons(flags))

View File

@ -52,6 +52,10 @@
extern "C" {
#endif
#define RAW_FLAGS_CONNECTED 0x01U
#define RAW_FLAGS_HDRINCL 0x02U
#define RAW_FLAGS_MULTICAST_LOOP 0x04U
struct raw_pcb;
/** Function prototype for raw pcb receive callback functions.
@ -75,6 +79,14 @@ struct raw_pcb {
struct raw_pcb *next;
u8_t protocol;
u8_t flags;
#if LWIP_MULTICAST_TX_OPTIONS
/** outgoing network interface for multicast packets, by interface index (if nonzero) */
u8_t mcast_ifindex;
/** TTL for outgoing multicast packets */
u8_t mcast_ttl;
#endif /* LWIP_MULTICAST_TX_OPTIONS */
/** receive callback function */
raw_recv_fn recv;
@ -93,22 +105,35 @@ struct raw_pcb * raw_new (u8_t proto);
struct raw_pcb * raw_new_ip_type(u8_t type, u8_t proto);
void raw_remove (struct raw_pcb *pcb);
err_t raw_bind (struct raw_pcb *pcb, const ip_addr_t *ipaddr);
void raw_bind_netif (struct raw_pcb *pcb, const struct netif *netif);
err_t raw_connect (struct raw_pcb *pcb, const ip_addr_t *ipaddr);
void raw_disconnect (struct raw_pcb *pcb);
err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr);
err_t raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, struct netif *netif, const ip_addr_t *src_ip);
err_t raw_send (struct raw_pcb *pcb, struct pbuf *p);
void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg);
/* The following functions are the lower layer interface to RAW. */
u8_t raw_input (struct pbuf *p, struct netif *inp);
#define raw_init() /* Compatibility define, no init needed. */
#define raw_flags(pcb) ((pcb)->flags)
#define raw_setflags(pcb,f) ((pcb)->flags = (f))
void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
#define raw_set_flags(pcb, set_flags) do { (pcb)->flags = (u8_t)((pcb)->flags | (set_flags)); } while(0)
#define raw_clear_flags(pcb, clr_flags) do { (pcb)->flags = (u8_t)((pcb)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
#define raw_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0)
#define raw_init() /* Compatibility define, no init needed. */
/* for compatibility with older implementation */
#define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto)
#if LWIP_MULTICAST_TX_OPTIONS
#define raw_set_multicast_netif_index(pcb, idx) ((pcb)->mcast_ifindex = (idx))
#define raw_get_multicast_netif_index(pcb) ((pcb)->mcast_ifindex)
#define raw_set_multicast_ttl(pcb, value) ((pcb)->mcast_ttl = (value))
#define raw_get_multicast_ttl(pcb) ((pcb)->mcast_ttl)
#endif /* LWIP_MULTICAST_TX_OPTIONS */
#ifdef __cplusplus
}
#endif

View File

@ -40,14 +40,17 @@
#define LWIP_HDR_SOCKETS_H
#include "lwip/opt.h"
#include "sys/poll.h"
#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/err.h"
#include "lwip/inet.h"
#include "lwip/errno.h"
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -108,39 +111,11 @@ struct sockaddr_storage {
typedef u32_t socklen_t;
#endif
struct lwip_sock;
#if !LWIP_TCPIP_CORE_LOCKING
/** Maximum optlen used by setsockopt/getsockopt */
#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16
/** This struct is used to pass data to the set/getsockopt_internal
* functions running in tcpip_thread context (only a void* is allowed) */
struct lwip_setgetsockopt_data {
/** socket index for which to change options */
int s;
/** level of the option to process */
int level;
/** name of the option to process */
int optname;
/** set: value to set the option to
* get: value of the option is stored here */
#if LWIP_MPU_COMPATIBLE
u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
#else
union {
void *p;
const void *pc;
} optval;
#endif
/** size of *optval */
socklen_t optlen;
/** if an error occurs, it is temporarily stored here */
err_t err;
/** semaphore to wake up the calling task */
void* completed_sem;
};
#endif /* !LWIP_TCPIP_CORE_LOCKING */
#if !defined IOV_MAX
#define IOV_MAX 0xFFFF
#elif IOV_MAX > 0xFFFF
#error "IOV_MAX larger than supported by LwIP"
#endif /* IOV_MAX */
#if !defined(iovec)
struct iovec {
@ -159,6 +134,56 @@ struct msghdr {
int msg_flags;
};
/* struct msghdr->msg_flags bit field values */
#define MSG_TRUNC 0x04
#define MSG_CTRUNC 0x08
/* RFC 3542, Section 20: Ancillary Data */
struct cmsghdr {
socklen_t cmsg_len; /* number of bytes, including header */
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
};
/* Data section follows header and possible padding, typically referred to as
unsigned char cmsg_data[]; */
/* cmsg header/data alignment. NOTE: we align to native word size (double word
size on 16-bit arch) so structures are not placed at an unaligned address.
16-bit arch needs double word to ensure 32-bit alignment because socklen_t
could be 32 bits. If we ever have cmsg data with a 64-bit variable, alignment
will need to increase long long */
#define ALIGN_H(size) (((size) + sizeof(long) - 1U) & ~(sizeof(long)-1U))
#define ALIGN_D(size) ALIGN_H(size)
#define CMSG_FIRSTHDR(mhdr) \
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(mhdr)->msg_control : \
(struct cmsghdr *)NULL)
#define CMSG_NXTHDR(mhdr, cmsg) \
(((cmsg) == NULL) ? CMSG_FIRSTHDR(mhdr) : \
(((u8_t *)(cmsg) + ALIGN_H((cmsg)->cmsg_len) \
+ ALIGN_D(sizeof(struct cmsghdr)) > \
(u8_t *)((mhdr)->msg_control) + (mhdr)->msg_controllen) ? \
(struct cmsghdr *)NULL : \
(struct cmsghdr *)((void*)((u8_t *)(cmsg) + \
ALIGN_H((cmsg)->cmsg_len)))))
#define CMSG_DATA(cmsg) ((void*)((u8_t *)(cmsg) + \
ALIGN_D(sizeof(struct cmsghdr))))
#define CMSG_SPACE(length) (ALIGN_D(sizeof(struct cmsghdr)) + \
ALIGN_H(length))
#define CMSG_LEN(length) (ALIGN_D(sizeof(struct cmsghdr)) + \
length)
/* Set socket options argument */
#define IFNAMSIZ NETIF_NAMESIZE
struct ifreq {
char ifr_name[IFNAMSIZ]; /* Interface name */
};
/* Socket protocol types (TCP/UDP/RAW) */
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
@ -175,32 +200,32 @@ struct msghdr {
/*
* Additional options, not kept in so_options.
*/
#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_DONTLINGER ((int)(~SO_LINGER))
#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */
#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
#define SO_RCVBUF 0x1002 /* receive buffer size */
#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
#define SO_RCVTIMEO 0x1006 /* receive timeout */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */
#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_DONTLINGER ((int)(~SO_LINGER))
#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */
#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
#define SO_RCVBUF 0x1002 /* receive buffer size */
#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
#define SO_SNDTIMEO 0x1005 /* send timeout */
#define SO_RCVTIMEO 0x1006 /* receive timeout */
#define SO_ERROR 0x1007 /* get error status and clear */
#define SO_TYPE 0x1008 /* get socket type */
#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
#define SO_BINDTODEVICE 0x100b /* bind to device */
/*
* Structure used for manipulating linger option.
*/
struct linger {
int l_onoff; /* option on/off */
int l_linger; /* linger time in seconds */
int l_onoff; /* option on/off */
int l_linger; /* linger time in seconds */
};
/*
@ -237,6 +262,7 @@ struct linger {
#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
#define MSG_MORE 0x10 /* Sender will send more */
#define MSG_NOSIGNAL 0x20 /* Uninmplemented: Requests not to send the SIGPIPE signal if an attempt to send is made on a stream-oriented socket that is no longer connected. */
/*
@ -244,6 +270,7 @@ struct linger {
*/
#define IP_TOS 1
#define IP_TTL 2
#define IP_PKTINFO 8
#if LWIP_TCP
/*
@ -262,29 +289,6 @@ struct linger {
*/
#define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */
#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */
#if ESP_LWIP
#if LWIP_IPV6_MLD
/* Socket options for IPV6 multicast, uses the MLD interface to manage group memberships. RFC2133. */
#define IPV6_MULTICAST_IF 0x300
#define IPV6_MULTICAST_HOPS 0x301
#define IPV6_MULTICAST_LOOP 0x302
#define IPV6_ADD_MEMBERSHIP 0x303
#define IPV6_DROP_MEMBERSHIP 0x304
/* Structure used for IPV6_ADD/DROP_MEMBERSHIP */
typedef struct ip6_mreq {
struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast addr */
struct in6_addr ipv6mr_interface; /* local IP address of interface */
} ip6_mreq;
/* Commonly used synonyms for these options */
#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
#endif /* LWIP_IPV6_MLD */
#endif
#endif /* LWIP_IPV6 */
#if LWIP_UDP && LWIP_UDPLITE
@ -318,6 +322,34 @@ typedef struct ip_mreq {
} ip_mreq;
#endif /* LWIP_IGMP */
#if LWIP_IPV4
struct in_pktinfo {
unsigned int ipi_ifindex; /* Interface index */
struct in_addr ipi_addr; /* Destination (from header) address */
};
#endif /* LWIP_IPV4 */
#if LWIP_IPV6_MLD
/*
* Options and types related to IPv6 multicast membership
*/
#define IPV6_JOIN_GROUP 12
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
#define IPV6_LEAVE_GROUP 13
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#if ESP_IPV6
#define IPV6_MULTICAST_IF 0x300
#define IPV6_MULTICAST_HOPS 0x301
#define IPV6_MULTICAST_LOOP 0x302
#endif
typedef struct ipv6_mreq {
struct in6_addr ipv6mr_multiaddr; /* IPv6 multicast addr */
unsigned int ipv6mr_interface; /* interface index, or 0 */
} ipv6_mreq;
#endif /* LWIP_IPV6_MLD */
/*
* The Type of Service provides an indication of the abstract
* parameters of the quality of service desired. These parameters are
@ -381,11 +413,11 @@ typedef struct ip_mreq {
#define IOC_INOUT (IOC_IN|IOC_OUT)
/* 0x20000000 distinguishes new &
old ioctl's */
#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
#define _IO(x,y) ((long)(IOC_VOID|((x)<<8)|(y)))
#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define _IOR(x,y,t) ((long)(IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)))
#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define _IOW(x,y,t) ((long)(IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)))
#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
#ifndef FIONREAD
@ -418,7 +450,16 @@ typedef struct ip_mreq {
#define O_NONBLOCK 1 /* nonblocking I/O */
#endif
#ifndef O_NDELAY
#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */
#define O_NDELAY O_NONBLOCK /* same as O_NONBLOCK, for compatibility */
#endif
#ifndef O_RDONLY
#define O_RDONLY 2
#endif
#ifndef O_WRONLY
#define O_WRONLY 4
#endif
#ifndef O_RDWR
#define O_RDWR (O_RDONLY|O_WRONLY)
#endif
#ifndef SHUT_RD
@ -432,13 +473,14 @@ typedef struct ip_mreq {
#undef FD_SETSIZE
/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
#define FD_SETSIZE MEMP_NUM_NETCONN
#define LWIP_SELECT_MAXNFDS (FD_SETSIZE + LWIP_SOCKET_OFFSET)
#define FDSETSAFESET(n, code) do { \
if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \
code; }} while(0)
#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
(code) : 0)
#define FD_SET(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
#define FD_CLR(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
#define FD_SET(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] | (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))))
#define FD_CLR(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] = (u8_t)((p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7))))
#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET) & 7)))
#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
@ -447,8 +489,37 @@ typedef struct fd_set
unsigned char fd_bits [(FD_SETSIZE+7)/8];
} fd_set;
#elif FD_SETSIZE < (LWIP_SOCKET_OFFSET + MEMP_NUM_NETCONN)
#error "external FD_SETSIZE too small for number of sockets"
#else
#define LWIP_SELECT_MAXNFDS FD_SETSIZE
#endif /* FD_SET */
/* poll-related defines and types */
/* @todo: find a better way to guard the definition of these defines and types if already defined */
#if !defined(POLLIN) && !defined(POLLOUT)
#define POLLIN 0x1
#define POLLOUT 0x2
#define POLLERR 0x4
#define POLLNVAL 0x8
/* Below values are unimplemented */
#define POLLRDNORM 0x10
#define POLLRDBAND 0x20
#define POLLPRI 0x40
#define POLLWRNORM 0x80
#define POLLWRBAND 0x100
#define POLLHUP 0x200
#ifdef NO_POLLFD
typedef unsigned int nfds_t;
struct pollfd
{
int fd;
short events;
short revents;
};
#endif/* NO_POLLFD*/
#endif
/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
* by your system, set this to 0 and include <sys/time.h> in cc.h */
#ifndef LWIP_TIMEVAL_PRIVATE
@ -479,23 +550,34 @@ void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destro
#define lwip_connect connect
#define lwip_listen listen
#define lwip_recv recv
#define lwip_recvmsg recvmsg
#define lwip_recvfrom recvfrom
#define lwip_send send
#define lwip_sendmsg sendmsg
#define lwip_sendto sendto
#define lwip_socket socket
#if LWIP_SOCKET_SELECT
#define lwip_select select
#define lwip_ioctlsocket ioctl
#endif
#if LWIP_SOCKET_POLL
#define lwip_poll poll
#endif
#define lwip_ioctl ioctlsocket
#define lwip_inet_ntop inet_ntop
#define lwip_inet_pton inet_pton
#if LWIP_POSIX_SOCKETS_IO_NAMES
#define lwip_read read
#define lwip_readv readv
#define lwip_write write
#define lwip_writev writev
#undef lwip_close
#define lwip_close close
#define closesocket(s) close(s)
#define lwip_fcntl fcntl
int fcntl(int s, int cmd, ...);
#undef lwip_ioctl
#define lwip_ioctl ioctl
#define ioctlsocket ioctl
#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
#endif /* LWIP_COMPAT_SOCKETS == 2 */
@ -509,86 +591,67 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
int lwip_close(int s);
int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen);
int lwip_listen(int s, int backlog);
int lwip_recv(int s, void *mem, size_t len, int flags);
int lwip_read(int s, void *mem, size_t len);
int lwip_recvfrom(int s, void *mem, size_t len, int flags,
ssize_t lwip_recv(int s, void *mem, size_t len, int flags);
ssize_t lwip_read(int s, void *mem, size_t len);
ssize_t lwip_readv(int s, const struct iovec *iov, int iovcnt);
ssize_t lwip_recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
int lwip_send(int s, const void *dataptr, size_t size, int flags);
int lwip_sendmsg(int s, const struct msghdr *message, int flags);
int lwip_sendto(int s, const void *dataptr, size_t size, int flags,
ssize_t lwip_recvmsg(int s, struct msghdr *message, int flags);
ssize_t lwip_send(int s, const void *dataptr, size_t size, int flags);
ssize_t lwip_sendmsg(int s, const struct msghdr *message, int flags);
ssize_t lwip_sendto(int s, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen);
int lwip_socket(int domain, int type, int protocol);
int lwip_write(int s, const void *dataptr, size_t size);
int lwip_writev(int s, const struct iovec *iov, int iovcnt);
ssize_t lwip_write(int s, const void *dataptr, size_t size);
ssize_t lwip_writev(int s, const struct iovec *iov, int iovcnt);
#if LWIP_SOCKET_SELECT
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
struct timeval *timeout);
#endif
#if LWIP_SOCKET_POLL
int lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout);
#endif
int lwip_ioctl(int s, long cmd, void *argp);
int lwip_fcntl(int s, int cmd, int val);
const char *lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size);
int lwip_inet_pton(int af, const char *src, void *dst);
#if LWIP_COMPAT_SOCKETS
#if LWIP_COMPAT_SOCKETS != 2
#if ESP_THREAD_SAFE
int lwip_accept_r(int s, struct sockaddr *addr, socklen_t *addrlen);
int lwip_bind_r(int s, const struct sockaddr *name, socklen_t namelen);
int lwip_shutdown_r(int s, int how);
int lwip_getpeername_r (int s, struct sockaddr *name, socklen_t *namelen);
int lwip_getsockname_r (int s, struct sockaddr *name, socklen_t *namelen);
int lwip_getsockopt_r (int s, int level, int optname, void *optval, socklen_t *optlen);
int lwip_setsockopt_r (int s, int level, int optname, const void *optval, socklen_t optlen);
int lwip_close_r(int s);
int lwip_connect_r(int s, const struct sockaddr *name, socklen_t namelen);
int lwip_listen_r(int s, int backlog);
int lwip_recvmsg_r(int s, struct msghdr *message, int flags);
int lwip_recv_r(int s, void *mem, size_t len, int flags);
int lwip_read_r(int s, void *mem, size_t len);
int lwip_recvfrom_r(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
int lwip_send_r(int s, const void *dataptr, size_t size, int flags);
int lwip_sendmsg_r(int s, const struct msghdr *message, int flags);
int lwip_sendto_r(int s, const void *dataptr, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen);
int lwip_socket(int domain, int type, int protocol);
int lwip_write_r(int s, const void *dataptr, size_t size);
int lwip_writev_r(int s, const struct iovec *iov, int iovcnt);
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
struct timeval *timeout);
int lwip_ioctl_r(int s, long cmd, void *argp);
int lwip_fcntl_r(int s, int cmd, int val);
#if ESP_SOCKET
static inline int accept(int s,struct sockaddr *addr,socklen_t *addrlen)
{ return lwip_accept_r(s,addr,addrlen); }
{ return lwip_accept(s,addr,addrlen); }
static inline int bind(int s,const struct sockaddr *name, socklen_t namelen)
{ return lwip_bind_r(s,name,namelen); }
{ return lwip_bind(s,name,namelen); }
static inline int shutdown(int s,int how)
{ return lwip_shutdown_r(s,how); }
{ return lwip_shutdown(s,how); }
static inline int getpeername(int s,struct sockaddr *name,socklen_t *namelen)
{ return lwip_getpeername_r(s,name,namelen); }
{ return lwip_getpeername(s,name,namelen); }
static inline int getsockname(int s,struct sockaddr *name,socklen_t *namelen)
{ return lwip_getsockname_r(s,name,namelen); }
{ return lwip_getsockname(s,name,namelen); }
static inline int setsockopt(int s,int level,int optname,const void *opval,socklen_t optlen)
{ return lwip_setsockopt_r(s,level,optname,opval,optlen); }
{ return lwip_setsockopt(s,level,optname,opval,optlen); }
static inline int getsockopt(int s,int level,int optname,void *opval,socklen_t *optlen)
{ return lwip_getsockopt_r(s,level,optname,opval,optlen); }
{ return lwip_getsockopt(s,level,optname,opval,optlen); }
static inline int closesocket(int s)
{ return lwip_close_r(s); }
{ return lwip_close(s); }
static inline int connect(int s,const struct sockaddr *name,socklen_t namelen)
{ return lwip_connect_r(s,name,namelen); }
{ return lwip_connect(s,name,namelen); }
static inline int listen(int s,int backlog)
{ return lwip_listen_r(s,backlog); }
static inline int recvmsg(int sockfd, struct msghdr *msg, int flags)
{ return lwip_recvmsg_r(sockfd, msg, flags); }
static inline int recv(int s,void *mem,size_t len,int flags)
{ return lwip_recv_r(s,mem,len,flags); }
static inline int recvfrom(int s,void *mem,size_t len,int flags,struct sockaddr *from,socklen_t *fromlen)
{ return lwip_recvfrom_r(s,mem,len,flags,from,fromlen); }
static inline int send(int s,const void *dataptr,size_t size,int flags)
{ return lwip_send_r(s,dataptr,size,flags); }
static inline int sendmsg(int s,const struct msghdr *message,int flags)
{ return lwip_sendmsg_r(s,message,flags); }
static inline int sendto(int s,const void *dataptr,size_t size,int flags,const struct sockaddr *to,socklen_t tolen)
{ return lwip_sendto_r(s,dataptr,size,flags,to,tolen); }
{ return lwip_listen(s,backlog); }
static inline ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
{ return lwip_recvmsg(sockfd, msg, flags); }
static inline ssize_t recv(int s,void *mem,size_t len,int flags)
{ return lwip_recv(s,mem,len,flags); }
static inline ssize_t recvfrom(int s,void *mem,size_t len,int flags,struct sockaddr *from,socklen_t *fromlen)
{ return lwip_recvfrom(s,mem,len,flags,from,fromlen); }
static inline ssize_t send(int s,const void *dataptr,size_t size,int flags)
{ return lwip_send(s,dataptr,size,flags); }
static inline ssize_t sendmsg(int s,const struct msghdr *message,int flags)
{ return lwip_sendmsg(s,message,flags); }
static inline ssize_t sendto(int s,const void *dataptr,size_t size,int flags,const struct sockaddr *to,socklen_t tolen)
{ return lwip_sendto(s,dataptr,size,flags,to,tolen); }
static inline int socket(int domain,int type,int protocol)
{ return lwip_socket(domain,type,protocol); }
#ifndef ESP_HAS_SELECT
@ -596,21 +659,21 @@ static inline int select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set *ex
{ return lwip_select(maxfdp1,readset,writeset,exceptset,timeout); }
#endif /* ESP_HAS_SELECT */
static inline int ioctlsocket(int s,long cmd,void *argp)
{ return lwip_ioctl_r(s,cmd,argp); }
{ return lwip_ioctl(s,cmd,argp); }
#if LWIP_POSIX_SOCKETS_IO_NAMES
static inline int read(int s,void *mem,size_t len)
{ return lwip_read_r(s,mem,len); }
static inline int write(int s,const void *dataptr,size_t len)
{ return lwip_write_r(s,dataptr,len); }
static inline int writev(int s,const struct iovec *iov,int iovcnt)
{ return lwip_writev_r(s,iov,iovcnt); }
static inline ssize_t read(int s,void *mem,size_t len)
{ return lwip_read(s,mem,len); }
static inline ssize_t write(int s,const void *dataptr,size_t len)
{ return lwip_write(s,dataptr,len); }
static inline ssize_t writev(int s,const struct iovec *iov,int iovcnt)
{ return lwip_writev(s,iov,iovcnt); }
static inline int close(int s)
{ return lwip_close_r(s); }
{ return lwip_close(s); }
static inline int fcntl(int s,int cmd,int val)
{ return lwip_fcntl_r(s,cmd,val); }
{ return lwip_fcntl(s,cmd,val); }
static inline int ioctl(int s,long cmd,void *argp)
{ return lwip_ioctl_r(s,cmd,argp); }
{ return lwip_ioctl(s,cmd,argp); }
#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
#else
@ -638,6 +701,8 @@ static inline int ioctl(int s,long cmd,void *argp)
/** @ingroup socket */
#define recv(s,mem,len,flags) lwip_recv(s,mem,len,flags)
/** @ingroup socket */
#define recvmsg(s,message,flags) lwip_recvmsg(s,message,flags)
/** @ingroup socket */
#define recvfrom(s,mem,len,flags,from,fromlen) lwip_recvfrom(s,mem,len,flags,from,fromlen)
/** @ingroup socket */
#define send(s,dataptr,size,flags) lwip_send(s,dataptr,size,flags)
@ -647,8 +712,14 @@ static inline int ioctl(int s,long cmd,void *argp)
#define sendto(s,dataptr,size,flags,to,tolen) lwip_sendto(s,dataptr,size,flags,to,tolen)
/** @ingroup socket */
#define socket(domain,type,protocol) lwip_socket(domain,type,protocol)
#if LWIP_SOCKET_SELECT
/** @ingroup socket */
#define select(maxfdp1,readset,writeset,exceptset,timeout) lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
#endif
#if LWIP_SOCKET_POLL
/** @ingroup socket */
#define poll(fds,nfds,timeout) lwip_poll(fds,nfds,timeout)
#endif
/** @ingroup socket */
#define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
@ -656,6 +727,8 @@ static inline int ioctl(int s,long cmd,void *argp)
/** @ingroup socket */
#define read(s,mem,len) lwip_read(s,mem,len)
/** @ingroup socket */
#define readv(s,iov,iovcnt) lwip_readv(s,iov,iovcnt)
/** @ingroup socket */
#define write(s,dataptr,len) lwip_write(s,dataptr,len)
/** @ingroup socket */
#define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt)
@ -667,66 +740,24 @@ static inline int ioctl(int s,long cmd,void *argp)
#define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp)
#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
#endif /* ESP_THREAD_SAFE */
#endif /* ESP_SOCKET */
#endif /* LWIP_COMPAT_SOCKETS != 2 */
#if ESP_LWIP
#if LWIP_IPV4 && LWIP_IPV6
#define lwip_inet_ntop(af,src,dst,size) \
(((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) \
: (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL))
#define lwip_inet_pton(af,src,dst) \
(((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
: (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
#define lwip_inet_ntop(af,src,dst,size) \
(((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL)
#define lwip_inet_pton(af,src,dst) \
(((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
#else /* LWIP_IPV4 && LWIP_IPV6 */
#define lwip_inet_ntop(af,src,dst,size) \
(((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) : NULL)
#define lwip_inet_pton(af,src,dst) \
(((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#if ESP_SOCKET
#if LWIP_COMPAT_SOCKET_INET == 1
/* Some libraries have problems with inet_... being macros, so please use this define
to declare normal functions */
static inline const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{ lwip_inet_ntop(af, src, dst, size); return dst; }
{ return lwip_inet_ntop(af, src, dst, size); }
static inline int inet_pton(int af, const char *src, void *dst)
{ lwip_inet_pton(af, src, dst); return 1; }
{ return lwip_inet_pton(af, src, dst); }
#else
/* By default fall back to original inet_... macros */
# define inet_ntop(a,b,c,d) lwip_inet_ntop(a,b,c,d)
# define inet_pton(a,b,c) lwip_inet_pton(a,b,c)
#endif /* LWIP_COMPAT_SOCKET_INET */
#else /* ESP_LWIP*/
#if LWIP_IPV4 && LWIP_IPV6
/** @ingroup socket */
#define inet_ntop(af,src,dst,size) \
(((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) \
: (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL))
/** @ingroup socket */
#define inet_pton(af,src,dst) \
(((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
: (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
#define inet_ntop(af,src,dst,size) \
(((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL)
#define inet_pton(af,src,dst) \
(((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
#else /* LWIP_IPV4 && LWIP_IPV6 */
#define inet_ntop(af,src,dst,size) \
(((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) : NULL)
#define inet_pton(af,src,dst) \
(((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#endif /* ESP_LWIP */
#endif /* ESP_SOCKET */
#endif /* LWIP_COMPAT_SOCKETS */
#ifdef __cplusplus

View File

@ -228,25 +228,6 @@ struct stats_mib2_netif_ctrs {
u32_t ifouterrors;
};
#if ESP_STATS_DROP
struct stats_esp {
/* mbox post fail stats */
u32_t rx_rawmbox_post_fail;
u32_t rx_udpmbox_post_fail;
u32_t rx_tcpmbox_post_fail;
u32_t err_tcp_rxmbox_post_fail;
u32_t err_tcp_acceptmbox_post_fail;
u32_t acceptmbox_post_fail;
u32_t free_mbox_post_fail;
u32_t tcpip_inpkt_post_fail;
u32_t tcpip_cb_post_fail;
/* memory malloc/free/failed stats */
u32_t wlanif_input_pbuf_fail;
u32_t wlanif_outut_pbuf_fail;
};
#endif
/** lwIP stats container */
struct stats_ {
#if LINK_STATS
@ -317,10 +298,6 @@ struct stats_ {
/** SNMP MIB2 */
struct stats_mib2 mib2;
#endif
#if ESP_STATS_DROP
struct stats_esp esp;
#endif
};
/** Global variable containing lwIP internal statistics. Add this to your debugger's watchlist. */
@ -331,7 +308,7 @@ void stats_init(void);
#define STATS_INC(x) ++lwip_stats.x
#define STATS_DEC(x) --lwip_stats.x
#define STATS_INC_USED(x, y) do { lwip_stats.x.used += y; \
#define STATS_INC_USED(x, y, type) do { lwip_stats.x.used = (type)(lwip_stats.x.used + y); \
if (lwip_stats.x.max < lwip_stats.x.used) { \
lwip_stats.x.max = lwip_stats.x.used; \
} \
@ -341,7 +318,7 @@ void stats_init(void);
#define stats_init()
#define STATS_INC(x)
#define STATS_DEC(x)
#define STATS_INC_USED(x)
#define STATS_INC_USED(x, y, type)
#endif /* LWIP_STATS */
#if TCP_STATS
@ -410,9 +387,9 @@ void stats_init(void);
#if MEM_STATS
#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y
#define MEM_STATS_INC(x) SYS_ARCH_INC(lwip_stats.mem.x, 1)
#define MEM_STATS_INC_USED(x, y) SYS_ARCH_INC(lwip_stats.mem.x, y)
#define MEM_STATS_DEC_USED(x, y) SYS_ARCH_DEC(lwip_stats.mem.x, y)
#define MEM_STATS_INC(x) STATS_INC(mem.x)
#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y, mem_size_t)
#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x = (mem_size_t)((lwip_stats.mem.x) - (y))
#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP")
#else
#define MEM_STATS_AVAIL(x, y)
@ -435,7 +412,7 @@ void stats_init(void);
#if SYS_STATS
#define SYS_STATS_INC(x) STATS_INC(sys.x)
#define SYS_STATS_DEC(x) STATS_DEC(sys.x)
#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1)
#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1, STAT_COUNTER)
#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys)
#else
#define SYS_STATS_INC(x)
@ -490,14 +467,6 @@ void stats_init(void);
#define MIB2_STATS_INC(x)
#endif
#if ESP_STATS_DROP
#define ESP_STATS_DROP_INC(x) STATS_INC(x)
#define ESP_STATS_DROP_DISPLAY() stats_display_esp(&lwip_stats.esp);
#else
#define ESP_STATS_DROP_INC(x)
#define ESP_STATS_DROP_DISPLAY()
#endif
/* Display of statistics */
#if LWIP_STATS_DISPLAY
void stats_display(void);
@ -506,10 +475,6 @@ void stats_display_igmp(struct stats_igmp *igmp, const char *name);
void stats_display_mem(struct stats_mem *mem, const char *name);
void stats_display_memp(struct stats_mem *mem, int index);
void stats_display_sys(struct stats_sys *sys);
#if ESP_STATS_DROP
void stats_display_esp(struct stats_esp *esp);
#endif
#else /* LWIP_STATS_DISPLAY */
#define stats_display()
#define stats_display_proto(proto, name)
@ -517,10 +482,6 @@ void stats_display_esp(struct stats_esp *esp);
#define stats_display_mem(mem, name)
#define stats_display_memp(mem, index)
#define stats_display_sys(sys)
#if ESP_STATS_DROP
#define stats_display_esp(esp)
#endif
#endif /* LWIP_STATS_DISPLAY */
#ifdef __cplusplus

View File

@ -83,6 +83,24 @@ typedef u8_t sys_mbox_t;
#else /* NO_SYS */
#if ESP_LWIP_LOCK
#define SYS_ARCH_PROTECT_CONN(_conn) do {\
sys_mutex_lock(&(_conn)->lock);\
} while(0)
#define SYS_ARCH_UNPROTECT_CONN(_conn) do {\
sys_mutex_unlock(&(_conn)->lock);\
} while(0)
#define SYS_ARCH_PROTECT_SOCK(_sock) do {\
sys_mutex_lock(&(_sock)->lock);\
} while(0)
#define SYS_ARCH_UNPROTECT_SOCK(_sock) do{\
sys_mutex_unlock(&(_sock)->lock);\
} while(0)
#endif /* ESP_LWIP_LOCK */
/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */
#define SYS_ARCH_TIMEOUT 0xffffffffUL
@ -125,39 +143,51 @@ typedef void (*lwip_thread_fn)(void *arg);
* Create a new mutex.
* Note that mutexes are expected to not be taken recursively by the lwIP code,
* so both implementation types (recursive or non-recursive) should work.
* The mutex is allocated to the memory that 'mutex'
* points to (which can be both a pointer or the actual OS structure).
* If the mutex has been created, ERR_OK should be returned. Returning any
* other error will provide a hint what went wrong, but except for assertions,
* no real error handling is implemented.
*
* @param mutex pointer to the mutex to create
* @return ERR_OK if successful, another err_t otherwise
*/
err_t sys_mutex_new(sys_mutex_t *mutex);
/**
* @ingroup sys_mutex
* Lock a mutex
* Blocks the thread until the mutex can be grabbed.
* @param mutex the mutex to lock
*/
void sys_mutex_lock(sys_mutex_t *mutex);
/**
* @ingroup sys_mutex
* Unlock a mutex
* Releases the mutex previously locked through 'sys_mutex_lock()'.
* @param mutex the mutex to unlock
*/
void sys_mutex_unlock(sys_mutex_t *mutex);
/**
* @ingroup sys_mutex
* Delete a semaphore
* Deallocates a mutex.
* @param mutex the mutex to delete
*/
void sys_mutex_free(sys_mutex_t *mutex);
#ifndef sys_mutex_valid
/**
* @ingroup sys_mutex
* Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid
* Returns 1 if the mutes is valid, 0 if it is not valid.
* When using pointers, a simple way is to check the pointer for != NULL.
* When directly using OS structures, implementing this may be more complex.
* This may also be a define, in which case the function is not prototyped.
*/
int sys_mutex_valid(sys_mutex_t *mutex);
#endif
#ifndef sys_mutex_set_invalid
/**
* @ingroup sys_mutex
* Set a mutex invalid so that sys_mutex_valid returns 0
* Invalidate a mutex so that sys_mutex_valid() returns 0.
* ATTENTION: This does NOT mean that the mutex shall be deallocated:
* sys_mutex_free() is always called before calling this function!
* This may also be a define, in which case the function is not prototyped.
*/
void sys_mutex_set_invalid(sys_mutex_t *mutex);
#endif
@ -168,6 +198,14 @@ void sys_mutex_set_invalid(sys_mutex_t *mutex);
/**
* @ingroup sys_sem
* Create a new semaphore
* Creates a new semaphore. The semaphore is allocated to the memory that 'sem'
* points to (which can be both a pointer or the actual OS structure).
* The "count" argument specifies the initial state of the semaphore (which is
* either 0 or 1).
* If the semaphore has been created, ERR_OK should be returned. Returning any
* other error will provide a hint what went wrong, but except for assertions,
* no real error handling is implemented.
*
* @param sem pointer to the semaphore to create
* @param count initial count of the semaphore
* @return ERR_OK if successful, another err_t otherwise
@ -189,16 +227,25 @@ int sys_sem_signal_isr(sys_sem_t *sem);
/**
* @ingroup sys_sem
* Wait for a semaphore for the specified timeout
* Blocks the thread while waiting for the semaphore to be signaled. If the
* "timeout" argument is non-zero, the thread should only be blocked for the
* specified time (measured in milliseconds). If the "timeout" argument is zero,
* the thread should be blocked until the semaphore is signalled.
*
* The return value is SYS_ARCH_TIMEOUT if the semaphore wasn't signaled within
* the specified time or any other value if it was signaled (with or without
* waiting).
* Notice that lwIP implements a function with a similar name,
* sys_sem_wait(), that uses the sys_arch_sem_wait() function.
*
* @param sem the semaphore to wait for
* @param timeout timeout in milliseconds to wait (0 = wait forever)
* @return time (in milliseconds) waited for the semaphore
* or SYS_ARCH_TIMEOUT on timeout
* @return SYS_ARCH_TIMEOUT on timeout, any other value on success
*/
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout);
/**
* @ingroup sys_sem
* Delete a semaphore
* Deallocates a semaphore.
* @param sem semaphore to delete
*/
void sys_sem_free(sys_sem_t *sem);
@ -207,14 +254,20 @@ void sys_sem_free(sys_sem_t *sem);
#ifndef sys_sem_valid
/**
* @ingroup sys_sem
* Check if a semaphore is valid/allocated: return 1 for valid, 0 for invalid
* Returns 1 if the semaphore is valid, 0 if it is not valid.
* When using pointers, a simple way is to check the pointer for != NULL.
* When directly using OS structures, implementing this may be more complex.
* This may also be a define, in which case the function is not prototyped.
*/
int sys_sem_valid(sys_sem_t *sem);
#endif
#ifndef sys_sem_set_invalid
/**
* @ingroup sys_sem
* Set a semaphore invalid so that sys_sem_valid returns 0
* Invalidate a semaphore so that sys_sem_valid() returns 0.
* ATTENTION: This does NOT mean that the semaphore shall be deallocated:
* sys_sem_free() is always called before calling this function!
* This may also be a define, in which case the function is not prototyped.
*/
void sys_sem_set_invalid(sys_sem_t *sem);
#endif
@ -243,7 +296,14 @@ void sys_msleep(u32_t ms); /* only has a (close to) 1 ms resolution. */
/**
* @ingroup sys_mbox
* Create a new mbox of specified size
* Creates an empty mailbox for maximum "size" elements. Elements stored
* in mailboxes are pointers. You have to define macros "_MBOX_SIZE"
* in your lwipopts.h, or ignore this parameter in your implementation
* and use a default size.
* If the mailbox has been created, ERR_OK should be returned. Returning any
* other error will provide a hint what went wrong, but except for assertions,
* no real error handling is implemented.
*
* @param mbox pointer to the mbox to create
* @param size (minimum) number of messages in this mbox
* @return ERR_OK if successful, another err_t otherwise
@ -252,45 +312,67 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size);
/**
* @ingroup sys_mbox
* Post a message to an mbox - may not fail
* -> blocks if full, only used from tasks not from ISR
* -> blocks if full, only to be used from tasks NOT from ISR!
*
* @param mbox mbox to posts the message
* @param msg message to post (ATTENTION: can be NULL)
*/
void sys_mbox_post(sys_mbox_t *mbox, void *msg);
/**
* @ingroup sys_mbox
* Try to post a message to an mbox - may fail if full or ISR
* Try to post a message to an mbox - may fail if full.
* Can be used from ISR (if the sys arch layer allows this).
* Returns ERR_MEM if it is full, else, ERR_OK if the "msg" is posted.
*
* @param mbox mbox to posts the message
* @param msg message to post (ATTENTION: can be NULL)
*/
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg);
/**
* @ingroup sys_mbox
* Wait for a new message to arrive in the mbox
* Try to post a message to an mbox - may fail if full.
* To be be used from ISR.
* Returns ERR_MEM if it is full, else, ERR_OK if the "msg" is posted.
*
* @param mbox mbox to posts the message
* @param msg message to post (ATTENTION: can be NULL)
*/
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg);
/**
* @ingroup sys_mbox
* Blocks the thread until a message arrives in the mailbox, but does
* not block the thread longer than "timeout" milliseconds (similar to
* the sys_arch_sem_wait() function). If "timeout" is 0, the thread should
* be blocked until a message arrives. The "msg" argument is a result
* parameter that is set by the function (i.e., by doing "*msg =
* ptr"). The "msg" parameter maybe NULL to indicate that the message
* should be dropped.
* The return values are the same as for the sys_arch_sem_wait() function:
* SYS_ARCH_TIMEOUT if there was a timeout, any other value if a messages
* is received.
*
* Note that a function with a similar name, sys_mbox_fetch(), is
* implemented by lwIP.
*
* @param mbox mbox to get a message from
* @param msg pointer where the message is stored
* @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever)
* @return time (in milliseconds) waited for a message, may be 0 if not waited
or SYS_ARCH_TIMEOUT on timeout
* The returned time has to be accurate to prevent timer jitter!
* @return SYS_ARCH_TIMEOUT on timeout, any other value if a message has been received
*/
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout);
#if ESP_THREAD_SAFE
/**
* @ingroup sys_mbox
* Set the owner of the mbox
* @param mbox mbox to set the owner
* @param owner the owner of the mbox, it's a pointer to struct netconn
*/
void sys_mbox_set_owner(sys_mbox_t *mbox, void *owner);
#endif
/* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */
#ifndef sys_arch_mbox_tryfetch
/**
* @ingroup sys_mbox
* Wait for a new message to arrive in the mbox
* This is similar to sys_arch_mbox_fetch, however if a message is not
* present in the mailbox, it immediately returns with the code
* SYS_MBOX_EMPTY. On success 0 is returned.
* To allow for efficient implementations, this can be defined as a
* function-like macro in sys_arch.h instead of a normal function. For
* example, a naive implementation could be:
* \#define sys_arch_mbox_tryfetch(mbox,msg) sys_arch_mbox_fetch(mbox,msg,1)
* although this would introduce unnecessary delays.
*
* @param mbox mbox to get a message from
* @param msg pointer where the message is stored
* @return 0 (milliseconds) if a message has been received
@ -304,7 +386,10 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg);
#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg)
/**
* @ingroup sys_mbox
* Delete an mbox
* Deallocates a mailbox. If there are messages still present in the
* mailbox when the mailbox is deallocated, it is an indication of a
* programming error in lwIP and the developer should be notified.
*
* @param mbox mbox to delete
*/
void sys_mbox_free(sys_mbox_t *mbox);
@ -312,14 +397,20 @@ void sys_mbox_free(sys_mbox_t *mbox);
#ifndef sys_mbox_valid
/**
* @ingroup sys_mbox
* Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid
* Returns 1 if the mailbox is valid, 0 if it is not valid.
* When using pointers, a simple way is to check the pointer for != NULL.
* When directly using OS structures, implementing this may be more complex.
* This may also be a define, in which case the function is not prototyped.
*/
int sys_mbox_valid(sys_mbox_t *mbox);
#endif
#ifndef sys_mbox_set_invalid
/**
* @ingroup sys_mbox
* Set an mbox invalid so that sys_mbox_valid returns 0
* Invalidate a mailbox so that sys_mbox_valid() returns 0.
* ATTENTION: This does NOT mean that the mailbox shall be deallocated:
* sys_mbox_free() is always called before calling this function!
* This may also be a define, in which case the function is not prototyped.
*/
void sys_mbox_set_invalid(sys_mbox_t *mbox);
#endif
@ -340,8 +431,13 @@ void sys_mbox_set_invalid(sys_mbox_t *mbox);
/**
* @ingroup sys_misc
* The only thread function:
* Creates a new thread
* Starts a new thread named "name" with priority "prio" that will begin its
* execution in the function "thread()". The "arg" argument will be passed as an
* argument to the thread() function. The stack size to used for this thread is
* the "stacksize" parameter. The id of the new thread is returned. Both the id
* and the priority are system dependent.
* ATTENTION: although this function returns a value, it MUST NOT FAIL (ports have to assert this!)
*
* @param name human-readable name for the thread (used for debugging purposes)
* @param thread thread-function
* @param arg parameter passed to 'thread'
@ -351,7 +447,11 @@ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg,
#endif /* NO_SYS */
/* sys_init() must be called before anything else. */
/**
* @ingroup sys_misc
* sys_init() must be called before anything else.
* Initialize the sys_arch layer.
*/
void sys_init(void);
#ifndef sys_jiffies
@ -365,6 +465,9 @@ u32_t sys_jiffies(void);
* @ingroup sys_time
* Returns the current time in milliseconds,
* may be the same as sys_jiffies or at least based on it.
* Don't care for wraparound, this is only used for time diffs.
* Not implementing this function means you cannot use some modules (e.g. TCP
* timestamps, internal timeouts for NO_SYS==1).
*/
u32_t sys_now(void);
@ -466,6 +569,15 @@ void sys_arch_unprotect(sys_prot_t pval);
} while(0)
#endif /* SYS_ARCH_SET */
#ifndef SYS_ARCH_LOCKED
#define SYS_ARCH_LOCKED(code) do { \
SYS_ARCH_DECL_PROTECT(old_level); \
SYS_ARCH_PROTECT(old_level); \
code; \
SYS_ARCH_UNPROTECT(old_level); \
} while(0)
#endif /* SYS_ARCH_LOCKED */
#ifdef __cplusplus
}

View File

@ -42,6 +42,7 @@
#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/tcpbase.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/ip.h"
@ -55,6 +56,7 @@ extern "C" {
#endif
struct tcp_pcb;
struct tcp_pcb_listen;
/** Function prototype for tcp accept callback functions. Called when a new
* connection can be accepted on a listening pcb.
@ -136,34 +138,73 @@ typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err);
#define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale))
#define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF))
#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND)))
typedef u32_t tcpwnd_size_t;
#else
#define RCV_WND_SCALE(pcb, wnd) (wnd)
#define SND_WND_SCALE(pcb, wnd) (wnd)
#define TCPWND16(x) (x)
#define TCP_WND_MAX(pcb) TCP_WND
typedef u16_t tcpwnd_size_t;
#endif
/* Increments a tcpwnd_size_t and holds at max value rather than rollover */
#define TCP_WND_INC(wnd, inc) do { \
if ((tcpwnd_size_t)(wnd + inc) >= wnd) { \
wnd = (tcpwnd_size_t)(wnd + inc); \
} else { \
wnd = (tcpwnd_size_t)-1; \
} \
} while(0)
#if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG || LWIP_TCP_TIMESTAMPS
typedef u16_t tcpflags_t;
#else
typedef u8_t tcpflags_t;
#endif
enum tcp_state {
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
#if LWIP_TCP_SACK_OUT
/** SACK ranges to include in ACK packets.
* SACK entry is invalid if left==right. */
struct tcp_sack_range {
/** Left edge of the SACK: the first acknowledged sequence number. */
u32_t left;
/** Right edge of the SACK: the last acknowledged sequence number +1 (so first NOT acknowledged). */
u32_t right;
};
#endif /* LWIP_TCP_SACK_OUT */
/** Function prototype for deallocation of arguments. Called *just before* the
* pcb is freed, so don't expect to be able to do anything with this pcb!
*
* @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id)
* @param data pointer to the data (set via @ref tcp_ext_arg_set before)
*/
typedef void (*tcp_extarg_callback_pcb_destroyed_fn)(u8_t id, void *data);
/** Function prototype to transition arguments from a listening pcb to an accepted pcb
*
* @param id ext arg id (allocated via @ref tcp_ext_arg_alloc_id)
* @param lpcb the listening pcb accepting a connection
* @param cpcb the newly allocated connection pcb
* @return ERR_OK if OK, any error if connection should be dropped
*/
typedef err_t (*tcp_extarg_callback_passive_open_fn)(u8_t id, struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb);
/** A table of callback functions that is invoked for ext arguments */
struct tcp_ext_arg_callbacks {
/** @ref tcp_extarg_callback_pcb_destroyed_fn */
tcp_extarg_callback_pcb_destroyed_fn destroy;
/** @ref tcp_extarg_callback_passive_open_fn */
tcp_extarg_callback_passive_open_fn passive_open;
};
#define LWIP_TCP_PCB_NUM_EXT_ARG_ID_INVALID 0xFF
#if LWIP_TCP_PCB_NUM_EXT_ARGS
/* This is the structure for ext args in tcp pcbs (used as array) */
struct tcp_pcb_ext_args {
const struct tcp_ext_arg_callbacks *callbacks;
void *data;
};
/* This is a helper define to prevent zero size arrays if disabled */
#define TCP_PCB_EXTARGS struct tcp_pcb_ext_args ext_args[LWIP_TCP_PCB_NUM_EXT_ARGS];
#else
#define TCP_PCB_EXTARGS
#endif
typedef u16_t tcpflags_t;
#define TCP_ALLFLAGS 0xffffU
/**
* members common to struct tcp_pcb and struct tcp_listen_pcb
@ -171,6 +212,7 @@ enum tcp_state {
#define TCP_PCB_COMMON(type) \
type *next; /* for the linked list */ \
void *callback_arg; \
TCP_PCB_EXTARGS \
enum tcp_state state; /* TCP state */ \
u8_t prio; \
/* ports are in host byte order */ \
@ -223,6 +265,10 @@ struct tcp_pcb {
#endif
#if LWIP_TCP_TIMESTAMPS
#define TF_TIMESTAMP 0x0400U /* Timestamp option enabled */
#endif
#define TF_RTO 0x0800U /* RTO timer has fired, in-flight data moved to unsent and being retransmitted */
#if LWIP_TCP_SACK_OUT
#define TF_SACK 0x1000U /* Selective ACKs enabled */
#endif
/* the rest of the fields are in host byte order
@ -239,6 +285,12 @@ struct tcp_pcb {
tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */
u32_t rcv_ann_right_edge; /* announced right edge of window */
#if LWIP_TCP_SACK_OUT
/* SACK ranges to include in ACK packets (entry is invalid if left==right) */
struct tcp_sack_range rcv_sacks[LWIP_TCP_MAX_SACK_NUM];
#define LWIP_TCP_SACK_VALID(pcb, idx) ((pcb)->rcv_sacks[idx].left != (pcb)->rcv_sacks[idx].right)
#endif /* LWIP_TCP_SACK_OUT */
/* Retransmission timer. */
s16_t rtime;
@ -247,9 +299,9 @@ struct tcp_pcb {
/* RTT (round trip time) estimation variables */
u32_t rttest; /* RTT estimate in 500ms ticks */
u32_t rtseq; /* sequence number being timed */
s16_t sa, sv; /* @todo document this */
s16_t sa, sv; /* @see "Congestion Avoidance and Control" by Van Jacobson and Karels */
s16_t rto; /* retransmission time-out */
s16_t rto; /* retransmission time-out (in ticks of TCP_SLOW_INTERVAL) */
u8_t nrtx; /* number of retransmissions */
/* fast retransmit/recovery */
@ -260,6 +312,9 @@ struct tcp_pcb {
tcpwnd_size_t cwnd;
tcpwnd_size_t ssthresh;
/* first byte following last rto byte */
u32_t rto_end;
/* sender variables */
u32_t snd_nxt; /* next new seqno to be sent */
u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last
@ -277,6 +332,8 @@ struct tcp_pcb {
u16_t unsent_oversize;
#endif /* TCP_OVERSIZE */
tcpwnd_size_t bytes_acked;
/* These are ordered by sequence number: */
struct tcp_seg *unsent; /* Unsent (queued) segments. */
struct tcp_seg *unacked; /* Sent but unacknowledged segments. */
@ -319,6 +376,8 @@ struct tcp_pcb {
u8_t persist_cnt;
/* Persist timer back-off */
u8_t persist_backoff;
/* Number of persist probes */
u8_t persist_probe;
/* KEEPALIVE counter */
u8_t keep_cnt_sent;
@ -327,29 +386,8 @@ struct tcp_pcb {
u8_t snd_scale;
u8_t rcv_scale;
#endif
#if ESP_STATS_TCP
#define ESP_STATS_TCP_ARRAY_SIZE 20
u16_t retry_cnt[TCP_MAXRTX];
u16_t rto_cnt[ESP_STATS_TCP_ARRAY_SIZE];
#endif
};
#if ESP_STATS_TCP
#define ESP_STATS_TCP_PCB(_pcb) do {\
if ((_pcb)->unacked) {\
(_pcb)->retry_cnt[(_pcb)->nrtx]++;\
if ((_pcb)->rto < ESP_STATS_TCP_ARRAY_SIZE) {\
(_pcb)->rto_cnt[(_pcb)->rto]++;\
} else {\
(_pcb)->rto_cnt[ESP_STATS_TCP_ARRAY_SIZE-1] ++;\
}\
}\
} while(0)
#else
#define ESP_STATS_TCP_PCB(pcb)
#endif
#if LWIP_EVENT_API
enum lwip_event {
@ -382,19 +420,26 @@ void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept);
#endif /* LWIP_CALLBACK_API */
void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval);
#define tcp_set_flags(pcb, set_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags | (set_flags)); } while(0)
#define tcp_clear_flags(pcb, clr_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags & (tcpflags_t)(~(clr_flags) & TCP_ALLFLAGS)); } while(0)
#define tcp_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0)
#if LWIP_TCP_TIMESTAMPS
#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss)
#else /* LWIP_TCP_TIMESTAMPS */
/** @ingroup tcp_raw */
#define tcp_mss(pcb) ((pcb)->mss)
#endif /* LWIP_TCP_TIMESTAMPS */
/** @ingroup tcp_raw */
#define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf))
/** @ingroup tcp_raw */
#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen)
/** @ingroup tcp_raw */
#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY)
#define tcp_nagle_disable(pcb) tcp_set_flags(pcb, TF_NODELAY)
/** @ingroup tcp_raw */
#define tcp_nagle_enable(pcb) ((pcb)->flags = (tcpflags_t)((pcb)->flags & ~TF_NODELAY))
#define tcp_nagle_enable(pcb) tcp_clear_flags(pcb, TF_NODELAY)
/** @ingroup tcp_raw */
#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0)
#define tcp_nagle_disabled(pcb) tcp_is_flag_set(pcb, TF_NODELAY)
#if TCP_LISTEN_BACKLOG
#define tcp_backlog_set(pcb, new_backlog) do { \
@ -407,11 +452,12 @@ void tcp_backlog_accepted(struct tcp_pcb* pcb);
#define tcp_backlog_delayed(pcb)
#define tcp_backlog_accepted(pcb)
#endif /* TCP_LISTEN_BACKLOG */
#define tcp_accepted(pcb) /* compatibility define, not needed any more */
#define tcp_accepted(pcb) do { LWIP_UNUSED_ARG(pcb); } while(0) /* compatibility define, not needed any more */
void tcp_recved (struct tcp_pcb *pcb, u16_t len);
err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port);
void tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif);
err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
u16_t port, tcp_connected_fn connected);
@ -424,27 +470,27 @@ void tcp_abort (struct tcp_pcb *pcb);
err_t tcp_close (struct tcp_pcb *pcb);
err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx);
/* Flags for "apiflags" parameter in tcp_write */
#define TCP_WRITE_FLAG_COPY 0x01
#define TCP_WRITE_FLAG_MORE 0x02
err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
u8_t apiflags);
void tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
#define TCP_PRIO_MIN 1
#define TCP_PRIO_NORMAL 64
#define TCP_PRIO_MAX 127
err_t tcp_output (struct tcp_pcb *pcb);
err_t tcp_tcp_get_tcp_addrinfo(struct tcp_pcb *pcb, int local, ip_addr_t *addr, u16_t *port);
const char* tcp_debug_state_str(enum tcp_state s);
#define tcp_dbg_get_tcp_state(pcb) ((pcb)->state)
/* for compatibility with older implementation */
#define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6)
#if LWIP_TCP_PCB_NUM_EXT_ARGS
u8_t tcp_ext_arg_alloc_id(void);
void tcp_ext_arg_set_callbacks(struct tcp_pcb *pcb, uint8_t id, const struct tcp_ext_arg_callbacks * const callbacks);
void tcp_ext_arg_set(struct tcp_pcb *pcb, uint8_t id, void *arg);
void *tcp_ext_arg_get(const struct tcp_pcb *pcb, uint8_t id);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,88 @@
/**
* @file
* Base TCP API definitions shared by TCP and ALTCP\n
* See also @ref tcp_raw
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_TCPBASE_H
#define LWIP_HDR_TCPBASE_H
#include "lwip/opt.h"
#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_WND_SCALE
typedef u32_t tcpwnd_size_t;
#else
typedef u16_t tcpwnd_size_t;
#endif
enum tcp_state {
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
};
/* ATTENTION: this depends on state number ordering! */
#define TCP_STATE_IS_CLOSING(state) ((state) >= FIN_WAIT_1)
/* Flags for "apiflags" parameter in tcp_write */
#define TCP_WRITE_FLAG_COPY 0x01
#define TCP_WRITE_FLAG_MORE 0x02
#define TCP_PRIO_MIN 1
#define TCP_PRIO_NORMAL 64
#define TCP_PRIO_MAX 127
const char* tcp_debug_state_str(enum tcp_state s);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_TCP */
#endif /* LWIP_HDR_TCPBASE_H */

Some files were not shown because too many files have changed in this diff Show More