Upgraded lwIP to 2.0.3

This commit is contained in:
Joseph Henry
2017-09-19 10:50:17 -07:00
parent 4991c85598
commit 91eb869e02
24 changed files with 568 additions and 304 deletions

View File

@@ -4,6 +4,22 @@ HISTORY
* [Enter new changes just after this line - do not remove this line]
(STABLE-2.0.3)
++ Bugfixes:
2017-09-11: Simon Goldschmidt
* tcp_in.c: fix bug #51937 (leaking tcp_pcbs on passive close with unacked data)
2017-08-02: Abroz Bizjak/Simon Goldschmidt
* multiple fixes in IPv4 reassembly (leading to corrupted datagrams received)
2017-03-30: Simon Goldschmidt
* dhcp.c: return ERR_VAL instead of asserting on offset-out-of-pbuf
2017-03-23: Dirk Ziegelmeier
* dhcp.h: fix bug #50618 (dhcp_remove_struct() macro does not work)
(STABLE-2.0.2)
++ New features:
@@ -13,6 +29,9 @@ HISTORY
We now have a #define for a header file name that is #included in every .c
file that provides hooks.
2017-02-10: Simon Goldschmidt
* tcp_close does not fail on memory error (instead, FIN is sent from tcp_tmr)
++ Bugfixes:
2017-03-08

View File

