Compare commits
84 Commits
STABLE-0_7
...
POST_PACK_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79110ba469 | ||
|
|
9dd10e46ab | ||
|
|
29df95c514 | ||
|
|
015cb1a35d | ||
|
|
b217b020a5 | ||
|
|
0c960a82ce | ||
|
|
e84cc8c0ad | ||
|
|
c69b93b246 | ||
|
|
5e13b9528d | ||
|
|
8bb3cab9d2 | ||
|
|
ed201c35d2 | ||
|
|
4eadc22a36 | ||
|
|
4e2260c74c | ||
|
|
a5148c14a1 | ||
|
|
955d6206ee | ||
|
|
5df22b3468 | ||
|
|
aef86ec5ef | ||
|
|
94d3b04d68 | ||
|
|
d31830225c | ||
|
|
8f309a3fec | ||
|
|
1fe4edbe1c | ||
|
|
fe1696cef7 | ||
|
|
de2e311e6e | ||
|
|
384fb3c353 | ||
|
|
8603e19516 | ||
|
|
7a2751043a | ||
|
|
e2b0c6c702 | ||
|
|
5b12c61a81 | ||
|
|
b8ee8808b4 | ||
|
|
2db9551750 | ||
|
|
7dc51270ee | ||
|
|
237b5a2467 | ||
|
|
110e5af36c | ||
|
|
7d4aef9576 | ||
|
|
811b360df7 | ||
|
|
d91b54882a | ||
|
|
9106a1f2d5 | ||
|
|
2e2dada561 | ||
|
|
6d704c728e | ||
|
|
6c6f32f17f | ||
|
|
0e4ce326c2 | ||
|
|
d27448da8a | ||
|
|
d36b723056 | ||
|
|
2c8aa6f6f4 | ||
|
|
6f7c8fb355 | ||
|
|
82f852abf3 | ||
|
|
239c6fe070 | ||
|
|
579d2ad811 | ||
|
|
0cb355cd7c | ||
|
|
86135d12b9 | ||
|
|
10d42c6fa3 | ||
|
|
6434f7efad | ||
|
|
bfdf19f56c | ||
|
|
79c7a7a43d | ||
|
|
175053085a | ||
|
|
3d90c062fd | ||
|
|
fda71b1230 | ||
|
|
a916de3b66 | ||
|
|
30e5dfddb9 | ||
|
|
f9dea9d35b | ||
|
|
4ea55b1bbc | ||
|
|
caf3c16826 | ||
|
|
a6f1111469 | ||
|
|
33d0096b81 | ||
|
|
ed4c5d88a3 | ||
|
|
e85a892111 | ||
|
|
70cd10beae | ||
|
|
3a784509df | ||
|
|
5c7189124c | ||
|
|
f81c2744cc | ||
|
|
4bf3359574 | ||
|
|
47984b0496 | ||
|
|
3c339323ed | ||
|
|
7399722a88 | ||
|
|
7bfea6edb7 | ||
|
|
f75da2c393 | ||
|
|
475576ec20 | ||
|
|
f6a8e1df03 | ||
|
|
e1c4bfad05 | ||
|
|
1ed40e7983 | ||
|
|
035fcce9de | ||
|
|
19eed5ff8a | ||
|
|
7129d4797c | ||
|
|
707d31a083 |
31
CHANGELOG
31
CHANGELOG
@@ -1,12 +1,37 @@
|
|||||||
TODO
|
FUTURE
|
||||||
|
|
||||||
* TODO: The lwIP source code makes some invalid assumptions on processor
|
* TODO: The lwIP source code makes some invalid assumptions on processor
|
||||||
word-length, storage sizes and alignment. See the mailing lists for
|
word-length, storage sizes and alignment. See the mailing lists for
|
||||||
problems with exoteric architectures showing these problems.
|
problems with exoteric (/DSP) architectures showing these problems.
|
||||||
We still have to fix this neatly.
|
We still have to fix some of these issues neatly.
|
||||||
|
|
||||||
HISTORY
|
HISTORY
|
||||||
|
|
||||||
|
(HEAD)
|
||||||
|
|
||||||
|
++ Changes:
|
||||||
|
|
||||||
|
2004-04-29 Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||||
|
* tcp*.c: Cleaned up source comment documentation for Doxygen processing.
|
||||||
|
* opt.h: ETHHARP_ALWAYS_INSERT option removed to comply with ARP RFC.
|
||||||
|
* etharp.c: update_arp_entry() only adds new ARP entries when adviced to by
|
||||||
|
the caller. This deprecates the ETHHARP_ALWAYS_INSERT overrule option.
|
||||||
|
|
||||||
|
++ Bug fixes:
|
||||||
|
|
||||||
|
2004-04-27 Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||||
|
* etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution
|
||||||
|
suggested by Timmy Brolin. Fix for 32-bit processors that cannot access
|
||||||
|
non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix
|
||||||
|
is to prefix the 14-bit Ethernet headers with two padding bytes.
|
||||||
|
|
||||||
|
2004-04-23 Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||||
|
* ip_addr.c: Fix in the ip_addr_isbroadcast() check.
|
||||||
|
* etharp.c: Fixed the case where the packet that initiates the ARP request
|
||||||
|
is not queued, and gets lost. Fixed the case where the packets destination
|
||||||
|
address is already known; we now always queue the packet and perform an ARP
|
||||||
|
request.
|
||||||
|
|
||||||
(STABLE-0_7_0)
|
(STABLE-0_7_0)
|
||||||
|
|
||||||
++ Bug fixes:
|
++ Bug fixes:
|
||||||
|
|||||||
@@ -272,6 +272,11 @@ level of complexity of UDP, the interface is significantly simpler.
|
|||||||
Sets the remote end of the pcb. This function does not generate any
|
Sets the remote end of the pcb. This function does not generate any
|
||||||
network traffic, but only set the remote address of the pcb.
|
network traffic, but only set the remote address of the pcb.
|
||||||
|
|
||||||
|
- err_t udp_disconnect(struct udp_pcb *pcb)
|
||||||
|
|
||||||
|
Remove the remote end of the pcb. This function does not generate
|
||||||
|
any network traffic, but only removes the remote address of the pcb.
|
||||||
|
|
||||||
- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||||
|
|
||||||
Sends the pbuf p. The pbuf is not deallocated.
|
Sends the pbuf p. The pbuf is not deallocated.
|
||||||
|
|||||||
@@ -2,16 +2,18 @@ Daily Use Guide for using Savannah for lwIP
|
|||||||
|
|
||||||
Table of Contents:
|
Table of Contents:
|
||||||
|
|
||||||
1 - Anonymous CVS checkouts and updates (to be elaborated)
|
1 - Obtaining lwIP from the CVS repository
|
||||||
2 - Committers/developers CVS access using SSH (to be written)
|
2 - Committers/developers CVS access using SSH (to be written)
|
||||||
3 - Merging from DEVEL branch to main trunk (stable branch)
|
3 - Merging from DEVEL branch to main trunk (stable branch)
|
||||||
4 - How to release lwIP
|
4 - How to release lwIP
|
||||||
|
|
||||||
|
|
||||||
1 Anonymous CVS checkouts and updates
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
Obtain lwIP from the CVS main trunk (stable)
|
1 Obtaining lwIP from the CVS repository
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
To perform an anonymous CVS checkout of the main trunk (this is where
|
||||||
|
bug fixes and incremental enhancements occur), do this:
|
||||||
|
|
||||||
export CVS_RSH=ssh
|
export CVS_RSH=ssh
|
||||||
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout lwip
|
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout lwip
|
||||||
@@ -19,15 +21,51 @@ cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout lwip
|
|||||||
(If SSH asks about authenticity of the host, you can check the key
|
(If SSH asks about authenticity of the host, you can check the key
|
||||||
fingerprint against http://savannah.nongnu.org/cvs/?group=lwip)
|
fingerprint against http://savannah.nongnu.org/cvs/?group=lwip)
|
||||||
|
|
||||||
Or, obtain a specific release as follows:
|
Or, obtain a stable branch (updated with bug fixes only) as follows:
|
||||||
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r STABLE-0_6_3 -d lwip-0.6.3 lwip
|
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r STABLE-0_7 -d lwip-0.7 lwip
|
||||||
|
|
||||||
Or, obtain a development branch as follows:
|
Or, obtain a specific (fixed) release as follows:
|
||||||
|
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r STABLE-0_7_0 -d lwip-0.7.0 lwip
|
||||||
|
|
||||||
|
Or, obtain a development branch (considered unstable!) as follows:
|
||||||
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r DEVEL -d lwip-DEVEL lwip
|
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r DEVEL -d lwip-DEVEL lwip
|
||||||
|
|
||||||
|
3 Committers/developers CVS access using SSH
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption.
|
||||||
|
As such, CVS commits to the server occur through a SSH tunnel for project members.
|
||||||
|
To create a SSH2 key pair in UNIX-like environments, do this:
|
||||||
|
|
||||||
|
ssh-keygen -t dsa
|
||||||
|
|
||||||
|
Under Windows, a recommended SSH client is "PuTTY", freely available with good
|
||||||
|
documentation and a graphic user interface. Use its key generator.
|
||||||
|
|
||||||
|
Now paste the id_dsa.pub contents into your Savannah account public key list. Wait
|
||||||
|
a while so that Savannah can update its configuration (This can take minutes).
|
||||||
|
|
||||||
|
Try to login using SSH:
|
||||||
|
|
||||||
|
ssh -v your_login@subversions.gnu.org
|
||||||
|
|
||||||
|
If it tells you:
|
||||||
|
|
||||||
|
Authenticating with public key "your_key_name"...
|
||||||
|
Server refused to allocate pty
|
||||||
|
|
||||||
|
then you could login; Savannah refuses to give you a shell - which is OK, as we
|
||||||
|
are allowed to use SSH for CVS only. Now, you should be able to do this:
|
||||||
|
|
||||||
|
export CVS_RSH=ssh
|
||||||
|
cvs -d:ext:your_login@subversions.gnu.org:/cvsroot/lwip checkout lwip
|
||||||
|
|
||||||
|
after which you can edit your local files with bug fixes or new features and
|
||||||
|
commit them. Make sure you know what you are doing when using CVS to make
|
||||||
|
changes on the repository. If in doubt, ask on the lwip-members mailing list.
|
||||||
|
|
||||||
3 Merging from DEVEL branch to main trunk (stable)
|
3 Merging from DEVEL branch to main trunk (stable)
|
||||||
---------------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
Merging is a delicate process in CVS and requires the
|
Merging is a delicate process in CVS and requires the
|
||||||
following disciplined steps in order to prevent conflicts
|
following disciplined steps in order to prevent conflicts
|
||||||
@@ -74,6 +112,8 @@ cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip export -r STABLE-0_6_3 -d l
|
|||||||
Archive this directory using tar, gzip'd, bzip2'd and zip'd.
|
Archive this directory using tar, gzip'd, bzip2'd and zip'd.
|
||||||
|
|
||||||
tar czvf lwip-0.6.3.tar.gz lwip-0.6.3
|
tar czvf lwip-0.6.3.tar.gz lwip-0.6.3
|
||||||
|
tar cjvf lwip-0.6.3.tar.bz2 lwip-0.6.3
|
||||||
|
zip -r lwip-0.6.3.zip lwip-0.6.3
|
||||||
|
|
||||||
First, make a local release directory to work in, I use "lwip-releases":
|
First, make a local release directory to work in, I use "lwip-releases":
|
||||||
|
|
||||||
|
|||||||
@@ -154,12 +154,6 @@ cc.h - Architecture environment, some compiler specific, some
|
|||||||
Typedefs for the types used by lwip -
|
Typedefs for the types used by lwip -
|
||||||
u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t
|
u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t
|
||||||
|
|
||||||
Compiler hints for packing lwip's structures -
|
|
||||||
PACK_STRUCT_FIELD(x)
|
|
||||||
PACK_STRUCT_STRUCT
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
PACK_STRUCT_END
|
|
||||||
|
|
||||||
Platform specific diagnostic output -
|
Platform specific diagnostic output -
|
||||||
LWIP_PLATFORM_DIAG(x) - non-fatal, print a message.
|
LWIP_PLATFORM_DIAG(x) - non-fatal, print a message.
|
||||||
LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution.
|
LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "lwip/arch.h"
|
#include "lwip/arch.h"
|
||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
|
#define LWIP_TIMEVAL_PRIVATE
|
||||||
#include "lwip/sockets.h"
|
#include "lwip/sockets.h"
|
||||||
|
|
||||||
#define NUM_SOCKETS MEMP_NUM_NETCONN
|
#define NUM_SOCKETS MEMP_NUM_NETCONN
|
||||||
@@ -993,7 +994,7 @@ int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *opt
|
|||||||
/* UNIMPL case SO_SNDBUF: */
|
/* UNIMPL case SO_SNDBUF: */
|
||||||
/* UNIMPL case SO_RCVLOWAT: */
|
/* UNIMPL case SO_RCVLOWAT: */
|
||||||
/* UNIMPL case SO_SNDLOWAT: */
|
/* UNIMPL case SO_SNDLOWAT: */
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
case SO_REUSEADDR:
|
case SO_REUSEADDR:
|
||||||
case SO_REUSEPORT:
|
case SO_REUSEPORT:
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
@@ -1079,7 +1080,7 @@ int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *opt
|
|||||||
/* UNIMPL case SO_DONTROUTE: */
|
/* UNIMPL case SO_DONTROUTE: */
|
||||||
case SO_KEEPALIVE:
|
case SO_KEEPALIVE:
|
||||||
/* UNIMPL case SO_OOBINCLUDE: */
|
/* UNIMPL case SO_OOBINCLUDE: */
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
case SO_REUSEADDR:
|
case SO_REUSEADDR:
|
||||||
case SO_REUSEPORT:
|
case SO_REUSEPORT:
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
@@ -1182,7 +1183,7 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
|
|||||||
/* UNIMPL case SO_SNDBUF: */
|
/* UNIMPL case SO_SNDBUF: */
|
||||||
/* UNIMPL case SO_RCVLOWAT: */
|
/* UNIMPL case SO_RCVLOWAT: */
|
||||||
/* UNIMPL case SO_SNDLOWAT: */
|
/* UNIMPL case SO_SNDLOWAT: */
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
case SO_REUSEADDR:
|
case SO_REUSEADDR:
|
||||||
case SO_REUSEPORT:
|
case SO_REUSEPORT:
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
@@ -1264,7 +1265,7 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
|
|||||||
/* UNIMPL case SO_DONTROUTE: */
|
/* UNIMPL case SO_DONTROUTE: */
|
||||||
case SO_KEEPALIVE:
|
case SO_KEEPALIVE:
|
||||||
/* UNIMPL case SO_OOBINCLUDE: */
|
/* UNIMPL case SO_OOBINCLUDE: */
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
case SO_REUSEADDR:
|
case SO_REUSEADDR:
|
||||||
case SO_REUSEPORT:
|
case SO_REUSEPORT:
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2003 Leon Woestenberg <leon.woestenberg@gmx.net>
|
* Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||||
* Copyright (c) 2001-2003 Axon Digital Design B.V., The Netherlands.
|
* Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -70,15 +70,17 @@
|
|||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
#include "lwip/mem.h"
|
#include "lwip/mem.h"
|
||||||
#include "lwip/udp.h"
|
#include "lwip/udp.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
#include "lwip/inet.h"
|
#include "lwip/inet.h"
|
||||||
#include "lwip/ip_addr.h"
|
|
||||||
#include "netif/etharp.h"
|
#include "netif/etharp.h"
|
||||||
|
|
||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
#include "lwip/dhcp.h"
|
#include "lwip/dhcp.h"
|
||||||
|
|
||||||
|
#if LWIP_DHCP /* don't build if not configured for use in lwipopt.h */
|
||||||
|
|
||||||
/** global transaction identifier, must be
|
/** global transaction identifier, must be
|
||||||
* unique for each DHCP request. */
|
* unique for each DHCP request. */
|
||||||
static u32_t xid = 0xABCD0000;
|
static u32_t xid = 0xABCD0000;
|
||||||
@@ -404,7 +406,6 @@ static void dhcp_t2_timeout(struct netif *netif)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract options from the server ACK message.
|
|
||||||
*
|
*
|
||||||
* @param netif the netif under DHCP control
|
* @param netif the netif under DHCP control
|
||||||
*/
|
*/
|
||||||
@@ -706,15 +707,9 @@ static err_t dhcp_discover(struct netif *netif)
|
|||||||
/* set receive callback function with netif as user data */
|
/* set receive callback function with netif as user data */
|
||||||
udp_recv(dhcp->pcb, dhcp_recv, netif);
|
udp_recv(dhcp->pcb, dhcp_recv, netif);
|
||||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||||
udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
|
||||||
|
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: send()ing\n"));
|
|
||||||
|
|
||||||
udp_send(dhcp->pcb, dhcp->p_out);
|
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: bind()ing\n"));
|
|
||||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: connect()ing\n"));
|
|
||||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||||
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
|
||||||
|
udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
|
||||||
dhcp_delete_request(netif);
|
dhcp_delete_request(netif);
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover: SELECTING\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover: SELECTING\n"));
|
||||||
@@ -881,10 +876,11 @@ static err_t dhcp_rebind(struct netif *netif)
|
|||||||
|
|
||||||
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
||||||
|
|
||||||
|
/* set remote IP association to any DHCP server */
|
||||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||||
udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
|
||||||
udp_send(dhcp->pcb, dhcp->p_out);
|
|
||||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||||
|
/* broadcast to server */
|
||||||
|
udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
||||||
dhcp_delete_request(netif);
|
dhcp_delete_request(netif);
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind: REBINDING\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind: REBINDING\n"));
|
||||||
} else {
|
} else {
|
||||||
@@ -1243,10 +1239,10 @@ static err_t dhcp_create_request(struct netif *netif)
|
|||||||
dhcp->msg_out->xid = htonl(dhcp->xid);
|
dhcp->msg_out->xid = htonl(dhcp->xid);
|
||||||
dhcp->msg_out->secs = 0;
|
dhcp->msg_out->secs = 0;
|
||||||
dhcp->msg_out->flags = 0;
|
dhcp->msg_out->flags = 0;
|
||||||
dhcp->msg_out->ciaddr = netif->ip_addr.addr;
|
dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr;
|
||||||
dhcp->msg_out->yiaddr = 0;
|
dhcp->msg_out->yiaddr.addr = 0;
|
||||||
dhcp->msg_out->siaddr = 0;
|
dhcp->msg_out->siaddr.addr = 0;
|
||||||
dhcp->msg_out->giaddr = 0;
|
dhcp->msg_out->giaddr.addr = 0;
|
||||||
for (i = 0; i < DHCP_CHADDR_LEN; i++) {
|
for (i = 0; i < DHCP_CHADDR_LEN; i++) {
|
||||||
/* copy netif hardware address, pad with zeroes */
|
/* copy netif hardware address, pad with zeroes */
|
||||||
dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/;
|
dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/;
|
||||||
@@ -1418,3 +1414,5 @@ static u32_t dhcp_get_option_long(u8_t *ptr)
|
|||||||
LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value));
|
LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* LWIP_DHCP */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -300,9 +300,10 @@ inet_chksum_pbuf(struct pbuf *p)
|
|||||||
/* Convert numeric IP address into decimal dotted ASCII representation.
|
/* Convert numeric IP address into decimal dotted ASCII representation.
|
||||||
* returns ptr to static buffer; not reentrant!
|
* returns ptr to static buffer; not reentrant!
|
||||||
*/
|
*/
|
||||||
u8_t *inet_ntoa(u32_t addr)
|
char *inet_ntoa(struct in_addr addr)
|
||||||
{
|
{
|
||||||
static u8_t str[16];
|
static u8_t str[16];
|
||||||
|
u32_t s_addr = addr.s_addr;
|
||||||
u8_t inv[3];
|
u8_t inv[3];
|
||||||
u8_t *rp;
|
u8_t *rp;
|
||||||
u8_t *ap;
|
u8_t *ap;
|
||||||
@@ -311,7 +312,7 @@ u8_t *inet_ntoa(u32_t addr)
|
|||||||
u8_t i;
|
u8_t i;
|
||||||
|
|
||||||
rp = str;
|
rp = str;
|
||||||
ap = (u8_t *)&addr;
|
ap = (char *)&s_addr;
|
||||||
for(n = 0; n < 4; n++) {
|
for(n = 0; n < 4; n++) {
|
||||||
i = 0;
|
i = 0;
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -72,8 +72,8 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
code = *(((u8_t *)p->payload)+1);
|
code = *(((u8_t *)p->payload)+1);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ICMP_ECHO:
|
case ICMP_ECHO:
|
||||||
if (ip_addr_isbroadcast(&iphdr->dest, &inp->netmask) ||
|
/* broadcast or multicast destination address? */
|
||||||
ip_addr_ismulticast(&iphdr->dest)) {
|
if (ip_addr_isbroadcast(&iphdr->dest, inp) || ip_addr_ismulticast(&iphdr->dest)) {
|
||||||
LWIP_DEBUGF(ICMP_DEBUG, ("Smurf.\n"));
|
LWIP_DEBUGF(ICMP_DEBUG, ("Smurf.\n"));
|
||||||
ICMP_STATS_INC(icmp.err);
|
ICMP_STATS_INC(icmp.err);
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
|
/* @file
|
||||||
|
*
|
||||||
|
* This is the IP layer implementation for incoming and outgoing IP traffic.
|
||||||
|
*
|
||||||
|
* @see ip_frag.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -30,18 +37,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ip.c
|
|
||||||
*
|
|
||||||
* This is the code for the IP layer.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "lwip/mem.h"
|
#include "lwip/mem.h"
|
||||||
#include "lwip/ip.h"
|
#include "lwip/ip.h"
|
||||||
@@ -63,69 +60,17 @@
|
|||||||
#endif /* LWIP_DHCP */
|
#endif /* LWIP_DHCP */
|
||||||
|
|
||||||
|
|
||||||
/* ip_init:
|
/**
|
||||||
*
|
|
||||||
* Initializes the IP layer.
|
* Initializes the IP layer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
ip_init(void)
|
ip_init(void)
|
||||||
{
|
{
|
||||||
|
/* no initializations as of yet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ip_lookup:
|
/**
|
||||||
*
|
|
||||||
* An experimental feature that will be changed in future versions. Do
|
|
||||||
* not depend on it yet...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef LWIP_DEBUG
|
|
||||||
u8_t
|
|
||||||
ip_lookup(void *header, struct netif *inp)
|
|
||||||
{
|
|
||||||
struct ip_hdr *iphdr;
|
|
||||||
|
|
||||||
iphdr = header;
|
|
||||||
|
|
||||||
/* not IP v4? */
|
|
||||||
if (IPH_V(iphdr) != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Immediately accept/decline packets that are fragments or has
|
|
||||||
options. */
|
|
||||||
#if IP_REASSEMBLY == 0
|
|
||||||
/* if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
|
|
||||||
return 0;
|
|
||||||
}*/
|
|
||||||
#endif /* IP_REASSEMBLY == 0 */
|
|
||||||
|
|
||||||
#if IP_OPTIONS == 0
|
|
||||||
if (IPH_HL(iphdr) != 5) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* IP_OPTIONS == 0 */
|
|
||||||
|
|
||||||
switch (IPH_PROTO(iphdr)) {
|
|
||||||
#if LWIP_UDP
|
|
||||||
case IP_PROTO_UDP:
|
|
||||||
case IP_PROTO_UDPLITE:
|
|
||||||
return udp_lookup(iphdr, inp);
|
|
||||||
#endif /* LWIP_UDP */
|
|
||||||
#if LWIP_TCP
|
|
||||||
case IP_PROTO_TCP:
|
|
||||||
return 1;
|
|
||||||
#endif /* LWIP_TCP */
|
|
||||||
case IP_PROTO_ICMP:
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* LWIP_DEBUG */
|
|
||||||
|
|
||||||
/* ip_route:
|
|
||||||
*
|
|
||||||
* Finds the appropriate network interface for a given IP address. It
|
* Finds the appropriate network interface for a given IP address. It
|
||||||
* searches the list of network interfaces linearly. A match is found
|
* searches the list of network interfaces linearly. A match is found
|
||||||
* if the masked IP address of the network interface equals the masked
|
* if the masked IP address of the network interface equals the masked
|
||||||
@@ -150,8 +95,7 @@ ip_route(struct ip_addr *dest)
|
|||||||
}
|
}
|
||||||
#if IP_FORWARD
|
#if IP_FORWARD
|
||||||
|
|
||||||
/* ip_forward:
|
/**
|
||||||
*
|
|
||||||
* Forwards an IP packet. It finds an appropriate route for the
|
* Forwards an IP packet. It finds an appropriate route for the
|
||||||
* packet, decrements the TTL value of the packet, adjusts the
|
* packet, decrements the TTL value of the packet, adjusts the
|
||||||
* checksum and outputs the packet on the appropriate interface.
|
* checksum and outputs the packet on the appropriate interface.
|
||||||
@@ -172,7 +116,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Do not forward packets onto the same network interface on which
|
/* Do not forward packets onto the same network interface on which
|
||||||
they arrived. */
|
* they arrived. */
|
||||||
if (netif == inp) {
|
if (netif == inp) {
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
|
LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
|
||||||
snmp_inc_ipnoroutes();
|
snmp_inc_ipnoroutes();
|
||||||
@@ -211,8 +155,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||||||
}
|
}
|
||||||
#endif /* IP_FORWARD */
|
#endif /* IP_FORWARD */
|
||||||
|
|
||||||
/* ip_input:
|
/**
|
||||||
*
|
|
||||||
* This function is called by the network interface device driver when
|
* This function is called by the network interface device driver when
|
||||||
* an IP packet is received. The function does the basic checks of the
|
* an IP packet is received. The function does the basic checks of the
|
||||||
* IP header such as packet size being at least larger than the header
|
* IP header such as packet size being at least larger than the header
|
||||||
@@ -260,6 +203,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* verify checksum */
|
/* verify checksum */
|
||||||
|
#if CHECKSUM_CHECK_IP
|
||||||
if (inet_chksum(iphdr, iphdrlen) != 0) {
|
if (inet_chksum(iphdr, iphdrlen) != 0) {
|
||||||
|
|
||||||
LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
|
LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%x) failed, IP packet dropped.\n", inet_chksum(iphdr, iphdrlen)));
|
||||||
@@ -270,9 +214,10 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
snmp_inc_ipindiscards();
|
snmp_inc_ipindiscards();
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Trim pbuf. This should have been done at the netif layer,
|
/* Trim pbuf. This should have been done at the netif layer,
|
||||||
but we'll do it anyway just to be sure that its done. */
|
* but we'll do it anyway just to be sure that its done. */
|
||||||
pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
|
pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
|
||||||
|
|
||||||
/* is this packet for us? */
|
/* is this packet for us? */
|
||||||
@@ -290,7 +235,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
/* unicast to this interface address? */
|
/* unicast to this interface address? */
|
||||||
if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
|
if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
|
||||||
/* or broadcast matching this interface network address? */
|
/* or broadcast matching this interface network address? */
|
||||||
(ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) &&
|
(ip_addr_isbroadcast(&(iphdr->dest), netif) &&
|
||||||
ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
|
ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
|
||||||
/* or restricted broadcast? */
|
/* or restricted broadcast? */
|
||||||
ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
|
ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
|
||||||
@@ -303,8 +248,8 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
}
|
}
|
||||||
#if LWIP_DHCP
|
#if LWIP_DHCP
|
||||||
/* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
|
/* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
|
||||||
using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
|
* using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
|
||||||
According to RFC 1542 section 3.1.1, referred by RFC 2131). */
|
* According to RFC 1542 section 3.1.1, referred by RFC 2131). */
|
||||||
if (netif == NULL) {
|
if (netif == NULL) {
|
||||||
/* remote port is DHCP server? */
|
/* remote port is DHCP server? */
|
||||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
|
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
|
||||||
@@ -323,7 +268,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
|
LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
|
||||||
#if IP_FORWARD
|
#if IP_FORWARD
|
||||||
/* non-broadcast packet? */
|
/* non-broadcast packet? */
|
||||||
if (!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) {
|
if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {
|
||||||
/* try to forward IP packet on (other) interfaces */
|
/* try to forward IP packet on (other) interfaces */
|
||||||
ip_forward(p, iphdr, inp);
|
ip_forward(p, iphdr, inp);
|
||||||
}
|
}
|
||||||
@@ -335,19 +280,19 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
/* packet consists of multiple fragments? */
|
||||||
#if IP_REASSEMBLY
|
|
||||||
if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
|
if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
|
||||||
|
#if IP_REASSEMBLY /* packet fragment reassembly code present? */
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n",
|
LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n",
|
||||||
ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
|
ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
|
||||||
|
/* reassemble the packet*/
|
||||||
p = ip_reass(p);
|
p = ip_reass(p);
|
||||||
|
/* packet not fully reassembled yet? */
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
}
|
#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
|
||||||
#else /* IP_REASSEMBLY */
|
|
||||||
if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
|
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
|
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
|
||||||
ntohs(IPH_OFFSET(iphdr))));
|
ntohs(IPH_OFFSET(iphdr))));
|
||||||
@@ -355,10 +300,10 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
IP_STATS_INC(ip.drop);
|
IP_STATS_INC(ip.drop);
|
||||||
snmp_inc_ipunknownprotos();
|
snmp_inc_ipunknownprotos();
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
|
||||||
#endif /* IP_REASSEMBLY */
|
#endif /* IP_REASSEMBLY */
|
||||||
|
}
|
||||||
|
|
||||||
#if IP_OPTIONS == 0
|
#if IP_OPTIONS == 0 /* no support for IP options in the IP header? */
|
||||||
if (iphdrlen > IP_HLEN) {
|
if (iphdrlen > IP_HLEN) {
|
||||||
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
|
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
@@ -375,7 +320,8 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
|
LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
|
||||||
|
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
if (!raw_input(p, inp)) {
|
/* raw input did not eat the packet? */
|
||||||
|
if (raw_input(p, inp) == 0) {
|
||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
|
|
||||||
switch (IPH_PROTO(iphdr)) {
|
switch (IPH_PROTO(iphdr)) {
|
||||||
@@ -398,8 +344,8 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* send ICMP destination protocol unreachable unless is was a broadcast */
|
/* send ICMP destination protocol unreachable unless is was a broadcast */
|
||||||
if (!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) &&
|
if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&
|
||||||
!ip_addr_ismulticast(&(iphdr->dest))) {
|
!ip_addr_ismulticast(&(iphdr->dest))) {
|
||||||
p->payload = iphdr;
|
p->payload = iphdr;
|
||||||
icmp_dest_unreach(p, ICMP_DUR_PROTO);
|
icmp_dest_unreach(p, ICMP_DUR_PROTO);
|
||||||
}
|
}
|
||||||
@@ -410,7 +356,6 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
IP_STATS_INC(ip.proterr);
|
IP_STATS_INC(ip.proterr);
|
||||||
IP_STATS_INC(ip.drop);
|
IP_STATS_INC(ip.drop);
|
||||||
snmp_inc_ipunknownprotos();
|
snmp_inc_ipunknownprotos();
|
||||||
|
|
||||||
}
|
}
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
} /* LWIP_RAW */
|
} /* LWIP_RAW */
|
||||||
@@ -418,9 +363,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/* ip_output_if:
|
|
||||||
*
|
|
||||||
* Sends an IP packet on a network interface. This function constructs
|
* Sends an IP packet on a network interface. This function constructs
|
||||||
* the IP header and calculates the IP header checksum. If the source
|
* the IP header and calculates the IP header checksum. If the source
|
||||||
* IP address is NULL, the IP address of the outgoing network
|
* IP address is NULL, the IP address of the outgoing network
|
||||||
@@ -466,7 +409,9 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IPH_CHKSUM_SET(iphdr, 0);
|
IPH_CHKSUM_SET(iphdr, 0);
|
||||||
|
#if CHECKSUM_GEN_IP
|
||||||
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
|
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
dest = &(iphdr->dest);
|
dest = &(iphdr->dest);
|
||||||
@@ -488,8 +433,7 @@ ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
|||||||
return netif->output(netif, p, dest);
|
return netif->output(netif, p, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ip_output:
|
/**
|
||||||
*
|
|
||||||
* Simple interface to ip_output_if. It finds the outgoing network
|
* Simple interface to ip_output_if. It finds the outgoing network
|
||||||
* interface and calls upon ip_output_if to do the actual work.
|
* interface and calls upon ip_output_if to do the actual work.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -32,7 +32,38 @@
|
|||||||
|
|
||||||
#include "lwip/ip_addr.h"
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/inet.h"
|
#include "lwip/inet.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
|
/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
|
||||||
const struct ip_addr ip_addr_any = { 0x00000000UL };
|
const struct ip_addr ip_addr_any = { 0x00000000UL };
|
||||||
const struct ip_addr ip_addr_broadcast = { 0xffffffffUL };
|
const struct ip_addr ip_addr_broadcast = { 0xffffffffUL };
|
||||||
|
|
||||||
|
/* Determine if an address is a broadcast address on a network interface
|
||||||
|
*
|
||||||
|
* @param addr address to be checked
|
||||||
|
* @param netif the network interface against which the address is checked
|
||||||
|
* @return returns non-zero if the address is a broadcast address
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif)
|
||||||
|
{
|
||||||
|
/* all ones (broadcast) or all zeroes (old skool broadcast) */
|
||||||
|
if ((addr->addr == ip_addr_broadcast.addr) ||
|
||||||
|
(addr->addr == ip_addr_any.addr))
|
||||||
|
return 1;
|
||||||
|
/* no broadcast support on this network interface? */
|
||||||
|
else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)
|
||||||
|
/* the given address cannot be a broadcast address
|
||||||
|
* nor can we check against any broadcast addresses */
|
||||||
|
return 0;
|
||||||
|
/* address matches network interface address exactly? => no broadcast */
|
||||||
|
else if (addr->addr == netif->ip_addr.addr)
|
||||||
|
return 0;
|
||||||
|
/* host identifier bits are all ones? => network broadcast address */
|
||||||
|
else if ((addr->addr & ~netif->netmask.addr) ==
|
||||||
|
(ip_addr_broadcast.addr & ~netif->netmask.addr))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
|
/* @file
|
||||||
|
*
|
||||||
|
* This is the IP packet segmentation and reassembly implementation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -31,14 +37,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* ip_frag.c
|
|
||||||
*
|
|
||||||
* This is the code for IP segmentation and reassembly
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
#include "lwip/ip.h"
|
#include "lwip/ip.h"
|
||||||
@@ -294,7 +292,6 @@ ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest)
|
|||||||
rambuf->tot_len = rambuf->len = mtu;
|
rambuf->tot_len = rambuf->len = mtu;
|
||||||
rambuf->payload = MEM_ALIGN((void *)buf);
|
rambuf->payload = MEM_ALIGN((void *)buf);
|
||||||
|
|
||||||
|
|
||||||
/* Copy the IP header in it */
|
/* Copy the IP header in it */
|
||||||
iphdr = rambuf->payload;
|
iphdr = rambuf->payload;
|
||||||
memcpy(iphdr, p->payload, IP_HLEN);
|
memcpy(iphdr, p->payload, IP_HLEN);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -54,6 +54,8 @@ struct mem {
|
|||||||
u16_t used;
|
u16_t used;
|
||||||
#elif MEM_ALIGNMENT == 4
|
#elif MEM_ALIGNMENT == 4
|
||||||
u32_t used;
|
u32_t used;
|
||||||
|
#elif MEM_ALIGNMENT == 8
|
||||||
|
u64_t used;
|
||||||
#else
|
#else
|
||||||
#error "unhandled MEM_ALIGNMENT size"
|
#error "unhandled MEM_ALIGNMENT size"
|
||||||
#endif /* MEM_ALIGNMENT */
|
#endif /* MEM_ALIGNMENT */
|
||||||
@@ -292,7 +294,7 @@ mem_malloc(mem_size_t size)
|
|||||||
}
|
}
|
||||||
sys_sem_signal(mem_sem);
|
sys_sem_signal(mem_sem);
|
||||||
LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
|
LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
|
||||||
(u32_t)mem + SIZEOF_STRUCT_MEM + size <= (u32_t)ram_end);
|
(mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
|
||||||
LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
|
LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
|
||||||
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
|
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
|
||||||
return (u8_t *)mem + SIZEOF_STRUCT_MEM;
|
return (u8_t *)mem + SIZEOF_STRUCT_MEM;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -120,7 +120,7 @@ static u8_t memp_memory[(MEMP_NUM_PBUF *
|
|||||||
static sys_sem_t mutex;
|
static sys_sem_t mutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LWIP_NOASSERT
|
#if MEMP_SANITY_CHECK
|
||||||
static int
|
static int
|
||||||
memp_sanity(void)
|
memp_sanity(void)
|
||||||
{
|
{
|
||||||
@@ -140,7 +140,7 @@ memp_sanity(void)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif /* LWIP_DEBUG */
|
#endif /* MEMP_SANITY_CHECK*/
|
||||||
|
|
||||||
void
|
void
|
||||||
memp_init(void)
|
memp_init(void)
|
||||||
@@ -217,7 +217,7 @@ memp_malloc(memp_t type)
|
|||||||
sys_sem_signal(mutex);
|
sys_sem_signal(mutex);
|
||||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||||
LWIP_ASSERT("memp_malloc: memp properly aligned",
|
LWIP_ASSERT("memp_malloc: memp properly aligned",
|
||||||
((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
|
((mem_ptr_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
|
||||||
|
|
||||||
mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
|
mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
|
||||||
return mem;
|
return mem;
|
||||||
@@ -261,7 +261,9 @@ memp_free(memp_t type, void *mem)
|
|||||||
memp->next = memp_tab[type];
|
memp->next = memp_tab[type];
|
||||||
memp_tab[type] = memp;
|
memp_tab[type] = memp;
|
||||||
|
|
||||||
|
#if MEMP_SANITY_CHECK
|
||||||
LWIP_ASSERT("memp sanity", memp_sanity());
|
LWIP_ASSERT("memp sanity", memp_sanity());
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SYS_LIGHTWEIGHT_PROT
|
#if SYS_LIGHTWEIGHT_PROT
|
||||||
SYS_ARCH_UNPROTECT(old_level);
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -39,23 +39,24 @@
|
|||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "lwip/netif.h"
|
|
||||||
#include "lwip/ip_addr.h"
|
#include "lwip/ip_addr.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
#include "lwip/tcp.h"
|
#include "lwip/tcp.h"
|
||||||
|
|
||||||
|
|
||||||
struct netif *netif_list = NULL;
|
struct netif *netif_list = NULL;
|
||||||
struct netif *netif_default = NULL;
|
struct netif *netif_default = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a network interface to the list of lwIP netifs.
|
* Add a network interface to the list of lwIP netifs.
|
||||||
*
|
*
|
||||||
|
* @param netif a pre-allocated netif structure
|
||||||
* @param ipaddr IP address for the new netif
|
* @param ipaddr IP address for the new netif
|
||||||
* @param netmask network mask for the new netif
|
* @param netmask network mask for the new netif
|
||||||
* @param gw default gateway IP address for the new netif
|
* @param gw default gateway IP address for the new netif
|
||||||
* @param state opaque data passed to the new netif
|
* @param state opaque data passed to the new netif
|
||||||
* @param init callback function that initializes the interface
|
* @param init callback function that initializes the interface
|
||||||
* @param input callback function that...
|
* @param input callback function that is called to pass
|
||||||
|
* ingress packets up in the protocol layer stack.
|
||||||
*
|
*
|
||||||
* @return netif, or NULL if failed.
|
* @return netif, or NULL if failed.
|
||||||
*/
|
*/
|
||||||
@@ -171,7 +172,7 @@ netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
|
|||||||
/* address is actually being changed? */
|
/* address is actually being changed? */
|
||||||
if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
|
if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
|
||||||
{
|
{
|
||||||
extern struct tcp_pcb *tcp_active_pcbs;
|
/* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
|
||||||
LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
|
LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
|
||||||
pcb = tcp_active_pcbs;
|
pcb = tcp_active_pcbs;
|
||||||
while (pcb != NULL) {
|
while (pcb != NULL) {
|
||||||
@@ -186,7 +187,7 @@ netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
|
|||||||
pcb = pcb->next;
|
pcb = pcb->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||||
/* PCB bound to current local interface address? */
|
/* PCB bound to current local interface address? */
|
||||||
if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {
|
if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {
|
||||||
/* The PCB is listening to the old ipaddr and
|
/* The PCB is listening to the old ipaddr and
|
||||||
@@ -197,6 +198,14 @@ netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ip_addr_set(&(netif->ip_addr), ipaddr);
|
ip_addr_set(&(netif->ip_addr), ipaddr);
|
||||||
|
#if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */
|
||||||
|
/** For Ethernet network interfaces, we would like to send a
|
||||||
|
* "gratuitous ARP"; this is an ARP packet sent by a node in order
|
||||||
|
* to spontaneously cause other nodes to update an entry in their
|
||||||
|
* ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
|
||||||
|
*/
|
||||||
|
etharp_query(netif, ipaddr, NULL);
|
||||||
|
#endif
|
||||||
LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %u.%u.%u.%u\n",
|
LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %u.%u.%u.%u\n",
|
||||||
netif->name[0], netif->name[1],
|
netif->name[0], netif->name[1],
|
||||||
(unsigned int)(ntohl(netif->ip_addr.addr) >> 24 & 0xff),
|
(unsigned int)(ntohl(netif->ip_addr.addr) >> 24 & 0xff),
|
||||||
|
|||||||
105
src/core/pbuf.c
105
src/core/pbuf.c
@@ -11,12 +11,15 @@
|
|||||||
* list. This is called a "pbuf chain".
|
* list. This is called a "pbuf chain".
|
||||||
*
|
*
|
||||||
* Multiple packets may be queued, also using this singly linked list.
|
* Multiple packets may be queued, also using this singly linked list.
|
||||||
* This is called a "packet queue". So, a packet queue consists of one
|
* This is called a "packet queue".
|
||||||
* or more pbuf chains, each of which consist of one or more pbufs.
|
*
|
||||||
|
* So, a packet queue consists of one or more pbuf chains, each of
|
||||||
|
* which consist of one or more pbufs. Currently, queues are only
|
||||||
|
* supported in a limited section of lwIP, this is the etharp queueing
|
||||||
|
* code. Outside of this section no packet queues are supported yet.
|
||||||
|
*
|
||||||
* The differences between a pbuf chain and a packet queue are very
|
* The differences between a pbuf chain and a packet queue are very
|
||||||
* subtle. Currently, queues are only supported in a limited section
|
* precise but subtle.
|
||||||
* of lwIP, this is the etharp queueing code. Outside of this section
|
|
||||||
* no packet queues are supported as of yet.
|
|
||||||
*
|
*
|
||||||
* The last pbuf of a packet has a ->tot_len field that equals the
|
* The last pbuf of a packet has a ->tot_len field that equals the
|
||||||
* ->len field. It can be found by traversing the list. If the last
|
* ->len field. It can be found by traversing the list. If the last
|
||||||
@@ -28,7 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -100,7 +103,7 @@ pbuf_init(void)
|
|||||||
u16_t i;
|
u16_t i;
|
||||||
|
|
||||||
pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
|
pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
|
||||||
LWIP_ASSERT("pbuf_init: pool aligned", (long)pbuf_pool % MEM_ALIGNMENT == 0);
|
LWIP_ASSERT("pbuf_init: pool aligned", (mem_ptr_t)pbuf_pool % MEM_ALIGNMENT == 0);
|
||||||
|
|
||||||
#if PBUF_STATS
|
#if PBUF_STATS
|
||||||
lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
|
lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
|
||||||
@@ -254,7 +257,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
|||||||
/* make the payload pointer point 'offset' bytes into pbuf data memory */
|
/* make the payload pointer point 'offset' bytes into pbuf data memory */
|
||||||
p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
|
p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
|
||||||
LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
|
LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
|
||||||
((u32_t)p->payload % MEM_ALIGNMENT) == 0);
|
((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
|
||||||
/* the total length of the pbuf chain is the requested size */
|
/* the total length of the pbuf chain is the requested size */
|
||||||
p->tot_len = length;
|
p->tot_len = length;
|
||||||
/* set the length of the first pbuf in the chain */
|
/* set the length of the first pbuf in the chain */
|
||||||
@@ -290,7 +293,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
|||||||
q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;
|
q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;
|
||||||
q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
|
q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
|
||||||
LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
|
LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
|
||||||
((u32_t)q->payload % MEM_ALIGNMENT) == 0);
|
((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
|
||||||
q->ref = 1;
|
q->ref = 1;
|
||||||
/* calculate remaining length to be allocated */
|
/* calculate remaining length to be allocated */
|
||||||
rem_len -= q->len;
|
rem_len -= q->len;
|
||||||
@@ -314,7 +317,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
|||||||
p->flags = PBUF_FLAG_RAM;
|
p->flags = PBUF_FLAG_RAM;
|
||||||
|
|
||||||
LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
|
LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
|
||||||
((u32_t)p->payload % MEM_ALIGNMENT) == 0);
|
((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
|
||||||
break;
|
break;
|
||||||
/* pbuf references existing (static constant) ROM payload? */
|
/* pbuf references existing (static constant) ROM payload? */
|
||||||
case PBUF_ROM:
|
case PBUF_ROM:
|
||||||
@@ -450,32 +453,35 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
|
|||||||
*
|
*
|
||||||
* The ->payload, ->tot_len and ->len fields are adjusted.
|
* The ->payload, ->tot_len and ->len fields are adjusted.
|
||||||
*
|
*
|
||||||
* @param hdr_size Number of bytes to increment header size which
|
* @param hdr_size_inc Number of bytes to increment header size which
|
||||||
* increases the size of the pbuf. New space is on the front.
|
* increases the size of the pbuf. New space is on the front.
|
||||||
* (Using a negative value decreases the header size.)
|
* (Using a negative value decreases the header size.)
|
||||||
|
* If hdr_size_inc is 0, this function does nothing and returns succesful.
|
||||||
*
|
*
|
||||||
* PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
|
* PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
|
||||||
* the call will fail. A check is made that the increase in header size does
|
* the call will fail. A check is made that the increase in header size does
|
||||||
* not move the payload pointer in front of the start of the buffer.
|
* not move the payload pointer in front of the start of the buffer.
|
||||||
* @return 1 on failure, 0 on success.
|
* @return non-zero on failure, zero on success.
|
||||||
*
|
*
|
||||||
* @note May not be called on a packet queue.
|
|
||||||
*/
|
*/
|
||||||
u8_t
|
u8_t
|
||||||
pbuf_header(struct pbuf *p, s16_t header_size)
|
pbuf_header(struct pbuf *p, s16_t header_size_increment)
|
||||||
{
|
{
|
||||||
void *payload;
|
void *payload;
|
||||||
|
|
||||||
|
LWIP_ASSERT("p != NULL", p != NULL);
|
||||||
|
if ((header_size_increment == 0) || (p == NULL)) return 0;
|
||||||
|
|
||||||
/* remember current payload pointer */
|
/* remember current payload pointer */
|
||||||
payload = p->payload;
|
payload = p->payload;
|
||||||
|
|
||||||
/* pbuf types containing payloads? */
|
/* pbuf types containing payloads? */
|
||||||
if (p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_POOL) {
|
if (p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_POOL) {
|
||||||
/* set new payload pointer */
|
/* set new payload pointer */
|
||||||
p->payload = (u8_t *)p->payload - header_size;
|
p->payload = (u8_t *)p->payload - header_size_increment;
|
||||||
/* boundary check fails? */
|
/* boundary check fails? */
|
||||||
if ((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {
|
if ((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {
|
||||||
LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_header: failed as %p < %p\n",
|
LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_header: failed as %p < %p (not enough space for new header size)\n",
|
||||||
(u8_t *)p->payload,
|
(u8_t *)p->payload,
|
||||||
(u8_t *)p + sizeof(struct pbuf)) );\
|
(u8_t *)p + sizeof(struct pbuf)) );\
|
||||||
/* restore old payload pointer */
|
/* restore old payload pointer */
|
||||||
@@ -483,35 +489,37 @@ pbuf_header(struct pbuf *p, s16_t header_size)
|
|||||||
/* bail out unsuccesfully */
|
/* bail out unsuccesfully */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* pbuf types refering to payloads? */
|
/* pbuf types refering to external payloads? */
|
||||||
} else if (p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_ROM) {
|
} else if (p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_ROM) {
|
||||||
/* hide a header in the payload? */
|
/* hide a header in the payload? */
|
||||||
if ((header_size < 0) && (header_size - p->len <= 0)) {
|
if ((header_size_increment < 0) && (header_size_increment - p->len <= 0)) {
|
||||||
/* increase payload pointer */
|
/* increase payload pointer */
|
||||||
p->payload = (u8_t *)p->payload - header_size;
|
p->payload = (u8_t *)p->payload - header_size_increment;
|
||||||
} else {
|
} else {
|
||||||
/* cannot expand payload to front (yet!)
|
/* cannot expand payload to front (yet!)
|
||||||
* bail out unsuccesfully */
|
* bail out unsuccesfully */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%d)\n", (void *)payload, (void *)p->payload, header_size) );
|
|
||||||
/* modify pbuf length fields */
|
/* modify pbuf length fields */
|
||||||
p->len += header_size;
|
p->len += header_size_increment;
|
||||||
p->tot_len += header_size;
|
p->tot_len += header_size_increment;
|
||||||
|
|
||||||
|
LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%d)\n",
|
||||||
|
(void *)payload, (void *)p->payload, header_size_increment));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dereference a pbuf (chain) and deallocate any no-longer-used
|
* Dereference a pbuf chain or queue and deallocate any no-longer-used
|
||||||
* pbufs at the head of this chain.
|
* pbufs at the head of this chain or queue.
|
||||||
*
|
*
|
||||||
* Decrements the pbuf reference count. If it reaches
|
* Decrements the pbuf reference count. If it reaches zero, the pbuf is
|
||||||
* zero, the pbuf is deallocated.
|
* deallocated.
|
||||||
*
|
*
|
||||||
* For a pbuf chain, this is repeated for each pbuf in the chain,
|
* For a pbuf chain, this is repeated for each pbuf in the chain,
|
||||||
* up to a pbuf which has a non-zero reference count after
|
* up to the first pbuf which has a non-zero reference count after
|
||||||
* decrementing. (This might de-allocate the whole chain.)
|
* decrementing. (This might de-allocate the whole chain.)
|
||||||
*
|
*
|
||||||
* @param pbuf The pbuf (chain) to be dereferenced.
|
* @param pbuf The pbuf (chain) to be dereferenced.
|
||||||
@@ -519,7 +527,7 @@ pbuf_header(struct pbuf *p, s16_t header_size)
|
|||||||
* @return the number of pbufs that were de-allocated
|
* @return the number of pbufs that were de-allocated
|
||||||
* from the head of the chain.
|
* from the head of the chain.
|
||||||
*
|
*
|
||||||
* @note MUST NOT be called on a packet queue.
|
* @note MUST NOT be called on a packet queue (Not verified to work yet).
|
||||||
* @note the reference counter of a pbuf equals the number of pointers
|
* @note the reference counter of a pbuf equals the number of pointers
|
||||||
* that refer to the pbuf (or into the pbuf).
|
* that refer to the pbuf (or into the pbuf).
|
||||||
*
|
*
|
||||||
@@ -542,6 +550,8 @@ pbuf_free(struct pbuf *p)
|
|||||||
u8_t count;
|
u8_t count;
|
||||||
SYS_ARCH_DECL_PROTECT(old_level);
|
SYS_ARCH_DECL_PROTECT(old_level);
|
||||||
|
|
||||||
|
LWIP_ASSERT("p != NULL", p != NULL);
|
||||||
|
/* if assertions are disabled, proceed with debug output */
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.\n"));
|
LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.\n"));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -708,11 +718,13 @@ pbuf_chain(struct pbuf *h, struct pbuf *t)
|
|||||||
void
|
void
|
||||||
pbuf_queue(struct pbuf *p, struct pbuf *n)
|
pbuf_queue(struct pbuf *p, struct pbuf *n)
|
||||||
{
|
{
|
||||||
|
#if PBUF_DEBUG /* remember head of queue */
|
||||||
|
struct pbuf *q = p;
|
||||||
|
#endif
|
||||||
|
/* programmer stupidity checks */
|
||||||
LWIP_ASSERT("p != NULL", p != NULL);
|
LWIP_ASSERT("p != NULL", p != NULL);
|
||||||
LWIP_ASSERT("n != NULL", n != NULL);
|
LWIP_ASSERT("n != NULL", n != NULL);
|
||||||
|
if ((p == NULL) || (n == NULL)) return;
|
||||||
if ((p == NULL) || (n == NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* iterate through all packets on queue */
|
/* iterate through all packets on queue */
|
||||||
while (p->next != NULL) {
|
while (p->next != NULL) {
|
||||||
@@ -720,25 +732,34 @@ pbuf_queue(struct pbuf *p, struct pbuf *n)
|
|||||||
#if PBUF_DEBUG
|
#if PBUF_DEBUG
|
||||||
/* iterate through all pbufs in packet */
|
/* iterate through all pbufs in packet */
|
||||||
while (p->tot_len != p->len) {
|
while (p->tot_len != p->len) {
|
||||||
|
/* make sure invariant condition holds */
|
||||||
|
LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);
|
||||||
/* make sure each packet is complete */
|
/* make sure each packet is complete */
|
||||||
LWIP_ASSERT("p->next != NULL", p->next != NULL);
|
LWIP_ASSERT("p->next != NULL", p->next != NULL);
|
||||||
p = p->next;
|
p = p->next;
|
||||||
|
/* { p->tot_len == p->len => p is last pbuf of a packet } */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* now p->tot_len == p->len */
|
/* { p->tot_len == p->len and p is last pbuf of a packet } */
|
||||||
/* proceed to next packet on queue */
|
/* proceed to next packet on queue */
|
||||||
p = p->next;
|
if (p->next != NULL) p = p->next;
|
||||||
}
|
}
|
||||||
|
/* { p->tot_len == p->len and p->next == NULL } ==>
|
||||||
|
* { p is last pbuf of last packet on queue } */
|
||||||
/* chain last pbuf of queue with n */
|
/* chain last pbuf of queue with n */
|
||||||
p->next = n;
|
p->next = n;
|
||||||
/* n is now referenced to one more time */
|
/* n is now referenced to by the (packet p in the) queue */
|
||||||
pbuf_ref(n);
|
pbuf_ref(n);
|
||||||
LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_queue: referencing queued packet %p\n", (void *)n));
|
LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2,
|
||||||
|
("pbuf_queue: newly queued packet %p sits after packet %p in queue %p\n",
|
||||||
|
(void *)n, (void *)p, (void *)q));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a packet from the head of a queue.
|
* Remove a packet from the head of a queue.
|
||||||
*
|
*
|
||||||
|
* The caller MUST reference the remainder of the queue (as returned).
|
||||||
|
*
|
||||||
* @param p pointer to first packet on the queue which will be dequeued.
|
* @param p pointer to first packet on the queue which will be dequeued.
|
||||||
* @return first packet on the remaining queue (NULL if no further packets).
|
* @return first packet on the remaining queue (NULL if no further packets).
|
||||||
*
|
*
|
||||||
@@ -751,17 +772,25 @@ pbuf_dequeue(struct pbuf *p)
|
|||||||
|
|
||||||
/* iterate through all pbufs in packet */
|
/* iterate through all pbufs in packet */
|
||||||
while (p->tot_len != p->len) {
|
while (p->tot_len != p->len) {
|
||||||
|
/* make sure invariant condition holds */
|
||||||
|
LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);
|
||||||
/* make sure each packet is complete */
|
/* make sure each packet is complete */
|
||||||
LWIP_ASSERT("p->next != NULL", p->next != NULL);
|
LWIP_ASSERT("p->next != NULL", p->next != NULL);
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
/* { p->tot_len == p->len } => p is the last pbuf of the first packet */
|
||||||
/* remember next packet on queue */
|
/* remember next packet on queue */
|
||||||
q = p->next;
|
q = p->next;
|
||||||
/* dequeue p from queue */
|
/* dequeue p from queue */
|
||||||
p->next = NULL;
|
p->next = NULL;
|
||||||
/* q is now referenced to one less time */
|
/* any next packet on queue? */
|
||||||
pbuf_free(q);
|
if (q != NULL) {
|
||||||
LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: dereferencing remaining queue %p\n", (void *)q));
|
/* although q is no longer referenced by p, it MUST be referenced by
|
||||||
|
* the caller, who is maintaining this packet queue */
|
||||||
|
LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: at least one packet on queue, first %p\n", (void *)q));
|
||||||
|
} else {
|
||||||
|
LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: no further packets on queue\n"));
|
||||||
|
}
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
118
src/core/raw.c
118
src/core/raw.c
@@ -1,10 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* Raw Access module
|
*
|
||||||
|
* Implementation of raw protocol PCBs for low-level handling of
|
||||||
|
* different types of protocols besides (or overriding) those
|
||||||
|
* already available in lwIP.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -35,20 +38,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* raw.c
|
|
||||||
*
|
|
||||||
* The code for the Raw Access to the IP
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "lwip/memp.h"
|
#include "lwip/memp.h"
|
||||||
#include "lwip/inet.h"
|
#include "lwip/inet.h"
|
||||||
#include "lwip/netif.h"
|
|
||||||
#include "lwip/ip_addr.h"
|
#include "lwip/ip_addr.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
#include "lwip/raw.h"
|
#include "lwip/raw.h"
|
||||||
|
|
||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
@@ -57,11 +53,10 @@
|
|||||||
#include "lwip/snmp.h"
|
#include "lwip/snmp.h"
|
||||||
|
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
/* The list of RAW PCBs */
|
|
||||||
|
|
||||||
|
/** The list of RAW PCBs */
|
||||||
static struct raw_pcb *raw_pcbs = NULL;
|
static struct raw_pcb *raw_pcbs = NULL;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
raw_init(void)
|
raw_init(void)
|
||||||
{
|
{
|
||||||
@@ -69,42 +64,54 @@ raw_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if in incoming IP packet is covered by a RAW pcb and
|
* Determine if in incoming IP packet is covered by a RAW PCB
|
||||||
* and process it if possible
|
* and if so, pass it to a user-provided receive callback function.
|
||||||
*
|
*
|
||||||
* Given an incoming IP datagram (as a chain of pbufs) this function
|
* Given an incoming IP datagram (as a chain of pbufs) this function
|
||||||
* finds a corresponding RAW PCB and
|
* finds a corresponding RAW PCB and calls the corresponding receive
|
||||||
|
* callback function.
|
||||||
*
|
*
|
||||||
* @param pbuf pbuf to be demultiplexed to a RAW PCB.
|
* @param pbuf pbuf to be demultiplexed to a RAW PCB.
|
||||||
* @param netif network interface on which the datagram was received.
|
* @param netif network interface on which the datagram was received.
|
||||||
* @return 0 if packet is not eated (pbuf needs to be freed then)
|
* @Return - 1 if the packet has been eaten by a RAW PCB receive
|
||||||
* or 1 if the packet has been eaten (pbuf needs not to be freed
|
* callback function. The caller MAY NOT not reference the
|
||||||
* then)
|
* packet any longer, and MAY NOT call pbuf_free().
|
||||||
|
* @return - 0 if packet is not eaten (pbuf is still referenced by the
|
||||||
|
* caller).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int
|
u8_t
|
||||||
raw_input(struct pbuf *p, struct netif *inp)
|
raw_input(struct pbuf *p, struct netif *inp)
|
||||||
{
|
{
|
||||||
struct raw_pcb *pcb;
|
struct raw_pcb *pcb;
|
||||||
struct ip_hdr *iphdr;
|
struct ip_hdr *iphdr;
|
||||||
int proto;
|
int proto;
|
||||||
int rc = 0;
|
u8_t eaten = 0;
|
||||||
|
|
||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
proto = IPH_PROTO(iphdr);
|
proto = IPH_PROTO(iphdr);
|
||||||
|
|
||||||
for(pcb = raw_pcbs; pcb != NULL; pcb = pcb->next) {
|
pcb = raw_pcbs;
|
||||||
|
/* loop through all raw pcbs until the packet is eaten by one */
|
||||||
|
/* this allows multiple pcbs to match against the packet by design */
|
||||||
|
while ((eaten == 0) && (pcb != NULL)) {
|
||||||
if (pcb->protocol == proto) {
|
if (pcb->protocol == proto) {
|
||||||
if (pcb->recv) {
|
/* receive callback function available? */
|
||||||
if (!pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src)))
|
if (pcb->recv != NULL) {
|
||||||
return 0;
|
/* the receive callback function did not eat the packet? */
|
||||||
|
if (pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src)) != 0)
|
||||||
|
{
|
||||||
|
/* receive function ate the packet */
|
||||||
|
p = NULL;
|
||||||
|
eaten = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pbuf_free(p);
|
/* no receive callback function was set for this raw PCB */
|
||||||
rc = 1;
|
/* drop the packet */
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
pcb = pcb->next;
|
||||||
}
|
}
|
||||||
return rc;
|
return eaten;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,7 +123,7 @@ raw_input(struct pbuf *p, struct netif *inp)
|
|||||||
*
|
*
|
||||||
* @return lwIP error code.
|
* @return lwIP error code.
|
||||||
* - ERR_OK. Successful. No error occured.
|
* - ERR_OK. Successful. No error occured.
|
||||||
* - ERR_USE. The specified ipaddr is already bound to by
|
* - ERR_USE. The specified IP address is already bound to by
|
||||||
* another RAW PCB.
|
* another RAW PCB.
|
||||||
*
|
*
|
||||||
* @see raw_disconnect()
|
* @see raw_disconnect()
|
||||||
@@ -130,7 +137,7 @@ raw_bind(struct raw_pcb *pcb, struct ip_addr *ipaddr)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect an RAW PCB. This function is required by upper layers
|
* Connect an RAW PCB. This function is required by upper layers
|
||||||
* of lwip. Using the raw api you could use raw_send_to() instead
|
* of lwip. Using the raw api you could use raw_sendto() instead
|
||||||
*
|
*
|
||||||
* This will associate the RAW PCB with the remote address.
|
* This will associate the RAW PCB with the remote address.
|
||||||
*
|
*
|
||||||
@@ -139,7 +146,7 @@ raw_bind(struct raw_pcb *pcb, struct ip_addr *ipaddr)
|
|||||||
*
|
*
|
||||||
* @return lwIP error code
|
* @return lwIP error code
|
||||||
*
|
*
|
||||||
* @see raw_disconnect() and raw_send_to()
|
* @see raw_disconnect() and raw_sendto()
|
||||||
*/
|
*/
|
||||||
err_t
|
err_t
|
||||||
raw_connect(struct raw_pcb *pcb, struct ip_addr *ipaddr)
|
raw_connect(struct raw_pcb *pcb, struct ip_addr *ipaddr)
|
||||||
@@ -150,14 +157,21 @@ raw_connect(struct raw_pcb *pcb, struct ip_addr *ipaddr)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the callback function if a RAW packet with the pcb's protocol
|
* Set the callback function for received packets that match the
|
||||||
* is received. If the callback function returns a value unequal 0
|
* raw PCB's protocol and binding.
|
||||||
* the raw packet is "eaten" and not forwarded to any other raw pcb
|
*
|
||||||
* including lwip itself
|
* The callback function MUST either
|
||||||
|
* - eat the packet by calling pbuf_free() and returning non-zero. The
|
||||||
|
* packet will not be passed to other raw PCBs or other protocol layers.
|
||||||
|
* - not free the packet, and return zero. The packet will be matched
|
||||||
|
* against further PCBs and/or forwarded to another protocol layers.
|
||||||
|
*
|
||||||
|
* @return non-zero if the packet was free()d, zero if the packet remains
|
||||||
|
* available for others.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
raw_recv(struct raw_pcb *pcb,
|
raw_recv(struct raw_pcb *pcb,
|
||||||
int (* recv)(void *arg, struct raw_pcb *upcb, struct pbuf *p,
|
u8_t (* recv)(void *arg, struct raw_pcb *upcb, struct pbuf *p,
|
||||||
struct ip_addr *addr),
|
struct ip_addr *addr),
|
||||||
void *recv_arg)
|
void *recv_arg)
|
||||||
{
|
{
|
||||||
@@ -168,25 +182,25 @@ raw_recv(struct raw_pcb *pcb,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the raw IP packet to the given address. Note that actually you cannot
|
* Send the raw IP packet to the given address. Note that actually you cannot
|
||||||
* modify the IP headers (this is inconsitent with the receive callback where
|
* modify the IP headers (this is inconsistent with the receive callback where
|
||||||
* you actually get the IP headers), you can only specifiy the ip payload here.
|
* you actually get the IP headers), you can only specify the IP payload here.
|
||||||
* It requires some more changes in LWIP. (there will be a raw_send() function
|
* It requires some more changes in lwIP. (there will be a raw_send() function
|
||||||
* then)
|
* then.)
|
||||||
*
|
*
|
||||||
* @param pcb the raw pcb which to send
|
* @param pcb the raw pcb which to send
|
||||||
* @param p the ip payload to send
|
* @param p the IP payload to send
|
||||||
* @param ipaddr the destination address of the whole IP packet
|
* @param ipaddr the destination address of the IP packet
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
err_t
|
err_t
|
||||||
raw_send_to(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
|
raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
|
||||||
{
|
{
|
||||||
err_t err;
|
err_t err;
|
||||||
struct netif *netif;
|
struct netif *netif;
|
||||||
struct ip_addr *src_ip;
|
struct ip_addr *src_ip;
|
||||||
struct pbuf *q; /* q will be sent down the stack */
|
struct pbuf *q; /* q will be sent down the stack */
|
||||||
|
|
||||||
LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_send_to\n"));
|
LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_sendto\n"));
|
||||||
|
|
||||||
/* not enough space to add an IP header to first pbuf in given p chain? */
|
/* not enough space to add an IP header to first pbuf in given p chain? */
|
||||||
if (pbuf_header(p, IP_HLEN)) {
|
if (pbuf_header(p, IP_HLEN)) {
|
||||||
@@ -194,13 +208,13 @@ raw_send_to(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
|
|||||||
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
|
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
|
||||||
/* new header pbuf could not be allocated? */
|
/* new header pbuf could not be allocated? */
|
||||||
if (q == NULL) {
|
if (q == NULL) {
|
||||||
LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 2, ("raw_send_to: could not allocate header\n"));
|
LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 2, ("raw_sendto: could not allocate header\n"));
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
/* chain header q in front of given pbuf p */
|
/* chain header q in front of given pbuf p */
|
||||||
pbuf_chain(q, p);
|
pbuf_chain(q, p);
|
||||||
/* { first pbuf q points to header pbuf } */
|
/* { first pbuf q points to header pbuf } */
|
||||||
LWIP_DEBUGF(RAW_DEBUG, ("raw_send_to: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
||||||
} else {
|
} else {
|
||||||
/* first pbuf q equals given pbuf */
|
/* first pbuf q equals given pbuf */
|
||||||
q = p;
|
q = p;
|
||||||
@@ -208,10 +222,11 @@ raw_send_to(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((netif = ip_route(ipaddr)) == NULL) {
|
if ((netif = ip_route(ipaddr)) == NULL) {
|
||||||
LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_send_to: No route to 0x%lx\n", ipaddr->addr));
|
LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_sendto: No route to 0x%lx\n", ipaddr->addr));
|
||||||
#if RAW_STATS
|
#if RAW_STATS
|
||||||
/* ++lwip_stats.raw.rterr;*/
|
/* ++lwip_stats.raw.rterr;*/
|
||||||
#endif /* RAW_STATS */
|
#endif /* RAW_STATS */
|
||||||
|
/* free any temporary header pbuf allocated by pbuf_header() */
|
||||||
if (q != p) {
|
if (q != p) {
|
||||||
pbuf_free(q);
|
pbuf_free(q);
|
||||||
}
|
}
|
||||||
@@ -240,14 +255,14 @@ raw_send_to(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
|
|||||||
* Send the raw IP packet to the address given by raw_connect()
|
* Send the raw IP packet to the address given by raw_connect()
|
||||||
*
|
*
|
||||||
* @param pcb the raw pcb which to send
|
* @param pcb the raw pcb which to send
|
||||||
* @param p the ip payload to send
|
* @param p the IP payload to send
|
||||||
* @param ipaddr the destination address of the whole IP packet
|
* @param ipaddr the destination address of the IP packet
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
err_t
|
err_t
|
||||||
raw_send(struct raw_pcb *pcb, struct pbuf *p)
|
raw_send(struct raw_pcb *pcb, struct pbuf *p)
|
||||||
{
|
{
|
||||||
return raw_send_to(pcb,p,&pcb->remote_ip);
|
return raw_sendto(pcb, p, &pcb->remote_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -266,7 +281,7 @@ raw_remove(struct raw_pcb *pcb)
|
|||||||
if (raw_pcbs == pcb) {
|
if (raw_pcbs == pcb) {
|
||||||
/* make list start at 2nd pcb */
|
/* make list start at 2nd pcb */
|
||||||
raw_pcbs = raw_pcbs->next;
|
raw_pcbs = raw_pcbs->next;
|
||||||
/* pcb not 1st in list */
|
/* pcb not 1st in list */
|
||||||
} else for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
|
} else for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
|
||||||
/* find pcb in raw_pcbs list */
|
/* find pcb in raw_pcbs list */
|
||||||
if (pcb2->next != NULL && pcb2->next == pcb) {
|
if (pcb2->next != NULL && pcb2->next == pcb) {
|
||||||
@@ -303,7 +318,6 @@ raw_new(u16_t proto) {
|
|||||||
pcb->next = raw_pcbs;
|
pcb->next = raw_pcbs;
|
||||||
raw_pcbs = pcb;
|
raw_pcbs = pcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pcb;
|
return pcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -47,5 +47,68 @@ stats_init(void)
|
|||||||
{
|
{
|
||||||
memset(&lwip_stats, 0, sizeof(struct stats_));
|
memset(&lwip_stats, 0, sizeof(struct stats_));
|
||||||
}
|
}
|
||||||
|
#if LWIP_STATS_DISPLAY
|
||||||
|
void
|
||||||
|
stats_display_proto(struct stats_proto *proto, char *name)
|
||||||
|
{
|
||||||
|
LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
|
||||||
|
LWIP_PLATFORM_DIAG(("xmit: %d\n\t", proto->xmit));
|
||||||
|
LWIP_PLATFORM_DIAG(("rexmit: %d\n\t", proto->rexmit));
|
||||||
|
LWIP_PLATFORM_DIAG(("recv: %d\n\t", proto->recv));
|
||||||
|
LWIP_PLATFORM_DIAG(("fw: %d\n\t", proto->fw));
|
||||||
|
LWIP_PLATFORM_DIAG(("drop: %d\n\t", proto->drop));
|
||||||
|
LWIP_PLATFORM_DIAG(("chkerr: %d\n\t", proto->chkerr));
|
||||||
|
LWIP_PLATFORM_DIAG(("lenerr: %d\n\t", proto->lenerr));
|
||||||
|
LWIP_PLATFORM_DIAG(("memerr: %d\n\t", proto->memerr));
|
||||||
|
LWIP_PLATFORM_DIAG(("rterr: %d\n\t", proto->rterr));
|
||||||
|
LWIP_PLATFORM_DIAG(("proterr: %d\n\t", proto->proterr));
|
||||||
|
LWIP_PLATFORM_DIAG(("opterr: %d\n\t", proto->opterr));
|
||||||
|
LWIP_PLATFORM_DIAG(("err: %d\n\t", proto->err));
|
||||||
|
LWIP_PLATFORM_DIAG(("cachehit: %d\n", proto->cachehit));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stats_display_pbuf(struct stats_pbuf *pbuf)
|
||||||
|
{
|
||||||
|
LWIP_PLATFORM_DIAG(("\nPBUF\n\t"));
|
||||||
|
LWIP_PLATFORM_DIAG(("avail: %d\n\t", pbuf->avail));
|
||||||
|
LWIP_PLATFORM_DIAG(("used: %d\n\t", pbuf->used));
|
||||||
|
LWIP_PLATFORM_DIAG(("max: %d\n\t", pbuf->max));
|
||||||
|
LWIP_PLATFORM_DIAG(("err: %d\n\t", pbuf->err));
|
||||||
|
LWIP_PLATFORM_DIAG(("alloc_locked: %d\n\t", pbuf->alloc_locked));
|
||||||
|
LWIP_PLATFORM_DIAG(("refresh_locked: %d\n", pbuf->refresh_locked));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stats_display_mem(struct stats_mem *mem, char *name)
|
||||||
|
{
|
||||||
|
LWIP_PLATFORM_DIAG(("\n MEM %s\n\t", name));
|
||||||
|
LWIP_PLATFORM_DIAG(("avail: %d\n\t", mem->avail));
|
||||||
|
LWIP_PLATFORM_DIAG(("used: %d\n\t", mem->used));
|
||||||
|
LWIP_PLATFORM_DIAG(("max: %d\n\t", mem->max));
|
||||||
|
LWIP_PLATFORM_DIAG(("err: %d\n", mem->err));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
stats_display(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char * memp_names[] = {"PBUF", "RAW_PCB", "UDP_PCB", "TCP_PCB", "TCP_PCB_LISTEN",
|
||||||
|
"TCP_SEG", "NETBUF", "NETCONN", "API_MSG", "TCP_MSG", "TIMEOUT"};
|
||||||
|
stats_display_proto(&lwip_stats.link, "LINK");
|
||||||
|
stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG");
|
||||||
|
stats_display_proto(&lwip_stats.ip, "IP");
|
||||||
|
stats_display_proto(&lwip_stats.icmp, "ICMP");
|
||||||
|
stats_display_proto(&lwip_stats.udp, "UDP");
|
||||||
|
stats_display_proto(&lwip_stats.tcp, "TCP");
|
||||||
|
stats_display_pbuf(&lwip_stats.pbuf);
|
||||||
|
stats_display_mem(&lwip_stats.mem, "HEAP");
|
||||||
|
for (i = 0; i < MEMP_MAX; i++) {
|
||||||
|
stats_display_mem(&lwip_stats.memp[i], memp_names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif /* LWIP_STATS_DISPLAY */
|
||||||
#endif /* LWIP_STATS */
|
#endif /* LWIP_STATS */
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -174,6 +174,7 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
|
|||||||
(void *)timeout, msecs, (void *)h, (void *)arg));
|
(void *)timeout, msecs, (void *)h, (void *)arg));
|
||||||
|
|
||||||
LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
|
LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
|
||||||
|
|
||||||
if (timeouts->next == NULL) {
|
if (timeouts->next == NULL) {
|
||||||
timeouts->next = timeout;
|
timeouts->next = timeout;
|
||||||
return;
|
return;
|
||||||
@@ -186,14 +187,13 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
|
|||||||
} else {
|
} else {
|
||||||
for(t = timeouts->next; t != NULL; t = t->next) {
|
for(t = timeouts->next; t != NULL; t = t->next) {
|
||||||
timeout->time -= t->time;
|
timeout->time -= t->time;
|
||||||
if (t->next == NULL ||
|
if (t->next == NULL || t->next->time > timeout->time) {
|
||||||
t->next->time > timeout->time) {
|
if (t->next != NULL) {
|
||||||
if (t->next != NULL) {
|
t->next->time -= timeout->time;
|
||||||
t->next->time -= timeout->time;
|
}
|
||||||
}
|
timeout->next = t->next;
|
||||||
timeout->next = t->next;
|
t->next = timeout;
|
||||||
t->next = timeout;
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
181
src/core/tcp.c
181
src/core/tcp.c
@@ -2,10 +2,15 @@
|
|||||||
* @file
|
* @file
|
||||||
*
|
*
|
||||||
* Transmission Control Protocol for IP
|
* Transmission Control Protocol for IP
|
||||||
|
*
|
||||||
|
* This file contains common functions for the TCP implementation, such as functinos
|
||||||
|
* for manipulating the data structures and the TCP timer functions. TCP functions
|
||||||
|
* related to input and output is found in tcp_in.c and tcp_out.c respectively.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -36,17 +41,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* tcp.c
|
|
||||||
*
|
|
||||||
* This file contains common functions for the TCP implementation, such as functinos
|
|
||||||
* for manipulating the data structures and the TCP timer functions. TCP functions
|
|
||||||
* related to input and output is found in tcp_input.c and tcp_output.c respectively.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "lwip/mem.h"
|
#include "lwip/mem.h"
|
||||||
@@ -62,30 +56,28 @@ const u8_t tcp_backoff[13] =
|
|||||||
{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
|
{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
|
||||||
|
|
||||||
/* The TCP PCB lists. */
|
/* The TCP PCB lists. */
|
||||||
struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */
|
|
||||||
struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
|
/** List of all TCP PCBs in LISTEN state */
|
||||||
state in which they accept or send
|
union tcp_listen_pcbs_t tcp_listen_pcbs;
|
||||||
data. */
|
/** List of all TCP PCBs that are in a state in which
|
||||||
struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */
|
* they accept or send data. */
|
||||||
|
struct tcp_pcb *tcp_active_pcbs;
|
||||||
|
/** List of all TCP PCBs in TIME-WAIT state */
|
||||||
|
struct tcp_pcb *tcp_tw_pcbs;
|
||||||
|
|
||||||
struct tcp_pcb *tcp_tmp_pcb;
|
struct tcp_pcb *tcp_tmp_pcb;
|
||||||
|
|
||||||
static u8_t tcp_timer;
|
static u8_t tcp_timer;
|
||||||
|
|
||||||
static u16_t tcp_new_port(void);
|
static u16_t tcp_new_port(void);
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
|
||||||
* tcp_init():
|
|
||||||
*
|
|
||||||
* Initializes the TCP layer.
|
* Initializes the TCP layer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_init(void)
|
tcp_init(void)
|
||||||
{
|
{
|
||||||
/* Clear globals. */
|
/* Clear globals. */
|
||||||
tcp_listen_pcbs = NULL;
|
tcp_listen_pcbs.listen_pcbs = NULL;
|
||||||
tcp_active_pcbs = NULL;
|
tcp_active_pcbs = NULL;
|
||||||
tcp_tw_pcbs = NULL;
|
tcp_tw_pcbs = NULL;
|
||||||
tcp_tmp_pcb = NULL;
|
tcp_tmp_pcb = NULL;
|
||||||
@@ -96,13 +88,10 @@ tcp_init(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_tmr():
|
|
||||||
*
|
|
||||||
* Called periodically to dispatch TCP timers.
|
* Called periodically to dispatch TCP timers.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_tmr(void)
|
tcp_tmr(void)
|
||||||
{
|
{
|
||||||
@@ -116,13 +105,10 @@ tcp_tmr(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_close():
|
|
||||||
*
|
|
||||||
* Closes the connection held by the PCB.
|
* Closes the connection held by the PCB.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
err_t
|
err_t
|
||||||
tcp_close(struct tcp_pcb *pcb)
|
tcp_close(struct tcp_pcb *pcb)
|
||||||
{
|
{
|
||||||
@@ -136,7 +122,7 @@ tcp_close(struct tcp_pcb *pcb)
|
|||||||
switch (pcb->state) {
|
switch (pcb->state) {
|
||||||
case LISTEN:
|
case LISTEN:
|
||||||
err = ERR_OK;
|
err = ERR_OK;
|
||||||
tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs, pcb);
|
tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
|
||||||
memp_free(MEMP_TCP_PCB_LISTEN, pcb);
|
memp_free(MEMP_TCP_PCB_LISTEN, pcb);
|
||||||
pcb = NULL;
|
pcb = NULL;
|
||||||
break;
|
break;
|
||||||
@@ -172,15 +158,12 @@ tcp_close(struct tcp_pcb *pcb)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_abort()
|
|
||||||
*
|
|
||||||
* Aborts a connection by sending a RST to the remote host and deletes
|
* Aborts a connection by sending a RST to the remote host and deletes
|
||||||
* the local protocol control block. This is done when a connection is
|
* the local protocol control block. This is done when a connection is
|
||||||
* killed because of shortage of memory.
|
* killed because of shortage of memory.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_abort(struct tcp_pcb *pcb)
|
tcp_abort(struct tcp_pcb *pcb)
|
||||||
{
|
{
|
||||||
@@ -229,9 +212,7 @@ tcp_abort(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_bind():
|
|
||||||
*
|
|
||||||
* Binds the connection to a local portnumber and IP address. If the
|
* Binds the connection to a local portnumber and IP address. If the
|
||||||
* IP address is not given (i.e., ipaddr == NULL), the IP address of
|
* IP address is not given (i.e., ipaddr == NULL), the IP address of
|
||||||
* the outgoing network interface is used instead.
|
* the outgoing network interface is used instead.
|
||||||
@@ -242,16 +223,16 @@ err_t
|
|||||||
tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
||||||
{
|
{
|
||||||
struct tcp_pcb *cpcb;
|
struct tcp_pcb *cpcb;
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
int reuse_port_all_set = 1;
|
int reuse_port_all_set = 1;
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
|
|
||||||
if (port == 0) {
|
if (port == 0) {
|
||||||
port = tcp_new_port();
|
port = tcp_new_port();
|
||||||
}
|
}
|
||||||
#ifndef SO_REUSE
|
#if SO_REUSE == 0
|
||||||
/* Check if the address already is in use. */
|
/* Check if the address already is in use. */
|
||||||
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs;
|
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;
|
||||||
cpcb != NULL; cpcb = cpcb->next) {
|
cpcb != NULL; cpcb = cpcb->next) {
|
||||||
if (cpcb->local_port == port) {
|
if (cpcb->local_port == port) {
|
||||||
if (ip_addr_isany(&(cpcb->local_ip)) ||
|
if (ip_addr_isany(&(cpcb->local_ip)) ||
|
||||||
@@ -284,7 +265,7 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
|||||||
|
|
||||||
When the two options aren't set and specified port is already bound, ERR_USE is returned saying that
|
When the two options aren't set and specified port is already bound, ERR_USE is returned saying that
|
||||||
address is already in use. */
|
address is already in use. */
|
||||||
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs; cpcb != NULL; cpcb = cpcb->next) {
|
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; cpcb != NULL; cpcb = cpcb->next) {
|
||||||
if(cpcb->local_port == port) {
|
if(cpcb->local_port == port) {
|
||||||
if(ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
|
if(ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
|
||||||
if(pcb->so_options & SOF_REUSEPORT) {
|
if(pcb->so_options & SOF_REUSEPORT) {
|
||||||
@@ -386,16 +367,13 @@ tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
|
|||||||
}
|
}
|
||||||
#endif /* LWIP_CALLBACK_API */
|
#endif /* LWIP_CALLBACK_API */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_listen():
|
|
||||||
*
|
|
||||||
* Set the state of the connection to be LISTEN, which means that it
|
* Set the state of the connection to be LISTEN, which means that it
|
||||||
* is able to accept incoming connections. The protocol control block
|
* is able to accept incoming connections. The protocol control block
|
||||||
* is reallocated in order to consume less memory. Setting the
|
* is reallocated in order to consume less memory. Setting the
|
||||||
* connection to LISTEN is an irreversible process.
|
* connection to LISTEN is an irreversible process.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct tcp_pcb *
|
struct tcp_pcb *
|
||||||
tcp_listen(struct tcp_pcb *pcb)
|
tcp_listen(struct tcp_pcb *pcb)
|
||||||
{
|
{
|
||||||
@@ -421,19 +399,16 @@ tcp_listen(struct tcp_pcb *pcb)
|
|||||||
#if LWIP_CALLBACK_API
|
#if LWIP_CALLBACK_API
|
||||||
lpcb->accept = tcp_accept_null;
|
lpcb->accept = tcp_accept_null;
|
||||||
#endif /* LWIP_CALLBACK_API */
|
#endif /* LWIP_CALLBACK_API */
|
||||||
TCP_REG(&tcp_listen_pcbs, lpcb);
|
TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
|
||||||
return (struct tcp_pcb *)lpcb;
|
return (struct tcp_pcb *)lpcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_recved():
|
|
||||||
*
|
|
||||||
* This function should be called by the application when it has
|
* This function should be called by the application when it has
|
||||||
* processed the data. The purpose is to advertise a larger window
|
* processed the data. The purpose is to advertise a larger window
|
||||||
* when the data has been processed.
|
* when the data has been processed.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
||||||
{
|
{
|
||||||
@@ -444,6 +419,16 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
|||||||
}
|
}
|
||||||
if (!(pcb->flags & TF_ACK_DELAY) &&
|
if (!(pcb->flags & TF_ACK_DELAY) &&
|
||||||
!(pcb->flags & TF_ACK_NOW)) {
|
!(pcb->flags & TF_ACK_NOW)) {
|
||||||
|
/*
|
||||||
|
* We send an ACK here (if one is not already pending, hence
|
||||||
|
* the above tests) as tcp_recved() implies that the application
|
||||||
|
* has processed some data, and so we can open the receiver's
|
||||||
|
* window to allow more to be transmitted. This could result in
|
||||||
|
* two ACKs being sent for each received packet in some limited cases
|
||||||
|
* (where the application is only receiving data, and is slow to
|
||||||
|
* process it) but it is necessary to guarantee that the sender can
|
||||||
|
* continue to transmit.
|
||||||
|
*/
|
||||||
tcp_ack(pcb);
|
tcp_ack(pcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,13 +436,10 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
|
|||||||
len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
|
len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_new_port():
|
|
||||||
*
|
|
||||||
* A nastly hack featuring 'goto' statements that allocates a
|
* A nastly hack featuring 'goto' statements that allocates a
|
||||||
* new TCP local port.
|
* new TCP local port.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static u16_t
|
static u16_t
|
||||||
tcp_new_port(void)
|
tcp_new_port(void)
|
||||||
{
|
{
|
||||||
@@ -483,7 +465,7 @@ tcp_new_port(void)
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) {
|
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
|
||||||
if (pcb->local_port == port) {
|
if (pcb->local_port == port) {
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
@@ -491,14 +473,11 @@ tcp_new_port(void)
|
|||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_connect():
|
|
||||||
*
|
|
||||||
* Connects to another host. The function given as the "connected"
|
* Connects to another host. The function given as the "connected"
|
||||||
* argument will be called when the connection has been established.
|
* argument will be called when the connection has been established.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
err_t
|
err_t
|
||||||
tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
|
tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
|
||||||
err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
|
err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
|
||||||
@@ -546,14 +525,11 @@ tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_slowtmr():
|
|
||||||
*
|
|
||||||
* Called every 500 ms and implements the retransmission timer and the timer that
|
* Called every 500 ms and implements the retransmission timer and the timer that
|
||||||
* removes PCBs that have been in TIME-WAIT for enough time. It also increments
|
* removes PCBs that have been in TIME-WAIT for enough time. It also increments
|
||||||
* various timers such as the inactivity timer in each PCB.
|
* various timers such as the inactivity timer in each PCB.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_slowtmr(void)
|
tcp_slowtmr(void)
|
||||||
{
|
{
|
||||||
@@ -730,12 +706,9 @@ tcp_slowtmr(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_fasttmr():
|
|
||||||
*
|
|
||||||
* Is called every TCP_FAST_INTERVAL (250 ms) and sends delayed ACKs.
|
* Is called every TCP_FAST_INTERVAL (250 ms) and sends delayed ACKs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_fasttmr(void)
|
tcp_fasttmr(void)
|
||||||
{
|
{
|
||||||
@@ -751,13 +724,10 @@ tcp_fasttmr(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_segs_free():
|
|
||||||
*
|
|
||||||
* Deallocates a list of TCP segments (tcp_seg structures).
|
* Deallocates a list of TCP segments (tcp_seg structures).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u8_t
|
u8_t
|
||||||
tcp_segs_free(struct tcp_seg *seg)
|
tcp_segs_free(struct tcp_seg *seg)
|
||||||
{
|
{
|
||||||
@@ -771,13 +741,10 @@ tcp_segs_free(struct tcp_seg *seg)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_seg_free():
|
|
||||||
*
|
|
||||||
* Frees a TCP segment.
|
* Frees a TCP segment.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u8_t
|
u8_t
|
||||||
tcp_seg_free(struct tcp_seg *seg)
|
tcp_seg_free(struct tcp_seg *seg)
|
||||||
{
|
{
|
||||||
@@ -795,13 +762,10 @@ tcp_seg_free(struct tcp_seg *seg)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_setprio():
|
|
||||||
*
|
|
||||||
* Sets the priority of a connection.
|
* Sets the priority of a connection.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
|
tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
|
||||||
{
|
{
|
||||||
@@ -809,13 +773,10 @@ tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
|
|||||||
}
|
}
|
||||||
#if TCP_QUEUE_OOSEQ
|
#if TCP_QUEUE_OOSEQ
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_seg_copy():
|
|
||||||
*
|
|
||||||
* Returns a copy of the given TCP segment.
|
* Returns a copy of the given TCP segment.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct tcp_seg *
|
struct tcp_seg *
|
||||||
tcp_seg_copy(struct tcp_seg *seg)
|
tcp_seg_copy(struct tcp_seg *seg)
|
||||||
{
|
{
|
||||||
@@ -951,12 +912,13 @@ tcp_alloc(u8_t prio)
|
|||||||
return pcb;
|
return pcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_new():
|
|
||||||
*
|
|
||||||
* Creates a new TCP protocol control block but doesn't place it on
|
* Creates a new TCP protocol control block but doesn't place it on
|
||||||
* any of the TCP PCB lists.
|
* any of the TCP PCB lists.
|
||||||
*
|
*
|
||||||
|
* @internal: Maybe there should be a idle TCP PCB list where these
|
||||||
|
* PCBs are put on. We can then implement port reservation using
|
||||||
|
* tcp_bind(). Currently, we lack this (BSD socket type of) feature.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct tcp_pcb *
|
struct tcp_pcb *
|
||||||
@@ -980,14 +942,11 @@ tcp_arg(struct tcp_pcb *pcb, void *arg)
|
|||||||
}
|
}
|
||||||
#if LWIP_CALLBACK_API
|
#if LWIP_CALLBACK_API
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_recv():
|
|
||||||
*
|
|
||||||
* Used to specify the function that should be called when a TCP
|
* Used to specify the function that should be called when a TCP
|
||||||
* connection receives data.
|
* connection receives data.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_recv(struct tcp_pcb *pcb,
|
tcp_recv(struct tcp_pcb *pcb,
|
||||||
err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
|
err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
|
||||||
@@ -995,9 +954,7 @@ tcp_recv(struct tcp_pcb *pcb,
|
|||||||
pcb->recv = recv;
|
pcb->recv = recv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_sent():
|
|
||||||
*
|
|
||||||
* Used to specify the function that should be called when TCP data
|
* Used to specify the function that should be called when TCP data
|
||||||
* has been successfully delivered to the remote host.
|
* has been successfully delivered to the remote host.
|
||||||
*
|
*
|
||||||
@@ -1010,14 +967,11 @@ tcp_sent(struct tcp_pcb *pcb,
|
|||||||
pcb->sent = sent;
|
pcb->sent = sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_err():
|
|
||||||
*
|
|
||||||
* Used to specify the function that should be called when a fatal error
|
* Used to specify the function that should be called when a fatal error
|
||||||
* has occured on the connection.
|
* has occured on the connection.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_err(struct tcp_pcb *pcb,
|
tcp_err(struct tcp_pcb *pcb,
|
||||||
void (* errf)(void *arg, err_t err))
|
void (* errf)(void *arg, err_t err))
|
||||||
@@ -1025,14 +979,11 @@ tcp_err(struct tcp_pcb *pcb,
|
|||||||
pcb->errf = errf;
|
pcb->errf = errf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_accept():
|
|
||||||
*
|
|
||||||
* Used for specifying the function that should be called when a
|
* Used for specifying the function that should be called when a
|
||||||
* LISTENing connection has been connected to another host.
|
* LISTENing connection has been connected to another host.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_accept(struct tcp_pcb *pcb,
|
tcp_accept(struct tcp_pcb *pcb,
|
||||||
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
|
err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
|
||||||
@@ -1042,15 +993,12 @@ tcp_accept(struct tcp_pcb *pcb,
|
|||||||
#endif /* LWIP_CALLBACK_API */
|
#endif /* LWIP_CALLBACK_API */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_poll():
|
|
||||||
*
|
|
||||||
* Used to specify the function that should be called periodically
|
* Used to specify the function that should be called periodically
|
||||||
* from TCP. The interval is specified in terms of the TCP coarse
|
* from TCP. The interval is specified in terms of the TCP coarse
|
||||||
* timer interval, which is called twice a second.
|
* timer interval, which is called twice a second.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_poll(struct tcp_pcb *pcb,
|
tcp_poll(struct tcp_pcb *pcb,
|
||||||
err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
|
err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
|
||||||
@@ -1061,13 +1009,10 @@ tcp_poll(struct tcp_pcb *pcb,
|
|||||||
pcb->pollinterval = interval;
|
pcb->pollinterval = interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_pcb_purge():
|
|
||||||
*
|
|
||||||
* Purges a TCP PCB. Removes any buffered data and frees the buffer memory.
|
* Purges a TCP PCB. Removes any buffered data and frees the buffer memory.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_pcb_purge(struct tcp_pcb *pcb)
|
tcp_pcb_purge(struct tcp_pcb *pcb)
|
||||||
{
|
{
|
||||||
@@ -1097,13 +1042,10 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_pcb_remove():
|
|
||||||
*
|
|
||||||
* Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
|
* Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
|
tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
|
||||||
{
|
{
|
||||||
@@ -1123,13 +1065,10 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
|
|||||||
LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
|
LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* tcp_next_iss():
|
|
||||||
*
|
|
||||||
* Calculates a new initial sequence number for new connections.
|
* Calculates a new initial sequence number for new connections.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u32_t
|
u32_t
|
||||||
tcp_next_iss(void)
|
tcp_next_iss(void)
|
||||||
{
|
{
|
||||||
@@ -1253,7 +1192,7 @@ tcp_debug_print_pcbs(void)
|
|||||||
tcp_debug_print_state(pcb->state);
|
tcp_debug_print_state(pcb->state);
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
|
LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
|
||||||
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) {
|
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
|
||||||
LWIP_DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
|
LWIP_DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
|
||||||
pcb->local_port, pcb->remote_port,
|
pcb->local_port, pcb->remote_port,
|
||||||
pcb->snd_nxt, pcb->rcv_nxt));
|
pcb->snd_nxt, pcb->rcv_nxt));
|
||||||
|
|||||||
@@ -2,10 +2,16 @@
|
|||||||
* @file
|
* @file
|
||||||
*
|
*
|
||||||
* Transmission Control Protocol, incoming traffic
|
* Transmission Control Protocol, incoming traffic
|
||||||
|
*
|
||||||
|
* The input processing functions of TCP.
|
||||||
|
*
|
||||||
|
* These functions are generally called in the order (ip_input() ->) tcp_input() ->
|
||||||
|
* tcp_process() -> tcp_receive() (-> application).
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -36,21 +42,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* tcp_input.c
|
|
||||||
*
|
|
||||||
* The input processing functions of TCP.
|
|
||||||
*
|
|
||||||
* These functions are generally called in the order (ip_input() ->) tcp_input() ->
|
|
||||||
* tcp_process() -> tcp_receive() (-> application).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
#include "lwip/mem.h"
|
#include "lwip/mem.h"
|
||||||
#include "lwip/memp.h"
|
#include "lwip/memp.h"
|
||||||
@@ -102,7 +97,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
u8_t hdrlen;
|
u8_t hdrlen;
|
||||||
err_t err;
|
err_t err;
|
||||||
|
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
struct tcp_pcb *pcb_temp;
|
struct tcp_pcb *pcb_temp;
|
||||||
int reuse = 0;
|
int reuse = 0;
|
||||||
int reuse_port = 0;
|
int reuse_port = 0;
|
||||||
@@ -130,12 +125,13 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Don't even process incoming broadcasts/multicasts. */
|
/* Don't even process incoming broadcasts/multicasts. */
|
||||||
if (ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||
|
if (ip_addr_isbroadcast(&(iphdr->dest), inp) ||
|
||||||
ip_addr_ismulticast(&(iphdr->dest))) {
|
ip_addr_ismulticast(&(iphdr->dest))) {
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CHECKSUM_CHECK_TCP
|
||||||
/* Verify TCP checksum. */
|
/* Verify TCP checksum. */
|
||||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||||
(struct ip_addr *)&(iphdr->dest),
|
(struct ip_addr *)&(iphdr->dest),
|
||||||
@@ -152,7 +148,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Move the payload pointer in the pbuf so that it points to the
|
/* Move the payload pointer in the pbuf so that it points to the
|
||||||
TCP data instead of the TCP header. */
|
TCP data instead of the TCP header. */
|
||||||
@@ -173,7 +169,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
for an active connection. */
|
for an active connection. */
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
|
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
pcb_temp = tcp_active_pcbs;
|
pcb_temp = tcp_active_pcbs;
|
||||||
|
|
||||||
again_1:
|
again_1:
|
||||||
@@ -191,7 +187,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
|
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
|
||||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
|
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
|
||||||
|
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
if(pcb->so_options & SOF_REUSEPORT) {
|
if(pcb->so_options & SOF_REUSEPORT) {
|
||||||
if(reuse) {
|
if(reuse) {
|
||||||
/* We processed one PCB already */
|
/* We processed one PCB already */
|
||||||
@@ -255,7 +251,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
/* Finally, if we still did not get a match, we check all PCBs that
|
/* Finally, if we still did not get a match, we check all PCBs that
|
||||||
are LISTENing for incoming connections. */
|
are LISTENing for incoming connections. */
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||||
if ((ip_addr_isany(&(lpcb->local_ip)) ||
|
if ((ip_addr_isany(&(lpcb->local_ip)) ||
|
||||||
ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
|
ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
|
||||||
lpcb->local_port == tcphdr->dest) {
|
lpcb->local_port == tcphdr->dest) {
|
||||||
@@ -265,9 +261,9 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
if (prev != NULL) {
|
if (prev != NULL) {
|
||||||
((struct tcp_pcb_listen *)prev)->next = lpcb->next;
|
((struct tcp_pcb_listen *)prev)->next = lpcb->next;
|
||||||
/* our successor is the remainder of the listening list */
|
/* our successor is the remainder of the listening list */
|
||||||
lpcb->next = tcp_listen_pcbs;
|
lpcb->next = tcp_listen_pcbs.listen_pcbs;
|
||||||
/* put this listening pcb at the head of the listening list */
|
/* put this listening pcb at the head of the listening list */
|
||||||
tcp_listen_pcbs = lpcb;
|
tcp_listen_pcbs.listen_pcbs = lpcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
|
||||||
@@ -361,7 +357,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
tcp_debug_print_state(pcb->state);
|
tcp_debug_print_state(pcb->state);
|
||||||
#endif /* TCP_DEBUG */
|
#endif /* TCP_DEBUG */
|
||||||
#endif /* TCP_INPUT_DEBUG */
|
#endif /* TCP_INPUT_DEBUG */
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
/* First socket should receive now */
|
/* First socket should receive now */
|
||||||
if(reuse_port) {
|
if(reuse_port) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n"));
|
||||||
@@ -373,7 +369,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
if(reuse) {
|
if(reuse) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
@@ -392,7 +388,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
}
|
}
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
}
|
}
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
end:
|
end:
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
|
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
|
||||||
|
|||||||
@@ -2,9 +2,13 @@
|
|||||||
* @file
|
* @file
|
||||||
*
|
*
|
||||||
* Transmission Control Protocol, outgoing traffic
|
* Transmission Control Protocol, outgoing traffic
|
||||||
|
*
|
||||||
|
* The output functions of TCP.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -35,15 +39,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* tcp_output.c
|
|
||||||
*
|
|
||||||
* The output functions of TCP.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
@@ -51,6 +46,7 @@
|
|||||||
#include "lwip/memp.h"
|
#include "lwip/memp.h"
|
||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
#include "lwip/inet.h"
|
#include "lwip/inet.h"
|
||||||
@@ -63,8 +59,6 @@
|
|||||||
/* Forward declarations.*/
|
/* Forward declarations.*/
|
||||||
static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
|
static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_t
|
err_t
|
||||||
tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
|
tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
|
||||||
{
|
{
|
||||||
@@ -72,6 +66,14 @@ tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NB. tcp_write() enqueues data for sending, but does not send it
|
||||||
|
* straight away. It waits in the expectation of more data being sent
|
||||||
|
* soon (as it can send them more efficiently by combining them
|
||||||
|
* together). To prompt the system to send data now, call
|
||||||
|
* tcp_output() after calling tcp_write().
|
||||||
|
*/
|
||||||
|
|
||||||
err_t
|
err_t
|
||||||
tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
|
tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
|
||||||
{
|
{
|
||||||
@@ -400,9 +402,10 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
TCPH_HDRLEN_SET(tcphdr, 5);
|
TCPH_HDRLEN_SET(tcphdr, 5);
|
||||||
|
|
||||||
tcphdr->chksum = 0;
|
tcphdr->chksum = 0;
|
||||||
|
#if CHECKSUM_GEN_TCP
|
||||||
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
||||||
IP_PROTO_TCP, p->tot_len);
|
IP_PROTO_TCP, p->tot_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
|
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
|
||||||
IP_PROTO_TCP);
|
IP_PROTO_TCP);
|
||||||
@@ -518,10 +521,12 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
|||||||
seg->p->payload = seg->tcphdr;
|
seg->p->payload = seg->tcphdr;
|
||||||
|
|
||||||
seg->tcphdr->chksum = 0;
|
seg->tcphdr->chksum = 0;
|
||||||
|
#if CHECKSUM_GEN_TCP
|
||||||
seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
|
seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
|
||||||
&(pcb->local_ip),
|
&(pcb->local_ip),
|
||||||
&(pcb->remote_ip),
|
&(pcb->remote_ip),
|
||||||
IP_PROTO_TCP, seg->p->tot_len);
|
IP_PROTO_TCP, seg->p->tot_len);
|
||||||
|
#endif
|
||||||
TCP_STATS_INC(tcp.xmit);
|
TCP_STATS_INC(tcp.xmit);
|
||||||
|
|
||||||
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
|
ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
|
||||||
@@ -552,9 +557,10 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
|||||||
TCPH_HDRLEN_SET(tcphdr, 5);
|
TCPH_HDRLEN_SET(tcphdr, 5);
|
||||||
|
|
||||||
tcphdr->chksum = 0;
|
tcphdr->chksum = 0;
|
||||||
|
#if CHECKSUM_GEN_TCP
|
||||||
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
|
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
|
||||||
IP_PROTO_TCP, p->tot_len);
|
IP_PROTO_TCP, p->tot_len);
|
||||||
|
#endif
|
||||||
TCP_STATS_INC(tcp.xmit);
|
TCP_STATS_INC(tcp.xmit);
|
||||||
/* Send output with hardcoded TTL since we have no access to the pcb */
|
/* Send output with hardcoded TTL since we have no access to the pcb */
|
||||||
ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
|
ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP);
|
||||||
@@ -621,8 +627,9 @@ tcp_keepalive(struct tcp_pcb *pcb)
|
|||||||
TCPH_HDRLEN_SET(tcphdr, 5);
|
TCPH_HDRLEN_SET(tcphdr, 5);
|
||||||
|
|
||||||
tcphdr->chksum = 0;
|
tcphdr->chksum = 0;
|
||||||
|
#if CHECKSUM_GEN_TCP
|
||||||
tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, IP_PROTO_TCP, p->tot_len);
|
tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, IP_PROTO_TCP, p->tot_len);
|
||||||
|
#endif
|
||||||
TCP_STATS_INC(tcp.xmit);
|
TCP_STATS_INC(tcp.xmit);
|
||||||
|
|
||||||
/* Send output to IP */
|
/* Send output to IP */
|
||||||
|
|||||||
187
src/core/udp.c
187
src/core/udp.c
@@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -47,10 +47,10 @@
|
|||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "lwip/memp.h"
|
#include "lwip/memp.h"
|
||||||
#include "lwip/inet.h"
|
#include "lwip/inet.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
#include "lwip/udp.h"
|
#include "lwip/udp.h"
|
||||||
#include "lwip/icmp.h"
|
#include "lwip/icmp.h"
|
||||||
#include "lwip/ip_addr.h"
|
|
||||||
|
|
||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
|
|
||||||
@@ -71,76 +71,6 @@ udp_init(void)
|
|||||||
udp_pcbs = pcb_cache = NULL;
|
udp_pcbs = pcb_cache = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* udp_lookup:
|
|
||||||
*
|
|
||||||
* An experimental feature that will be changed in future versions. Do
|
|
||||||
* not depend on it yet...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef LWIP_DEBUG
|
|
||||||
u8_t
|
|
||||||
udp_lookup(struct ip_hdr *iphdr, struct netif *inp)
|
|
||||||
{
|
|
||||||
struct udp_pcb *pcb;
|
|
||||||
struct udp_hdr *udphdr;
|
|
||||||
u16_t src, dest;
|
|
||||||
|
|
||||||
PERF_START;
|
|
||||||
(void)inp;
|
|
||||||
|
|
||||||
udphdr = (struct udp_hdr *)(u8_t *)iphdr + IPH_HL(iphdr) * 4;
|
|
||||||
|
|
||||||
src = ntohs(udphdr->src);
|
|
||||||
dest = ntohs(udphdr->dest);
|
|
||||||
|
|
||||||
pcb = pcb_cache;
|
|
||||||
if (pcb != NULL &&
|
|
||||||
pcb->remote_port == src &&
|
|
||||||
pcb->local_port == dest &&
|
|
||||||
(ip_addr_isany(&pcb->remote_ip) ||
|
|
||||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
|
||||||
(ip_addr_isany(&pcb->local_ip) ||
|
|
||||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
|
|
||||||
if (pcb->remote_port == src &&
|
|
||||||
pcb->local_port == dest &&
|
|
||||||
(ip_addr_isany(&pcb->remote_ip) ||
|
|
||||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
|
||||||
(ip_addr_isany(&pcb->local_ip) ||
|
|
||||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
|
||||||
pcb_cache = pcb;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pcb == NULL) {
|
|
||||||
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
|
|
||||||
if (pcb->remote_port == 0 &&
|
|
||||||
pcb->local_port == dest &&
|
|
||||||
(ip_addr_isany(&pcb->remote_ip) ||
|
|
||||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
|
|
||||||
(ip_addr_isany(&pcb->local_ip) ||
|
|
||||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PERF_STOP("udp_lookup");
|
|
||||||
|
|
||||||
if (pcb != NULL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* LWIP_DEBUG */
|
|
||||||
/**
|
/**
|
||||||
* Process an incoming UDP datagram.
|
* Process an incoming UDP datagram.
|
||||||
*
|
*
|
||||||
@@ -159,7 +89,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
struct ip_hdr *iphdr;
|
struct ip_hdr *iphdr;
|
||||||
u16_t src, dest;
|
u16_t src, dest;
|
||||||
|
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
struct udp_pcb *pcb_temp;
|
struct udp_pcb *pcb_temp;
|
||||||
int reuse = 0;
|
int reuse = 0;
|
||||||
int reuse_port_1 = 0;
|
int reuse_port_1 = 0;
|
||||||
@@ -198,7 +128,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
|
ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
|
||||||
ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
|
ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
|
||||||
|
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
pcb_temp = udp_pcbs;
|
pcb_temp = udp_pcbs;
|
||||||
|
|
||||||
again_1:
|
again_1:
|
||||||
@@ -228,7 +158,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
(ip_addr_isany(&pcb->local_ip) ||
|
(ip_addr_isany(&pcb->local_ip) ||
|
||||||
/* PCB local IP address matches UDP destination IP address? */
|
/* PCB local IP address matches UDP destination IP address? */
|
||||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
if(pcb->so_options & SOF_REUSEPORT) {
|
if(pcb->so_options & SOF_REUSEPORT) {
|
||||||
if(reuse) {
|
if(reuse) {
|
||||||
/* We processed one PCB already */
|
/* We processed one PCB already */
|
||||||
@@ -257,7 +187,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
/* Iterate through the UDP PCB list for a pcb that matches
|
/* Iterate through the UDP PCB list for a pcb that matches
|
||||||
the local address. */
|
the local address. */
|
||||||
|
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
pcb_temp = udp_pcbs;
|
pcb_temp = udp_pcbs;
|
||||||
|
|
||||||
again_2:
|
again_2:
|
||||||
@@ -279,7 +209,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
(ip_addr_isany(&pcb->local_ip) ||
|
(ip_addr_isany(&pcb->local_ip) ||
|
||||||
/* ...matching interface address? */
|
/* ...matching interface address? */
|
||||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
if(pcb->so_options & SOF_REUSEPORT) {
|
if(pcb->so_options & SOF_REUSEPORT) {
|
||||||
if(reuse) {
|
if(reuse) {
|
||||||
/* We processed one PCB already */
|
/* We processed one PCB already */
|
||||||
@@ -316,6 +246,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
|
if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
|
||||||
#endif /* IPv4 */
|
#endif /* IPv4 */
|
||||||
/* Do the UDP Lite checksum */
|
/* Do the UDP Lite checksum */
|
||||||
|
#if CHECKSUM_CHECK_UDP
|
||||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||||
(struct ip_addr *)&(iphdr->dest),
|
(struct ip_addr *)&(iphdr->dest),
|
||||||
IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
|
IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
|
||||||
@@ -326,7 +257,9 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#if CHECKSUM_CHECK_UDP
|
||||||
if (udphdr->chksum != 0) {
|
if (udphdr->chksum != 0) {
|
||||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||||
(struct ip_addr *)&(iphdr->dest),
|
(struct ip_addr *)&(iphdr->dest),
|
||||||
@@ -340,12 +273,13 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
pbuf_header(p, -UDP_HLEN);
|
pbuf_header(p, -UDP_HLEN);
|
||||||
if (pcb != NULL) {
|
if (pcb != NULL) {
|
||||||
snmp_inc_udpindatagrams();
|
snmp_inc_udpindatagrams();
|
||||||
pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
|
pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
/* First socket should receive now */
|
/* First socket should receive now */
|
||||||
if(reuse_port_1 || reuse_port_2) {
|
if(reuse_port_1 || reuse_port_2) {
|
||||||
/* We want to search on next socket after receiving */
|
/* We want to search on next socket after receiving */
|
||||||
@@ -365,7 +299,7 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
}
|
}
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
} else {
|
} else {
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
if(reuse) {
|
if(reuse) {
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
@@ -375,10 +309,10 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
|
LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
|
||||||
|
|
||||||
/* No match was found, send ICMP destination port unreachable unless
|
/* No match was found, send ICMP destination port unreachable unless
|
||||||
destination address was broadcast/multicast. */
|
destination address was broadcast/multicast. */
|
||||||
|
|
||||||
if (!ip_addr_isbroadcast(&iphdr->dest, &inp->netmask) &&
|
if (!ip_addr_isbroadcast(&iphdr->dest, inp) &&
|
||||||
!ip_addr_ismulticast(&iphdr->dest)) {
|
!ip_addr_ismulticast(&iphdr->dest)) {
|
||||||
|
|
||||||
/* adjust pbuf pointer */
|
/* adjust pbuf pointer */
|
||||||
p->payload = iphdr;
|
p->payload = iphdr;
|
||||||
@@ -396,6 +330,46 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
|
|
||||||
PERF_STOP("udp_input");
|
PERF_STOP("udp_input");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data to a specified address using UDP.
|
||||||
|
*
|
||||||
|
* @param pcb UDP PCB used to send the data.
|
||||||
|
* @param pbuf chain of pbuf's to be sent.
|
||||||
|
* @param dst_ip Destination IP address.
|
||||||
|
* @param dst_port Destination UDP port.
|
||||||
|
*
|
||||||
|
* If the PCB already has a remote address association, it will
|
||||||
|
* be restored after the data is sent.
|
||||||
|
*
|
||||||
|
* @return lwIP error code.
|
||||||
|
* - ERR_OK. Successful. No error occured.
|
||||||
|
* - ERR_MEM. Out of memory.
|
||||||
|
* - ERR_RTE. Could not find route to destination address.
|
||||||
|
*
|
||||||
|
* @see udp_disconnect() udp_send()
|
||||||
|
*/
|
||||||
|
err_t
|
||||||
|
udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
|
||||||
|
struct ip_addr *dst_ip, u16_t dst_port)
|
||||||
|
{
|
||||||
|
err_t err;
|
||||||
|
struct ip_addr pcb_remote_ip;
|
||||||
|
u16_t pcb_remote_port;
|
||||||
|
/* remember remote peer address of PCB */
|
||||||
|
pcb_remote_ip.addr = pcb->remote_ip.addr;
|
||||||
|
pcb_remote_port = pcb->remote_port;
|
||||||
|
/* copy packet destination address to PCB remote peer address */
|
||||||
|
pcb->remote_ip.addr = dst_ip->addr;
|
||||||
|
pcb->remote_port = dst_port;
|
||||||
|
/* send to the packet destination address */
|
||||||
|
err = udp_send(pcb, p);
|
||||||
|
/* reset PCB remote peer address */
|
||||||
|
pcb->remote_ip.addr = pcb_remote_ip.addr;
|
||||||
|
pcb->remote_port = pcb_remote_port;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send data using UDP.
|
* Send data using UDP.
|
||||||
*
|
*
|
||||||
@@ -405,10 +379,9 @@ udp_input(struct pbuf *p, struct netif *inp)
|
|||||||
* @return lwIP error code.
|
* @return lwIP error code.
|
||||||
* - ERR_OK. Successful. No error occured.
|
* - ERR_OK. Successful. No error occured.
|
||||||
* - ERR_MEM. Out of memory.
|
* - ERR_MEM. Out of memory.
|
||||||
* - ERR_USE. The specified ipaddr and port are already bound to by
|
* - ERR_RTE. Could not find route to destination address.
|
||||||
* another UDP PCB.
|
|
||||||
*
|
*
|
||||||
* @see udp_disconnect()
|
* @see udp_disconnect() udp_sendto()
|
||||||
*/
|
*/
|
||||||
err_t
|
err_t
|
||||||
udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||||
@@ -433,7 +406,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
|||||||
|
|
||||||
/* not enough space to add an UDP header to first pbuf in given p chain? */
|
/* not enough space to add an UDP header to first pbuf in given p chain? */
|
||||||
if (pbuf_header(p, UDP_HLEN)) {
|
if (pbuf_header(p, UDP_HLEN)) {
|
||||||
/* allocate header in new pbuf */
|
/* allocate header in a seperate new pbuf */
|
||||||
q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
|
q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
|
||||||
/* new header pbuf could not be allocated? */
|
/* new header pbuf could not be allocated? */
|
||||||
if (q == NULL) {
|
if (q == NULL) {
|
||||||
@@ -445,23 +418,25 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
|||||||
/* { first pbuf q points to header pbuf } */
|
/* { first pbuf q points to header pbuf } */
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
||||||
/* adding a header within p succeeded */
|
/* adding a header within p succeeded */
|
||||||
} else {
|
} else {
|
||||||
/* first pbuf q equals given pbuf */
|
/* first pbuf q equals given pbuf */
|
||||||
q = p;
|
q = p;
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
|
||||||
}
|
}
|
||||||
/* { q now represents the packet to be sent */
|
/* { q now represents the packet to be sent } */
|
||||||
udphdr = q->payload;
|
udphdr = q->payload;
|
||||||
udphdr->src = htons(pcb->local_port);
|
udphdr->src = htons(pcb->local_port);
|
||||||
udphdr->dest = htons(pcb->remote_port);
|
udphdr->dest = htons(pcb->remote_port);
|
||||||
udphdr->chksum = 0x0000;
|
/* in UDP, 0 checksum means 'no checksum' */
|
||||||
|
udphdr->chksum = 0x0000;
|
||||||
|
|
||||||
|
/* find the outgoing network interface for this packet */
|
||||||
if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
|
if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
|
||||||
LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
|
LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
|
||||||
UDP_STATS_INC(udp.rterr);
|
UDP_STATS_INC(udp.rterr);
|
||||||
return ERR_RTE;
|
return ERR_RTE;
|
||||||
}
|
}
|
||||||
/* using IP_ANY_ADDR? */
|
/* PCB local address is IP_ANY_ADDR? */
|
||||||
if (ip_addr_isany(&pcb->local_ip)) {
|
if (ip_addr_isany(&pcb->local_ip)) {
|
||||||
/* use outgoing network interface IP address as source address */
|
/* use outgoing network interface IP address as source address */
|
||||||
src_ip = &(netif->ip_addr);
|
src_ip = &(netif->ip_addr);
|
||||||
@@ -478,34 +453,44 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
|||||||
/* set UDP message length in UDP header */
|
/* set UDP message length in UDP header */
|
||||||
udphdr->len = htons(pcb->chksum_len);
|
udphdr->len = htons(pcb->chksum_len);
|
||||||
/* calculate checksum */
|
/* calculate checksum */
|
||||||
|
#if CHECKSUM_GEN_UDP
|
||||||
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
|
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
|
||||||
IP_PROTO_UDP, pcb->chksum_len);
|
IP_PROTO_UDP, pcb->chksum_len);
|
||||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||||
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
||||||
|
#else
|
||||||
|
udphdr->chksum = 0x0000;
|
||||||
|
#endif
|
||||||
/* output to IP */
|
/* output to IP */
|
||||||
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
|
||||||
err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
|
err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
|
||||||
snmp_inc_udpoutdatagrams();
|
/* UDP */
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
|
||||||
udphdr->len = htons(q->tot_len);
|
udphdr->len = htons(q->tot_len);
|
||||||
/* calculate checksum */
|
/* calculate checksum */
|
||||||
|
#if CHECKSUM_GEN_UDP
|
||||||
if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
|
if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
|
||||||
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);
|
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);
|
||||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||||
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
udphdr->chksum = 0x0000;
|
||||||
|
#endif
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));
|
||||||
snmp_inc_udpoutdatagrams();
|
|
||||||
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
|
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
|
||||||
/* output to IP */
|
/* output to IP */
|
||||||
err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
|
err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
|
||||||
}
|
}
|
||||||
|
/* TODO: must this be increased even if error occured? */
|
||||||
|
snmp_inc_udpoutdatagrams();
|
||||||
|
|
||||||
/* did we chain a header earlier? */
|
/* did we chain a seperate header pbuf earlier? */
|
||||||
if (q != p) {
|
if (q != p) {
|
||||||
/* free the header */
|
/* free the header pbuf */
|
||||||
/* p is also still referenced by the caller, and will live on */
|
pbuf_free(q); q = NULL;
|
||||||
pbuf_free(q);
|
/* { p is still referenced by the caller, and will live on } */
|
||||||
}
|
}
|
||||||
|
|
||||||
UDP_STATS_INC(udp.xmit);
|
UDP_STATS_INC(udp.xmit);
|
||||||
@@ -532,7 +517,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
|||||||
{
|
{
|
||||||
struct udp_pcb *ipcb;
|
struct udp_pcb *ipcb;
|
||||||
u8_t rebind;
|
u8_t rebind;
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
int reuse_port_all_set = 1;
|
int reuse_port_all_set = 1;
|
||||||
#endif /* SO_REUSE */
|
#endif /* SO_REUSE */
|
||||||
LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));
|
LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));
|
||||||
@@ -550,7 +535,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
|||||||
rebind = 1;
|
rebind = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SO_REUSE
|
#if SO_REUSE == 0
|
||||||
/* this code does not allow upper layer to share a UDP port for
|
/* this code does not allow upper layer to share a UDP port for
|
||||||
listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
|
listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
|
||||||
SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
|
SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
|
||||||
@@ -604,7 +589,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SO_REUSE
|
#if SO_REUSE
|
||||||
/* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then
|
/* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then
|
||||||
{IP, port} can't be reused. */
|
{IP, port} can't be reused. */
|
||||||
if(!reuse_port_all_set) {
|
if(!reuse_port_all_set) {
|
||||||
@@ -717,6 +702,10 @@ udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
|
|||||||
void
|
void
|
||||||
udp_disconnect(struct udp_pcb *pcb)
|
udp_disconnect(struct udp_pcb *pcb)
|
||||||
{
|
{
|
||||||
|
/* reset remote address association */
|
||||||
|
ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
|
||||||
|
pcb->remote_port = 0;
|
||||||
|
/* mark PCB as unconnected */
|
||||||
pcb->flags &= ~UDP_FLAGS_CONNECTED;
|
pcb->flags &= ~UDP_FLAGS_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
#include "lwip/pbuf.h"
|
#include "lwip/pbuf.h"
|
||||||
|
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
#define ICMP_ER 0 /* echo reply */
|
#define ICMP_ER 0 /* echo reply */
|
||||||
@@ -70,36 +71,24 @@ void icmp_input(struct pbuf *p, struct netif *inp);
|
|||||||
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
|
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
|
||||||
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
|
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
|
||||||
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/bpstruct.h"
|
|
||||||
#endif
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct icmp_echo_hdr {
|
struct icmp_echo_hdr {
|
||||||
PACK_STRUCT_FIELD(u16_t _type_code);
|
u16_t _type_code;
|
||||||
PACK_STRUCT_FIELD(u16_t chksum);
|
u16_t chksum;
|
||||||
PACK_STRUCT_FIELD(u16_t id);
|
u16_t id;
|
||||||
PACK_STRUCT_FIELD(u16_t seqno);
|
u16_t seqno;
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct icmp_dur_hdr {
|
struct icmp_dur_hdr {
|
||||||
PACK_STRUCT_FIELD(u16_t _type_code);
|
u16_t _type_code;
|
||||||
PACK_STRUCT_FIELD(u16_t chksum);
|
u16_t chksum;
|
||||||
PACK_STRUCT_FIELD(u32_t unused);
|
u32_t unused;
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct icmp_te_hdr {
|
struct icmp_te_hdr {
|
||||||
PACK_STRUCT_FIELD(u16_t _type_code);
|
u16_t _type_code;
|
||||||
PACK_STRUCT_FIELD(u16_t chksum);
|
u16_t chksum;
|
||||||
PACK_STRUCT_FIELD(u32_t unused);
|
u32_t unused;
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/epstruct.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ICMPH_TYPE(hdr) (ntohs((hdr)->_type_code) >> 8)
|
#define ICMPH_TYPE(hdr) (ntohs((hdr)->_type_code) >> 8)
|
||||||
#define ICMPH_CODE(hdr) (ntohs((hdr)->_type_code) & 0xff)
|
#define ICMPH_CODE(hdr) (ntohs((hdr)->_type_code) & 0xff)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -46,7 +46,7 @@ u16_t inet_chksum_pseudo(struct pbuf *p,
|
|||||||
|
|
||||||
u32_t inet_addr(const char *cp);
|
u32_t inet_addr(const char *cp);
|
||||||
int inet_aton(const char *cp, struct in_addr *addr);
|
int inet_aton(const char *cp, struct in_addr *addr);
|
||||||
u8_t *inet_ntoa(u32_t addr); /* returns ptr to static buffer; not reentrant! */
|
char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */
|
||||||
|
|
||||||
#ifdef htons
|
#ifdef htons
|
||||||
#undef htons
|
#undef htons
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -43,7 +43,6 @@
|
|||||||
struct netif;
|
struct netif;
|
||||||
|
|
||||||
void ip_init(void);
|
void ip_init(void);
|
||||||
u8_t ip_lookup(void *header, struct netif *inp);
|
|
||||||
struct netif *ip_route(struct ip_addr *dest);
|
struct netif *ip_route(struct ip_addr *dest);
|
||||||
err_t ip_input(struct pbuf *p, struct netif *inp);
|
err_t ip_input(struct pbuf *p, struct netif *inp);
|
||||||
err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
||||||
@@ -95,37 +94,27 @@ err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
|||||||
#define SOF_OOBINLINE (u16_t)0x0100U /* leave received OOB data in line */
|
#define SOF_OOBINLINE (u16_t)0x0100U /* leave received OOB data in line */
|
||||||
#define SOF_REUSEPORT (u16_t)0x0200U /* allow local address & port reuse */
|
#define SOF_REUSEPORT (u16_t)0x0200U /* allow local address & port reuse */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/bpstruct.h"
|
|
||||||
#endif
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct ip_hdr {
|
struct ip_hdr {
|
||||||
/* version / header length / type of service */
|
/* version / header length / type of service */
|
||||||
PACK_STRUCT_FIELD(u16_t _v_hl_tos);
|
u16_t _v_hl_tos;
|
||||||
/* total length */
|
/* total length */
|
||||||
PACK_STRUCT_FIELD(u16_t _len);
|
u16_t _len;
|
||||||
/* identification */
|
/* identification */
|
||||||
PACK_STRUCT_FIELD(u16_t _id);
|
u16_t _id;
|
||||||
/* fragment offset field */
|
/* fragment offset field */
|
||||||
PACK_STRUCT_FIELD(u16_t _offset);
|
u16_t _offset;
|
||||||
#define IP_RF 0x8000 /* reserved fragment flag */
|
#define IP_RF 0x8000 /* reserved fragment flag */
|
||||||
#define IP_DF 0x4000 /* dont fragment flag */
|
#define IP_DF 0x4000 /* dont fragment flag */
|
||||||
#define IP_MF 0x2000 /* more fragments flag */
|
#define IP_MF 0x2000 /* more fragments flag */
|
||||||
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
|
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
|
||||||
/* time to live / protocol*/
|
/* time to live / protocol*/
|
||||||
PACK_STRUCT_FIELD(u16_t _ttl_proto);
|
u16_t _ttl_proto;
|
||||||
/* checksum */
|
/* checksum */
|
||||||
PACK_STRUCT_FIELD(u16_t _chksum);
|
u16_t _chksum;
|
||||||
/* source and destination IP addresses */
|
/* source and destination IP addresses */
|
||||||
PACK_STRUCT_FIELD(struct ip_addr src);
|
struct ip_addr src;
|
||||||
PACK_STRUCT_FIELD(struct ip_addr dest);
|
struct ip_addr dest;
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/epstruct.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IPH_V(hdr) (ntohs((hdr)->_v_hl_tos) >> 12)
|
#define IPH_V(hdr) (ntohs((hdr)->_v_hl_tos) >> 12)
|
||||||
#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
|
#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -34,6 +34,24 @@
|
|||||||
|
|
||||||
#include "lwip/arch.h"
|
#include "lwip/arch.h"
|
||||||
|
|
||||||
|
struct ip_addr {
|
||||||
|
u32_t addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip_addr2 {
|
||||||
|
u16_t addrw[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* For compatibility with BSD code */
|
||||||
|
struct in_addr {
|
||||||
|
u32_t s_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct netif;
|
||||||
|
|
||||||
|
extern const struct ip_addr ip_addr_any;
|
||||||
|
extern const struct ip_addr ip_addr_broadcast;
|
||||||
|
|
||||||
/** IP_ADDR_ can be used as a fixed IP address
|
/** IP_ADDR_ can be used as a fixed IP address
|
||||||
* for the wildcard and the broadcast address
|
* for the wildcard and the broadcast address
|
||||||
*/
|
*/
|
||||||
@@ -76,32 +94,13 @@
|
|||||||
|
|
||||||
#define IN_LOOPBACKNET 127 /* official! */
|
#define IN_LOOPBACKNET 127 /* official! */
|
||||||
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/bpstruct.h"
|
|
||||||
#endif
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct ip_addr {
|
|
||||||
PACK_STRUCT_FIELD(u32_t addr);
|
|
||||||
} PACK_STRUCT_STRUCT;
|
|
||||||
PACK_STRUCT_END
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/epstruct.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For compatibility with BSD code */
|
|
||||||
struct in_addr {
|
|
||||||
u32_t s_addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct ip_addr ip_addr_any;
|
|
||||||
extern const struct ip_addr ip_addr_broadcast;
|
|
||||||
|
|
||||||
#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = htonl(((u32_t)(a & 0xff) << 24) | ((u32_t)(b & 0xff) << 16) | \
|
#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = htonl(((u32_t)(a & 0xff) << 24) | ((u32_t)(b & 0xff) << 16) | \
|
||||||
((u32_t)(c & 0xff) << 8) | (u32_t)(d & 0xff))
|
((u32_t)(c & 0xff) << 8) | (u32_t)(d & 0xff))
|
||||||
|
|
||||||
#define ip_addr_set(dest, src) (dest)->addr = \
|
#define ip_addr_set(dest, src) (dest)->addr = \
|
||||||
((src) == NULL? 0:\
|
((src) == NULL? 0:\
|
||||||
((struct ip_addr *)src)->addr)
|
(src)->addr)
|
||||||
#define ip_addr_maskcmp(addr1, addr2, mask) (((addr1)->addr & \
|
#define ip_addr_maskcmp(addr1, addr2, mask) (((addr1)->addr & \
|
||||||
(mask)->addr) == \
|
(mask)->addr) == \
|
||||||
((addr2)->addr & \
|
((addr2)->addr & \
|
||||||
@@ -110,10 +109,7 @@ extern const struct ip_addr ip_addr_broadcast;
|
|||||||
|
|
||||||
#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0)
|
#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0)
|
||||||
|
|
||||||
#define ip_addr_isbroadcast(addr1, mask) (((((addr1)->addr) & ~((mask)->addr)) == \
|
u8_t ip_addr_isbroadcast(struct ip_addr *, struct netif *);
|
||||||
(0xffffffff & ~((mask)->addr))) || \
|
|
||||||
((addr1)->addr == 0xffffffff) || \
|
|
||||||
((addr1)->addr == 0x00000000))
|
|
||||||
|
|
||||||
#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000)) == ntohl(0xe0000000))
|
#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000)) == ntohl(0xe0000000))
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -42,20 +42,6 @@
|
|||||||
|
|
||||||
#include "arch/cc.h"
|
#include "arch/cc.h"
|
||||||
|
|
||||||
#ifndef PACK_STRUCT_BEGIN
|
|
||||||
#define PACK_STRUCT_BEGIN
|
|
||||||
#endif /* PACK_STRUCT_BEGIN */
|
|
||||||
|
|
||||||
#ifndef PACK_STRUCT_END
|
|
||||||
#define PACK_STRUCT_END
|
|
||||||
#endif /* PACK_STRUCT_END */
|
|
||||||
|
|
||||||
#ifndef PACK_STRUCT_FIELD
|
|
||||||
#define PACK_STRUCT_FIELD(x) x
|
|
||||||
#endif /* PACK_STRUCT_FIELD */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef LWIP_PROVIDE_ERRNO
|
#ifdef LWIP_PROVIDE_ERRNO
|
||||||
|
|
||||||
#define EPERM 1 /* Operation not permitted */
|
#define EPERM 1 /* Operation not permitted */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -55,44 +55,35 @@ struct dhcp
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* MUST be compiled with "pack structs" or equivalent! */
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/bpstruct.h"
|
|
||||||
#endif
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
/** minimum set of fields of any DHCP message */
|
/** minimum set of fields of any DHCP message */
|
||||||
struct dhcp_msg
|
struct dhcp_msg
|
||||||
{
|
{
|
||||||
PACK_STRUCT_FIELD(u8_t op);
|
u8_t op;
|
||||||
PACK_STRUCT_FIELD(u8_t htype);
|
u8_t htype;
|
||||||
PACK_STRUCT_FIELD(u8_t hlen);
|
u8_t hlen;
|
||||||
PACK_STRUCT_FIELD(u8_t hops);
|
u8_t hops;
|
||||||
PACK_STRUCT_FIELD(u32_t xid);
|
u32_t xid;
|
||||||
PACK_STRUCT_FIELD(u16_t secs);
|
u16_t secs;
|
||||||
PACK_STRUCT_FIELD(u16_t flags);
|
u16_t flags;
|
||||||
PACK_STRUCT_FIELD(u32_t ciaddr);
|
struct ip_addr ciaddr;
|
||||||
PACK_STRUCT_FIELD(u32_t yiaddr);
|
struct ip_addr yiaddr;
|
||||||
PACK_STRUCT_FIELD(u32_t siaddr);
|
struct ip_addr siaddr;
|
||||||
PACK_STRUCT_FIELD(u32_t giaddr);
|
struct ip_addr giaddr;
|
||||||
#define DHCP_CHADDR_LEN 16U
|
#define DHCP_CHADDR_LEN 16U
|
||||||
PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]);
|
u8_t chaddr[DHCP_CHADDR_LEN];
|
||||||
#define DHCP_SNAME_LEN 64U
|
#define DHCP_SNAME_LEN 64U
|
||||||
PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]);
|
u8_t sname[DHCP_SNAME_LEN];
|
||||||
#define DHCP_FILE_LEN 128U
|
#define DHCP_FILE_LEN 128U
|
||||||
PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]);
|
u8_t file[DHCP_FILE_LEN];
|
||||||
PACK_STRUCT_FIELD(u32_t cookie);
|
u32_t cookie;
|
||||||
#define DHCP_MIN_OPTIONS_LEN 68U
|
#define DHCP_MIN_OPTIONS_LEN 68U
|
||||||
/** allow this to be configured in lwipopts.h, but not too small */
|
/** allow this to be configured in lwipopts.h, but not too small */
|
||||||
#if ((!defined(DHCP_OPTIONS_LEN)) || (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
|
#if ((!defined(DHCP_OPTIONS_LEN)) || (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN))
|
||||||
/** set this to be sufficient for your options in outgoing DHCP msgs */
|
/** set this to be sufficient for your options in outgoing DHCP msgs */
|
||||||
# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
|
# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN
|
||||||
#endif
|
#endif
|
||||||
PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]);
|
u8_t options[DHCP_OPTIONS_LEN];
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/epstruct.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** start DHCP configuration */
|
/** start DHCP configuration */
|
||||||
err_t dhcp_start(struct netif *netif);
|
err_t dhcp_start(struct netif *netif);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -59,6 +59,7 @@ typedef s8_t err_t;
|
|||||||
#define ERR_USE -10 /* Address in use. */
|
#define ERR_USE -10 /* Address in use. */
|
||||||
|
|
||||||
#define ERR_IF -11 /* Low-level netif error */
|
#define ERR_IF -11 /* Low-level netif error */
|
||||||
|
#define ERR_ISCONN -12 /* Already connected. */
|
||||||
|
|
||||||
|
|
||||||
#ifdef LWIP_DEBUG
|
#ifdef LWIP_DEBUG
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -40,7 +40,9 @@
|
|||||||
|
|
||||||
#include "lwip/inet.h"
|
#include "lwip/inet.h"
|
||||||
#include "lwip/pbuf.h"
|
#include "lwip/pbuf.h"
|
||||||
#include "lwip/dhcp.h"
|
#if LWIP_DHCP
|
||||||
|
# include "lwip/dhcp.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/** must be the maximum of all used hardware address lengths
|
/** must be the maximum of all used hardware address lengths
|
||||||
across all types of interfaces in use */
|
across all types of interfaces in use */
|
||||||
@@ -50,7 +52,8 @@
|
|||||||
|
|
||||||
/** whether the network interface is 'up'. this is
|
/** whether the network interface is 'up'. this is
|
||||||
* a software flag used to control whether this network
|
* a software flag used to control whether this network
|
||||||
* interface is enabled and processes traffic */
|
* interface is enabled and processes traffic.
|
||||||
|
* TODO: who should act on this flag, lwIP stack or driver?? */
|
||||||
#define NETIF_FLAG_UP 0x1U
|
#define NETIF_FLAG_UP 0x1U
|
||||||
/** if set, the netif has broadcast capability */
|
/** if set, the netif has broadcast capability */
|
||||||
#define NETIF_FLAG_BROADCAST 0x2U
|
#define NETIF_FLAG_BROADCAST 0x2U
|
||||||
@@ -59,35 +62,36 @@
|
|||||||
/** if set, the interface is configured using DHCP */
|
/** if set, the interface is configured using DHCP */
|
||||||
#define NETIF_FLAG_DHCP 0x08U
|
#define NETIF_FLAG_DHCP 0x08U
|
||||||
/** if set, the interface has an active link
|
/** if set, the interface has an active link
|
||||||
* (set by the interface) */
|
* (set by the network interface driver) */
|
||||||
#define NETIF_FLAG_LINK_UP 0x10U
|
#define NETIF_FLAG_LINK_UP 0x10U
|
||||||
|
|
||||||
/** generic data structure used for all lwIP network interfaces */
|
/** Generic data structure used for all lwIP network interfaces.
|
||||||
|
* The following fields should be filled in by the initialization
|
||||||
|
* function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
|
||||||
|
|
||||||
struct netif {
|
struct netif {
|
||||||
/** pointer to next in linked list */
|
/** pointer to next in linked list */
|
||||||
struct netif *next;
|
struct netif *next;
|
||||||
/** The following fields should be filled in by the
|
|
||||||
initialization function for the device driver. */
|
|
||||||
|
|
||||||
/** IP address configuration in network byte order */
|
/** IP address configuration in network byte order */
|
||||||
struct ip_addr ip_addr;
|
struct ip_addr ip_addr;
|
||||||
struct ip_addr netmask;
|
struct ip_addr netmask;
|
||||||
struct ip_addr gw;
|
struct ip_addr gw;
|
||||||
|
|
||||||
/** This function is called by the network device driver
|
/** This function is called by the network device driver
|
||||||
to pass a packet up the TCP/IP stack. */
|
* to pass a packet up the TCP/IP stack. */
|
||||||
err_t (* input)(struct pbuf *p, struct netif *inp);
|
err_t (* input)(struct pbuf *p, struct netif *inp);
|
||||||
/** This function is called by the IP module when it wants
|
/** This function is called by the IP module when it wants
|
||||||
to send a packet on the interface. This function typically
|
* to send a packet on the interface. This function typically
|
||||||
first resolves the hardware address, then sends the packet. */
|
* first resolves the hardware address, then sends the packet. */
|
||||||
err_t (* output)(struct netif *netif, struct pbuf *p,
|
err_t (* output)(struct netif *netif, struct pbuf *p,
|
||||||
struct ip_addr *ipaddr);
|
struct ip_addr *ipaddr);
|
||||||
/** This function is called by the ARP module when it wants
|
/** This function is called by the ARP module when it wants
|
||||||
to send a packet on the interface. This function outputs
|
* to send a packet on the interface. This function outputs
|
||||||
the pbuf as-is on the link medium. */
|
* the pbuf as-is on the link medium. */
|
||||||
err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
|
err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
|
||||||
/** This field can be set by the device driver and could point
|
/** This field can be set by the device driver and could point
|
||||||
to state information for the device. */
|
* to state information for the device. */
|
||||||
void *state;
|
void *state;
|
||||||
#if LWIP_DHCP
|
#if LWIP_DHCP
|
||||||
/** the DHCP client state information for this netif */
|
/** the DHCP client state information for this netif */
|
||||||
@@ -99,12 +103,12 @@ struct netif {
|
|||||||
unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];
|
unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];
|
||||||
/** maximum transfer unit (in bytes) */
|
/** maximum transfer unit (in bytes) */
|
||||||
u16_t mtu;
|
u16_t mtu;
|
||||||
|
/** flags (see NETIF_FLAG_ above) */
|
||||||
|
u8_t flags;
|
||||||
/** descriptive abbreviation */
|
/** descriptive abbreviation */
|
||||||
char name[2];
|
char name[2];
|
||||||
/** number of this interface */
|
/** number of this interface */
|
||||||
u8_t num;
|
u8_t num;
|
||||||
/** NETIF_FLAG_* */
|
|
||||||
u8_t flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The list of network interfaces. */
|
/** The list of network interfaces. */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -67,6 +67,10 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
#define MEM_SIZE 1600
|
#define MEM_SIZE 1600
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MEMP_SANITY_CHECK
|
||||||
|
#define MEMP_SANITY_CHECK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||||
sends a lot of data out of ROM (or other static memory), this
|
sends a lot of data out of ROM (or other static memory), this
|
||||||
should be set high. */
|
should be set high. */
|
||||||
@@ -171,14 +175,10 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
#ifndef ARP_QUEUE_FIRST
|
#ifndef ARP_QUEUE_FIRST
|
||||||
#define ARP_QUEUE_FIRST 0
|
#define ARP_QUEUE_FIRST 0
|
||||||
#endif
|
#endif
|
||||||
/**
|
|
||||||
* If defined to 1, cache entries are updated or added for every kind of ARP traffic
|
/* This option is removed to comply with the ARP standard */
|
||||||
* or broadcast IP traffic. Recommended for routers.
|
#ifdef ETHARP_ALWAYS_INSERT
|
||||||
* If defined to 0, only existing cache entries are updated. Entries are added when
|
#error ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h.
|
||||||
* lwIP is sending to them. Recommended for embedded devices.
|
|
||||||
*/
|
|
||||||
#ifndef ETHARP_ALWAYS_INSERT
|
|
||||||
#define ETHARP_ALWAYS_INSERT 1
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------- IP options ---------- */
|
/* ---------- IP options ---------- */
|
||||||
@@ -218,6 +218,10 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
|
|
||||||
/* ---------- RAW options ---------- */
|
/* ---------- RAW options ---------- */
|
||||||
|
|
||||||
|
#ifndef LWIP_RAW
|
||||||
|
#define LWIP_RAW 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef RAW_TTL
|
#ifndef RAW_TTL
|
||||||
#define RAW_TTL 255
|
#define RAW_TTL 255
|
||||||
#endif
|
#endif
|
||||||
@@ -348,6 +352,10 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
|
|
||||||
#if LWIP_STATS
|
#if LWIP_STATS
|
||||||
|
|
||||||
|
#ifndef LWIP_STATS_DISPLAY
|
||||||
|
#define LWIP_STATS_DISPLAY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef LINK_STATS
|
#ifndef LINK_STATS
|
||||||
#define LINK_STATS 1
|
#define LINK_STATS 1
|
||||||
#endif
|
#endif
|
||||||
@@ -405,6 +413,7 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
#define PBUF_STATS 0
|
#define PBUF_STATS 0
|
||||||
#define SYS_STATS 0
|
#define SYS_STATS 0
|
||||||
#define RAW_STATS 0
|
#define RAW_STATS 0
|
||||||
|
#define LWIP_STATS_DISPLAY 0
|
||||||
|
|
||||||
#endif /* LWIP_STATS */
|
#endif /* LWIP_STATS */
|
||||||
|
|
||||||
@@ -495,6 +504,31 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
|
|
||||||
#endif /* PPP_SUPPORT */
|
#endif /* PPP_SUPPORT */
|
||||||
|
|
||||||
|
/* checksum options - set to zero for hardware checksum support */
|
||||||
|
|
||||||
|
#ifndef CHECKSUM_GEN_IP
|
||||||
|
#define CHECKSUM_GEN_IP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CHECKSUM_GEN_UDP
|
||||||
|
#define CHECKSUM_GEN_UDP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CHECKSUM_GEN_TCP
|
||||||
|
#define CHECKSUM_GEN_TCP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CHECKSUM_CHECK_IP
|
||||||
|
#define CHECKSUM_CHECK_IP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CHECKSUM_CHECK_UDP
|
||||||
|
#define CHECKSUM_CHECK_UDP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CHECKSUM_CHECK_TCP
|
||||||
|
#define CHECKSUM_CHECK_TCP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Debugging options all default to off */
|
/* Debugging options all default to off */
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -53,8 +53,8 @@ typedef enum {
|
|||||||
PBUF_POOL
|
PBUF_POOL
|
||||||
} pbuf_flag;
|
} pbuf_flag;
|
||||||
|
|
||||||
/* Definitions for the pbuf flag field (these are not the flags that
|
/* Definitions for the pbuf flag field. These are NOT the flags that
|
||||||
are passed to pbuf_alloc()). */
|
* are passed to pbuf_alloc(). */
|
||||||
#define PBUF_FLAG_RAM 0x00U /* Flags that pbuf data is stored in RAM */
|
#define PBUF_FLAG_RAM 0x00U /* Flags that pbuf data is stored in RAM */
|
||||||
#define PBUF_FLAG_ROM 0x01U /* Flags that pbuf data is stored in ROM */
|
#define PBUF_FLAG_ROM 0x01U /* Flags that pbuf data is stored in ROM */
|
||||||
#define PBUF_FLAG_POOL 0x02U /* Flags that the pbuf comes from the pbuf pool */
|
#define PBUF_FLAG_POOL 0x02U /* Flags that the pbuf comes from the pbuf pool */
|
||||||
@@ -79,10 +79,10 @@ struct pbuf {
|
|||||||
*/
|
*/
|
||||||
u16_t tot_len;
|
u16_t tot_len;
|
||||||
|
|
||||||
/* length of this buffer */
|
/** length of this buffer */
|
||||||
u16_t len;
|
u16_t len;
|
||||||
|
|
||||||
/* flags telling the type of pbuf */
|
/** flags telling the type of pbuf, see PBUF_FLAG_ */
|
||||||
u16_t flags;
|
u16_t flags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,11 +94,6 @@ struct pbuf {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* pbuf_init():
|
|
||||||
|
|
||||||
Initializes the pbuf module. The num parameter determines how many
|
|
||||||
pbufs that should be allocated to the pbuf pool, and the size
|
|
||||||
parameter specifies the size of the data allocated to those. */
|
|
||||||
void pbuf_init(void);
|
void pbuf_init(void);
|
||||||
|
|
||||||
struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag);
|
struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag);
|
||||||
@@ -112,5 +107,7 @@ void pbuf_cat(struct pbuf *h, struct pbuf *t);
|
|||||||
void pbuf_chain(struct pbuf *h, struct pbuf *t);
|
void pbuf_chain(struct pbuf *h, struct pbuf *t);
|
||||||
struct pbuf *pbuf_take(struct pbuf *f);
|
struct pbuf *pbuf_take(struct pbuf *f);
|
||||||
struct pbuf *pbuf_dechain(struct pbuf *p);
|
struct pbuf *pbuf_dechain(struct pbuf *p);
|
||||||
|
void pbuf_queue(struct pbuf *p, struct pbuf *n);
|
||||||
|
struct pbuf * pbuf_dequeue(struct pbuf *p);
|
||||||
|
|
||||||
#endif /* __LWIP_PBUF_H__ */
|
#endif /* __LWIP_PBUF_H__ */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -46,7 +46,7 @@ struct raw_pcb {
|
|||||||
|
|
||||||
u16_t protocol;
|
u16_t protocol;
|
||||||
|
|
||||||
int (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
u8_t (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
||||||
struct ip_addr *addr);
|
struct ip_addr *addr);
|
||||||
void *recv_arg;
|
void *recv_arg;
|
||||||
};
|
};
|
||||||
@@ -59,15 +59,15 @@ err_t raw_bind (struct raw_pcb *pcb, struct ip_addr *ipaddr);
|
|||||||
err_t raw_connect (struct raw_pcb *pcb, struct ip_addr *ipaddr);
|
err_t raw_connect (struct raw_pcb *pcb, struct ip_addr *ipaddr);
|
||||||
|
|
||||||
void raw_recv (struct raw_pcb *pcb,
|
void raw_recv (struct raw_pcb *pcb,
|
||||||
int (* recv)(void *arg, struct raw_pcb *pcb,
|
u8_t (* recv)(void *arg, struct raw_pcb *pcb,
|
||||||
struct pbuf *p,
|
struct pbuf *p,
|
||||||
struct ip_addr *addr),
|
struct ip_addr *addr),
|
||||||
void *recv_arg);
|
void *recv_arg);
|
||||||
err_t raw_send_to (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);
|
err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr);
|
||||||
err_t raw_send (struct raw_pcb *pcb, struct pbuf *p);
|
err_t raw_send (struct raw_pcb *pcb, struct pbuf *p);
|
||||||
|
|
||||||
/* The following functions are the lower layer interface to RAW. */
|
/* The following functions are the lower layer interface to RAW. */
|
||||||
int raw_input (struct pbuf *p, struct netif *inp);
|
u8_t raw_input (struct pbuf *p, struct netif *inp);
|
||||||
void raw_init (void);
|
void raw_init (void);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -205,10 +205,16 @@ struct linger {
|
|||||||
unsigned char fd_bits [(FD_SETSIZE+7)/8];
|
unsigned char fd_bits [(FD_SETSIZE+7)/8];
|
||||||
} fd_set;
|
} fd_set;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* only define this in sockets.c so it does not interfere
|
||||||
|
* with other projects namespaces where timeval is present
|
||||||
|
*/
|
||||||
|
#ifdef LWIP_TIMEVAL_PRIVATE
|
||||||
struct timeval {
|
struct timeval {
|
||||||
long tv_sec; /* seconds */
|
long tv_sec; /* seconds */
|
||||||
long tv_usec; /* and microseconds */
|
long tv_usec; /* and microseconds */
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -144,6 +144,13 @@ void stats_init(void);
|
|||||||
#define LINK_STATS_INC(x)
|
#define LINK_STATS_INC(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Display of statistics */
|
||||||
|
#if LWIP_STATS_DISPLAY
|
||||||
|
void stats_display(void);
|
||||||
|
#else
|
||||||
|
#define stats_display()
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __LWIP_STATS_H__ */
|
#endif /* __LWIP_STATS_H__ */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -40,8 +40,6 @@
|
|||||||
#include "lwip/ip.h"
|
#include "lwip/ip.h"
|
||||||
#include "lwip/icmp.h"
|
#include "lwip/icmp.h"
|
||||||
|
|
||||||
#include "lwip/sys.h"
|
|
||||||
|
|
||||||
#include "lwip/err.h"
|
#include "lwip/err.h"
|
||||||
|
|
||||||
struct tcp_pcb;
|
struct tcp_pcb;
|
||||||
@@ -163,25 +161,16 @@ void tcp_rexmit (struct tcp_pcb *pcb);
|
|||||||
#define TCP_KEEPCNT 9 /* Counter for KEEPALIVE probes */
|
#define TCP_KEEPCNT 9 /* Counter for KEEPALIVE probes */
|
||||||
#define TCP_MAXIDLE TCP_KEEPCNT * TCP_KEEPINTVL /* Maximum KEEPALIVE probe time */
|
#define TCP_MAXIDLE TCP_KEEPCNT * TCP_KEEPINTVL /* Maximum KEEPALIVE probe time */
|
||||||
|
|
||||||
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/bpstruct.h"
|
|
||||||
#endif
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct tcp_hdr {
|
struct tcp_hdr {
|
||||||
PACK_STRUCT_FIELD(u16_t src);
|
u16_t src;
|
||||||
PACK_STRUCT_FIELD(u16_t dest);
|
u16_t dest;
|
||||||
PACK_STRUCT_FIELD(u32_t seqno);
|
u32_t seqno;
|
||||||
PACK_STRUCT_FIELD(u32_t ackno);
|
u32_t ackno;
|
||||||
PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
|
u16_t _hdrlen_rsvd_flags;
|
||||||
PACK_STRUCT_FIELD(u16_t wnd);
|
u16_t wnd;
|
||||||
PACK_STRUCT_FIELD(u16_t chksum);
|
u16_t chksum;
|
||||||
PACK_STRUCT_FIELD(u16_t urgp);
|
u16_t urgp;
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/epstruct.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
|
#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8)
|
||||||
#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
|
#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
|
||||||
@@ -457,7 +446,11 @@ void tcp_timer_needed(void);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The TCP PCB lists. */
|
/* The TCP PCB lists. */
|
||||||
extern struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */
|
union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
|
||||||
|
struct tcp_pcb_listen *listen_pcbs;
|
||||||
|
struct tcp_pcb *pcbs;
|
||||||
|
};
|
||||||
|
extern union tcp_listen_pcbs_t tcp_listen_pcbs;
|
||||||
extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
|
extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
|
||||||
state in which they accept or send
|
state in which they accept or send
|
||||||
data. */
|
data. */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -41,11 +41,11 @@
|
|||||||
#define UDP_HLEN 8
|
#define UDP_HLEN 8
|
||||||
|
|
||||||
struct udp_hdr {
|
struct udp_hdr {
|
||||||
PACK_STRUCT_FIELD(u16_t src);
|
u16_t src;
|
||||||
PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */
|
u16_t dest; /* src/dest UDP ports */
|
||||||
PACK_STRUCT_FIELD(u16_t len);
|
u16_t len;
|
||||||
PACK_STRUCT_FIELD(u16_t chksum);
|
u16_t chksum;
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
|
|
||||||
#define UDP_FLAGS_NOCHKSUM 0x01U
|
#define UDP_FLAGS_NOCHKSUM 0x01U
|
||||||
#define UDP_FLAGS_UDPLITE 0x02U
|
#define UDP_FLAGS_UDPLITE 0x02U
|
||||||
@@ -84,14 +84,13 @@ void udp_recv (struct udp_pcb *pcb,
|
|||||||
struct ip_addr *addr,
|
struct ip_addr *addr,
|
||||||
u16_t port),
|
u16_t port),
|
||||||
void *recv_arg);
|
void *recv_arg);
|
||||||
|
err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port);
|
||||||
err_t udp_send (struct udp_pcb *pcb, struct pbuf *p);
|
err_t udp_send (struct udp_pcb *pcb, struct pbuf *p);
|
||||||
|
|
||||||
#define udp_flags(pcb) ((pcb)->flags)
|
#define udp_flags(pcb) ((pcb)->flags)
|
||||||
#define udp_setflags(pcb, f) ((pcb)->flags = (f))
|
#define udp_setflags(pcb, f) ((pcb)->flags = (f))
|
||||||
|
|
||||||
|
|
||||||
/* The following functions are the lower layer interface to UDP. */
|
/* The following functions are the lower layer interface to UDP. */
|
||||||
u8_t udp_lookup (struct ip_hdr *iphdr, struct netif *inp);
|
|
||||||
void udp_input (struct pbuf *p, struct netif *inp);
|
void udp_input (struct pbuf *p, struct netif *inp);
|
||||||
void udp_init (void);
|
void udp_init (void);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
|
||||||
|
* Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -33,51 +35,45 @@
|
|||||||
#ifndef __NETIF_ETHARP_H__
|
#ifndef __NETIF_ETHARP_H__
|
||||||
#define __NETIF_ETHARP_H__
|
#define __NETIF_ETHARP_H__
|
||||||
|
|
||||||
|
#ifndef ETH_PAD_SIZE
|
||||||
|
#define ETH_PAD_SIZE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "lwip/pbuf.h"
|
#include "lwip/pbuf.h"
|
||||||
#include "lwip/ip_addr.h"
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
#include "lwip/ip.h"
|
#include "lwip/ip.h"
|
||||||
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/bpstruct.h"
|
|
||||||
#endif
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct eth_addr {
|
struct eth_addr {
|
||||||
PACK_STRUCT_FIELD(u8_t addr[6]);
|
u8_t addr[6];
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct eth_hdr {
|
struct eth_hdr {
|
||||||
PACK_STRUCT_FIELD(struct eth_addr dest);
|
#if ETH_PAD_SIZE
|
||||||
PACK_STRUCT_FIELD(struct eth_addr src);
|
u8_t padding[ETH_PAD_SIZE];
|
||||||
PACK_STRUCT_FIELD(u16_t type);
|
#endif
|
||||||
} PACK_STRUCT_STRUCT;
|
struct eth_addr dest;
|
||||||
PACK_STRUCT_END
|
struct eth_addr src;
|
||||||
|
u16_t type;
|
||||||
|
};
|
||||||
|
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
/** the ARP message */
|
/** the ARP message */
|
||||||
struct etharp_hdr {
|
struct etharp_hdr {
|
||||||
PACK_STRUCT_FIELD(struct eth_hdr ethhdr);
|
struct eth_hdr ethhdr;
|
||||||
PACK_STRUCT_FIELD(u16_t hwtype);
|
u16_t hwtype;
|
||||||
PACK_STRUCT_FIELD(u16_t proto);
|
u16_t proto;
|
||||||
PACK_STRUCT_FIELD(u16_t _hwlen_protolen);
|
u16_t _hwlen_protolen;
|
||||||
PACK_STRUCT_FIELD(u16_t opcode);
|
u16_t opcode;
|
||||||
PACK_STRUCT_FIELD(struct eth_addr shwaddr);
|
struct eth_addr shwaddr;
|
||||||
PACK_STRUCT_FIELD(struct ip_addr sipaddr);
|
struct ip_addr2 sipaddr;
|
||||||
PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
|
struct eth_addr dhwaddr;
|
||||||
PACK_STRUCT_FIELD(struct ip_addr dipaddr);
|
struct ip_addr2 dipaddr;
|
||||||
} PACK_STRUCT_STRUCT;
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
|
struct ethip_hdr {
|
||||||
PACK_STRUCT_BEGIN
|
struct eth_hdr eth);
|
||||||
struct ethip_hdr {
|
struct ip_hdr ip;
|
||||||
PACK_STRUCT_FIELD(struct eth_hdr eth);
|
|
||||||
PACK_STRUCT_FIELD(struct ip_hdr ip);
|
|
||||||
};
|
};
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
|
||||||
# include "arch/epstruct.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ARP_TMR_INTERVAL 10000
|
#define ARP_TMR_INTERVAL 10000
|
||||||
|
|
||||||
@@ -86,13 +82,11 @@ struct ethip_hdr {
|
|||||||
|
|
||||||
void etharp_init(void);
|
void etharp_init(void);
|
||||||
void etharp_tmr(void);
|
void etharp_tmr(void);
|
||||||
struct pbuf *etharp_ip_input(struct netif *netif, struct pbuf *p);
|
void etharp_ip_input(struct netif *netif, struct pbuf *p);
|
||||||
struct pbuf *etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,
|
void etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,
|
||||||
struct pbuf *p);
|
struct pbuf *p);
|
||||||
struct pbuf *etharp_output(struct netif *netif, struct ip_addr *ipaddr,
|
err_t etharp_output(struct netif *netif, struct ip_addr *ipaddr,
|
||||||
struct pbuf *q);
|
struct pbuf *q);
|
||||||
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);
|
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __NETIF_ARP_H__ */
|
#endif /* __NETIF_ARP_H__ */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -6,12 +6,16 @@
|
|||||||
* to a physical address when sending a packet, and the second part answers
|
* to a physical address when sending a packet, and the second part answers
|
||||||
* requests from other machines for our physical address.
|
* requests from other machines for our physical address.
|
||||||
*
|
*
|
||||||
* This implementation complies with RFC 826 (Ethernet ARP) and supports
|
* This implementation complies with RFC 826 (Ethernet ARP). It supports
|
||||||
* Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6.
|
* Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6
|
||||||
|
* if an interface calls etharp_query(our_netif, its_ip_addr, NULL) upon
|
||||||
|
* address change.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
|
||||||
|
* Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -38,49 +42,8 @@
|
|||||||
*
|
*
|
||||||
* This file is part of the lwIP TCP/IP stack.
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO:
|
|
||||||
* - pbufs should be sent from the queue once an ARP entry state
|
|
||||||
* goes from PENDING to STABLE.
|
|
||||||
* - Non-PENDING entries MUST NOT have queued packets.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO:
|
|
||||||
*
|
|
||||||
RFC 3220 4.6 IP Mobility Support for IPv4 January 2002
|
|
||||||
|
|
||||||
- A Gratuitous ARP [45] is an ARP packet sent by a node in order
|
|
||||||
to spontaneously cause other nodes to update an entry in their
|
|
||||||
ARP cache. A gratuitous ARP MAY use either an ARP Request or
|
|
||||||
an ARP Reply packet. In either case, the ARP Sender Protocol
|
|
||||||
Address and ARP Target Protocol Address are both set to the IP
|
|
||||||
address of the cache entry to be updated, and the ARP Sender
|
|
||||||
Hardware Address is set to the link-layer address to which this
|
|
||||||
cache entry should be updated. When using an ARP Reply packet,
|
|
||||||
the Target Hardware Address is also set to the link-layer
|
|
||||||
address to which this cache entry should be updated (this field
|
|
||||||
is not used in an ARP Request packet).
|
|
||||||
|
|
||||||
In either case, for a gratuitous ARP, the ARP packet MUST be
|
|
||||||
transmitted as a local broadcast packet on the local link. As
|
|
||||||
specified in [36], any node receiving any ARP packet (Request
|
|
||||||
or Reply) MUST update its local ARP cache with the Sender
|
|
||||||
Protocol and Hardware Addresses in the ARP packet, if the
|
|
||||||
receiving node has an entry for that IP address already in its
|
|
||||||
ARP cache. This requirement in the ARP protocol applies even
|
|
||||||
for ARP Request packets, and for ARP Reply packets that do not
|
|
||||||
match any ARP Request transmitted by the receiving node [36].
|
|
||||||
*
|
|
||||||
My suggestion would be to send a ARP request for our newly obtained
|
|
||||||
address upon configuration of an Ethernet interface.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
#include "lwip/inet.h"
|
#include "lwip/inet.h"
|
||||||
#include "netif/etharp.h"
|
#include "netif/etharp.h"
|
||||||
@@ -92,10 +55,13 @@ RFC 3220 4.6 IP Mobility Support for IPv4 January 2002
|
|||||||
# include "lwip/dhcp.h"
|
# include "lwip/dhcp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* allows new queueing code to be disabled (0) for regression testing */
|
||||||
|
#define ARP_NEW_QUEUE 1
|
||||||
|
|
||||||
/** the time an ARP entry stays valid after its last update, (120 * 10) seconds = 20 minutes. */
|
/** the time an ARP entry stays valid after its last update, (120 * 10) seconds = 20 minutes. */
|
||||||
#define ARP_MAXAGE 120
|
#define ARP_MAXAGE 120
|
||||||
/** the time an ARP entry stays pending after first request, (2 * 10) seconds = 20 seconds. */
|
/** the time an ARP entry stays pending after first request, (1 * 10) seconds = 10 seconds. */
|
||||||
#define ARP_MAXPENDING 2
|
#define ARP_MAXPENDING 1
|
||||||
|
|
||||||
#define HWTYPE_ETHERNET 1
|
#define HWTYPE_ETHERNET 1
|
||||||
|
|
||||||
@@ -112,7 +78,9 @@ RFC 3220 4.6 IP Mobility Support for IPv4 January 2002
|
|||||||
enum etharp_state {
|
enum etharp_state {
|
||||||
ETHARP_STATE_EMPTY,
|
ETHARP_STATE_EMPTY,
|
||||||
ETHARP_STATE_PENDING,
|
ETHARP_STATE_PENDING,
|
||||||
ETHARP_STATE_STABLE
|
ETHARP_STATE_STABLE,
|
||||||
|
/** @internal convenience transitional state used in etharp_tmr() */
|
||||||
|
ETHARP_STATE_EXPIRED
|
||||||
};
|
};
|
||||||
|
|
||||||
struct etharp_entry {
|
struct etharp_entry {
|
||||||
@@ -132,12 +100,9 @@ static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
|||||||
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
|
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
|
||||||
|
|
||||||
static s8_t find_arp_entry(void);
|
static s8_t find_arp_entry(void);
|
||||||
|
/** ask update_arp_entry() to add instead of merely update an ARP entry */
|
||||||
#define ARP_INSERT_FLAG 1
|
#define ARP_INSERT_FLAG 1
|
||||||
static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
|
static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
|
||||||
#if ARP_QUEUEING
|
|
||||||
static struct pbuf *etharp_enqueue(s8_t i, struct pbuf *q);
|
|
||||||
static u8_t etharp_dequeue(s8_t i);
|
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* Initializes ARP module.
|
* Initializes ARP module.
|
||||||
*/
|
*/
|
||||||
@@ -175,24 +140,27 @@ etharp_tmr(void)
|
|||||||
/* entry has become old? */
|
/* entry has become old? */
|
||||||
(arp_table[i].ctime >= ARP_MAXAGE)) {
|
(arp_table[i].ctime >= ARP_MAXAGE)) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
|
||||||
goto empty;
|
arp_table[i].state = ETHARP_STATE_EXPIRED;
|
||||||
/* an unresolved/pending entry? */
|
/* an unresolved/pending entry? */
|
||||||
} else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&
|
} else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&
|
||||||
/* entry unresolved/pending for too long? */
|
/* entry unresolved/pending for too long? */
|
||||||
(arp_table[i].ctime >= ARP_MAXPENDING)) {
|
(arp_table[i].ctime >= ARP_MAXPENDING)) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
|
||||||
empty:
|
arp_table[i].state = ETHARP_STATE_EXPIRED;
|
||||||
/* empty old entry */
|
}
|
||||||
arp_table[i].state = ETHARP_STATE_EMPTY;
|
/* clean up entries that have just been expired */
|
||||||
|
if (arp_table[i].state == ETHARP_STATE_EXPIRED) {
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
/* and empty packet queue */
|
/* and empty packet queue */
|
||||||
if (arp_table[i].p != NULL) {
|
if (arp_table[i].p != NULL) {
|
||||||
/* remove any queued packet */
|
/* remove all queued packets */
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));
|
||||||
pbuf_free(arp_table[i].p);
|
pbuf_free(arp_table[i].p);
|
||||||
arp_table[i].p = NULL;
|
arp_table[i].p = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/* recycle entry for re-use */
|
||||||
|
arp_table[i].state = ETHARP_STATE_EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,82 +203,24 @@ find_arp_entry(void)
|
|||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up the recycled stable entry */
|
/* clean up the oldest stable entry (to be recycled) */
|
||||||
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
/* free packets on queue */
|
/* and empty the packet queue */
|
||||||
etharp_dequeue(i);
|
if (arp_table[i].p != NULL) {
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));
|
||||||
|
/* remove all queued packets */
|
||||||
|
pbuf_free(arp_table[i].p);
|
||||||
|
arp_table[i].p = NULL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_arp_entry: recycling oldest stable entry %u\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_arp_entry: recycling oldest stable entry %u\n", i));
|
||||||
arp_table[i].state = ETHARP_STATE_EMPTY;
|
arp_table[i].state = ETHARP_STATE_EMPTY;
|
||||||
arp_table[i].ctime = 0;
|
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u\n", i));
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARP_QUEUEING
|
|
||||||
/*
|
|
||||||
* Enqueues a pbuf (chain) on an ARP entry.
|
|
||||||
*
|
|
||||||
* Places the pbuf (chain) on the queue (if space allows). The
|
|
||||||
* caller may safely free the pbuf (chain) afterwards, as the
|
|
||||||
* pbufs will be referenced by the queue and copies are made of
|
|
||||||
* pbufs referencing external payloads.
|
|
||||||
*
|
|
||||||
* @ i the ARP entry index
|
|
||||||
* @arg q the pbuf (chain) to be queued on the ARP entry
|
|
||||||
*
|
|
||||||
* @return Returns the new head of queue of the ARP entry.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static struct pbuf *
|
|
||||||
etharp_enqueue(s8_t i, struct pbuf *q)
|
|
||||||
{
|
|
||||||
/* any pbuf to queue? */
|
|
||||||
if (q != NULL) {
|
|
||||||
/* queue later packet over earliers? TODO: Implement multiple pbuf queue */
|
|
||||||
#if ARP_QUEUE_FIRST == 0
|
|
||||||
/* remove any pbufs on queue */
|
|
||||||
u8_t deq = etharp_dequeue(i);
|
|
||||||
if (deq > 0) LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dequeued %u pbufs from ARP entry %u. Should not occur.\n", deq, i));
|
|
||||||
#endif
|
|
||||||
/* packet can be queued? TODO: Implement multiple pbuf queue */
|
|
||||||
if (arp_table[i].p == NULL) {
|
|
||||||
/* copy any PBUF_REF referenced payloads into PBUF_RAM */
|
|
||||||
q = pbuf_take(q);
|
|
||||||
/* add pbuf to queue */
|
|
||||||
arp_table[i].p = q;
|
|
||||||
/* pbuf (chain) now queued, increase the reference count */
|
|
||||||
pbuf_ref(q);
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arp_table[i].p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dequeues any pbufs queued on an ARP entry
|
|
||||||
*
|
|
||||||
* @return number of pbufs removed from the queue
|
|
||||||
*
|
|
||||||
* TODO: decide what is a sensible return value?
|
|
||||||
*/
|
|
||||||
static u8_t
|
|
||||||
etharp_dequeue(s8_t i)
|
|
||||||
{
|
|
||||||
/* queued packets on a stable entry (work in progress) */
|
|
||||||
if (arp_table[i].p != NULL) {
|
|
||||||
/* queue no longer references pbuf */
|
|
||||||
pbuf_free(arp_table[i].p);
|
|
||||||
arp_table[i].p = NULL;
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update (or insert) a IP/MAC address pair in the ARP cache.
|
* Update (or insert) a IP/MAC address pair in the ARP cache.
|
||||||
*
|
*
|
||||||
@@ -334,20 +244,22 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
|||||||
s8_t i, k;
|
s8_t i, k;
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
|
||||||
LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
|
LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
|
ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),
|
||||||
|
ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
|
||||||
|
ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
|
||||||
/* do not update for 0.0.0.0 addresses */
|
/* do not update for 0.0.0.0 addresses */
|
||||||
if (ipaddr->addr == 0) {
|
if (ipaddr->addr == 0) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: will not add 0.0.0.0 to ARP cache\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: will not add 0.0.0.0 to ARP cache\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Walk through the ARP mapping table and try to find an entry to
|
/* Walk through the ARP mapping table and try to find an entry to update.
|
||||||
update. If none is found, the IP -> MAC address mapping is
|
* If none is found, a new IP -> MAC address mapping is inserted. */
|
||||||
inserted in the ARP table. */
|
|
||||||
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
||||||
/* Check if the source IP address of the incoming packet matches
|
/* Check if the source IP address of the incoming packet matches
|
||||||
the IP address in this ARP table entry. */
|
* the IP address in this ARP table entry. */
|
||||||
if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
if (arp_table[i].state != ETHARP_STATE_EMPTY &&
|
||||||
|
ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
||||||
/* pending entry? */
|
/* pending entry? */
|
||||||
if (arp_table[i].state == ETHARP_STATE_PENDING) {
|
if (arp_table[i].state == ETHARP_STATE_PENDING) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: pending entry %u goes stable\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: pending entry %u goes stable\n", i));
|
||||||
@@ -355,12 +267,8 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
|||||||
arp_table[i].state = ETHARP_STATE_STABLE;
|
arp_table[i].state = ETHARP_STATE_STABLE;
|
||||||
/* fall-through to next if */
|
/* fall-through to next if */
|
||||||
}
|
}
|
||||||
/* stable entry? (possibly just marked to become stable) */
|
/* stable entry? (possibly just marked stable) */
|
||||||
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||||
#if ARP_QUEUEING
|
|
||||||
struct pbuf *p;
|
|
||||||
struct eth_hdr *ethhdr;
|
|
||||||
#endif
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %u\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %u\n", i));
|
||||||
/* An old entry found, update this and return. */
|
/* An old entry found, update this and return. */
|
||||||
for (k = 0; k < netif->hwaddr_len; ++k) {
|
for (k = 0; k < netif->hwaddr_len; ++k) {
|
||||||
@@ -370,52 +278,39 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
|||||||
arp_table[i].ctime = 0;
|
arp_table[i].ctime = 0;
|
||||||
/* this is where we will send out queued packets! */
|
/* this is where we will send out queued packets! */
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
/* get the first packet on the queue (if any) */
|
while (arp_table[i].p != NULL) {
|
||||||
p = arp_table[i].p;
|
/* get the first packet on the queue (if any) */
|
||||||
/* queued packet present? */
|
struct pbuf *p = arp_table[i].p;
|
||||||
while (p != NULL) {
|
/* Ethernet header */
|
||||||
struct pbuf *q, *n;
|
struct eth_hdr *ethhdr = p->payload;;
|
||||||
/* search for second packet on queue (n) */
|
/* remember (and reference) remainder of queue */
|
||||||
q = p;
|
/* note: this will also terminate the p pbuf chain */
|
||||||
while (q->tot_len > q->len) {
|
arp_table[i].p = pbuf_dequeue(p);
|
||||||
/* proceed to next pbuf of this packet */
|
|
||||||
LWIP_ASSERT("q->next ! NULL", q->next != NULL);
|
|
||||||
q = q->next;
|
|
||||||
}
|
|
||||||
/* { q = last pbuf of first packet, q->tot_len = q->len } */
|
|
||||||
n = q->next;
|
|
||||||
/* { n = first pbuf of 2nd packet, or NULL if no 2nd packet } */
|
|
||||||
/* terminate the first packet pbuf chain */
|
|
||||||
q->next = NULL;
|
|
||||||
/* fill-in Ethernet header */
|
/* fill-in Ethernet header */
|
||||||
ethhdr = p->payload;
|
|
||||||
for (k = 0; k < netif->hwaddr_len; ++k) {
|
for (k = 0; k < netif->hwaddr_len; ++k) {
|
||||||
ethhdr->dest.addr[k] = ethaddr->addr[k];
|
ethhdr->dest.addr[k] = ethaddr->addr[k];
|
||||||
ethhdr->src.addr[k] = netif->hwaddr[k];
|
ethhdr->src.addr[k] = netif->hwaddr[k];
|
||||||
}
|
}
|
||||||
ethhdr->type = htons(ETHTYPE_IP);
|
ethhdr->type = htons(ETHTYPE_IP);
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n",(void *)p));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n", (void *)p));
|
||||||
/* send the queued IP packet */
|
/* send the queued IP packet */
|
||||||
netif->linkoutput(netif, p);
|
netif->linkoutput(netif, p);
|
||||||
/* free the queued IP packet */
|
/* free the queued IP packet */
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
/* proceed to next packet on queue */
|
|
||||||
p = n;
|
|
||||||
}
|
}
|
||||||
/* NULL attached buffer*/
|
|
||||||
arp_table[i].p = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
|
/* IP addresses should only occur once in the ARP entry, we are done */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} /* if */
|
} /* if STABLE */
|
||||||
} /* for */
|
} /* for all ARP entries */
|
||||||
|
|
||||||
/* no matching ARP entry was found */
|
/* no matching ARP entry was found */
|
||||||
LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE);
|
LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE);
|
||||||
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: IP address not yet in table\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: IP address not yet in table\n"));
|
||||||
/* allowed to insert an entry? */
|
/* allowed to insert a new entry? */
|
||||||
if ((ETHARP_ALWAYS_INSERT) || (flags & ARP_INSERT_FLAG))
|
if (flags & ARP_INSERT_FLAG)
|
||||||
{
|
{
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n"));
|
||||||
/* find an empty or old entry. */
|
/* find an empty or old entry. */
|
||||||
@@ -461,7 +356,7 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
|||||||
*
|
*
|
||||||
* @see pbuf_free()
|
* @see pbuf_free()
|
||||||
*/
|
*/
|
||||||
struct pbuf *
|
void
|
||||||
etharp_ip_input(struct netif *netif, struct pbuf *p)
|
etharp_ip_input(struct netif *netif, struct pbuf *p)
|
||||||
{
|
{
|
||||||
struct ethip_hdr *hdr;
|
struct ethip_hdr *hdr;
|
||||||
@@ -472,13 +367,12 @@ etharp_ip_input(struct netif *netif, struct pbuf *p)
|
|||||||
/* source is on local network? */
|
/* source is on local network? */
|
||||||
if (!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
|
if (!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
|
||||||
/* update ARP table, ask to insert entry */
|
/* update ARP table, ask to insert entry */
|
||||||
update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), ARP_INSERT_FLAG);
|
update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), ARP_INSERT_FLAG);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -497,10 +391,12 @@ etharp_ip_input(struct netif *netif, struct pbuf *p)
|
|||||||
*
|
*
|
||||||
* @see pbuf_free()
|
* @see pbuf_free()
|
||||||
*/
|
*/
|
||||||
struct pbuf *
|
void
|
||||||
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
||||||
{
|
{
|
||||||
struct etharp_hdr *hdr;
|
struct etharp_hdr *hdr;
|
||||||
|
/* these are aligned properly, whereas the ARP header fields might not be */
|
||||||
|
struct ip_addr sipaddr, dipaddr;
|
||||||
u8_t i;
|
u8_t i;
|
||||||
u8_t for_us;
|
u8_t for_us;
|
||||||
|
|
||||||
@@ -508,33 +404,43 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
|||||||
if (p->tot_len < sizeof(struct etharp_hdr)) {
|
if (p->tot_len < sizeof(struct etharp_hdr)) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr)));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr)));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = p->payload;
|
hdr = p->payload;
|
||||||
|
|
||||||
|
/* get aligned copies of addresses */
|
||||||
|
*(struct ip_addr2 *)&sipaddr = hdr->sipaddr;
|
||||||
|
*(struct ip_addr2 *)&dipaddr = hdr->dipaddr;
|
||||||
|
|
||||||
/* this interface is not configured? */
|
/* this interface is not configured? */
|
||||||
if (netif->ip_addr.addr == 0) {
|
if (netif->ip_addr.addr == 0) {
|
||||||
for_us = 0;
|
for_us = 0;
|
||||||
} else {
|
} else {
|
||||||
/* ARP packet directed to us? */
|
/* ARP packet directed to us? */
|
||||||
for_us = ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr));
|
for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARP message directed to us? */
|
||||||
|
if (for_us) {
|
||||||
|
/* add IP address in ARP cache; assume requester wants to talk to us.
|
||||||
|
* can result in directly sending the queued packets for this host. */
|
||||||
|
update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ARP_INSERT_FLAG);
|
||||||
|
/* ARP message not directed to us? */
|
||||||
|
} else {
|
||||||
|
/* update the source IP address in the cache, if present */
|
||||||
|
update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now act on the message itself */
|
||||||
switch (htons(hdr->opcode)) {
|
switch (htons(hdr->opcode)) {
|
||||||
/* ARP request? */
|
/* ARP request? */
|
||||||
case ARP_REQUEST:
|
case ARP_REQUEST:
|
||||||
/* ARP request. If it asked for our address, we send out a
|
/* ARP request. If it asked for our address, we send out a
|
||||||
reply. In any case, we time-stamp any existing ARP entry,
|
* reply. In any case, we time-stamp any existing ARP entry,
|
||||||
and possiby send out an IP packet that was queued on it. */
|
* and possiby send out an IP packet that was queued on it. */
|
||||||
|
|
||||||
LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
|
LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
|
||||||
/* we are not configured? */
|
|
||||||
if (netif->ip_addr.addr == 0) {
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
|
|
||||||
pbuf_free(p);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* ARP request for our address? */
|
/* ARP request for our address? */
|
||||||
if (for_us) {
|
if (for_us) {
|
||||||
|
|
||||||
@@ -542,8 +448,8 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
|||||||
/* re-use pbuf to send ARP reply */
|
/* re-use pbuf to send ARP reply */
|
||||||
hdr->opcode = htons(ARP_REPLY);
|
hdr->opcode = htons(ARP_REPLY);
|
||||||
|
|
||||||
ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr));
|
hdr->dipaddr = hdr->sipaddr;
|
||||||
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
|
hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
|
||||||
|
|
||||||
for(i = 0; i < netif->hwaddr_len; ++i) {
|
for(i = 0; i < netif->hwaddr_len; ++i) {
|
||||||
hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
|
hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
|
||||||
@@ -561,41 +467,30 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
|||||||
hdr->ethhdr.type = htons(ETHTYPE_ARP);
|
hdr->ethhdr.type = htons(ETHTYPE_ARP);
|
||||||
/* return ARP reply */
|
/* return ARP reply */
|
||||||
netif->linkoutput(netif, p);
|
netif->linkoutput(netif, p);
|
||||||
|
/* we are not configured? */
|
||||||
|
} else if (netif->ip_addr.addr == 0) {
|
||||||
|
/* { for_us == 0 and netif->ip_addr.addr == 0 } */
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
|
||||||
/* request was not directed to us */
|
/* request was not directed to us */
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request was not for us.\n"));
|
/* { for_us == 0 and netif->ip_addr.addr != 0 } */
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARP_REPLY:
|
case ARP_REPLY:
|
||||||
/* ARP reply. We insert or update the ARP table later. */
|
/* ARP reply. We already updated the ARP cache earlier. */
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
|
||||||
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
|
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
|
||||||
/* DHCP needs to know about ARP replies to our address */
|
/* DHCP wants to know about ARP replies to our wanna-have-address */
|
||||||
if (for_us) dhcp_arp_reply(netif, &hdr->sipaddr);
|
if (for_us) dhcp_arp_reply(netif, &sipaddr);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* add or update entries in the ARP cache */
|
|
||||||
if (for_us) {
|
|
||||||
/* insert IP address in ARP cache (assume requester wants to talk to us)
|
|
||||||
* we might even send out a queued packet to this host */
|
|
||||||
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG);
|
|
||||||
/* request was not directed to us, but snoop anyway */
|
|
||||||
} else {
|
|
||||||
/* update or insert the source IP address in the cache */
|
|
||||||
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
|
|
||||||
/* update or insert the destination IP address pair in the cache */
|
|
||||||
update_arp_entry(netif, &(hdr->dipaddr), &(hdr->dhwaddr), 0);
|
|
||||||
}
|
|
||||||
/* free ARP packet */
|
/* free ARP packet */
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
p = NULL;
|
|
||||||
/* nothing to send, we did it! */
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -619,33 +514,36 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
|||||||
*
|
*
|
||||||
* @return If non-NULL, a packet ready to be sent by caller.
|
* @return If non-NULL, a packet ready to be sent by caller.
|
||||||
*
|
*
|
||||||
|
* @return
|
||||||
|
* - ERR_BUF Could not make room for Ethernet header.
|
||||||
|
* - ERR_MEM Hardware address unknown, and no more ARP entries available
|
||||||
|
* to query for address or queue the packet.
|
||||||
|
* - ERR_RTE No route to destination (no gateway to external networks).
|
||||||
*/
|
*/
|
||||||
struct pbuf *
|
err_t
|
||||||
etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
{
|
{
|
||||||
struct eth_addr *dest, *srcaddr, mcastaddr;
|
struct eth_addr *dest, *srcaddr, mcastaddr;
|
||||||
struct eth_hdr *ethhdr;
|
struct eth_hdr *ethhdr;
|
||||||
s8_t i;
|
s8_t i;
|
||||||
|
err_t result = ERR_OK;
|
||||||
|
|
||||||
/* make room for Ethernet header */
|
/* make room for Ethernet header - should not fail*/
|
||||||
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
|
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
|
||||||
/* The pbuf_header() call shouldn't fail, and we'll just bail
|
/* bail out */
|
||||||
out if it does.. */
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
|
||||||
LINK_STATS_INC(link.lenerr);
|
LINK_STATS_INC(link.lenerr);
|
||||||
return NULL;
|
pbuf_free(q);
|
||||||
|
return ERR_BUF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assume unresolved Ethernet address */
|
/* assume unresolved Ethernet address */
|
||||||
dest = NULL;
|
dest = NULL;
|
||||||
/* Construct Ethernet header. Start with looking up deciding which
|
/* Determine on destination hardware address. Broadcasts and multicasts
|
||||||
MAC address to use as a destination address. Broadcasts and
|
* are special, other IP addresses are looked up in the ARP table. */
|
||||||
multicasts are special, all other addresses are looked up in the
|
|
||||||
ARP table. */
|
|
||||||
|
|
||||||
/* destination IP address is an IP broadcast address? */
|
/* destination IP address is an IP broadcast address? */
|
||||||
if (ip_addr_isany(ipaddr) ||
|
if (ip_addr_isany(ipaddr) || ip_addr_isbroadcast(ipaddr, netif)) {
|
||||||
ip_addr_isbroadcast(ipaddr, &(netif->netmask))) {
|
|
||||||
/* broadcast on Ethernet also */
|
/* broadcast on Ethernet also */
|
||||||
dest = (struct eth_addr *)ðbroadcast;
|
dest = (struct eth_addr *)ðbroadcast;
|
||||||
}
|
}
|
||||||
@@ -663,86 +561,67 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
|||||||
}
|
}
|
||||||
/* destination IP address is an IP unicast address */
|
/* destination IP address is an IP unicast address */
|
||||||
else {
|
else {
|
||||||
/* destination IP network address not on local network?
|
/* outside local network? */
|
||||||
* IP layer wants us to forward to the default gateway */
|
|
||||||
if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
|
if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
|
||||||
/* interface has default gateway? */
|
/* interface has default gateway? */
|
||||||
if (netif->gw.addr != 0)
|
if (netif->gw.addr != 0) {
|
||||||
{
|
/* send to hardware address of default gateway IP address */
|
||||||
/* route to default gateway IP address */
|
|
||||||
ipaddr = &(netif->gw);
|
ipaddr = &(netif->gw);
|
||||||
}
|
/* no default gateway available? */
|
||||||
/* no gateway available? */
|
} else {
|
||||||
else
|
/* destination unreachable, discard packet */
|
||||||
{
|
pbuf_free(q);
|
||||||
/* IP destination address outside local network, but no gateway available */
|
return ERR_RTE;
|
||||||
/* { packet is discarded } */
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result = etharp_query(netif, ipaddr, q);
|
||||||
/* Ethernet address for IP destination address is in ARP cache? */
|
} /* else unicast */
|
||||||
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
|
||||||
/* match found? */
|
|
||||||
if (arp_table[i].state == ETHARP_STATE_STABLE &&
|
|
||||||
ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
|
||||||
dest = &arp_table[i].ethaddr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* could not find the destination Ethernet address in ARP cache? */
|
|
||||||
if (dest == NULL) {
|
|
||||||
/* ARP query for the IP address, submit this IP packet for queueing */
|
|
||||||
/* TODO: How do we handle netif->ipaddr == ipaddr? */
|
|
||||||
etharp_query(netif, ipaddr, q);
|
|
||||||
/* { packet was queued (ERR_OK), or discarded } */
|
|
||||||
/* return nothing */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* destination Ethernet address resolved from ARP cache */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* fallthrough */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destination Ethernet address known */
|
/* destination Ethernet address known */
|
||||||
if (dest != NULL) {
|
if (dest != NULL) {
|
||||||
/* obtain source Ethernet address of the given interface */
|
/* obtain source Ethernet address of the given interface */
|
||||||
srcaddr = (struct eth_addr *)netif->hwaddr;
|
srcaddr = (struct eth_addr *)netif->hwaddr;
|
||||||
|
|
||||||
/* A valid IP->MAC address mapping was found, fill in the
|
/* A valid IP->MAC address mapping was found, fill in the
|
||||||
* Ethernet header for the outgoing packet */
|
* Ethernet header for the outgoing packet */
|
||||||
ethhdr = q->payload;
|
ethhdr = q->payload;
|
||||||
|
|
||||||
for(i = 0; i < netif->hwaddr_len; i++) {
|
for(i = 0; i < netif->hwaddr_len; i++) {
|
||||||
ethhdr->dest.addr[i] = dest->addr[i];
|
ethhdr->dest.addr[i] = dest->addr[i];
|
||||||
ethhdr->src.addr[i] = srcaddr->addr[i];
|
ethhdr->src.addr[i] = srcaddr->addr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ethhdr->type = htons(ETHTYPE_IP);
|
ethhdr->type = htons(ETHTYPE_IP);
|
||||||
/* return the outgoing packet */
|
/* send packet */
|
||||||
return q;
|
result = netif->linkoutput(netif, q);
|
||||||
}
|
}
|
||||||
/* never reached; here for safety */
|
/* never reached; here for safety */
|
||||||
return NULL;
|
pbuf_free(q);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an ARP request for the given IP address.
|
* Send an ARP request for the given IP address.
|
||||||
*
|
*
|
||||||
* Sends an ARP request for the given IP address, unless
|
* If the IP address was not yet in the cache, a pending ARP cache entry
|
||||||
* a request for this address is already pending. Optionally
|
* is added and an ARP request is sent for the given address. The packet
|
||||||
* queues an outgoing packet on the resulting ARP entry.
|
* is queued on this entry.
|
||||||
*
|
*
|
||||||
|
* If the IP address was already pending in the cache, a new ARP request
|
||||||
|
* is sent for the given address. The packet is queued on this entry.
|
||||||
|
*
|
||||||
|
* If the IP address was already stable in the cache, the packet is
|
||||||
|
* directly sent. An ARP request is sent out.
|
||||||
|
*
|
||||||
* @param netif The lwIP network interface where ipaddr
|
* @param netif The lwIP network interface where ipaddr
|
||||||
* must be queried for.
|
* must be queried for.
|
||||||
* @param ipaddr The IP address to be resolved.
|
* @param ipaddr The IP address to be resolved.
|
||||||
* @param q If non-NULL, a pbuf that must be queued on the
|
* @param q If non-NULL, a pbuf that must be delivered to the IP address.
|
||||||
* ARP entry for the ipaddr IP address.
|
|
||||||
*
|
|
||||||
* @return NULL.
|
|
||||||
*
|
*
|
||||||
|
* @return
|
||||||
|
* - ERR_BUF Could not make room for Ethernet header.
|
||||||
|
* - ERR_MEM Hardware address unknown, and no more ARP entries available
|
||||||
|
* to query for address or queue the packet.
|
||||||
|
* - ERR_MEM Could not queue packet due to memory shortage.
|
||||||
|
* - ERR_RTE No route to destination (no gateway to external networks).
|
||||||
|
*
|
||||||
* @note Might be used in the future by manual IP configuration
|
* @note Might be used in the future by manual IP configuration
|
||||||
* as well.
|
* as well.
|
||||||
*
|
*
|
||||||
@@ -751,29 +630,73 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
|||||||
*/
|
*/
|
||||||
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
{
|
{
|
||||||
struct eth_addr *srcaddr;
|
struct pbuf *p;
|
||||||
struct etharp_hdr *hdr;
|
struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
|
||||||
err_t result = ERR_OK;
|
err_t result = ERR_OK;
|
||||||
s8_t i;
|
s8_t i; /* ARP entry index */
|
||||||
u8_t perform_arp_request = 1;
|
u8_t k; /* Ethernet address octet index */
|
||||||
/* prevent 'unused argument' warning if ARP_QUEUEING == 0 */
|
|
||||||
(void)q;
|
/* Do three things in this order (by design):
|
||||||
srcaddr = (struct eth_addr *)netif->hwaddr;
|
*
|
||||||
/* bail out if this IP address is pending */
|
* 1) send out ARP request
|
||||||
|
* 2) find entry in ARP cache
|
||||||
|
* 3) handle the packet
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* allocate a pbuf for the outgoing ARP request packet */
|
||||||
|
p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
|
||||||
|
/* could allocate a pbuf for an ARP request? */
|
||||||
|
if (p != NULL) {
|
||||||
|
struct etharp_hdr *hdr = p->payload;
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
|
||||||
|
hdr->opcode = htons(ARP_REQUEST);
|
||||||
|
for (k = 0; k < netif->hwaddr_len; k++)
|
||||||
|
{
|
||||||
|
hdr->shwaddr.addr[k] = srcaddr->addr[k];
|
||||||
|
/* the hardware address is what we ask for, in
|
||||||
|
* a request it is a don't-care value, we use zeroes */
|
||||||
|
hdr->dhwaddr.addr[k] = 0x00;
|
||||||
|
}
|
||||||
|
hdr->dipaddr = *(struct ip_addr2 *)ipaddr;
|
||||||
|
hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
|
||||||
|
|
||||||
|
hdr->hwtype = htons(HWTYPE_ETHERNET);
|
||||||
|
ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
|
||||||
|
|
||||||
|
hdr->proto = htons(ETHTYPE_IP);
|
||||||
|
ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
|
||||||
|
for (k = 0; k < netif->hwaddr_len; ++k)
|
||||||
|
{
|
||||||
|
/* broadcast to all network interfaces on the local network */
|
||||||
|
hdr->ethhdr.dest.addr[k] = 0xff;
|
||||||
|
hdr->ethhdr.src.addr[k] = srcaddr->addr[k];
|
||||||
|
}
|
||||||
|
hdr->ethhdr.type = htons(ETHTYPE_ARP);
|
||||||
|
/* send ARP query */
|
||||||
|
result = netif->linkoutput(netif, p);
|
||||||
|
/* free ARP query packet */
|
||||||
|
pbuf_free(p);
|
||||||
|
p = NULL;
|
||||||
|
/* could not allocate pbuf for ARP request */
|
||||||
|
} else {
|
||||||
|
result = ERR_MEM;
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_query: could not allocate pbuf for ARP request.\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* search entry of queried IP address in the ARP cache */
|
||||||
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
||||||
if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
/* valid ARP cache entry with matching IP address? */
|
||||||
|
if (arp_table[i].state != ETHARP_STATE_EMPTY &&
|
||||||
|
ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
||||||
|
/* pending entry? */
|
||||||
if (arp_table[i].state == ETHARP_STATE_PENDING) {
|
if (arp_table[i].state == ETHARP_STATE_PENDING) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending in entry %u\n", i));
|
||||||
/* break out of for-loop, user may wish to queue a packet on a pending entry */
|
/* { i != ARP_TABLE_SIZE } */
|
||||||
/* TODO: we will issue a new ARP request, which should not occur too often */
|
|
||||||
/* we might want to run a faster timer on ARP to limit this */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
else if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already stable as entry %u\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already stable in entry %u\n", i));
|
||||||
/* user may wish to queue a packet on a stable entry, so we proceed without ARP requesting */
|
/* { i != ARP_TABLE_SIZE } */
|
||||||
/* TODO: even if the ARP entry is stable, we might do an ARP request anyway */
|
|
||||||
perform_arp_request = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -791,53 +714,42 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
|||||||
/* i is available, create ARP entry */
|
/* i is available, create ARP entry */
|
||||||
arp_table[i].state = ETHARP_STATE_PENDING;
|
arp_table[i].state = ETHARP_STATE_PENDING;
|
||||||
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
|
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
|
||||||
/* queried address was already in ARP table */
|
arp_table[i].p = NULL;
|
||||||
} else {
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: added pending entry %u for IP address\n", i));
|
||||||
#if ARP_QUEUEING
|
|
||||||
etharp_enqueue(i, q);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/* ARP request? */
|
|
||||||
if (perform_arp_request)
|
|
||||||
{
|
|
||||||
struct pbuf *p;
|
|
||||||
/* allocate a pbuf for the outgoing ARP request packet */
|
|
||||||
p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
|
|
||||||
/* could allocate pbuf? */
|
|
||||||
if (p != NULL) {
|
|
||||||
u8_t j;
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
|
|
||||||
hdr = p->payload;
|
|
||||||
hdr->opcode = htons(ARP_REQUEST);
|
|
||||||
for (j = 0; j < netif->hwaddr_len; ++j)
|
|
||||||
{
|
|
||||||
hdr->shwaddr.addr[j] = srcaddr->addr[j];
|
|
||||||
/* the hardware address is what we ask for, in
|
|
||||||
* a request it is a don't-care, we use 0's */
|
|
||||||
hdr->dhwaddr.addr[j] = 0x00;
|
|
||||||
}
|
|
||||||
ip_addr_set(&(hdr->dipaddr), ipaddr);
|
|
||||||
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
|
|
||||||
|
|
||||||
hdr->hwtype = htons(HWTYPE_ETHERNET);
|
/* { i is either a (new or existing) PENDING or STABLE entry } */
|
||||||
ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
|
|
||||||
|
/* packet given? */
|
||||||
hdr->proto = htons(ETHTYPE_IP);
|
if (q != NULL) {
|
||||||
ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
|
/* stable entry? */
|
||||||
for (j = 0; j < netif->hwaddr_len; ++j)
|
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||||
{
|
/* we have a valid IP->Ethernet address mapping,
|
||||||
hdr->ethhdr.dest.addr[j] = 0xff;
|
* fill in the Ethernet header for the outgoing packet */
|
||||||
hdr->ethhdr.src.addr[j] = srcaddr->addr[j];
|
struct eth_hdr *ethhdr = q->payload;
|
||||||
|
for(k = 0; k < netif->hwaddr_len; k++) {
|
||||||
|
ethhdr->dest.addr[k] = arp_table[i].ethaddr.addr[k];
|
||||||
|
ethhdr->src.addr[k] = srcaddr->addr[k];
|
||||||
}
|
}
|
||||||
hdr->ethhdr.type = htons(ETHTYPE_ARP);
|
ethhdr->type = htons(ETHTYPE_IP);
|
||||||
/* send ARP query */
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending packet %p\n", (void *)q));
|
||||||
result = netif->linkoutput(netif, p);
|
/* send the packet */
|
||||||
/* free ARP query packet */
|
result = netif->linkoutput(netif, q);
|
||||||
pbuf_free(p);
|
#if ARP_QUEUEING /* queue the given q packet */
|
||||||
p = NULL;
|
/* pending entry? (either just created or already pending */
|
||||||
} else {
|
} else if (arp_table[i].state == ETHARP_STATE_PENDING) {
|
||||||
result = ERR_MEM;
|
/* copy any PBUF_REF referenced payloads into PBUF_RAM */
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_query: could not allocate pbuf for ARP request.\n"));
|
/* (the caller assumes the referenced payload can be freed) */
|
||||||
|
p = pbuf_take(q);
|
||||||
|
/* queue packet */
|
||||||
|
if (p != NULL) {
|
||||||
|
pbuf_queue(arp_table[i].p, p);
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %d\n", (void *)q, i));
|
||||||
|
} else {
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
|
||||||
|
result = ERR_MEM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -35,8 +35,6 @@
|
|||||||
* drivers for lwIP. Add code to the low_level functions and do a
|
* drivers for lwIP. Add code to the low_level functions and do a
|
||||||
* search-and-replace for the word "ethernetif" to replace it with
|
* search-and-replace for the word "ethernetif" to replace it with
|
||||||
* something that better describes your network interface.
|
* something that better describes your network interface.
|
||||||
*
|
|
||||||
* THIS CODE NEEDS TO BE FIXED - IT IS NOT In SYNC WITH CURRENT ETHARP API
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
@@ -45,11 +43,11 @@
|
|||||||
#include "lwip/pbuf.h"
|
#include "lwip/pbuf.h"
|
||||||
#include "lwip/sys.h"
|
#include "lwip/sys.h"
|
||||||
|
|
||||||
#include "netif/arp.h"
|
#include "netif/etharp.h"
|
||||||
|
|
||||||
/* Define those to better describe your network interface. */
|
/* Define those to better describe your network interface. */
|
||||||
#define IFNAME0 'e'
|
#define IFNAME0 'e'
|
||||||
#define IFNAME1 't'
|
#define IFNAME1 'n'
|
||||||
|
|
||||||
struct ethernetif {
|
struct ethernetif {
|
||||||
struct eth_addr *ethaddr;
|
struct eth_addr *ethaddr;
|
||||||
@@ -63,7 +61,6 @@ static void ethernetif_input(struct netif *netif);
|
|||||||
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
|
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
|
||||||
struct ip_addr *ipaddr);
|
struct ip_addr *ipaddr);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
low_level_init(struct netif *netif)
|
low_level_init(struct netif *netif)
|
||||||
{
|
{
|
||||||
@@ -77,7 +74,7 @@ low_level_init(struct netif *netif)
|
|||||||
/* set MAC hardware address */
|
/* set MAC hardware address */
|
||||||
netif->hwaddr[0] = ;
|
netif->hwaddr[0] = ;
|
||||||
...
|
...
|
||||||
netif->hwaddr[6] = ;
|
netif->hwaddr[5] = ;
|
||||||
|
|
||||||
/* maximum transfer unit */
|
/* maximum transfer unit */
|
||||||
netif->mtu = 1500;
|
netif->mtu = 1500;
|
||||||
@@ -97,7 +94,6 @@ low_level_init(struct netif *netif)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static err_t
|
static err_t
|
||||||
low_level_output(struct ethernetif *ethernetif, struct pbuf *p)
|
low_level_output(struct ethernetif *ethernetif, struct pbuf *p)
|
||||||
{
|
{
|
||||||
@@ -105,6 +101,10 @@ low_level_output(struct ethernetif *ethernetif, struct pbuf *p)
|
|||||||
|
|
||||||
initiate transfer();
|
initiate transfer();
|
||||||
|
|
||||||
|
#if ETH_PAD_SIZE
|
||||||
|
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||||
|
#endif
|
||||||
|
|
||||||
for(q = p; q != NULL; q = q->next) {
|
for(q = p; q != NULL; q = q->next) {
|
||||||
/* Send the data from the pbuf to the interface, one pbuf at a
|
/* Send the data from the pbuf to the interface, one pbuf at a
|
||||||
time. The size of the data in each pbuf is kept in the ->len
|
time. The size of the data in each pbuf is kept in the ->len
|
||||||
@@ -113,6 +113,10 @@ low_level_output(struct ethernetif *ethernetif, struct pbuf *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
signal that packet should be sent();
|
signal that packet should be sent();
|
||||||
|
|
||||||
|
#if ETH_PAD_SIZE
|
||||||
|
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LINK_STATS
|
#ifdef LINK_STATS
|
||||||
lwip_stats.link.xmit++;
|
lwip_stats.link.xmit++;
|
||||||
@@ -139,19 +143,33 @@ low_level_input(struct ethernetif *ethernetif)
|
|||||||
variable. */
|
variable. */
|
||||||
len = ;
|
len = ;
|
||||||
|
|
||||||
|
#if ETH_PAD_SIZE
|
||||||
|
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We allocate a pbuf chain of pbufs from the pool. */
|
/* We allocate a pbuf chain of pbufs from the pool. */
|
||||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
||||||
|
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
|
|
||||||
|
#if ETH_PAD_SIZE
|
||||||
|
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We iterate over the pbuf chain until we have read the entire
|
/* We iterate over the pbuf chain until we have read the entire
|
||||||
packet into the pbuf. */
|
* packet into the pbuf. */
|
||||||
for(q = p; q != NULL; q = q->next) {
|
for(q = p; q != NULL; q = q->next) {
|
||||||
/* Read enough bytes to fill this pbuf in the chain. The
|
/* Read enough bytes to fill this pbuf in the chain. The
|
||||||
available data in the pbuf is given by the q->len
|
* available data in the pbuf is given by the q->len
|
||||||
variable. */
|
* variable. */
|
||||||
read data into(q->payload, q->len);
|
read data into(q->payload, q->len);
|
||||||
}
|
}
|
||||||
acknowledge that packet has been read();
|
acknowledge that packet has been read();
|
||||||
|
|
||||||
|
#if ETH_PAD_SIZE
|
||||||
|
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LINK_STATS
|
#ifdef LINK_STATS
|
||||||
lwip_stats.link.recv++;
|
lwip_stats.link.recv++;
|
||||||
#endif /* LINK_STATS */
|
#endif /* LINK_STATS */
|
||||||
@@ -171,7 +189,7 @@ low_level_input(struct ethernetif *ethernetif)
|
|||||||
*
|
*
|
||||||
* This function is called by the TCP/IP stack when an IP packet
|
* This function is called by the TCP/IP stack when an IP packet
|
||||||
* should be sent. It calls the function called low_level_output() to
|
* should be sent. It calls the function called low_level_output() to
|
||||||
* do the actuall transmission of the packet.
|
* do the actual transmission of the packet.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -179,90 +197,10 @@ static err_t
|
|||||||
ethernetif_output(struct netif *netif, struct pbuf *p,
|
ethernetif_output(struct netif *netif, struct pbuf *p,
|
||||||
struct ip_addr *ipaddr)
|
struct ip_addr *ipaddr)
|
||||||
{
|
{
|
||||||
struct ethernetif *ethernetif;
|
|
||||||
struct pbuf *q;
|
|
||||||
struct eth_hdr *ethhdr;
|
|
||||||
struct eth_addr *dest, mcastaddr;
|
|
||||||
struct ip_addr *queryaddr;
|
|
||||||
err_t err;
|
|
||||||
u8_t i;
|
|
||||||
|
|
||||||
ethernetif = netif->state;
|
/* resolve hardware address, then send (or queue) packet */
|
||||||
|
return etharp_output(netif, ipaddr, p);
|
||||||
/* Make room for Ethernet header. */
|
|
||||||
if (pbuf_header(p, 14) != 0) {
|
|
||||||
/* The pbuf_header() call shouldn't fail, but we allocate an extra
|
|
||||||
pbuf just in case. */
|
|
||||||
q = pbuf_alloc(PBUF_LINK, 14, PBUF_RAM);
|
|
||||||
if (q == NULL) {
|
|
||||||
#ifdef LINK_STATS
|
|
||||||
lwip_stats.link.drop++;
|
|
||||||
lwip_stats.link.memerr++;
|
|
||||||
#endif /* LINK_STATS */
|
|
||||||
return ERR_MEM;
|
|
||||||
}
|
|
||||||
pbuf_chain(q, p);
|
|
||||||
p = q;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Construct Ethernet header. Start with looking up deciding which
|
|
||||||
MAC address to use as a destination address. Broadcasts and
|
|
||||||
multicasts are special, all other addresses are looked up in the
|
|
||||||
ARP table. */
|
|
||||||
queryaddr = ipaddr;
|
|
||||||
if (ip_addr_isany(ipaddr) ||
|
|
||||||
ip_addr_isbroadcast(ipaddr, &(netif->netmask))) {
|
|
||||||
dest = (struct eth_addr *)ðbroadcast;
|
|
||||||
} else if (ip_addr_ismulticast(ipaddr)) {
|
|
||||||
/* Hash IP multicast address to MAC address. */
|
|
||||||
mcastaddr.addr[0] = 0x01;
|
|
||||||
mcastaddr.addr[1] = 0x0;
|
|
||||||
mcastaddr.addr[2] = 0x5e;
|
|
||||||
mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
|
|
||||||
mcastaddr.addr[4] = ip4_addr3(ipaddr);
|
|
||||||
mcastaddr.addr[5] = ip4_addr4(ipaddr);
|
|
||||||
dest = &mcastaddr;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
|
|
||||||
/* Use destination IP address if the destination is on the same
|
|
||||||
subnet as we are. */
|
|
||||||
queryaddr = ipaddr;
|
|
||||||
} else {
|
|
||||||
/* Otherwise we use the default router as the address to send
|
|
||||||
the Ethernet frame to. */
|
|
||||||
queryaddr = &(netif->gw);
|
|
||||||
}
|
|
||||||
dest = arp_lookup(queryaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If the arp_lookup() didn't find an address, we send out an ARP
|
|
||||||
query for the IP address. */
|
|
||||||
if (dest == NULL) {
|
|
||||||
q = arp_query(netif, ethernetif->ethaddr, queryaddr);
|
|
||||||
if (q != NULL) {
|
|
||||||
err = low_level_output(ethernetif, q);
|
|
||||||
pbuf_free(q);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#ifdef LINK_STATS
|
|
||||||
lwip_stats.link.drop++;
|
|
||||||
lwip_stats.link.memerr++;
|
|
||||||
#endif /* LINK_STATS */
|
|
||||||
return ERR_MEM;
|
|
||||||
}
|
|
||||||
ethhdr = p->payload;
|
|
||||||
|
|
||||||
for(i = 0; i < 6; i++) {
|
|
||||||
ethhdr->dest.addr[i] = dest->addr[i];
|
|
||||||
ethhdr->src.addr[i] = ethernetif->ethaddr->addr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
ethhdr->type = htons(ETHTYPE_IP);
|
|
||||||
|
|
||||||
return low_level_output(ethernetif, p);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -282,43 +220,47 @@ ethernetif_input(struct netif *netif)
|
|||||||
struct eth_hdr *ethhdr;
|
struct eth_hdr *ethhdr;
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
|
|
||||||
|
|
||||||
ethernetif = netif->state;
|
ethernetif = netif->state;
|
||||||
|
|
||||||
|
/* move received packet into a new pbuf */
|
||||||
p = low_level_input(ethernetif);
|
p = low_level_input(ethernetif);
|
||||||
|
/* no packet could be read, silently ignore this */
|
||||||
if (p != NULL) {
|
if (p == NULL) return;
|
||||||
|
/* points to packet payload, which starts with an Ethernet header */
|
||||||
|
ethhdr = p->payload;
|
||||||
|
|
||||||
#ifdef LINK_STATS
|
#ifdef LINK_STATS
|
||||||
lwip_stats.link.recv++;
|
lwip_stats.link.recv++;
|
||||||
#endif /* LINK_STATS */
|
#endif /* LINK_STATS */
|
||||||
|
|
||||||
ethhdr = p->payload;
|
ethhdr = p->payload;
|
||||||
|
|
||||||
switch (htons(ethhdr->type)) {
|
switch (htons(ethhdr->type)) {
|
||||||
case ETHTYPE_IP:
|
/* IP packet? */
|
||||||
arp_ip_input(netif, p);
|
case ETHTYPE_IP:
|
||||||
pbuf_header(p, -14);
|
/* update ARP table */
|
||||||
netif->input(p, netif);
|
etharp_ip_input(netif, p);
|
||||||
break;
|
/* skip Ethernet header */
|
||||||
|
pbuf_header(p, -sizeof(struct eth_hdr));
|
||||||
|
/* pass to network layer */
|
||||||
|
netif->input(p, netif);
|
||||||
|
break;
|
||||||
|
|
||||||
case ETHTYPE_ARP:
|
case ETHTYPE_ARP:
|
||||||
p = arp_arp_input(netif, ethernetif->ethaddr, p);
|
/* pass p to ARP module */
|
||||||
if (p != NULL) {
|
etharp_arp_input(netif, ethernetif->ethaddr, p);
|
||||||
low_level_output(ethernetif, p);
|
|
||||||
pbuf_free(p);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
|
p = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
arp_timer(void *arg)
|
arp_timer(void *arg)
|
||||||
{
|
{
|
||||||
arp_tmr();
|
etharp_tmr();
|
||||||
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
|
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,6 +279,13 @@ ethernetif_init(struct netif *netif)
|
|||||||
struct ethernetif *ethernetif;
|
struct ethernetif *ethernetif;
|
||||||
|
|
||||||
ethernetif = mem_malloc(sizeof(struct ethernetif));
|
ethernetif = mem_malloc(sizeof(struct ethernetif));
|
||||||
|
|
||||||
|
if (ethernetif == NULL)
|
||||||
|
{
|
||||||
|
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
netif->state = ethernetif;
|
netif->state = ethernetif;
|
||||||
netif->name[0] = IFNAME0;
|
netif->name[0] = IFNAME0;
|
||||||
netif->name[1] = IFNAME1;
|
netif->name[1] = IFNAME1;
|
||||||
@@ -346,7 +295,8 @@ ethernetif_init(struct netif *netif)
|
|||||||
ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
|
ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
|
||||||
|
|
||||||
low_level_init(netif);
|
low_level_init(netif);
|
||||||
arp_init();
|
|
||||||
|
etharp_init();
|
||||||
|
|
||||||
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
|
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
|||||||
@@ -610,7 +610,7 @@ int get_secret(
|
|||||||
|
|
||||||
addrs = NULL;
|
addrs = NULL;
|
||||||
|
|
||||||
if(!client || !client[0] && strcmp(client, ppp_settings.user)) {
|
if(!client || !client[0] || strcmp(client, ppp_settings.user)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Id: chpms.h,v 1.2 2003/11/14 14:56:31 likewise Exp $
|
* $Id: chpms.h,v 1.3 2004/02/07 00:30:03 likewise Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CHPMS_H
|
#ifndef CHPMS_H
|
||||||
|
|||||||
@@ -178,6 +178,20 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
|
|||||||
/*** LOCAL FUNCTION DEFINITIONS ***/
|
/*** LOCAL FUNCTION DEFINITIONS ***/
|
||||||
/**********************************/
|
/**********************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non-standard inet_ntoa left here for compat with original ppp
|
||||||
|
* sources. Assumes u32_t instead of struct in_addr.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char * _inet_ntoa(u32_t n)
|
||||||
|
{
|
||||||
|
struct in_addr ia;
|
||||||
|
ia.s_addr = n;
|
||||||
|
return inet_ntoa(ia);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define inet_ntoa _inet_ntoa
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ipcp_init - Initialize IPCP.
|
* ipcp_init - Initialize IPCP.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Definitions for tcp compression routines.
|
* Definitions for tcp compression routines.
|
||||||
*
|
*
|
||||||
* $Id: vj.h,v 1.3 2003/11/14 14:56:31 likewise Exp $
|
* $Id: vj.h,v 1.4 2004/02/07 00:30:03 likewise Exp $
|
||||||
*
|
*
|
||||||
* Copyright (c) 1989 Regents of the University of California.
|
* Copyright (c) 1989 Regents of the University of California.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
* pragmatically since otherwise unsigned comparisons can result
|
* pragmatically since otherwise unsigned comparisons can result
|
||||||
* against negative integers quite easily, and fail in subtle ways.
|
* against negative integers quite easily, and fail in subtle ways.
|
||||||
*/
|
*/
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct ip
|
struct ip
|
||||||
{
|
{
|
||||||
#if defined(NO_CHAR_BITFIELDS)
|
#if defined(NO_CHAR_BITFIELDS)
|
||||||
@@ -39,7 +38,6 @@ struct ip
|
|||||||
u_short ip_sum; /* checksum */
|
u_short ip_sum; /* checksum */
|
||||||
struct in_addr ip_src,ip_dst; /* source and dest address */
|
struct in_addr ip_src,ip_dst; /* source and dest address */
|
||||||
};
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
|
|
||||||
typedef u32_t tcp_seq;
|
typedef u32_t tcp_seq;
|
||||||
|
|
||||||
@@ -47,7 +45,6 @@ typedef u32_t tcp_seq;
|
|||||||
* TCP header.
|
* TCP header.
|
||||||
* Per RFC 793, September, 1981.
|
* Per RFC 793, September, 1981.
|
||||||
*/
|
*/
|
||||||
PACK_STRUCT_BEGIN
|
|
||||||
struct tcphdr
|
struct tcphdr
|
||||||
{
|
{
|
||||||
u_short th_sport; /* source port */
|
u_short th_sport; /* source port */
|
||||||
@@ -71,6 +68,5 @@ struct tcphdr
|
|||||||
u_short th_sum; /* checksum */
|
u_short th_sum; /* checksum */
|
||||||
u_short th_urp; /* urgent pointer */
|
u_short th_urp; /* urgent pointer */
|
||||||
};
|
};
|
||||||
PACK_STRUCT_END
|
|
||||||
|
|
||||||
#endif /* VJBSDHDR_H */
|
#endif /* VJBSDHDR_H */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -199,6 +199,7 @@ slipif_init(struct netif *netif)
|
|||||||
netif->name[1] = 'l';
|
netif->name[1] = 'l';
|
||||||
netif->output = slipif_output;
|
netif->output = slipif_output;
|
||||||
netif->mtu = 1500;
|
netif->mtu = 1500;
|
||||||
|
netif->flags = NETIF_FLAG_POINTTOPOINT;
|
||||||
|
|
||||||
netif->state = sio_open(netif->num);
|
netif->state = sio_open(netif->num);
|
||||||
if (!netif->state)
|
if (!netif->state)
|
||||||
|
|||||||
Reference in New Issue
Block a user