@@ -1,235 +1,243 @@
This file lists major changes between release versions that require
ports or applications to be changed. Use it to update a port or an
application written for an older version of lwIP to correctly work
with newer versions.
(git master)
* [Enter new changes just after this line - do not remove this line]
This file lists major changes between release versions that require
ports or applications to be changed. Use it to update a port or an
application written for an older version of lwIP to correctly work
with newer versions.
(git master)
* [Enter new changes just after this line - do not remove this line]
(2.0.2)
++ Application changes:
* slipif: The way to pass serial port number has changed. netif->num is not
supported any more, netif->state is interpreted as an u8_t port number now
(it's not a POINTER to an u8_t any more!)
(2.0.1)
++ Application changes:
* UDP does NOT receive multicast traffic from ALL netifs on an UDP PCB bound to a specific
netif any more. Users need to bind to IP_ADDR_ANY to receive multicast traffic and compare
ip_current_netif() to the desired netif for every packet.
See bug #49662 for an explanation.
(2.0.0)
++ Application changes:
* Changed netif "up" flag handling to be an administrative flag (as opposed to the previous meaning of
"ip4-address-valid", a netif will now not be used for transmission if not up) -> even a DHCP netif
has to be set "up" before starting the DHCP client
* Added IPv6 support (dual-stack or IPv4/IPv6 only)
* Changed ip_addr_t to be a union in dual-stack mode (use ip4_addr_t where referring to IPv4 only).
* Major rewrite of SNMP (added MIB parser that creates code stubs for custom MIBs);
supports SNMPv2c (experimental v3 support)
* Moved some core applications from contrib repository to src/apps (and include/lwip/apps)
+++ Raw API:
* Changed TCP listen backlog: removed tcp_accepted(), added the function pair tcp_backlog_delayed()/
tcp_backlog_accepted() to explicitly delay backlog handling on a connection pcb
+++ Socket API:
* Added an implementation for posix sendmsg()
* Added LWIP_FIONREAD_LINUXMODE that makes ioctl/FIONREAD return the size of the next pending datagram
++ Port changes
+++ new files:
* MANY new and moved files!
* Added src/Filelists.mk for use in Makefile projects
* Continued moving stack-internal parts from abc.h to abc_priv.h in sub-folder "priv"
to let abc.h only contain the actual application programmer's API
+++ sys layer:
* Made LWIP_TCPIP_CORE_LOCKING==1 the default as it usually performs better than
the traditional message passing (although with LWIP_COMPAT_MUTEX you are still
open to priority inversion, so this is not recommended any more)
* Added LWIP_NETCONN_SEM_PER_THREAD to use one "op_completed" semaphore per thread
instead of using one per netconn (these semaphores are used even with core locking
enabled as some longer lasting functions like big writes still need to delay)
* Added generalized abstraction for itoa(), strnicmp(), stricmp() and strnstr()
in def.h (to be overridden in cc.h) instead of config
options for netbiosns, httpd, dns, etc. ...
* New abstraction for hton* and ntoh* functions in def.h.
To override them, use the following in cc.h:
#define lwip_htons(x) <your_htons>
#define lwip_htonl(x) <your_htonl>
+++ new options:
* TODO
+++ new pools:
* Added LWIP_MEMPOOL_* (declare/init/alloc/free) to declare private memp pools
that share memp.c code but do not have to be made global via lwippools.h
* Added pools for IPv6, MPU_COMPATIBLE, dns-api, netif-api, etc.
* added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when a memp pool was empty and an item
is now available
* Signature of LWIP_HOOK_VLAN_SET macro was changed
* LWIP_DECLARE_MEMORY_ALIGNED() may be used to declare aligned memory buffers (mem/memp)
or to move buffers to dedicated memory using compiler attributes
* Standard C headers are used to define sized types and printf formatters
(disable by setting LWIP_NO_STDINT_H=1 or LWIP_NO_INTTYPES_H=1 if your compiler
does not support these)
++ Major bugfixes/improvements
* Added IPv6 support (dual-stack or IPv4/IPv6 only)
* Major rewrite of PPP (incl. keep-up with apache pppd)
see doc/ppp.txt for an upgrading how-to
* Major rewrite of SNMP (incl. MIB parser)
* Fixed timing issues that might have lead to losing a DHCP lease
* Made rx processing path more robust against crafted errors
* TCP window scaling support
* modification of api modules to support FreeRTOS-MPU (don't pass stack-pointers to other threads)
* made DNS client more robust
* support PBUF_REF for RX packets
* LWIP_NETCONN_FULLDUPLEX allows netconn/sockets to be used for reading/writing from separate
threads each (needs LWIP_NETCONN_SEM_PER_THREAD)
* Moved and reordered stats (mainly memp/mib2)
(1.4.0)
++ Application changes:
* Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for
compatibility to old applications, but will be removed in the future).
* Renamed mem_realloc() to mem_trim() to prevent confusion with realloc()
+++ Raw API:
* Changed the semantics of tcp_close() (since it was rather a
shutdown before): Now the application does *NOT* get any calls to the recv
callback (aside from NULL/closed) after calling tcp_close()
* When calling tcp_abort() from a raw API TCP callback function,
make sure you return ERR_ABRT to prevent accessing unallocated memory.
(ERR_ABRT now means the applicaiton has called tcp_abort!)
+++ Netconn API:
* Changed netconn_receive() and netconn_accept() to return
err_t, not a pointer to new data/netconn.
+++ Socket API:
* LWIP_SO_RCVTIMEO: when accept() or recv() time out, they
now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT.
* Added a minimal version of posix fctl() to have a
standardised way to set O_NONBLOCK for nonblocking sockets.
+++ all APIs:
* correctly implemented SO(F)_REUSEADDR
++ Port changes
+++ new files:
* Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h:
* Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains
the actual application programmer's API
* Separated timer implementation from sys.h/.c, moved to timers.h/.c;
Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you
still want to use your own timer implementation for NO_SYS==0 (as before).
+++ sys layer:
* Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/
sys_sem_t;
* Converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
* Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use
binary semaphores instead of mutexes - as before)
+++ new options:
* Don't waste memory when chaining segments, added option TCP_OVERSIZE to
prevent creating many small pbufs when calling tcp_write with many small
blocks of data. Instead, pbufs are allocated larger than needed and the
space is used for later calls to tcp_write.
* Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs
in tcp_write/udp_send.
* Added an additional option LWIP_ETHERNET to support ethernet without ARP
(necessary for pure PPPoE)
* Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may
be used to place these pools into user-defined memory by using external
declaration.
* Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT
+++ new pools:
* Netdb uses a memp pool for allocating memory when getaddrinfo() is called,
so MEMP_NUM_NETDB has to be set accordingly.
* DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so
MEMP_NUM_LOCALHOSTLIST has to be set accordingly.
* Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have
to be set accordingly.
* PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES
has to be set accordingly
* Integrated loopif into netif.c - loopif does not have to be created by the
port any more, just define LWIP_HAVE_LOOPIF to 1.
* Added define LWIP_RAND() for lwip-wide randomization (needs to be defined
in cc.h, e.g. used by igmp)
* Added printf-formatter X8_F to printf u8_t as hex
* The heap now may be moved to user-defined memory by defining
LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
* added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work
with user-allocated structs instead of calling mem_malloc
* Added const char* name to mem- and memp-stats for easier debugging.
* Calculate the TCP/UDP checksum while copying to only fetch data once:
Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
* Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
more than one pcb.
* Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
off any more, if this is set to 0, only one packet (the most recent one) is
queued (like demanded by RFC 1122).
++ Major bugfixes/improvements
* Implemented tcp_shutdown() to only shut down one end of a connection
* Implemented shutdown() at socket- and netconn-level
* Added errorset support to select() + improved select speed overhead
* Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x)
* Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1
* Use macros defined in ip_addr.h to work with IP addresses
* Implemented many nonblocking socket/netconn functions
* Fixed ARP input processing: only add a new entry if a request was directed as us
* mem_realloc() to mem_trim() to prevent confusion with realloc()
* Some improvements for AutoIP (don't route/forward link-local addresses, don't break
existing connections when assigning a routable address)
* Correctly handle remote side overrunning our rcv_wnd in ooseq case
* Removed packing from ip_addr_t, the packed version is now only used in protocol headers
* Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0
* Added support for static ARP table entries
(STABLE-1.3.2)
* initial version of this file
++ Application changes:
* UDP does NOT receive multicast traffic from ALL netifs on an UDP PCB bound to a specific
netif any more. Users need to bind to IP_ADDR_ANY to receive multicast traffic and compare
ip_current_netif() to the desired netif for every packet.
See bug #49662 for an explanation.
(2.0.0)
++ Application changes:
* Changed netif "up" flag handling to be an administrative flag (as opposed to the previous meaning of
"ip4-address-valid", a netif will now not be used for transmission if not up) -> even a DHCP netif
has to be set "up" before starting the DHCP client
* Added IPv6 support (dual-stack or IPv4/IPv6 only)
* Changed ip_addr_t to be a union in dual-stack mode (use ip4_addr_t where referring to IPv4 only).
* Major rewrite of SNMP (added MIB parser that creates code stubs for custom MIBs);
supports SNMPv2c (experimental v3 support)
* Moved some core applications from contrib repository to src/apps (and include/lwip/apps)
+++ Raw API:
* Changed TCP listen backlog: removed tcp_accepted(), added the function pair tcp_backlog_delayed()/
tcp_backlog_accepted() to explicitly delay backlog handling on a connection pcb
+++ Socket API:
* Added an implementation for posix sendmsg()
* Added LWIP_FIONREAD_LINUXMODE that makes ioctl/FIONREAD return the size of the next pending datagram
++ Port changes
+++ new files:
* MANY new and moved files!
* Added src/Filelists.mk for use in Makefile projects
* Continued moving stack-internal parts from abc.h to abc_priv.h in sub-folder "priv"
to let abc.h only contain the actual application programmer's API
+++ sys layer:
* Made LWIP_TCPIP_CORE_LOCKING==1 the default as it usually performs better than
the traditional message passing (although with LWIP_COMPAT_MUTEX you are still
open to priority inversion, so this is not recommended any more)
* Added LWIP_NETCONN_SEM_PER_THREAD to use one "op_completed" semaphore per thread
instead of using one per netconn (these semaphores are used even with core locking
enabled as some longer lasting functions like big writes still need to delay)
* Added generalized abstraction for itoa(), strnicmp(), stricmp() and strnstr()
in def.h (to be overridden in cc.h) instead of config
options for netbiosns, httpd, dns, etc. ...
* New abstraction for hton* and ntoh* functions in def.h.
To override them, use the following in cc.h:
#define lwip_htons(x) <your_htons>
#define lwip_htonl(x) <your_htonl>
+++ new options:
* TODO
+++ new pools:
* Added LWIP_MEMPOOL_* (declare/init/alloc/free) to declare private memp pools
that share memp.c code but do not have to be made global via lwippools.h
* Added pools for IPv6, MPU_COMPATIBLE, dns-api, netif-api, etc.
* added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when a memp pool was empty and an item
is now available
* Signature of LWIP_HOOK_VLAN_SET macro was changed
* LWIP_DECLARE_MEMORY_ALIGNED() may be used to declare aligned memory buffers (mem/memp)
or to move buffers to dedicated memory using compiler attributes
* Standard C headers are used to define sized types and printf formatters
(disable by setting LWIP_NO_STDINT_H=1 or LWIP_NO_INTTYPES_H=1 if your compiler
does not support these)
++ Major bugfixes/improvements
* Added IPv6 support (dual-stack or IPv4/IPv6 only)
* Major rewrite of PPP (incl. keep-up with apache pppd)
see doc/ppp.txt for an upgrading how-to
* Major rewrite of SNMP (incl. MIB parser)
* Fixed timing issues that might have lead to losing a DHCP lease
* Made rx processing path more robust against crafted errors
* TCP window scaling support
* modification of api modules to support FreeRTOS-MPU (don't pass stack-pointers to other threads)
* made DNS client more robust
* support PBUF_REF for RX packets
* LWIP_NETCONN_FULLDUPLEX allows netconn/sockets to be used for reading/writing from separate
threads each (needs LWIP_NETCONN_SEM_PER_THREAD)
* Moved and reordered stats (mainly memp/mib2)
(1.4.0)
++ Application changes:
* Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for
compatibility to old applications, but will be removed in the future).
* Renamed mem_realloc() to mem_trim() to prevent confusion with realloc()
+++ Raw API:
* Changed the semantics of tcp_close() (since it was rather a
shutdown before): Now the application does *NOT* get any calls to the recv
callback (aside from NULL/closed) after calling tcp_close()
* When calling tcp_abort() from a raw API TCP callback function,
make sure you return ERR_ABRT to prevent accessing unallocated memory.
(ERR_ABRT now means the applicaiton has called tcp_abort!)
+++ Netconn API:
* Changed netconn_receive() and netconn_accept() to return
err_t, not a pointer to new data/netconn.
+++ Socket API:
* LWIP_SO_RCVTIMEO: when accept() or recv() time out, they
now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT.
* Added a minimal version of posix fctl() to have a
standardised way to set O_NONBLOCK for nonblocking sockets.
+++ all APIs:
* correctly implemented SO(F)_REUSEADDR
++ Port changes
+++ new files:
* Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h:
* Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains
the actual application programmer's API
* Separated timer implementation from sys.h/.c, moved to timers.h/.c;
Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you
still want to use your own timer implementation for NO_SYS==0 (as before).
+++ sys layer:
* Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/
sys_sem_t;
* Converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
* Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use
binary semaphores instead of mutexes - as before)
+++ new options:
* Don't waste memory when chaining segments, added option TCP_OVERSIZE to
prevent creating many small pbufs when calling tcp_write with many small
blocks of data. Instead, pbufs are allocated larger than needed and the
space is used for later calls to tcp_write.
* Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs
in tcp_write/udp_send.
* Added an additional option LWIP_ETHERNET to support ethernet without ARP
(necessary for pure PPPoE)
* Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may
be used to place these pools into user-defined memory by using external
declaration.
* Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT
+++ new pools:
* Netdb uses a memp pool for allocating memory when getaddrinfo() is called,
so MEMP_NUM_NETDB has to be set accordingly.
* DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so
MEMP_NUM_LOCALHOSTLIST has to be set accordingly.
* Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have
to be set accordingly.
* PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES
has to be set accordingly
* Integrated loopif into netif.c - loopif does not have to be created by the
port any more, just define LWIP_HAVE_LOOPIF to 1.
* Added define LWIP_RAND() for lwip-wide randomization (needs to be defined
in cc.h, e.g. used by igmp)
* Added printf-formatter X8_F to printf u8_t as hex
* The heap now may be moved to user-defined memory by defining
LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
* added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work
with user-allocated structs instead of calling mem_malloc
* Added const char* name to mem- and memp-stats for easier debugging.
* Calculate the TCP/UDP checksum while copying to only fetch data once:
Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
* Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
more than one pcb.
* Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
off any more, if this is set to 0, only one packet (the most recent one) is
queued (like demanded by RFC 1122).
++ Major bugfixes/improvements
* Implemented tcp_shutdown() to only shut down one end of a connection
* Implemented shutdown() at socket- and netconn-level
* Added errorset support to select() + improved select speed overhead
* Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x)
* Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1
* Use macros defined in ip_addr.h to work with IP addresses
* Implemented many nonblocking socket/netconn functions
* Fixed ARP input processing: only add a new entry if a request was directed as us
* mem_realloc() to mem_trim() to prevent confusion with realloc()
* Some improvements for AutoIP (don't route/forward link-local addresses, don't break
existing connections when assigning a routable address)
* Correctly handle remote side overrunning our rcv_wnd in ooseq case
* Removed packing from ip_addr_t, the packed version is now only used in protocol headers
* Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0
* Added support for static ARP table entries
(STABLE-1.3.2)
* initial version of this file

View File

@@ -1,4 +1,5 @@
void eth_mac_irq()
void
eth_mac_irq()
{
/* Service MAC IRQ here */
@@ -17,7 +18,8 @@ void eth_mac_irq()
}
}
static err_t netif_output(struct netif *netif, struct pbuf *p)
static err_t
netif_output(struct netif *netif, struct pbuf *p)
{
LINK_STATS_INC(link.xmit);
@@ -38,12 +40,14 @@ static err_t netif_output(struct netif *netif, struct pbuf *p)
return ERR_OK;
}
static void netif_status_callback(struct netif *netif)
static void
netif_status_callback(struct netif *netif)
{
printf("netif status changed %s\n", ip4addr_ntoa(netif_ip4_addr(netif)));
}
static err_t netif_init(struct netif *netif)
static err_t
netif_init(struct netif *netif)
{
netif->linkoutput = netif_output;
netif->output = etharp_output;
@@ -58,7 +62,8 @@ static err_t netif_init(struct netif *netif)
return ERR_OK;
}
void main(void)
void
main(void)
{
struct netif netif;
@@ -74,7 +79,7 @@ void main(void)
netif_set_up(&netif);
/* Start DHCP and HTTPD */
dhcp_init();
dhcp_start(&netif );
httpd_init();
while(1) {

View File

@@ -177,14 +177,20 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
conn = (struct netconn *)arg;
if (conn == NULL) {
pbuf_free(p);
return;
}
LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
#if LWIP_SO_RCVBUF
SYS_ARCH_GET(conn->recv_avail, recv_avail);
if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) ||
if (!sys_mbox_valid(&conn->recvmbox) ||
((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
#else /* LWIP_SO_RCVBUF */
if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox)) {
if (!sys_mbox_valid(&conn->recvmbox)) {
#endif /* LWIP_SO_RCVBUF */
pbuf_free(p);
return;
@@ -471,8 +477,6 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
struct netconn *newconn;
struct netconn *conn = (struct netconn *)arg;
LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state)));
if (conn == NULL) {
return ERR_VAL;
}
@@ -490,6 +494,8 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
return ERR_VAL;
}
LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state)));
/* We have to set the callback here even though
* the new socket is unknown. newconn->socket is marked as -1. */
newconn = netconn_alloc(conn->type, conn->callback);

View File

@@ -41,6 +41,7 @@
#include "lwip/sys.h"
#include <errno.h>
//#include "lwip/errno.h"
#if !NO_SYS
/** Table to quickly map an lwIP error (err_t) to a socket error

View File

@@ -360,8 +360,9 @@ mqtt_take_request(struct mqtt_request_t **tail, u16_t pkt_id)
static void
mqtt_request_time_elapsed(struct mqtt_request_t **tail, u8_t t)
{
struct mqtt_request_t *r = *tail;
struct mqtt_request_t *r;
LWIP_ASSERT("mqtt_request_time_elapsed: tail != NULL", tail != NULL);
r = *tail;
while (t > 0 && r != NULL) {
if (t >= r->timeout_diff) {
t -= (u8_t)r->timeout_diff;

View File

@@ -337,7 +337,7 @@ void
lwip_init(void)
{
#ifndef LWIP_SKIP_CONST_CHECK
int a;
int a = 0;
LWIP_UNUSED_ARG(a);
LWIP_ASSERT("LWIP_CONST_CAST not implemented correctly. Check your lwIP port.", LWIP_CONST_CAST(void*, &a) == &a);
#endif

View File

@@ -736,7 +736,7 @@ dhcp_start(struct netif *netif)
/* no DHCP client attached yet? */
if (dhcp == NULL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n"));
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): mallocing new DHCP client\n"));
dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp));
if (dhcp == NULL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n"));
@@ -1500,7 +1500,7 @@ again:
offset_max = options_idx_max;
options = (u8_t*)q->payload;
/* at least 1 byte to read and no end marker, then at least 3 bytes to read? */
while ((q != NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) {
while ((q != NULL) && (offset < offset_max) && (options[offset] != DHCP_OPTION_END)) {
u8_t op = options[offset];
u8_t len;
u8_t decode_len = 0;
@@ -1617,7 +1617,7 @@ decode_next:
offset_max -= q->len;
if ((offset < offset_max) && offset_max) {
q = q->next;
LWIP_ASSERT("next pbuf was null", q);
LWIP_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
options = (u8_t*)q->payload;
} else {
/* We've run out of bytes, probably no end marker. Don't proceed. */
@@ -1832,7 +1832,7 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type)
(dhcp->p_out->len >= sizeof(struct dhcp_msg)));
/* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */
if (message_type != DHCP_REQUEST) {
if ((message_type != DHCP_REQUEST) || (dhcp->state == DHCP_STATE_REBOOTING)) {
/* reuse transaction identifier in retransmissions */
if (dhcp->tries == 0) {
#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND)
@@ -1942,7 +1942,8 @@ dhcp_supplied_address(const struct netif *netif)
{
if ((netif != NULL) && (netif_dhcp_data(netif) != NULL)) {
struct dhcp* dhcp = netif_dhcp_data(netif);
return (dhcp->state == DHCP_STATE_BOUND) || (dhcp->state == DHCP_STATE_RENEWING);
return (dhcp->state == DHCP_STATE_BOUND) || (dhcp->state == DHCP_STATE_RENEWING) ||
(dhcp->state == DHCP_STATE_REBINDING);
}
return 0;
}

View File

@@ -79,6 +79,10 @@
#define IP_REASS_FLAG_LASTFRAG 0x01
#define IP_REASS_VALIDATE_TELEGRAM_FINISHED 1
#define IP_REASS_VALIDATE_PBUF_QUEUED 0
#define IP_REASS_VALIDATE_PBUF_DROPPED -1
/** This is a helper struct which holds the starting
* offset and the ending offset of this fragment to
* easily chain the fragments.
@@ -333,10 +337,11 @@ ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
* fragment was received at least once).
* @param ipr points to the reassembly state
* @param new_p points to the pbuf for the current fragment
* @return 0 if invalid, >0 otherwise
* @param is_last is 1 if this pbuf has MF==0 (ipr->flags not updated yet)
* @return see IP_REASS_VALIDATE_* defines
*/
static int
ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p)
ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p, int is_last)
{
struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL;
struct pbuf *q;
@@ -375,7 +380,18 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
}
#endif /* IP_REASS_CHECK_OVERLAP */
iprh_prev->next_pbuf = new_p;
if (iprh_prev->end != iprh->start) {
/* There is a fragment missing between the current
* and the previous fragment */
valid = 0;
}
} else {
#if IP_REASS_CHECK_OVERLAP
if (iprh->end > iprh_tmp->start) {
/* fragment overlaps with following, throw away */
goto freepbuf;
}
#endif /* IP_REASS_CHECK_OVERLAP */
/* fragment with the lowest offset */
ipr->p = new_p;
}
@@ -426,7 +442,7 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
/* At this point, the validation part begins: */
/* If we already received the last fragment */
if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) {
if (is_last || ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0)) {
/* and had no holes so far */
if (valid) {
/* then check if the rest of the fragments is here */
@@ -454,23 +470,21 @@ ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct
((struct ip_reass_helper*)ipr->p->payload) != iprh);
LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
iprh->next_pbuf == NULL);
LWIP_ASSERT("validate_datagram:datagram end!=datagram len",
iprh->end == ipr->datagram_len);
}
}
}
/* If valid is 0 here, there are some fragments missing in the middle
* (since MF == 0 has already arrived). Such datagrams simply time out if
* no more fragments are received... */
return valid;
return valid ? IP_REASS_VALIDATE_TELEGRAM_FINISHED : IP_REASS_VALIDATE_PBUF_QUEUED;
}
/* If we come here, not all fragments were received, yet! */
return 0; /* not yet valid! */
return IP_REASS_VALIDATE_PBUF_QUEUED; /* not yet valid! */
#if IP_REASS_CHECK_OVERLAP
freepbuf:
ip_reass_pbufcount -= pbuf_clen(new_p);
pbuf_free(new_p);
return 0;
return IP_REASS_VALIDATE_PBUF_DROPPED;
#endif /* IP_REASS_CHECK_OVERLAP */
}
@@ -488,6 +502,8 @@ ip4_reass(struct pbuf *p)
struct ip_reassdata *ipr;
struct ip_reass_helper *iprh;
u16_t offset, len, clen;
int valid;
int is_last;
IPFRAG_STATS_INC(ip_frag.recv);
MIB2_STATS_INC(mib2.ipreasmreqds);
@@ -552,24 +568,41 @@ ip4_reass(struct pbuf *p)
SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN);
}
}
/* Track the current number of pbufs current 'in-flight', in order to limit
the number of fragments that may be enqueued at any one time */
ip_reass_pbufcount += clen;
/* At this point, we have either created a new entry or pointing
* to an existing one */
/* check for 'no more fragments', and update queue entry*/
if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) {
is_last = (IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0;
if (is_last) {
u16_t datagram_len = (u16_t)(offset + len);
if ((datagram_len < offset) || (datagram_len > (0xFFFF - IP_HLEN))) {
/* u16_t overflow, cannot handle this */
goto nullreturn;
}
}
/* find the right place to insert this pbuf */
/* @todo: trim pbufs if fragments are overlapping */
valid = ip_reass_chain_frag_into_datagram_and_validate(ipr, p, is_last);
if (valid == IP_REASS_VALIDATE_PBUF_DROPPED) {
goto nullreturn;
}
/* if we come here, the pbuf has been enqueued */
/* Track the current number of pbufs current 'in-flight', in order to limit
the number of fragments that may be enqueued at any one time
(overflow checked by testing against IP_REASS_MAX_PBUFS) */
ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount + clen);
if (is_last) {
u16_t datagram_len = (u16_t)(offset + len);
ipr->datagram_len = datagram_len;
ipr->flags |= IP_REASS_FLAG_LASTFRAG;
ipr->datagram_len = offset + len;
LWIP_DEBUGF(IP_REASS_DEBUG,
("ip4_reass: last fragment seen, total len %"S16_F"\n",
ipr->datagram_len));
}
/* find the right place to insert this pbuf */
/* @todo: trim pbufs if fragments are overlapping */
if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) {
if (valid == IP_REASS_VALIDATE_TELEGRAM_FINISHED) {
struct ip_reassdata *ipr_prev;
/* the totally last fragment (flag more fragments = 0) was received at least
* once AND all fragments are received */

View File

@@ -849,7 +849,9 @@ netif_loop_output(struct netif *netif, struct pbuf *p)
netif_poll(). */
/* let last point to the last pbuf in chain r */
for (last = r; last->next != NULL; last = last->next);
for (last = r; last->next != NULL; last = last->next) {
/* nothing to do here, just get to the last pbuf */
}
SYS_ARCH_PROTECT(lev);
if (netif->loop_first != NULL) {

View File

@@ -358,7 +358,6 @@ tcp_close_shutdown_fin(struct tcp_pcb *pcb)
default:
/* Has already been closed, do nothing. */
return ERR_OK;
break;
}
if (err == ERR_OK) {
@@ -371,6 +370,12 @@ tcp_close_shutdown_fin(struct tcp_pcb *pcb)
} else if (err == ERR_MEM) {
/* Mark this pcb for closing. Closing is retried from tcp_tmr. */
pcb->flags |= TF_CLOSEPEND;
/* We have to return ERR_OK from here to indicate to the callers that this
pcb should not be used any more as it will be freed soon via tcp_tmr.
This is OK here since sending FIN does not guarantee a time frime for
actually freeing the pcb, either (it is left in closure states for
remote ACK or timeout) */
return ERR_OK;
}
return err;
}
@@ -408,8 +413,8 @@ tcp_close(struct tcp_pcb *pcb)
* @ingroup tcp_raw
* Causes all or part of a full-duplex connection of this PCB to be shut down.
* This doesn't deallocate the PCB unless shutting down both sides!
* Shutting down both sides is the same as calling tcp_close, so if it succeds,
* the PCB should not be referenced any more.
* Shutting down both sides is the same as calling tcp_close, so if it succeds
* (i.e. returns ER_OK), the PCB must not be referenced any more!
*
* @param pcb PCB to shutdown
* @param shut_rx shut down receive side if this is != 0

View File

@@ -89,6 +89,8 @@ static void tcp_parseopt(struct tcp_pcb *pcb);
static void tcp_listen_input(struct tcp_pcb_listen *pcb);
static void tcp_timewait_input(struct tcp_pcb *pcb);
static int tcp_input_delayed_close(struct tcp_pcb *pcb);
/**
* The initial input processing of TCP. It verifies the TCP header, demultiplexes
* the segment between the PCBs and passes it on to tcp_process(), which implements
@@ -404,17 +406,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
}
recv_acked = 0;
}
if (recv_flags & TF_CLOSED) {
/* The connection has been closed and we will deallocate the
PCB. */
if (!(pcb->flags & TF_RXCLOSED)) {
/* Connection closed although the application has only shut down the
tx side: call the PCB's err callback and indicate the closure to
ensure the application doesn't continue using the PCB. */
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
}
tcp_pcb_remove(&tcp_active_pcbs, pcb);
memp_free(MEMP_TCP_PCB, pcb);
if (tcp_input_delayed_close(pcb)) {
goto aborted;
}
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
@@ -488,6 +480,9 @@ tcp_input(struct pbuf *p, struct netif *inp)
}
tcp_input_pcb = NULL;
if (tcp_input_delayed_close(pcb)) {
goto aborted;
}
/* Try to send something out. */
tcp_output(pcb);
#if TCP_INPUT_DEBUG
@@ -532,6 +527,30 @@ dropped:
pbuf_free(p);
}
/** Called from tcp_input to check for TF_CLOSED flag. This results in closing
* and deallocating a pcb at the correct place to ensure noone references it
* any more.
* @returns 1 if the pcb has been closed and deallocated, 0 otherwise
*/
static int
tcp_input_delayed_close(struct tcp_pcb *pcb)
{
if (recv_flags & TF_CLOSED) {
/* The connection has been closed and we will deallocate the
PCB. */
if (!(pcb->flags & TF_RXCLOSED)) {
/* Connection closed although the application has only shut down the
tx side: call the PCB's err callback and indicate the closure to
ensure the application doesn't continue using the PCB. */
TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD);
}
tcp_pcb_remove(&tcp_active_pcbs, pcb);
memp_free(MEMP_TCP_PCB, pcb);
return 1;
}
return 0;
}
/**
* Called by tcp_input() when a segment arrives for a listening
* connection (from tcp_input()).
@@ -1749,11 +1768,11 @@ tcp_parseopt(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
return;
}
/* An WND_SCALE option with the right option length. */
data = tcp_getoptbyte();
/* If syn was received with wnd scale option,
activate wnd scale opt, but only if this is not a retransmission */
if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) {
/* An WND_SCALE option with the right option length. */
data = tcp_getoptbyte();
pcb->snd_scale = data;
if (pcb->snd_scale > 14U) {
pcb->snd_scale = 14U;

View File

@@ -176,7 +176,7 @@ void sys_timeouts_init(void)
{
size_t i;
/* tcp_tmr() at index 0 is started on demand */
for (i = 1; i < LWIP_ARRAYSIZE(lwip_cyclic_timers); i++) {
for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE(lwip_cyclic_timers); i++) {
/* we have to cast via size_t to get rid of const warning
(this is OK as cyclic_timer() casts back to const* */
sys_timeout(lwip_cyclic_timers[i].interval_ms, cyclic_timer, LWIP_CONST_CAST(void*, &lwip_cyclic_timers[i]));

View File

@@ -76,8 +76,7 @@
* systems, this should be defined to something less resource-consuming.
*/
#ifndef LWIP_PLATFORM_DIAG
#include "Debug.hpp"
#define LWIP_PLATFORM_DIAG(x) printf(x);
#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
#include <stdio.h>
#include <stdlib.h>
#endif

View File

@@ -91,14 +91,6 @@ u32_t lwip_htonl(u32_t x);
#endif
#define lwip_ntohl(x) lwip_htonl(x)
/* Provide usual function names as macros for users, but this can be turned off */
#ifndef LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
#define htons(x) lwip_htons(x)
#define ntohs(x) lwip_ntohs(x)
#define htonl(x) lwip_htonl(x)
#define ntohl(x) lwip_ntohl(x)
#endif
/* 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). */
@@ -109,9 +101,16 @@ u32_t lwip_htonl(u32_t x);
(((x) & 0x00ff0000UL) >> 8) | \
(((x) & 0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#endif /* BYTE_ORDER == BIG_ENDIAN */
/* Provide usual function names as macros for users, but this can be turned off */
#ifndef LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
#define htons(x) lwip_htons(x)
#define ntohs(x) lwip_ntohs(x)
#define htonl(x) lwip_htonl(x)
#define ntohl(x) lwip_ntohl(x)
#endif
/* Functions that are not available as standard implementations.
* In cc.h, you can #define these to implementations available on
* your platform to save some code bytes if you use these functions

View File

@@ -108,7 +108,7 @@ struct dhcp
void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp);
/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */
#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0)
#define dhcp_remove_struct(netif) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL)
void dhcp_cleanup(struct netif *netif);
err_t dhcp_start(struct netif *netif);
err_t dhcp_renew(struct netif *netif);

View File

@@ -43,8 +43,6 @@
extern "C" {
#endif
#define LWIP_PROVIDE_ERRNO 0
#ifdef LWIP_PROVIDE_ERRNO
#define EPERM 1 /* Operation not permitted */
@@ -176,13 +174,12 @@ extern "C" {
#define EMEDIUMTYPE 124 /* Wrong medium type */
#ifndef errno
//extern int errno;
extern int errno;
#endif
#else /* LWIP_PROVIDE_ERRNO */
/* Define LWIP_ERRNO_INCLUDE to <errno.h> to include the error defines here */
#define LWIP_ERRNO_INCLUDE <errno.h>
#ifdef LWIP_ERRNO_INCLUDE
#include LWIP_ERRNO_INCLUDE
#endif /* LWIP_ERRNO_INCLUDE */

View File

@@ -54,7 +54,7 @@ extern "C" {
/** x.X.x: Minor version of the stack */
#define LWIP_VERSION_MINOR 0
/** x.x.X: Revision of the stack */
#define LWIP_VERSION_REVISION 2
#define LWIP_VERSION_REVISION 3
/** For release candidates, this is set to 1..254
* For official releases, this is set to 255 (LWIP_RC_RELEASE)
* For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */

View File

@@ -38,6 +38,8 @@
#ifndef LWIP_HDR_MEMP_H
#define LWIP_HDR_MEMP_H
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -387,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) STATS_INC(mem.x)
#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y)
#define MEM_STATS_DEC_USED(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_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP")
#else
#define MEM_STATS_AVAIL(x, y)

154
ext/lwip/test/unit/ip4/test_ip4.c Executable file
View File

@@ -0,0 +1,154 @@
#include "test_ip4.h"
#include "lwip/ip4.h"
#include "lwip/inet_chksum.h"
#include "lwip/stats.h"
#include "lwip/prot/ip.h"
#include "lwip/prot/ip4.h"
#if !LWIP_IPV4 || !IP_REASSEMBLY || !MIB2_STATS || !IPFRAG_STATS
#error "This tests needs LWIP_IPV4, IP_REASSEMBLY; MIB2- and IPFRAG-statistics enabled"
#endif
/* Helper functions */
static void
create_ip4_input_fragment(u16_t ip_id, u16_t start, u16_t len, int last)
{
struct pbuf *p;
struct netif *input_netif = netif_list; /* just use any netif */
fail_unless((start & 7) == 0);
fail_unless(((len & 7) == 0) || last);
fail_unless(input_netif != NULL);
p = pbuf_alloc(PBUF_RAW, len + sizeof(struct ip_hdr), PBUF_RAM);
fail_unless(p != NULL);
if (p != NULL) {
err_t err;
struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
IPH_VHL_SET(iphdr, 4, sizeof(struct ip_hdr) / 4);
IPH_TOS_SET(iphdr, 0);
IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
IPH_ID_SET(iphdr, lwip_htons(ip_id));
if (last) {
IPH_OFFSET_SET(iphdr, lwip_htons(start / 8));
} else {
IPH_OFFSET_SET(iphdr, lwip_htons((start / 8) | IP_MF));
}
IPH_TTL_SET(iphdr, 5);
IPH_PROTO_SET(iphdr, IP_PROTO_UDP);
IPH_CHKSUM_SET(iphdr, 0);
ip4_addr_copy(iphdr->src, *netif_ip4_addr(input_netif));
iphdr->src.addr = lwip_htonl(lwip_htonl(iphdr->src.addr) + 1);
ip4_addr_copy(iphdr->dest, *netif_ip4_addr(input_netif));
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, sizeof(struct ip_hdr)));
err = ip4_input(p, input_netif);
if (err != ERR_OK) {
pbuf_free(p);
}
fail_unless(err == ERR_OK);
}
}
/* Setups/teardown functions */
static void
ip4_setup(void)
{
}
static void
ip4_teardown(void)
{
if (netif_list->loop_first != NULL) {
pbuf_free(netif_list->loop_first);
netif_list->loop_first = NULL;
}
netif_list->loop_last = NULL;
}
/* Test functions */
START_TEST(test_ip4_reass)
{
const u16_t ip_id = 128;
LWIP_UNUSED_ARG(_i);
memset(&lwip_stats.mib2, 0, sizeof(lwip_stats.mib2));
create_ip4_input_fragment(ip_id, 8*200, 200, 1);
fail_unless(lwip_stats.ip_frag.recv == 1);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 0);
create_ip4_input_fragment(ip_id, 0*200, 200, 0);
fail_unless(lwip_stats.ip_frag.recv == 2);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 0);
create_ip4_input_fragment(ip_id, 1*200, 200, 0);
fail_unless(lwip_stats.ip_frag.recv == 3);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 0);
create_ip4_input_fragment(ip_id, 2*200, 200, 0);
fail_unless(lwip_stats.ip_frag.recv == 4);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 0);
create_ip4_input_fragment(ip_id, 3*200, 200, 0);
fail_unless(lwip_stats.ip_frag.recv == 5);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 0);
create_ip4_input_fragment(ip_id, 4*200, 200, 0);
fail_unless(lwip_stats.ip_frag.recv == 6);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 0);
create_ip4_input_fragment(ip_id, 7*200, 200, 0);
fail_unless(lwip_stats.ip_frag.recv == 7);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 0);
create_ip4_input_fragment(ip_id, 6*200, 200, 0);
fail_unless(lwip_stats.ip_frag.recv == 8);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 0);
create_ip4_input_fragment(ip_id, 5*200, 200, 0);
fail_unless(lwip_stats.ip_frag.recv == 9);
fail_unless(lwip_stats.ip_frag.err == 0);
fail_unless(lwip_stats.ip_frag.memerr == 0);
fail_unless(lwip_stats.ip_frag.drop == 0);
fail_unless(lwip_stats.mib2.ipreasmoks == 1);
}
END_TEST
/** Create the suite including all tests for this module */
Suite *
ip4_suite(void)
{
testfunc tests[] = {
TESTFUNC(test_ip4_reass),
};
return create_suite("IPv4", tests, sizeof(tests)/sizeof(testfunc), ip4_setup, ip4_teardown);
}

View File

@@ -0,0 +1,8 @@
#ifndef LWIP_HDR_TEST_IP4_H
#define LWIP_HDR_TEST_IP4_H
#include "../lwip_check.h"
Suite* ip4_suite(void);
#endif

View File

@@ -1,5 +1,6 @@
#include "lwip_check.h"
#include "ip4/test_ip4.h"
#include "udp/test_udp.h"
#include "tcp/test_tcp.h"
#include "tcp/test_tcp_oos.h"
@@ -37,6 +38,7 @@ int main(void)
SRunner *sr;
size_t i;
suite_getter_fn* suites[] = {
ip4_suite,
udp_suite,
tcp_suite,
tcp_oos_suite,

View File

@@ -59,4 +59,7 @@
/* Minimal changes to opt.h required for etharp unit tests: */
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
/* MIB2 stats are required to check IPv4 reassembly results */
#define MIB2_STATS 1
#endif /* LWIP_HDR_LWIPOPTS_H */