Compare commits

...

64 Commits

Author SHA1 Message Date
kieranm
6d73f82f41 Update version for 1.3.2 rc 1 2009-10-28 15:17:16 +00:00
kieranm
71ddff4964 Fix BUG#27445: grow cwnd with every duplicate ACK 2009-10-28 15:13:51 +00:00
goldsimon
af3b796488 Corrected parameter spelling in doc 2009-10-27 20:30:44 +00:00
goldsimon
e2de2c6bb2 Added netifapi_netif_set_addr() 2009-10-27 20:29:16 +00:00
goldsimon
2ff0ce2d0a Minor: Improved memory layout/alignment of struct dhcp for 32-bit platforms 2009-10-26 09:59:54 +00:00
goldsimon
b09b8a0ccc Tiny code size improvement using goto instead of duplicating code 2009-10-26 09:55:46 +00:00
goldsimon
db259c3557 Improved heap usage of lwip_getaddrinfo by only allocating one block of memory per call. 2009-10-26 09:30:50 +00:00
goldsimon
bcc87ef851 bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if pcb->recv is NULL to keep rcv_wnd correct) 2009-10-25 18:47:44 +00:00
goldsimon
650f16b6d9 Minor: fixed typo 2009-10-25 16:47:41 +00:00
goldsimon
ae2dd38e0d Another fix for bug #26251: RST process in TIME_WAIT TCP state 2009-10-25 11:45:11 +00:00
kieranm
0319c1cf90 Update link to wiki in README file 2009-10-23 15:23:23 +00:00
goldsimon
81f9442ac7 Fixed bug #27783: Silly window avoidance for small window sizes 2009-10-23 13:17:18 +00:00
goldsimon
18ab274af3 Fixed bug #26251: RST process in TIME_WAIT TCP state 2009-10-22 13:37:44 +00:00
goldsimon
65d1f52423 Changed fix for bug #27215 (TCP sent() callback gives leagin and trailing 1 byte len (SYN/FIN)) by decreasing pcb->acked appropriately 2009-10-21 15:42:14 +00:00
goldsimon
f1b82e0e9a bug #27315: zero window probe and FIN: only send pure FIN if the enqueued FIN segment doesn't contain any other data 2009-10-21 15:15:34 +00:00
goldsimon
67411c4299 Minor code simplification (don't store received pbuf, change conditional code to assert where applicable), check pbuf length before testing for valid reply 2009-10-19 20:06:01 +00:00
goldsimon
a37e62b7d0 Removed most calls to udp_connect since they aren't necessary when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. 2009-10-19 16:43:50 +00:00
goldsimon
e2c1f7d5b5 dhcp_unfold_reply: NULL memory might have been freed after mem_malloc returned NULL 2009-10-18 09:26:27 +00:00
goldsimon
ec97fbd101 dhcp_inform(): netif->dhcp pointed to unallocated memory when udp_new() failed 2009-10-18 09:13:47 +00:00
goldsimon
b7d7559cc9 Fixed bug #27215: TCP sent() callback gives leadin and trailing 1 byte len (SYN/FIN) 2009-10-18 08:30:44 +00:00
goldsimon
b4404ff0c8 Corrected typo 2009-10-18 08:23:05 +00:00
goldsimon
502e89f4ad Fixed bug #27315: zero window probe and FIN 2009-10-16 21:07:48 +00:00
goldsimon
d8d8cf7e98 Fixed bug #27390: Source IP check in ip_input() causes it to drop valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is enabled 2009-10-16 12:39:24 +00:00
goldsimon
d9a5094068 Fixed bug #27329: dupacks by unidirectional data transmit 2009-10-15 20:09:13 +00:00
goldsimon
a9740c6a44 Fixed bug #27709: conn->err race condition on netconn_recv() timeout by directly returning when sys_arch_mbox_fetch times out. 2009-10-15 14:33:18 +00:00
goldsimon
2dc027401f Fixed bug #27704: autoip starts with wrong address: LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead of network byte order 2009-10-15 14:05:35 +00:00
goldsimon
ac638c85f3 Fixed bug #27504: tcp_enqueue wrongly concatenates segments which are not consecutive when retransmitting unacked segments 2009-10-11 13:06:44 +00:00
goldsimon
c0e22c255c Fixed default values of some stats to only be enabled if used Fixes bug #27338: sys_stats is defined when NO_SYS = 1 2009-10-09 20:18:15 +00:00
goldsimon
1309e5e86f Accidentally endabled to compile the code -> back to #if 0 2009-10-09 20:16:26 +00:00
goldsimon
c34c024dd5 Updated comment in low_level_input() about pbuf len vs. tot_len if using preallocated pbufs (as requested in bug #27576: pbuf_realloc will assert or crash on a non-chained pbuf list) 2009-10-09 19:56:54 +00:00
goldsimon
6ef69ece95 patch #6930: [PATCH trivial] TCP_RMV remove unnecessary check - removed two checks for NULL which are not necessary. 2009-10-07 18:04:24 +00:00
goldsimon
a9cbdc141b patch #6888: Patch for UDP Netbufs to support dest-addr and dest-port 2009-10-07 17:58:30 +00:00
goldsimon
9e5cf1cf8e Reverted change for bug #27252 (Address pointer invalid after freeing pbuf in UDP receive callback) as it made more problems than before :-( 2009-10-07 17:50:46 +00:00
goldsimon
ddc783bee7 Make ip_current_netif() and ip_current_header() a define referring to extern variables to be save the function call. 2009-10-07 17:47:05 +00:00
goldsimon
68f92050e9 Make tcp_debug_state_str() always available, not only in DEBUG mode 2009-10-07 17:44:59 +00:00
goldsimon
bd2bc2ee14 Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK function" by checking for loopback before calling ip_frag 2009-08-30 20:52:43 +00:00
goldsimon
8a7c1c4926 do_connect: LWIP_ERROR on invalid/disabled protocol 2009-08-30 20:24:08 +00:00
goldsimon
cff3e0cad2 bug #26397: Added SLIP polling support (uses sio_tryread) 2009-08-26 21:06:18 +00:00
stoklund
b55cfbc342 Add patch #6725 to CHANGELOG 2009-08-26 07:18:50 +00:00
goldsimon
3115087d26 Commented the functions, added sio_tryread() for non-blocking read (to be used in slipif-polling mode) 2009-08-25 17:54:28 +00:00
goldsimon
057c51ff6d Use LWIP_UNUSED_ARG() instead of if(){}, fix unused arg warning if LWIP_ARP==0 2009-08-25 17:50:59 +00:00
goldsimon
f2f20cf133 fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 2009-08-25 17:49:47 +00:00
goldsimon
2c618705f0 task #9033: Support IEEE 802.1q tagged frame (VLAN), New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. 2009-08-25 15:24:49 +00:00
goldsimon
bc10ad2356 patch #6900: added define ip_ntoa(struct ip_addr*) 2009-08-25 14:53:25 +00:00
stoklund
857fac1168 Add C++ guards to autoip.h header. 2009-08-24 13:17:42 +00:00
stoklund
103ba9b0fc The DHCP client should enter the REBOOTING state when connecting to a
new network. If DHCP has bound to an address, it must be verified
after netif_set_link_up.
2009-08-24 13:12:37 +00:00
stoklund
d83fc6893b Don't use an AutoIP-configured address on a new network until the address has been configured.
When connecting to a new network with an AutoIP address, take the
interface down until the old address has passed the
AUTOIP_STATE_PROBING state.
2009-08-24 13:11:35 +00:00
goldsimon
e7d5739ce7 Fixed bug #27078: Possible memory leak in pppInit() 2009-08-23 17:40:29 +00:00
goldsimon
8bf57c0e14 Fixed bug #26657: DNS, if host name is "localhost", result is error. 2009-08-23 13:51:12 +00:00
goldsimon
dea7255fc5 Fixed bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF, Fixed wrong parenthesis, added check in init.c 2009-08-23 13:03:20 +00:00
goldsimon
ce3082976c Fixed bug #27266: wait-state debug message in pppMain occurs every ms 2009-08-23 12:37:36 +00:00
goldsimon
362a295e06 Fixed bug #27252: Address pointer invalid after freeing pbuf in UDP receive callback 2009-08-23 11:32:38 +00:00
goldsimon
0e91e2adf2 bug #27267: Added include to string.h where needed 2009-08-23 11:24:51 +00:00
goldsimon
4d49d952b6 patch #6843: tcp.h macro optimization patch (for little endian) 2009-08-23 11:13:19 +00:00
goldsimon
ae7a7a0abf Added function tcp_debug_state_str() to convert a tcp state to a human-readable string. 2009-08-23 10:57:37 +00:00
kieranm
4f265dce60 Update version number for CVS development 2009-08-18 12:53:35 +00:00
kieranm
bd96db8c9f Update version number of 1.3.1 final release 2009-08-18 12:47:13 +00:00
kieranm
0b75917121 BUG27209: handle trimming of segments when out of window or out of
order properly
2009-08-12 08:34:48 +00:00
kieranm
fa2dbc2b1b BUG27199: use snd_wl2 instead of snd_wl1 2009-08-12 08:32:14 +00:00
goldsimon
3a6165f0b9 Added missing include to <string.h> 2009-08-11 14:38:55 +00:00
goldsimon
62c27f7fce Fixed bug #27155: "'NULL' undeclared in inet_checksum.c" 2009-08-03 19:28:35 +00:00
goldsimon
7feb116bae Fixed bug #27105: "realloc() cannot replace mem_realloc()" by making mem_realloc static doing nothing when MEM_LIBC_MALLOC==1 2009-07-28 17:18:46 +00:00
goldsimon
730a938912 Added debug print when rejecting incoming connections due to exceeded listen backlog 2009-07-28 17:04:04 +00:00
goldsimon
3553efb75e Added newline to TCP header flags debug print 2009-07-28 17:02:48 +00:00
44 changed files with 1046 additions and 398 deletions

115
CHANGELOG
View File

@@ -19,8 +19,114 @@ HISTORY
++ New features:
2009-10-27 Simon Goldschmidt/Stephan Lesage
* netifapi.c/.h: Added netifapi_netif_set_addr()
2009-10-07 Simon Goldschmidt/Fabian Koch
* api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to
support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO)
2009-08-26 Simon Goldschmidt/Simon Kallweit
* slipif.c/.h: bug #26397: SLIP polling support
2009-08-25 Simon Goldschmidt
* opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN),
New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK.
2009-08-25 Simon Goldschmidt
* ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*)
2009-08-24 Jakob Stoklund Olesen
* autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond
to netif_set_link_up().
2009-08-23 Simon Goldschmidt
* tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state
to a human-readable string.
++ Bugfixes:
2009-10-27: Kieran Mansley
* tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK
2009-10-25: Simon Goldschmidt
* tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if
pcb->recv is NULL to keep rcv_wnd correct)
2009-10-25: Simon Goldschmidt
* tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state
2009-10-23: Simon Goldschmidt (David Empson)
* tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes
2009-10-21: Simon Goldschmidt
* tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and
trailing 1 byte len (SYN/FIN)
2009-10-21: Simon Goldschmidt
* tcp_out.c: Fixed bug #27315: zero window probe and FIN
2009-10-19: Simon Goldschmidt
* dhcp.c/.h: Minor code simplification (don't store received pbuf, change
conditional code to assert where applicable), check pbuf length before
testing for valid reply
2009-10-19: Simon Goldschmidt
* dhcp.c: Removed most calls to udp_connect since they aren't necessary
when using udp_sendto_if() - always stay connected to IP_ADDR_ANY.
2009-10-16: Simon Goldschmidt
* ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop
valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is
enabled
2009-10-15: Simon Goldschmidt (Oleg Tyshev)
* tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit
2009-10-15: Simon Goldschmidt
* api_msg.c: Fixed bug #27709: conn->err race condition on netconn_recv()
timeout
2009-10-15: Simon Goldschmidt
* autoip.c: Fixed bug #27704: autoip starts with wrong address
LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead
of network byte order
2009-10-11 Simon Goldschmidt (J<>rg Kesten)
* tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments
which are not consecutive when retransmitting unacked segments
2009-10-09 Simon Goldschmidt
* opt.h: Fixed default values of some stats to only be enabled if used
Fixes bug #27338: sys_stats is defined when NO_SYS = 1
2009-08-30 Simon Goldschmidt
* ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK
function" by checking for loopback before calling ip_frag
2009-08-25 Simon Goldschmidt
* dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0
2009-08-23 Simon Goldschmidt
* ppp.c: bug #27078: Possible memory leak in pppInit()
2009-08-23 Simon Goldschmidt
* netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result
is error.
2009-08-23 Simon Goldschmidt
* opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF
Fixed wrong parenthesis, added check in init.c
2009-08-23 Simon Goldschmidt
* ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms
2009-08-23 Simon Goldschmidt
* many ppp files: bug #27267: Added include to string.h where needed
2009-08-23 Simon Goldschmidt
* tcp.h: patch #6843: tcp.h macro optimization patch (for little endian)
(STABLE-1.3.1)
@@ -115,6 +221,15 @@ HISTORY
++ Bugfixes:
2009-08-12 Kieran Mansley
* tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when
out of window or out of order properly
2009-08-12 Kieran Mansley
* tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1
2009-07-28 Simon Goldschmidt
* mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s
2009-07-27 Kieran Mansley
* api.h api_msg.h netdb.h sockets.h: add missing #include directives

2
README
View File

@@ -72,7 +72,7 @@ current CVS sources and is available from this web page:
http://www.nongnu.org/lwip/
There is now a constantly growin wiki about lwIP at
http://lwip.scribblewiki.com/
http://lwip.wikia.com/wiki/LwIP_Wiki
Also, there are mailing lists you can subscribe at
http://savannah.nongnu.org/mail/?group=lwip

View File

@@ -327,8 +327,9 @@ netconn_recv(struct netconn *conn)
#if LWIP_SO_RCVTIMEO
if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
memp_free(MEMP_NETBUF, buf);
conn->err = ERR_TIMEOUT;
p = NULL;
return NULL;
}
#else
sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, 0);

View File

@@ -168,6 +168,15 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
buf->ptr = p;
buf->addr = addr;
buf->port = port;
#if LWIP_NETBUF_RECVINFO
{
const struct ip_hdr* iphdr = ip_current_header();
/* get the UDP header - always in the first pbuf, ensured by udp_input */
const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));
buf->toaddr = (struct ip_addr*)&iphdr->dest;
buf->toport = udphdr->dest;
}
#endif /* LWIP_NETBUF_RECVINFO */
}
if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
@@ -807,6 +816,8 @@ do_connect(struct api_msg_msg *msg)
break;
#endif /* LWIP_TCP */
default:
LWIP_ERROR("Invalid netconn type", 0, do{ msg->conn->err = ERR_VAL;
sys_sem_signal(msg->conn->op_completed); }while(0));
break;
}
}

View File

@@ -62,6 +62,11 @@ netbuf *netbuf_new(void)
buf->p = NULL;
buf->ptr = NULL;
buf->addr = NULL;
buf->port = 0;
#if LWIP_NETBUF_RECVINFO
buf->toaddr = NULL;
buf->toport = 0;
#endif /* LWIP_NETBUF_RECVINFO */
return buf;
} else {
return NULL;

View File

@@ -42,6 +42,9 @@
#include "lwip/ip_addr.h"
#include "lwip/api.h"
#include <string.h>
#include <stdlib.h>
/** helper struct for gethostbyname_r to access the char* buffer */
struct gethostbyname_r_helper {
struct ip_addr *addrs;
@@ -113,7 +116,7 @@ lwip_gethostbyname(const char *name)
u8_t idx;
for ( idx=0; s_hostent.h_aliases[idx]; idx++) {
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx]));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx]));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx]));
}
}
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype));
@@ -123,7 +126,7 @@ lwip_gethostbyname(const char *name)
u8_t idx;
for ( idx=0; s_hostent.h_addr_list[idx]; idx++) {
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, inet_ntoa(*((struct in_addr*)(s_hostent.h_addr_list[idx])))));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa(s_hostent.h_addr_list[idx])));
}
}
#endif /* DNS_DEBUG */
@@ -231,12 +234,6 @@ lwip_freeaddrinfo(struct addrinfo *ai)
struct addrinfo *next;
while (ai != NULL) {
if (ai->ai_addr != NULL) {
mem_free(ai->ai_addr);
}
if (ai->ai_canonname != NULL) {
mem_free(ai->ai_canonname);
}
next = ai->ai_next;
mem_free(ai);
ai = next;
@@ -271,6 +268,8 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
struct addrinfo *ai;
struct sockaddr_in *sa = NULL;
int port_nr = 0;
size_t total_size;
size_t namelen = 0;
if (res == NULL) {
return EAI_FAIL;
@@ -297,19 +296,21 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
}
} else {
/* service location specified, use loopback address */
addr.addr = INADDR_LOOPBACK;
addr.addr = htonl(INADDR_LOOPBACK);
}
ai = mem_malloc(sizeof(struct addrinfo));
total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in);
if (nodename != NULL) {
namelen = strlen(nodename);
LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1);
total_size += namelen + 1;
}
ai = mem_malloc(total_size);
if (ai == NULL) {
goto memerr;
}
memset(ai, 0, sizeof(struct addrinfo));
sa = mem_malloc(sizeof(struct sockaddr_in));
if (sa == NULL) {
goto memerr;
}
memset(sa, 0, sizeof(struct sockaddr_in));
memset(ai, 0, total_size);
sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo));
/* set up sockaddr */
sa->sin_addr.s_addr = addr.addr;
sa->sin_family = AF_INET;
@@ -325,12 +326,7 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
}
if (nodename != NULL) {
/* copy nodename to canonname if specified */
size_t namelen = strlen(nodename);
LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1);
ai->ai_canonname = mem_malloc((mem_size_t)(namelen + 1));
if (ai->ai_canonname == NULL) {
goto memerr;
}
ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
MEMCPY(ai->ai_canonname, nodename, namelen);
ai->ai_canonname[namelen] = 0;
}
@@ -344,9 +340,6 @@ memerr:
if (ai != NULL) {
mem_free(ai);
}
if (sa != NULL) {
mem_free(sa);
}
return EAI_MEMORY;
}

View File

@@ -58,6 +58,20 @@ do_netifapi_netif_add( struct netifapi_msg_msg *msg)
TCPIP_NETIFAPI_ACK(msg);
}
/**
* Call netif_set_addr() inside the tcpip_thread context.
*/
void
do_netifapi_netif_set_addr( struct netifapi_msg_msg *msg)
{
netif_set_addr( msg->netif,
msg->msg.add.ipaddr,
msg->msg.add.netmask,
msg->msg.add.gw);
msg->err = ERR_OK;
TCPIP_NETIFAPI_ACK(msg);
}
/**
* Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
* tcpip_thread context.
@@ -103,6 +117,28 @@ netifapi_netif_add(struct netif *netif,
return msg.msg.err;
}
/**
* Call netif_set_addr() in a thread-safe way by running that function inside the
* tcpip_thread context.
*
* @note for params @see netif_set_addr()
*/
err_t
netifapi_netif_set_addr(struct netif *netif,
struct ip_addr *ipaddr,
struct ip_addr *netmask,
struct ip_addr *gw)
{
struct netifapi_msg msg;
msg.function = do_netifapi_netif_set_addr;
msg.msg.netif = netif;
msg.msg.msg.add.ipaddr = ipaddr;
msg.msg.msg.add.netmask = netmask;
msg.msg.msg.add.gw = gw;
TCPIP_NETIFAPI(&msg);
return msg.msg.err;
}
/**
* call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
* way by running that function inside the tcpip_thread context.

View File

@@ -99,6 +99,10 @@
* MTU is checked to be big enough in dhcp_start */
#define DHCP_MAX_MSG_LEN(netif) (netif->mtu)
#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576
/** Minimum length for reply before packet is parsed */
#define DHCP_MIN_REPLY_LEN 44
#define REBOOT_TRIES 2
/* DHCP client state machine functions */
static void dhcp_handle_ack(struct netif *netif);
@@ -107,17 +111,18 @@ static void dhcp_handle_offer(struct netif *netif);
static err_t dhcp_discover(struct netif *netif);
static err_t dhcp_select(struct netif *netif);
static void dhcp_check(struct netif *netif);
static void dhcp_bind(struct netif *netif);
#if DHCP_DOES_ARP_CHECK
static void dhcp_check(struct netif *netif);
static err_t dhcp_decline(struct netif *netif);
#endif /* DHCP_DOES_ARP_CHECK */
static err_t dhcp_rebind(struct netif *netif);
static err_t dhcp_reboot(struct netif *netif);
static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state);
/* receive, unfold, parse and free incoming messages */
static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
static err_t dhcp_unfold_reply(struct dhcp *dhcp);
static err_t dhcp_unfold_reply(struct dhcp *dhcp, struct pbuf *p);
static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type);
static u8_t dhcp_get_option_byte(u8_t *ptr);
#if 0
@@ -175,6 +180,7 @@ dhcp_handle_nak(struct netif *netif)
dhcp_discover(netif);
}
#if DHCP_DOES_ARP_CHECK
/**
* Checks if the offered IP address is already in use.
*
@@ -204,6 +210,7 @@ dhcp_check(struct netif *netif)
dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs));
}
#endif /* DHCP_DOES_ARP_CHECK */
/**
* Remember the configuration offered by a DHCP server.
@@ -286,12 +293,8 @@ dhcp_select(struct netif *netif)
/* shrink the pbuf to the actual content length */
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
/* TODO: we really should bind to a specific local interface here
but we cannot specify an unconfigured netif as it is addressless */
/* send broadcast to any DHCP server */
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
/* reconnect to any (or to server here?!) */
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
dhcp_delete_request(netif);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n"));
} else {
@@ -393,6 +396,7 @@ dhcp_timeout(struct netif *netif)
dhcp_release(netif);
dhcp_discover(netif);
}
#if DHCP_DOES_ARP_CHECK
/* received no ARP reply for the offered address (which is good) */
} else if (dhcp->state == DHCP_CHECKING) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
@@ -404,6 +408,7 @@ dhcp_timeout(struct netif *netif)
/* bind the interface to the offered address */
dhcp_bind(netif);
}
#endif /* DHCP_DOES_ARP_CHECK */
}
/* did not get response to renew request? */
else if (dhcp->state == DHCP_RENEWING) {
@@ -421,6 +426,12 @@ dhcp_timeout(struct netif *netif)
dhcp_release(netif);
dhcp_discover(netif);
}
} else if (dhcp->state == DHCP_REBOOTING) {
if (dhcp->tries < REBOOT_TRIES) {
dhcp_reboot(netif);
} else {
dhcp_discover(netif);
}
}
}
@@ -604,9 +615,9 @@ dhcp_start(struct netif *netif)
if (dhcp->pcb != NULL) {
udp_remove(dhcp->pcb);
}
if (dhcp->p != NULL) {
pbuf_free(dhcp->p);
}
LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL);
LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
dhcp->options_in == NULL && dhcp->options_in_len == 0);
}
/* clear data structure */
@@ -652,23 +663,23 @@ dhcp_start(struct netif *netif)
void
dhcp_inform(struct netif *netif)
{
struct dhcp *dhcp, *old_dhcp = netif->dhcp;
struct dhcp *dhcp, *old_dhcp;
err_t result = ERR_OK;
dhcp = mem_malloc(sizeof(struct dhcp));
if (dhcp == NULL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n"));
return;
}
netif->dhcp = dhcp;
memset(dhcp, 0, sizeof(struct dhcp));
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): allocated dhcp\n"));
dhcp->pcb = udp_new();
if (dhcp->pcb == NULL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 2, ("dhcp_inform(): could not obtain pcb"));
mem_free((void *)dhcp);
return;
goto free_dhcp_and_return;
}
old_dhcp = netif->dhcp;
netif->dhcp = dhcp;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n"));
/* create and initialize the DHCP message header */
result = dhcp_create_request(netif);
@@ -688,21 +699,48 @@ dhcp_inform(struct netif *netif)
dhcp->pcb->so_options|=SOF_BROADCAST;
#endif /* IP_SOF_BROADCAST */
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n"));
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
dhcp_delete_request(netif);
} else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 2, ("dhcp_inform: could not allocate DHCP request\n"));
}
if (dhcp->pcb != NULL) {
udp_remove(dhcp->pcb);
}
udp_remove(dhcp->pcb);
dhcp->pcb = NULL;
mem_free((void *)dhcp);
netif->dhcp = old_dhcp;
free_dhcp_and_return:
mem_free((void *)dhcp);
}
/** Handle a possible change in the network configuration.
*
* This enters the REBOOTING state to verify that the currently bound
* address is still valid.
*/
void
dhcp_network_changed(struct netif *netif)
{
struct dhcp *dhcp = netif->dhcp;
if (!dhcp)
return;
switch (dhcp->state) {
case DHCP_REBINDING:
case DHCP_RENEWING:
case DHCP_BOUND:
case DHCP_REBOOTING:
netif_set_down(netif);
dhcp->tries = 0;
dhcp_reboot(netif);
break;
case DHCP_OFF:
/* stay off */
break;
default:
dhcp->tries = 0;
dhcp_discover(netif);
break;
}
}
#if DHCP_DOES_ARP_CHECK
@@ -759,8 +797,6 @@ dhcp_decline(struct netif *netif)
/* resize pbuf to reflect true size of options */
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
/* @todo: should we really connect here? we are performing sendto() */
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
/* per section 4.4.4, broadcast DECLINE messages */
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
dhcp_delete_request(netif);
@@ -812,7 +848,6 @@ dhcp_discover(struct netif *netif)
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
@@ -974,7 +1009,6 @@ dhcp_renew(struct netif *netif)
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
dhcp_delete_request(netif);
@@ -1040,7 +1074,6 @@ dhcp_rebind(struct netif *netif)
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
/* broadcast to server */
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
dhcp_delete_request(netif);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
@@ -1054,6 +1087,52 @@ dhcp_rebind(struct netif *netif)
return result;
}
/**
* Enter REBOOTING state to verify an existing lease
*
* @param netif network interface which must reboot
*/
static err_t
dhcp_reboot(struct netif *netif)
{
struct dhcp *dhcp = netif->dhcp;
err_t result;
u16_t msecs;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n"));
dhcp_set_state(dhcp, DHCP_REBOOTING);
/* create and initialize the DHCP message header */
result = dhcp_create_request(netif);
if (result == ERR_OK) {
dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN);
dhcp_option_byte(dhcp, DHCP_REQUEST);
dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
dhcp_option_short(dhcp, 576);
dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
dhcp_option_trailer(dhcp);
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
/* broadcast to server */
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
dhcp_delete_request(netif);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n"));
} else {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 2, ("dhcp_reboot: could not allocate DHCP request\n"));
}
dhcp->tries++;
msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000;
dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs));
return result;
}
/**
* Release a DHCP lease.
*
@@ -1086,7 +1165,6 @@ dhcp_release(struct netif *netif)
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
dhcp_delete_request(netif);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));
@@ -1135,12 +1213,8 @@ dhcp_stop(struct netif *netif)
udp_remove(dhcp->pcb);
dhcp->pcb = NULL;
}
if (dhcp->p != NULL) {
pbuf_free(dhcp->p);
dhcp->p = NULL;
}
/* free unfolded reply */
dhcp_free_reply(dhcp);
LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
dhcp->options_in == NULL && dhcp->options_in_len == 0);
mem_free((void *)dhcp);
netif->dhcp = NULL;
}
@@ -1214,39 +1288,42 @@ dhcp_option_long(struct dhcp *dhcp, u32_t value)
*
*/
static err_t
dhcp_unfold_reply(struct dhcp *dhcp)
dhcp_unfold_reply(struct dhcp *dhcp, struct pbuf *p)
{
u16_t ret;
LWIP_ERROR("dhcp != NULL", (dhcp != NULL), return ERR_ARG;);
LWIP_ERROR("dhcp->p != NULL", (dhcp->p != NULL), return ERR_VAL;);
/* free any left-overs from previous unfolds */
dhcp_free_reply(dhcp);
/* options present? */
if (dhcp->p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN)) {
dhcp->options_in_len = dhcp->p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
if (p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN)) {
dhcp->options_in_len = p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
dhcp->options_in = mem_malloc(dhcp->options_in_len);
if (dhcp->options_in == NULL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));
dhcp->options_in_len = 0;
return ERR_MEM;
}
}
dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
if (dhcp->msg_in == NULL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));
mem_free((void *)dhcp->options_in);
dhcp->options_in = NULL;
if (dhcp->options_in != NULL) {
mem_free(dhcp->options_in);
dhcp->options_in = NULL;
dhcp->options_in_len = 0;
}
return ERR_MEM;
}
/** copy the DHCP message without options */
ret = pbuf_copy_partial(dhcp->p, dhcp->msg_in, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN, 0);
ret = pbuf_copy_partial(p, dhcp->msg_in, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN, 0);
LWIP_ASSERT("ret == sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN", ret == sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes into dhcp->msg_in[]\n",
sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN));
if (dhcp->options_in != NULL) {
/** copy the DHCP options */
ret = pbuf_copy_partial(dhcp->p, dhcp->options_in, dhcp->options_in_len, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
ret = pbuf_copy_partial(p, dhcp->options_in, dhcp->options_in_len, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
LWIP_ASSERT("ret == dhcp->options_in_len", ret == dhcp->options_in_len);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes to dhcp->options_in[]\n",
dhcp->options_in_len));
@@ -1258,7 +1335,6 @@ dhcp_unfold_reply(struct dhcp *dhcp)
/**
* Free the incoming DHCP message including contiguous copy of
* its DHCP options.
*
*/
static void dhcp_free_reply(struct dhcp *dhcp)
{
@@ -1267,14 +1343,13 @@ static void dhcp_free_reply(struct dhcp *dhcp)
dhcp->msg_in = NULL;
}
if (dhcp->options_in) {
mem_free((void *)dhcp->options_in);
mem_free(dhcp->options_in);
dhcp->options_in = NULL;
dhcp->options_in_len = 0;
}
LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));
}
/**
* If an incoming DHCP message is in response to us, then trigger the state machine
*/
@@ -1295,8 +1370,15 @@ static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_
LWIP_UNUSED_ARG(pcb);
LWIP_UNUSED_ARG(addr);
LWIP_UNUSED_ARG(port);
dhcp->p = p;
/* TODO: check packet length before reading them */
LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL &&
dhcp->options_in == NULL && dhcp->options_in_len == 0);
if (p->len < DHCP_MIN_REPLY_LEN) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 1, ("DHCP reply message too short\n"));
goto free_pbuf_and_return;
}
if (reply_msg->op != DHCP_BOOTREPLY) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 1, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op));
goto free_pbuf_and_return;
@@ -1315,7 +1397,7 @@ static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_
goto free_pbuf_and_return;
}
/* option fields could be unfold? */
if (dhcp_unfold_reply(dhcp) != ERR_OK) {
if (dhcp_unfold_reply(dhcp, p) != ERR_OK) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | 2, ("problem unfolding DHCP message - too short on memory?\n"));
goto free_pbuf_and_return;
}
@@ -1369,7 +1451,6 @@ static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_
free_pbuf_and_return:
dhcp_free_reply(dhcp);
pbuf_free(p);
dhcp->p = NULL;
}
/**

View File

@@ -961,7 +961,7 @@ dns_gethostbyname(const char *hostname, struct ip_addr *addr, dns_found_callback
#if LWIP_HAVE_LOOPIF
if (strcmp(hostname,"localhost")==0) {
addr->addr = INADDR_LOOPBACK;
addr->addr = htonl(INADDR_LOOPBACK);
return ERR_OK;
}
#endif /* LWIP_HAVE_LOOPIF */

View File

@@ -208,6 +208,8 @@ lwip_sanity_check(void)
#if LWIP_TCP
if (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN\n"));
if (TCP_SND_BUF < 2 * TCP_MSS)
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly\n"));
if (TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF/TCP_MSS)))
LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work\n"));
if (TCP_SNDLOWAT > TCP_SND_BUF)

View File

@@ -100,7 +100,7 @@
*/
#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
@@ -108,7 +108,10 @@
static void autoip_handle_arp_conflict(struct netif *netif);
/* creates a pseudo random LL IP-Address for a network interface */
static void autoip_create_addr(struct netif *netif, struct ip_addr *IPAddr);
static void autoip_create_addr(struct netif *netif, struct ip_addr *ipaddr);
/* sends an ARP probe */
static err_t autoip_arp_probe(struct netif *netif);
/* sends an ARP announce */
static err_t autoip_arp_announce(struct netif *netif);
@@ -116,6 +119,9 @@ static err_t autoip_arp_announce(struct netif *netif);
/* configure interface for use with current LL IP-Address */
static err_t autoip_bind(struct netif *netif);
/* start sending probes for llipaddr */
static void autoip_start_probing(struct netif *netif);
/**
* Initialize this module
*/
@@ -162,10 +168,10 @@ autoip_handle_arp_conflict(struct netif *netif)
* Create an IP-Address out of range 169.254.1.0 to 169.254.254.255
*
* @param netif network interface on which create the IP-Address
* @param IPAddr ip address to initialize
* @param ipaddr ip address to initialize
*/
static void
autoip_create_addr(struct netif *netif, struct ip_addr *IPAddr)
autoip_create_addr(struct netif *netif, struct ip_addr *ipaddr)
{
/* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
* compliant to RFC 3927 Section 2.1
@@ -183,12 +189,25 @@ autoip_create_addr(struct netif *netif, struct ip_addr *IPAddr)
addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
}
LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
(addr <= AUTOIP_RANGE_END));
IPAddr->addr = htonl(addr);
(addr <= AUTOIP_RANGE_END));
ipaddr->addr = htonl(addr);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 1,
("autoip_create_addr(): tried_llipaddr=%"U16_F", 0x%08"X32_F"\n",
(u16_t)(netif->autoip->tried_llipaddr), (u32_t)(IPAddr->addr)));
(u16_t)(netif->autoip->tried_llipaddr), (u32_t)(ipaddr->addr)));
}
/**
* Sends an ARP probe from a network interface
*
* @param netif network interface used to send the probe
*/
static err_t
autoip_arp_probe(struct netif *netif)
{
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
(struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, &ethzero,
&netif->autoip->llipaddr, ARP_REQUEST);
}
/**
@@ -281,6 +300,16 @@ autoip_start(struct netif *netif)
autoip_create_addr(netif, &(autoip->llipaddr));
autoip->tried_llipaddr++;
autoip_start_probing(netif);
return result;
}
static void
autoip_start_probing(struct netif *netif)
{
struct autoip *autoip = netif->autoip;
autoip->state = AUTOIP_STATE_PROBING;
autoip->sent_num = 0;
@@ -295,12 +324,24 @@ autoip_start(struct netif *netif)
* accquiring and probing address
* compliant to RFC 3927 Section 2.2.1
*/
if(autoip->tried_llipaddr > MAX_CONFLICTS) {
autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
}
return result;
/**
* Handle a possible change in the network configuration.
*
* If there is an AutoIP address configured, take the interface down
* and begin probing with the same address.
*/
void
autoip_network_changed(struct netif *netif)
{
if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) {
netif_set_down(netif);
autoip_start_probing(netif);
}
}
/**
@@ -340,12 +381,12 @@ autoip_tmr()
if(netif->autoip->ttw > 0) {
netif->autoip->ttw--;
} else {
if(netif->autoip->sent_num == PROBE_NUM) {
if(netif->autoip->sent_num >= PROBE_NUM) {
netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
netif->autoip->sent_num = 0;
netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
} else {
etharp_request(netif, &(netif->autoip->llipaddr));
autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
("autoip_tmr() PROBING Sent Probe\n"));
netif->autoip->sent_num++;
@@ -363,21 +404,24 @@ autoip_tmr()
} else {
if(netif->autoip->sent_num == 0) {
/* We are here the first time, so we waited ANNOUNCE_WAIT seconds
* Now we can bind to an IP address and use it
* Now we can bind to an IP address and use it.
*
* autoip_bind calls netif_set_up. This triggers a gratuitous ARP
* which counts as an announcement.
*/
autoip_bind(netif);
}
if(netif->autoip->sent_num == ANNOUNCE_NUM) {
netif->autoip->state = AUTOIP_STATE_BOUND;
netif->autoip->sent_num = 0;
netif->autoip->ttw = 0;
} else {
autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
("autoip_tmr() ANNOUNCING Sent Announce\n"));
netif->autoip->sent_num++;
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
netif->autoip->sent_num++;
if(netif->autoip->sent_num >= ANNOUNCE_NUM) {
netif->autoip->state = AUTOIP_STATE_BOUND;
netif->autoip->sent_num = 0;
netif->autoip->ttw = 0;
}
}
break;

View File

@@ -41,6 +41,8 @@
#include "lwip/inet_chksum.h"
#include "lwip/inet.h"
#include <stddef.h>
/* These are some reference implementations of the checksum algorithm, with the
* aim of being simple, correct and fully portable. Checksumming is the
* first thing you would want to optimize for your platform. If you create

View File

@@ -56,44 +56,18 @@
#include "lwip/stats.h"
#include "arch/perf.h"
#include <string.h>
/**
* The interface that provided the packet for the current callback
* invocation.
*/
static struct netif *current_netif;
struct netif *current_netif;
/**
* Header of the input packet currently being processed.
*/
static const struct ip_hdr *current_header;
/**
* Get the interface that received the current packet.
*
* This function must only be called from a receive callback (udp_recv,
* raw_recv, tcp_accept). It will return NULL otherwise.
*
* @param pcb Pointer to the pcb receiving a packet.
*/
struct netif *
ip_current_netif(void)
{
return current_netif;
}
/**
* Get the IP header of the current packet.
*
* This function must only be called from a receive callback (udp_recv,
* raw_recv, tcp_accept). It will return NULL otherwise.
*
* @param pcb Pointer to the pcb receiving a packet.
*/
const struct ip_hdr *
ip_current_header(void)
{
return current_header;
}
const struct ip_hdr *current_header;
/**
* Finds the appropriate network interface for a given IP address. It
@@ -347,7 +321,8 @@ ip_input(struct pbuf *p, struct netif *inp)
/* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
#if LWIP_DHCP
if (check_ip_src)
/* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
if (check_ip_src && (iphdr->src.addr != 0))
#endif /* LWIP_DHCP */
{ if ((ip_addr_isbroadcast(&(iphdr->src), inp)) ||
(ip_addr_ismulticast(&(iphdr->src)))) {
@@ -601,30 +576,27 @@ err_t ip_output_if_opt(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest
dest = &(iphdr->dest);
}
#if IP_FRAG
/* don't fragment if interface has mtu set to 0 [loopif] */
if (netif->mtu && (p->tot_len > netif->mtu))
return ip_frag(p,netif,dest);
#endif
IP_STATS_INC(ip.xmit);
LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
ip_debug_print(p);
#if (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
#if ENABLE_LOOPBACK
if (ip_addr_cmp(dest, &netif->ip_addr)) {
/* Packet to self, enqueue it for loopback */
LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
return netif_loop_output(netif, p, dest);
} else
#endif /* (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) */
{
LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
return netif->output(netif, p, dest);
}
#endif /* ENABLE_LOOPBACK */
#if IP_FRAG
/* don't fragment if interface has mtu set to 0 [loopif] */
if (netif->mtu && (p->tot_len > netif->mtu)) {
return ip_frag(p,netif,dest);
}
#endif
LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
return netif->output(netif, p, dest);
}
/**

View File

@@ -52,6 +52,13 @@
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
#endif /* ENABLE_LOOPBACK */
#if LWIP_AUTOIP
#include "lwip/autoip.h"
#endif /* LWIP_AUTOIP */
#if LWIP_DHCP
#include "lwip/dhcp.h"
#endif /* LWIP_DHCP */
#if LWIP_NETIF_STATUS_CALLBACK
#define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); }
#else
@@ -406,7 +413,13 @@ void netif_set_up(struct netif *netif)
etharp_gratuitous(netif);
}
#endif /* LWIP_ARP */
#if LWIP_IGMP
/* resend IGMP memberships */
if (netif->flags & NETIF_FLAG_IGMP) {
igmp_report_groups( netif);
}
#endif /* LWIP_IGMP */
}
}
@@ -459,6 +472,19 @@ void netif_set_link_up(struct netif *netif )
{
netif->flags |= NETIF_FLAG_LINK_UP;
#if LWIP_DHCP
if (netif->dhcp) {
dhcp_network_changed(netif);
}
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
if (netif->autoip) {
autoip_network_changed(netif);
}
#endif /* LWIP_AUTOIP */
if (netif->flags & NETIF_FLAG_UP) {
#if LWIP_ARP
/* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */
if (netif->flags & NETIF_FLAG_ETHARP) {
@@ -467,12 +493,12 @@ void netif_set_link_up(struct netif *netif )
#endif /* LWIP_ARP */
#if LWIP_IGMP
/* resend IGMP memberships */
if (netif->flags & NETIF_FLAG_IGMP) {
igmp_report_groups( netif);
}
/* resend IGMP memberships */
if (netif->flags & NETIF_FLAG_IGMP) {
igmp_report_groups( netif);
}
#endif /* LWIP_IGMP */
}
NETIF_LINK_CALLBACK(netif);
}

View File

@@ -2077,25 +2077,25 @@ void snmp_get_snmpenableauthentraps(u8_t *value)
void
noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
{
if (ident_len){}
if (ident){}
LWIP_UNUSED_ARG(ident_len);
LWIP_UNUSED_ARG(ident);
od->instance = MIB_OBJECT_NONE;
}
void
noleafs_get_value(struct obj_def *od, u16_t len, void *value)
{
if (od){}
if (len){}
if (value){}
LWIP_UNUSED_ARG(od);
LWIP_UNUSED_ARG(len);
LWIP_UNUSED_ARG(value);
}
u8_t
noleafs_set_test(struct obj_def *od, u16_t len, void *value)
{
if (od){}
if (len){}
if (value){}
LWIP_UNUSED_ARG(od);
LWIP_UNUSED_ARG(len);
LWIP_UNUSED_ARG(value);
/* can't set */
return 0;
}
@@ -2103,9 +2103,9 @@ noleafs_set_test(struct obj_def *od, u16_t len, void *value)
void
noleafs_set_value(struct obj_def *od, u16_t len, void *value)
{
if (od){}
if (len){}
if (value){}
LWIP_UNUSED_ARG(od);
LWIP_UNUSED_ARG(len);
LWIP_UNUSED_ARG(value);
}
@@ -2238,7 +2238,7 @@ system_set_test(struct obj_def *od, u16_t len, void *value)
{
u8_t id, set_ok;
if (value) {}
LWIP_UNUSED_ARG(value);
set_ok = 0;
id = od->id_inst_ptr[0];
switch (id)
@@ -2332,7 +2332,7 @@ interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
static void
interfaces_get_value(struct obj_def *od, u16_t len, void *value)
{
if (len){}
LWIP_UNUSED_ARG(len);
if (od->id_inst_ptr[0] == 1)
{
s32_t *sint_ptr = value;
@@ -2724,7 +2724,8 @@ atentry_get_value(struct obj_def *od, u16_t len, void *value)
struct ip_addr ip;
struct netif *netif;
if (len) {}
LWIP_UNUSED_ARG(len);
LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */
snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
snmp_oidtoip(&od->id_inst_ptr[2], &ip);
@@ -2831,7 +2832,7 @@ ip_get_value(struct obj_def *od, u16_t len, void *value)
{
u8_t id;
if (len) {}
LWIP_UNUSED_ARG(len);
id = od->id_inst_ptr[0];
switch (id)
{
@@ -2985,7 +2986,7 @@ ip_set_test(struct obj_def *od, u16_t len, void *value)
u8_t id, set_ok;
s32_t *sint_ptr = value;
if (len) {}
LWIP_UNUSED_ARG(len);
set_ok = 0;
id = od->id_inst_ptr[0];
switch (id)
@@ -3065,7 +3066,7 @@ ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value)
struct ip_addr ip;
struct netif *netif = netif_list;
if (len) {}
LWIP_UNUSED_ARG(len);
snmp_oidtoip(&od->id_inst_ptr[1], &ip);
ip.addr = htonl(ip.addr);
ifidx = 0;
@@ -3408,7 +3409,8 @@ ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value)
struct ip_addr ip;
struct netif *netif;
if (len) {}
LWIP_UNUSED_ARG(len);
LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */
snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
snmp_oidtoip(&od->id_inst_ptr[2], &ip);
@@ -3482,7 +3484,7 @@ icmp_get_value(struct obj_def *od, u16_t len, void *value)
u32_t *uint_ptr = value;
u8_t id;
if (len){}
LWIP_UNUSED_ARG(len);
id = od->id_inst_ptr[0];
switch (id)
{
@@ -3636,7 +3638,7 @@ tcp_get_value(struct obj_def *od, u16_t len, void *value)
s32_t *sint_ptr = value;
u8_t id;
if (len){}
LWIP_UNUSED_ARG(len);
id = od->id_inst_ptr[0];
switch (id)
{
@@ -3804,7 +3806,7 @@ udp_get_value(struct obj_def *od, u16_t len, void *value)
u32_t *uint_ptr = value;
u8_t id;
if (len){}
LWIP_UNUSED_ARG(len);
id = od->id_inst_ptr[0];
switch (id)
{
@@ -3870,7 +3872,7 @@ udpentry_get_value(struct obj_def *od, u16_t len, void *value)
struct ip_addr ip;
u16_t port;
if (len){}
LWIP_UNUSED_ARG(len);
snmp_oidtoip(&od->id_inst_ptr[1], &ip);
ip.addr = htonl(ip.addr);
port = od->id_inst_ptr[5];
@@ -3977,7 +3979,7 @@ snmp_get_value(struct obj_def *od, u16_t len, void *value)
u32_t *uint_ptr = value;
u8_t id;
if (len){}
LWIP_UNUSED_ARG(len);
id = od->id_inst_ptr[0];
switch (id)
{
@@ -4080,7 +4082,7 @@ snmp_set_test(struct obj_def *od, u16_t len, void *value)
{
u8_t id, set_ok;
if (len) {}
LWIP_UNUSED_ARG(len);
set_ok = 0;
id = od->id_inst_ptr[0];
if (id == 30)
@@ -4113,7 +4115,7 @@ snmp_set_value(struct obj_def *od, u16_t len, void *value)
{
u8_t id;
if (len) {}
LWIP_UNUSED_ARG(len);
id = od->id_inst_ptr[0];
if (id == 30)
{

View File

@@ -49,9 +49,24 @@
#include "lwip/memp.h"
#include "lwip/snmp.h"
#include "lwip/tcp.h"
#include "lwip/debug.h"
#include <string.h>
const char *tcp_state_str[] = {
"CLOSED",
"LISTEN",
"SYN_SENT",
"SYN_RCVD",
"ESTABLISHED",
"FIN_WAIT_1",
"FIN_WAIT_2",
"CLOSE_WAIT",
"CLOSING",
"LAST_ACK",
"TIME_WAIT"
};
/* Incremented every coarse grained timer shot (typically every 500 ms). */
u32_t tcp_ticks;
const u8_t tcp_backoff[13] =
@@ -393,7 +408,7 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
{
u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + pcb->mss)) {
if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
/* we can advertise more window */
pcb->rcv_ann_wnd = pcb->rcv_wnd;
return new_right_edge - pcb->rcv_ann_right_edge;
@@ -423,6 +438,9 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
{
int wnd_inflation;
LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",
len <= 0xffff - pcb->rcv_wnd );
pcb->rcv_wnd += len;
if (pcb->rcv_wnd > TCP_WND)
pcb->rcv_wnd = TCP_WND;
@@ -1284,6 +1302,12 @@ tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr)
}
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
const char*
tcp_debug_state_str(enum tcp_state s)
{
return tcp_state_str[s];
}
#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
/**
* Print a tcp header for debugging purposes.
@@ -1329,42 +1353,7 @@ tcp_debug_print(struct tcp_hdr *tcphdr)
void
tcp_debug_print_state(enum tcp_state s)
{
LWIP_DEBUGF(TCP_DEBUG, ("State: "));
switch (s) {
case CLOSED:
LWIP_DEBUGF(TCP_DEBUG, ("CLOSED\n"));
break;
case LISTEN:
LWIP_DEBUGF(TCP_DEBUG, ("LISTEN\n"));
break;
case SYN_SENT:
LWIP_DEBUGF(TCP_DEBUG, ("SYN_SENT\n"));
break;
case SYN_RCVD:
LWIP_DEBUGF(TCP_DEBUG, ("SYN_RCVD\n"));
break;
case ESTABLISHED:
LWIP_DEBUGF(TCP_DEBUG, ("ESTABLISHED\n"));
break;
case FIN_WAIT_1:
LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n"));
break;
case FIN_WAIT_2:
LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n"));
break;
case CLOSE_WAIT:
LWIP_DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n"));
break;
case CLOSING:
LWIP_DEBUGF(TCP_DEBUG, ("CLOSING\n"));
break;
case LAST_ACK:
LWIP_DEBUGF(TCP_DEBUG, ("LAST_ACK\n"));
break;
case TIME_WAIT:
LWIP_DEBUGF(TCP_DEBUG, ("TIME_WAIT\n"));
break;
}
LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
}
/**
@@ -1399,6 +1388,7 @@ tcp_debug_print_flags(u8_t flags)
if (flags & TCP_CWR) {
LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
}
LWIP_DEBUGF(TCP_DEBUG, ("\n"));
}
/**

View File

@@ -288,7 +288,6 @@ tcp_input(struct pbuf *p, struct netif *inp)
return;
}
}
tcp_input_pcb = pcb;
err = tcp_process(pcb);
tcp_input_pcb = NULL;
@@ -408,6 +407,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
#if TCP_LISTEN_BACKLOG
if (pcb->accepts_pending >= pcb->backlog) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
return ERR_ABRT;
}
#endif /* TCP_LISTEN_BACKLOG */
@@ -480,13 +480,36 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
static err_t
tcp_timewait_input(struct tcp_pcb *pcb)
{
if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {
pcb->rcv_nxt = seqno + tcplen;
/* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */
/* RFC 793 3.9 Event Processing - Segment Arrives:
* - first check sequence number - we skip that one in TIME_WAIT (always
* acceptable since we only send ACKs)
* - second check the RST bit (... return) */
if (flags & TCP_RST) {
return ERR_OK;
}
if (tcplen > 0) {
tcp_ack_now(pcb);
/* - fourth, check the SYN bit, */
if (flags & TCP_SYN) {
/* If an incoming segment is not acceptable, an acknowledgment
should be sent in reply */
if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
/* If the SYN is in the window it is an error, send a reset */
tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src),
tcphdr->dest, tcphdr->src);
return ERR_OK;
}
} else if (flags & TCP_FIN) {
/* - eighth, check the FIN bit: Remain in the TIME-WAIT state.
Restart the 2 MSL time-wait timeout.*/
pcb->tmr = tcp_ticks;
}
return tcp_output(pcb);
if ((tcplen > 0)) {
/* Acknowledge data, FIN or out-of-window SYN */
pcb->flags |= TF_ACK_NOW;
return tcp_output(pcb);
}
return ERR_OK;
}
/**
@@ -627,6 +650,11 @@ tcp_process(struct tcp_pcb *pcb)
* we'd better pass it on to the application as well. */
tcp_receive(pcb);
/* Prevent ACK for SYN to generate a sent event */
if (pcb->acked != 0) {
pcb->acked--;
}
pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
if (recv_flags & TF_GOT_FIN) {
@@ -737,7 +765,7 @@ tcp_receive(struct tcp_pcb *pcb)
u8_t accepted_inseq = 0;
if (flags & TCP_ACK) {
right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
/* Update window. */
if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
@@ -764,10 +792,11 @@ tcp_receive(struct tcp_pcb *pcb)
if (pcb->lastack == ackno) {
pcb->acked = 0;
if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){
if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
++pcb->dupacks;
if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
if (!(pcb->flags & TF_INFR)) {
if (pcb->dupacks >= 3) {
if (!(pcb->flags & TF_INFR) && pcb->unacked != NULL) {
/* This is fast retransmit. Retransmit the first unacked segment. */
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %"U16_F" (%"U32_F"), fast retransmit %"U32_F"\n",
(u16_t)pcb->dupacks, pcb->lastack,
@@ -775,20 +804,20 @@ tcp_receive(struct tcp_pcb *pcb)
tcp_rexmit(pcb);
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
/*pcb->ssthresh = LWIP_MAX((pcb->snd_max -
pcb->lastack) / 2,
2 * pcb->mss);*/
pcb->lastack) / 2,
2 * pcb->mss);*/
/* Set ssthresh to half of the minimum of the current cwnd and the advertised window */
if (pcb->cwnd > pcb->snd_wnd)
pcb->ssthresh = pcb->snd_wnd / 2;
else
pcb->ssthresh = pcb->cwnd / 2;
/* The minimum value for ssthresh should be 2 MSS */
if (pcb->ssthresh < 2*pcb->mss) {
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: The minimum value for ssthresh %"U16_F" should be min 2 mss %"U16_F"...\n", pcb->ssthresh, 2*pcb->mss));
pcb->ssthresh = 2*pcb->mss;
}
pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
pcb->flags |= TF_INFR;
} else {
@@ -799,9 +828,12 @@ tcp_receive(struct tcp_pcb *pcb)
}
}
}
if (pcb->unacked == NULL && pcb->unsent == NULL)
pcb->dupacks = 0;
} else {
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n",
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
pcb->snd_wl2 + pcb->snd_wnd, right_wnd_edge));
}
} else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
/* We come here when the ACK acknowledges new data. */
@@ -867,6 +899,11 @@ tcp_receive(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
/* Prevent ACK for FIN to generate a sent event */
if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
pcb->acked--;
}
pcb->snd_queuelen -= pbuf_clen(next->p);
tcp_seg_free(next);
@@ -907,6 +944,10 @@ tcp_receive(struct tcp_pcb *pcb)
pcb->unsent = pcb->unsent->next;
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
/* Prevent ACK for FIN to generate a sent event */
if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
pcb->acked--;
}
pcb->snd_queuelen -= pbuf_clen(next->p);
tcp_seg_free(next);
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
@@ -1054,35 +1095,73 @@ tcp_receive(struct tcp_pcb *pcb)
/* The incoming segment is the next in sequence. We check if
we have to trim the end of the segment and update rcv_nxt
and pass the data to the application. */
tcplen = TCP_TCPLEN(&inseg);
if (tcplen > pcb->rcv_wnd) {
LWIP_DEBUGF(TCP_INPUT_DEBUG,
("tcp_receive: other end overran receive window"
"seqno %"U32_F" len %"U32_F" right edge %"U32_F"\n",
seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
/* Must remove the FIN from the header as we're trimming
* that byte of sequence-space from the packet */
TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN);
}
/* Adjust length of segment to fit in the window. */
inseg.len = pcb->rcv_wnd;
if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
inseg.len -= 1;
}
pbuf_realloc(inseg.p, inseg.len);
tcplen = TCP_TCPLEN(&inseg);
LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
(seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
}
#if TCP_QUEUE_OOSEQ
if (pcb->ooseq != NULL &&
TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
if (pcb->ooseq->len > 0) {
/* We have to trim the second edge of the incoming
segment. */
inseg.len = (u16_t)(pcb->ooseq->tcphdr->seqno - seqno);
pbuf_realloc(inseg.p, inseg.len);
} else {
/* does the ooseq segment contain only flags that are in inseg also? */
if ((TCPH_FLAGS(inseg.tcphdr) & (TCP_FIN|TCP_SYN)) ==
(TCPH_FLAGS(pcb->ooseq->tcphdr) & (TCP_FIN|TCP_SYN))) {
if (pcb->ooseq != NULL) {
if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
LWIP_DEBUGF(TCP_INPUT_DEBUG,
("tcp_receive: received in-order FIN, binning ooseq queue\n"));
/* Received in-order FIN means anything that was received
* out of order must now have been received in-order, so
* bin the ooseq queue */
while (pcb->ooseq != NULL) {
struct tcp_seg *old_ooseq = pcb->ooseq;
pcb->ooseq = pcb->ooseq->next;
memp_free(MEMP_TCP_SEG, old_ooseq);
}
} else if (TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + tcplen)) {
if (pcb->ooseq->len > 0) {
/* We have to trim the second edge of the incoming segment. */
LWIP_ASSERT("tcp_receive: trimmed segment would have zero length\n",
TCP_SEQ_GT(pcb->ooseq->tcphdr->seqno, seqno));
/* FIN in inseg already handled by dropping whole ooseq queue */
inseg.len = (u16_t)(pcb->ooseq->tcphdr->seqno - seqno);
if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
inseg.len -= 1;
}
pbuf_realloc(inseg.p, inseg.len);
tcplen = TCP_TCPLEN(&inseg);
LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
(seqno + tcplen) == pcb->ooseq->tcphdr->seqno);
} else {
/* does the ooseq segment contain only flags that are in inseg also? */
if ((TCPH_FLAGS(inseg.tcphdr) & (TCP_FIN|TCP_SYN)) ==
(TCPH_FLAGS(pcb->ooseq->tcphdr) & (TCP_FIN|TCP_SYN))) {
struct tcp_seg *old_ooseq = pcb->ooseq;
pcb->ooseq = pcb->ooseq->next;
memp_free(MEMP_TCP_SEG, old_ooseq);
}
}
}
}
#endif /* TCP_QUEUE_OOSEQ */
tcplen = TCP_TCPLEN(&inseg);
pcb->rcv_nxt = seqno + tcplen;
/* Update the receiver's (our) window. */
if (pcb->rcv_wnd < tcplen) {
pcb->rcv_wnd = 0;
} else {
pcb->rcv_wnd -= tcplen;
}
LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
pcb->rcv_wnd -= tcplen;
tcp_update_rcv_ann_wnd(pcb);
@@ -1117,11 +1196,9 @@ tcp_receive(struct tcp_pcb *pcb)
seqno = pcb->ooseq->tcphdr->seqno;
pcb->rcv_nxt += TCP_TCPLEN(cseg);
if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
pcb->rcv_wnd = 0;
} else {
pcb->rcv_wnd -= TCP_TCPLEN(cseg);
}
LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
pcb->rcv_wnd >= TCP_TCPLEN(cseg));
pcb->rcv_wnd -= TCP_TCPLEN(cseg);
tcp_update_rcv_ann_wnd(pcb);

View File

@@ -347,7 +347,9 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
/* fit within max seg size */
(useg->len + queue->len <= pcb->mss) &&
/* only concatenate segments with the same options */
(useg->flags == queue->flags)) {
(useg->flags == queue->flags) &&
/* segments are consecutive */
(ntohl(useg->tcphdr->seqno) + useg->len == ntohl(queue->tcphdr->seqno)) ) {
/* Remove TCP header from first segment of our to-be-queued list */
if(pbuf_header(queue->p, -(TCP_HLEN + optlen))) {
/* Can we cope with this failing? Just assert for now */
@@ -924,6 +926,8 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
struct pbuf *p;
struct tcp_hdr *tcphdr;
struct tcp_seg *seg;
u16_t len;
u8_t is_fin;
LWIP_DEBUGF(TCP_DEBUG,
("tcp_zero_window_probe: sending ZERO WINDOW probe to %"
@@ -944,8 +948,10 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
if(seg == NULL)
return;
p = pbuf_alloc(PBUF_IP, TCP_HLEN + 1, PBUF_RAM);
is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0);
len = is_fin ? TCP_HLEN : TCP_HLEN + 1;
p = pbuf_alloc(PBUF_IP, len, PBUF_RAM);
if(p == NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n"));
return;
@@ -955,8 +961,13 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
tcphdr = tcp_output_set_header(pcb, p, 0, seg->tcphdr->seqno);
/* Copy in one byte from the head of the unacked queue */
*((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr;
if (is_fin) {
/* FIN segment, no data */
TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
} else {
/* Data segment, copy in one byte from the head of the unacked queue */
*((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr;
}
#if CHECKSUM_GEN_TCP
tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip,

View File

@@ -282,7 +282,7 @@ udp_input(struct pbuf *p, struct netif *inp)
/* callback */
if (pcb->recv != NULL) {
/* now the recv function is responsible for freeing p */
pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
pcb->recv(pcb->recv_arg, pcb, p, &iphdr->src, src);
} else {
/* no recv function registered? then we have to free the pbuf! */
pbuf_free(p);

View File

@@ -52,6 +52,10 @@
#include "lwip/udp.h"
#include "netif/etharp.h"
#ifdef __cplusplus
extern "C" {
#endif
/* AutoIP Timing */
#define AUTOIP_TMR_INTERVAL 100
#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL)
@@ -100,6 +104,13 @@ void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr);
/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */
void autoip_tmr(void);
/** Handle a possible change in the network configuration */
void autoip_network_changed(struct netif *netif);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_AUTOIP */
#endif /* __LWIP_AUTOIP_H__ */

View File

@@ -153,6 +153,11 @@ PACK_STRUCT_END
#define IPH_PROTO_SET(hdr, proto) (hdr)->_ttl_proto = (htons((proto) | (IPH_TTL(hdr) << 8)))
#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
/** The interface that provided the packet for the current callback invocation. */
extern struct netif *current_netif;
/** Header of the input packet currently being processed. */
extern const struct ip_hdr *current_header;
#define ip_init() /* Compatibility define, not init needed. */
struct netif *ip_route(struct ip_addr *dest);
err_t ip_input(struct pbuf *p, struct netif *inp);
@@ -170,8 +175,14 @@ err_t ip_output_if_opt(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest
u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
u16_t optlen);
#endif /* IP_OPTIONS_SEND */
struct netif *ip_current_netif(void);
const struct ip_hdr *ip_current_header(void);
/** Get the interface that received the current packet.
* This function must only be called from a receive callback (udp_recv,
* raw_recv, tcp_accept). It will return NULL otherwise. */
#define ip_current_netif() (current_netif)
/** Get the IP header of the current packet.
* This function must only be called from a receive callback (udp_recv,
* raw_recv, tcp_accept). It will return NULL otherwise. */
#define ip_current_header() (current_header)
#if IP_DEBUG
void ip_debug_print(struct pbuf *p);
#else

View File

@@ -161,6 +161,11 @@ u8_t ip_addr_isbroadcast(struct ip_addr *, struct netif *);
#define ip4_addr3(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff)
#define ip4_addr4(ipaddr) ((u16_t)(ntohl((ipaddr)->addr)) & 0xff)
/**
* Same as inet_ntoa() but takes a struct ip_addr*
*/
#define ip_ntoa(addr) ((addr != NULL) ? inet_ntoa(*((struct in_addr*)(addr))) : "NULL")
#ifdef __cplusplus
}
#endif

View File

@@ -83,7 +83,7 @@ struct api_msg_msg {
size_t len;
u8_t apiflags;
} w;
/** used ofr do_recv */
/** used for do_recv */
struct {
u16_t len;
} r;

View File

@@ -24,22 +24,20 @@ extern "C" {
struct dhcp
{
/** current DHCP state machine state */
u8_t state;
/** retries of current request */
u8_t tries;
/** transaction identifier of last sent request */
u32_t xid;
/** our connection to the DHCP server */
struct udp_pcb *pcb;
/** (first) pbuf of incoming msg */
struct pbuf *p;
/** incoming msg */
struct dhcp_msg *msg_in;
/** incoming msg options */
struct dhcp_msg *options_in;
void *options_in;
/** ingoing msg options length */
u16_t options_in_len;
/** current DHCP state machine state */
u8_t state;
/** retries of current request */
u8_t tries;
struct pbuf *p_out; /* pbuf of outcoming msg */
struct dhcp_msg *msg_out; /* outgoing msg */
@@ -124,6 +122,8 @@ err_t dhcp_release(struct netif *netif);
void dhcp_stop(struct netif *netif);
/** inform server of our manual IP address */
void dhcp_inform(struct netif *netif);
/** Handle a possible change in the network configuration */
void dhcp_network_changed(struct netif *netif);
/** if enabled, check whether the offered IP address is not in use, using ARP */
#if DHCP_DOES_ARP_CHECK

View File

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

View File

@@ -59,7 +59,11 @@ typedef size_t mem_size_t;
#define mem_calloc calloc
#endif
#ifndef mem_realloc
#define mem_realloc realloc
static void *mem_realloc(void *mem, mem_size_t size)
{
LWIP_UNUSED_ARG(size);
return mem;
}
#endif
#else /* MEM_LIBC_MALLOC */

View File

@@ -34,6 +34,7 @@
#include "lwip/opt.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
@@ -43,6 +44,10 @@ struct netbuf {
struct pbuf *p, *ptr;
struct ip_addr *addr;
u16_t port;
#if LWIP_NETBUF_RECVINFO
struct ip_addr *toaddr;
u16_t toport;
#endif /* LWIP_NETBUF_RECVINFO */
};
/* Network buffer functions: */
@@ -69,6 +74,10 @@ void netbuf_first (struct netbuf *buf);
#define netbuf_len(buf) ((buf)->p->tot_len)
#define netbuf_fromaddr(buf) ((buf)->addr)
#define netbuf_fromport(buf) ((buf)->port)
#if LWIP_NETBUF_RECVINFO
#define netbuf_destaddr(buf) ((buf)->toaddr)
#define netbuf_destport(buf) ((buf)->toport)
#endif /* LWIP_NETBUF_RECVINFO */
#ifdef __cplusplus
}

View File

@@ -78,6 +78,11 @@ err_t netifapi_netif_add ( struct netif *netif,
err_t (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif) );
err_t netifapi_netif_set_addr ( struct netif *netif,
struct ip_addr *ipaddr,
struct ip_addr *netmask,
struct ip_addr *gw );
err_t netifapi_netif_common ( struct netif *netif,
void (* voidfunc)(struct netif *netif),
err_t (* errtfunc)(struct netif *netif) );

View File

@@ -366,6 +366,16 @@
#define ETHARP_TRUST_IP_MAC 1
#endif
/**
* ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header.
* Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check.
* If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted.
* If ETHARP_VLAN_CHECK is not defined, all traffic is accepted.
*/
#ifndef ETHARP_SUPPORT_VLAN
#define ETHARP_SUPPORT_VLAN 0
#endif
/*
--------------------------------
---------- IP options ----------
@@ -718,6 +728,13 @@
#define UDP_TTL (IP_DEFAULT_TTL)
#endif
/**
* LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf.
*/
#ifndef LWIP_NETBUF_RECVINFO
#define LWIP_NETBUF_RECVINFO 0
#endif
/*
---------------------------------
---------- TCP options ----------
@@ -803,7 +820,7 @@
* as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
*/
#ifndef TCP_SND_QUEUELEN
#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF/TCP_MSS))
#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF)/(TCP_MSS))
#endif
/**
@@ -812,7 +829,7 @@
* TCP snd_buf for select to return writable.
*/
#ifndef TCP_SNDLOWAT
#define TCP_SNDLOWAT (TCP_SND_BUF/2)
#define TCP_SNDLOWAT ((TCP_SND_BUF)/2)
#endif
/**
@@ -1322,21 +1339,21 @@
* MEM_STATS==1: Enable mem.c stats.
*/
#ifndef MEM_STATS
#define MEM_STATS 1
#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0))
#endif
/**
* MEMP_STATS==1: Enable memp.c pool stats.
*/
#ifndef MEMP_STATS
#define MEMP_STATS 1
#define MEMP_STATS (MEMP_MEM_MALLOC == 0)
#endif
/**
* SYS_STATS==1: Enable system stats (sem and mbox counts, etc).
*/
#ifndef SYS_STATS
#define SYS_STATS 1
#define SYS_STATS (NO_SYS == 0)
#endif
#else

View File

@@ -51,27 +51,87 @@ typedef void * sio_fd_t;
or be implemented in your custom sio.c file. */
#ifndef sio_open
sio_fd_t sio_open(u8_t);
/**
* Opens a serial device for communication.
*
* @param devnum device number
* @return handle to serial device if successful, NULL otherwise
*/
sio_fd_t sio_open(u8_t devnum);
#endif
#ifndef sio_send
void sio_send(u8_t, sio_fd_t);
/**
* Sends a single character to the serial device.
*
* @param c character to send
* @param fd serial device handle
*
* @note This function will block until the character can be sent.
*/
void sio_send(u8_t c, sio_fd_t fd);
#endif
#ifndef sio_recv
u8_t sio_recv(sio_fd_t);
/**
* Receives a single character from the serial device.
*
* @param fd serial device handle
*
* @note This function will block until a character is received.
*/
u8_t sio_recv(sio_fd_t fd);
#endif
#ifndef sio_read
u32_t sio_read(sio_fd_t, u8_t *, u32_t);
/**
* Reads from the serial device.
*
* @param fd serial device handle
* @param data pointer to data buffer for receiving
* @param len maximum length (in bytes) of data to receive
* @return number of bytes actually received - may be 0 if aborted by sio_read_abort
*
* @note This function will block until data can be received. The blocking
* can be cancelled by calling sio_read_abort().
*/
u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len);
#endif
#ifndef sio_tryread
/**
* Tries to read from the serial device. Same as sio_read but returns
* immediately if no data is available and never blocks.
*
* @param fd serial device handle
* @param data pointer to data buffer for receiving
* @param len maximum length (in bytes) of data to receive
* @return number of bytes actually received
*/
u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len);
#endif
#ifndef sio_write
u32_t sio_write(sio_fd_t, u8_t *, u32_t);
/**
* Writes to the serial device.
*
* @param fd serial device handle
* @param data pointer to data to send
* @param len length (in bytes) of data to send
* @return number of bytes actually sent
*
* @note This function will block until all data can be sent.
*/
u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len);
#endif
#ifndef sio_read_abort
void sio_read_abort(sio_fd_t);
/**
* Aborts a blocking sio_read() call.
*
* @param fd serial device handle
*/
void sio_read_abort(sio_fd_t fd);
#endif
#ifdef __cplusplus

View File

@@ -230,12 +230,11 @@ PACK_STRUCT_END
#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr))
#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons((ntohs((phdr)->_hdrlen_rsvd_flags) & ~TCP_FLAGS) | (flags))
#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (flags))
#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & htons((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags))
#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags))
#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & TCP_FIN || \
TCPH_FLAGS((seg)->tcphdr) & TCP_SYN)? 1: 0))
#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0))
enum tcp_state {
CLOSED = 0,
@@ -490,8 +489,10 @@ err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
(ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); \
} else { \
(ret) = ERR_OK; \
if (p != NULL) \
if (p != NULL) { \
tcp_recved((pcb), ((struct pbuf*)(p))->tot_len); \
pbuf_free(p); \
} \
} \
} while (0)
@@ -588,6 +589,7 @@ u16_t tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr);
extern struct tcp_pcb *tcp_input_pcb;
extern u32_t tcp_ticks;
const char* tcp_debug_state_str(enum tcp_state s);
#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
void tcp_debug_print(struct tcp_hdr *tcphdr);
void tcp_debug_print_flags(u8_t flags);
@@ -651,7 +653,7 @@ extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
if(*pcbs == npcb) { \
*pcbs = (*pcbs)->next; \
} else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \
if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
if(tcp_tmp_pcb->next == npcb) { \
tcp_tmp_pcb->next = npcb->next; \
break; \
} \
@@ -679,7 +681,7 @@ extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */
for(tcp_tmp_pcb = *pcbs; \
tcp_tmp_pcb != NULL; \
tcp_tmp_pcb = tcp_tmp_pcb->next) { \
if(tcp_tmp_pcb->next != NULL && tcp_tmp_pcb->next == npcb) { \
if(tcp_tmp_pcb->next == npcb) { \
tcp_tmp_pcb->next = npcb->next; \
break; \
} \

View File

@@ -94,6 +94,9 @@ struct udp_pcb {
* The callback is responsible for freeing the pbuf
* if it's not used any more.
*
* ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf
* makes 'addr' invalid, too.
*
* @param arg user supplied argument (udp_pcb.recv_arg)
* @param pcb the udp_pcb which received data
* @param p the packet buffer that was received

View File

@@ -85,13 +85,34 @@ PACK_STRUCT_END
# include "arch/epstruct.h"
#endif
#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE)
#if ETHARP_SUPPORT_VLAN
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct eth_vlan_hdr {
PACK_STRUCT_FIELD(u16_t tpid);
PACK_STRUCT_FIELD(u16_t prio_vid);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_VLAN_HDR 4
#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF)
#endif /* ETHARP_SUPPORT_VLAN */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
/** the ARP message */
struct etharp_hdr {
PACK_STRUCT_FIELD(struct eth_hdr ethhdr);
PACK_STRUCT_FIELD(u16_t hwtype);
PACK_STRUCT_FIELD(u16_t proto);
PACK_STRUCT_FIELD(u16_t _hwlen_protolen);
@@ -106,24 +127,15 @@ PACK_STRUCT_END
# include "arch/epstruct.h"
#endif
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ethip_hdr {
PACK_STRUCT_FIELD(struct eth_hdr eth);
PACK_STRUCT_FIELD(struct ip_hdr ip);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define SIZEOF_ETHARP_HDR 28
#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR)
/** 5 seconds period */
#define ARP_TMR_INTERVAL 5000
#define ETHTYPE_ARP 0x0806
#define ETHTYPE_IP 0x0800
#define ETHTYPE_VLAN 0x8100
#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */

View File

@@ -41,6 +41,7 @@ extern "C" {
#endif
err_t slipif_init(struct netif * netif);
void slipif_poll(struct netif *netif);
#ifdef __cplusplus
}

View File

@@ -579,13 +579,21 @@ etharp_find_addr(struct netif *netif, struct ip_addr *ipaddr,
void
etharp_ip_input(struct netif *netif, struct pbuf *p)
{
struct ethip_hdr *hdr;
struct eth_hdr *ethhdr;
struct ip_hdr *iphdr;
LWIP_ERROR("netif != NULL", (netif != NULL), return;);
/* Only insert an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */
hdr = p->payload;
ethhdr = p->payload;
iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
#if ETHARP_SUPPORT_VLAN
if (ethhdr->type == ETHTYPE_VLAN) {
iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
}
#endif /* ETHARP_SUPPORT_VLAN */
/* source is not on the local network? */
if (!ip_addr_netcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
if (!ip_addr_netcmp(&(iphdr->src), &(netif->ip_addr), &(netif->netmask))) {
/* do nothing */
return;
}
@@ -594,7 +602,7 @@ etharp_ip_input(struct netif *netif, struct pbuf *p)
/* update ARP table */
/* @todo We could use ETHARP_TRY_HARD if we think we are going to talk
* back soon (for example, if the destination IP address is ours. */
update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), 0);
update_arp_entry(netif, &(iphdr->src), &(ethhdr->src), 0);
}
@@ -617,6 +625,7 @@ void
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
struct etharp_hdr *hdr;
struct eth_hdr *ethhdr;
/* these are aligned properly, whereas the ARP header fields might not be */
struct ip_addr sipaddr, dipaddr;
u8_t i;
@@ -629,24 +638,30 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
/* drop short ARP packets: we have to check for p->len instead of p->tot_len here
since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */
if (p->len < sizeof(struct etharp_hdr)) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, (s16_t)sizeof(struct etharp_hdr)));
if (p->len < SIZEOF_ETHARP_PACKET) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, (s16_t)SIZEOF_ETHARP_PACKET));
ETHARP_STATS_INC(etharp.lenerr);
ETHARP_STATS_INC(etharp.drop);
pbuf_free(p);
return;
}
hdr = p->payload;
ethhdr = p->payload;
hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
#if ETHARP_SUPPORT_VLAN
if (ethhdr->type == ETHTYPE_VLAN) {
hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
}
#endif /* ETHARP_SUPPORT_VLAN */
/* RFC 826 "Packet Reception": */
if ((hdr->hwtype != htons(HWTYPE_ETHERNET)) ||
(hdr->_hwlen_protolen != htons((ETHARP_HWADDR_LEN << 8) | sizeof(struct ip_addr))) ||
(hdr->proto != htons(ETHTYPE_IP)) ||
(hdr->ethhdr.type != htons(ETHTYPE_ARP))) {
(ethhdr->type != htons(ETHTYPE_ARP))) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 1,
("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
hdr->hwtype, ARPH_HWLEN(hdr), hdr->proto, ARPH_PROTOLEN(hdr), hdr->ethhdr.type));
hdr->hwtype, ARPH_HWLEN(hdr), hdr->proto, ARPH_PROTOLEN(hdr), ethhdr->type));
ETHARP_STATS_INC(etharp.proterr);
ETHARP_STATS_INC(etharp.drop);
pbuf_free(p);
@@ -719,12 +734,12 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
i--;
hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
#if LWIP_AUTOIP
hdr->ethhdr.dest.addr[i] = ethdst_hwaddr[i];
ethhdr->dest.addr[i] = ethdst_hwaddr[i];
#else /* LWIP_AUTOIP */
hdr->ethhdr.dest.addr[i] = hdr->shwaddr.addr[i];
ethhdr->dest.addr[i] = hdr->shwaddr.addr[i];
#endif /* LWIP_AUTOIP */
hdr->shwaddr.addr[i] = ethaddr->addr[i];
hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
ethhdr->src.addr[i] = ethaddr->addr[i];
}
/* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header
@@ -1034,13 +1049,14 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
struct pbuf *p;
err_t result = ERR_OK;
u8_t k; /* ARP entry index */
struct eth_hdr *ethhdr;
struct etharp_hdr *hdr;
#if LWIP_AUTOIP
const u8_t * ethdst_hwaddr;
#endif /* LWIP_AUTOIP */
/* allocate a pbuf for the outgoing ARP request packet */
p = pbuf_alloc(PBUF_RAW, sizeof(struct etharp_hdr), PBUF_RAM);
p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM);
/* could allocate a pbuf for an ARP request? */
if (p == NULL) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 2, ("etharp_raw: could not allocate pbuf for ARP request.\n"));
@@ -1048,9 +1064,10 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
return ERR_MEM;
}
LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
(p->len >= sizeof(struct etharp_hdr)));
(p->len >= SIZEOF_ETHARP_PACKET));
hdr = p->payload;
ethhdr = p->payload;
hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));
hdr->opcode = htons(opcode);
@@ -1070,11 +1087,11 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
hdr->dhwaddr.addr[k] = hwdst_addr->addr[k];
/* Write the Ethernet MAC-Addresses */
#if LWIP_AUTOIP
hdr->ethhdr.dest.addr[k] = ethdst_hwaddr[k];
ethhdr->dest.addr[k] = ethdst_hwaddr[k];
#else /* LWIP_AUTOIP */
hdr->ethhdr.dest.addr[k] = ethdst_addr->addr[k];
ethhdr->dest.addr[k] = ethdst_addr->addr[k];
#endif /* LWIP_AUTOIP */
hdr->ethhdr.src.addr[k] = ethsrc_addr->addr[k];
ethhdr->src.addr[k] = ethsrc_addr->addr[k];
}
hdr->sipaddr = *(struct ip_addr2 *)ipsrc_addr;
hdr->dipaddr = *(struct ip_addr2 *)ipdst_addr;
@@ -1084,7 +1101,7 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
/* set hwlen and protolen together */
hdr->_hwlen_protolen = htons((ETHARP_HWADDR_LEN << 8) | sizeof(struct ip_addr));
hdr->ethhdr.type = htons(ETHTYPE_ARP);
ethhdr->type = htons(ETHTYPE_ARP);
/* send ARP query */
result = netif->linkoutput(netif, p);
ETHARP_STATS_INC(etharp.xmit);
@@ -1126,6 +1143,7 @@ err_t
ethernet_input(struct pbuf *p, struct netif *netif)
{
struct eth_hdr* ethhdr;
u16_t type;
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
@@ -1137,7 +1155,22 @@ ethernet_input(struct pbuf *p, struct netif *netif)
(unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5],
(unsigned)htons(ethhdr->type)));
switch (htons(ethhdr->type)) {
type = htons(ethhdr->type);
#if ETHARP_SUPPORT_VLAN
if (type == ETHTYPE_VLAN) {
struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR);
#ifdef ETHARP_VLAN_CHECK /* if not, allow all VLANs */
if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
/* silently ignore this packet: not for our VLAN */
pbuf_free(p);
return ERR_OK;
}
#endif /* ETHARP_VLAN_CHECK */
type = htons(vlan->tpid);
}
#endif /* ETHARP_SUPPORT_VLAN */
switch (type) {
/* IP packet? */
case ETHTYPE_IP:
#if ETHARP_TRUST_IP_MAC
@@ -1145,7 +1178,7 @@ ethernet_input(struct pbuf *p, struct netif *netif)
etharp_ip_input(netif, p);
#endif /* ETHARP_TRUST_IP_MAC */
/* skip Ethernet header */
if(pbuf_header(p, -(s16_t)sizeof(struct eth_hdr))) {
if(pbuf_header(p, -(s16_t)SIZEOF_ETH_HDR)) {
LWIP_ASSERT("Can't move over header in packet", 0);
pbuf_free(p);
p = NULL;

View File

@@ -187,7 +187,12 @@ low_level_input(struct netif *netif)
for(q = p; q != NULL; q = q->next) {
/* Read enough bytes to fill this pbuf in the chain. The
* available data in the pbuf is given by the q->len
* variable. */
* variable.
* This does not necessarily have to be a memcpy, you can also preallocate
* pbufs for a DMA-enabled MAC and after receiving truncate it to the
* actually received size. In this case, ensure the tot_len member of the
* pbuf is the sum of the chained pbuf len members.
*/
read data into(q->payload, q->len);
}
acknowledge that packet has been read();

View File

@@ -82,6 +82,8 @@
#include "cbcp.h"
#endif /* CBCP_SUPPORT */
#include <string.h>
/*************************/
/*** LOCAL DEFINITIONS ***/
/*************************/

View File

@@ -82,6 +82,7 @@
#include "chap.h"
#include "chpms.h"
#include <string.h>
/*************************/
/*** LOCAL DEFINITIONS ***/

View File

@@ -64,6 +64,8 @@
#include "fsm.h"
#include <string.h>
/*************************/
/*** LOCAL DEFINITIONS ***/

View File

@@ -42,6 +42,8 @@
#include "md5.h"
#include <string.h>
/*
***********************************************************************
** Message-digest routines: **

View File

@@ -61,6 +61,8 @@
#include "auth.h"
#include "pap.h"
#include <string.h>
/***********************************/
/*** LOCAL FUNCTION DECLARATIONS ***/
/***********************************/

View File

@@ -395,13 +395,17 @@ pppInit(void)
magicInit();
subnetMask = htonl(0xffffff00);
for (i = 0; i < NUM_PPP; i++) {
pppControl[i].openFlag = 0;
subnetMask = htonl(0xffffff00);
outpacket_buf[i] = (u_char *)mem_malloc(PPP_MRU+PPP_HDRLEN);
if(!outpacket_buf[i]) {
if (!outpacket_buf[i]) {
for (j = 0; j < i; j++) {
/* deallocate all preceding buffers */
mem_free(outpacket_buf[j]);
}
return ERR_MEM;
}
@@ -1537,8 +1541,8 @@ pppMain(void *arg)
if(c > 0) {
pppInProc(pd, p->payload, c);
} else {
PPPDEBUG((LOG_DEBUG, "pppMain: unit %d sio_read len=%d returned %d\n", pd, p->len, c));
sys_msleep(1); /* give other tasks a chance to run */
/* nothing received, give other tasks a chance to run */
sys_msleep(1);
}
}
}

View File

@@ -41,6 +41,7 @@
#include "ppp.h"
#include "pppdebug.h"
#include <string.h>
#if MD5_SUPPORT /* this module depends on MD5 */
#define RANDPOOLSZ 16 /* Bytes stored in the pool of randomness. */

View File

@@ -54,12 +54,28 @@
#include "lwip/snmp.h"
#include "lwip/sio.h"
#define SLIP_BLOCK 1
#define SLIP_DONTBLOCK 0
#define SLIP_END 0300 /* 0xC0 */
#define SLIP_ESC 0333 /* 0xDB */
#define SLIP_ESC_END 0334 /* 0xDC */
#define SLIP_ESC_ESC 0335 /* 0xDD */
#define MAX_SIZE 1500
#define SLIP_MAX_SIZE 1500
enum slipif_recv_state {
SLIP_RECV_NORMAL,
SLIP_RECV_ESCAPE,
};
struct slipif_priv {
sio_fd_t sd;
/* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
struct pbuf *p, *q;
enum slipif_recv_state state;
u16_t i, recved;
};
/**
* Send a pbuf doing the necessary SLIP encapsulation
@@ -74,6 +90,7 @@
err_t
slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
struct slipif_priv *priv;
struct pbuf *q;
u16_t i;
u8_t c;
@@ -84,73 +101,101 @@ slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
LWIP_UNUSED_ARG(ipaddr);
priv = netif->state;
/* Send pbuf out on the serial I/O device. */
sio_send(SLIP_END, netif->state);
sio_send(SLIP_END, priv->sd);
for (q = p; q != NULL; q = q->next) {
for (i = 0; i < q->len; i++) {
c = ((u8_t *)q->payload)[i];
switch (c) {
case SLIP_END:
sio_send(SLIP_ESC, netif->state);
sio_send(SLIP_ESC_END, netif->state);
sio_send(SLIP_ESC, priv->sd);
sio_send(SLIP_ESC_END, priv->sd);
break;
case SLIP_ESC:
sio_send(SLIP_ESC, netif->state);
sio_send(SLIP_ESC_ESC, netif->state);
sio_send(SLIP_ESC, priv->sd);
sio_send(SLIP_ESC_ESC, priv->sd);
break;
default:
sio_send(c, netif->state);
sio_send(c, priv->sd);
break;
}
}
}
sio_send(SLIP_END, netif->state);
sio_send(SLIP_END, priv->sd);
return ERR_OK;
}
/**
* Static function for easy use of blockig or non-blocking
* sio_read
*
* @param fd serial device handle
* @param data pointer to data buffer for receiving
* @param len maximum length (in bytes) of data to receive
* @param block if 1, call sio_read; if 0, call sio_tryread
* @return return value of sio_read of sio_tryread
*/
static u32_t
slip_sio_read(sio_fd_t fd, u8_t* data, u32_t len, u8_t block)
{
if (block) {
return sio_read(fd, data, len);
} else {
return sio_tryread(fd, data, len);
}
}
/**
* Handle the incoming SLIP stream character by character
*
* Poll the serial layer by calling sio_recv()
*
* @param netif the lwip network interface structure for this slipif
* @return The IP packet when SLIP_END is received
* @param block if 1, block until data is received; if 0, return when all data
* from the buffer is received (multiple calls to this function will
* return a complete packet, NULL is returned before - used for polling)
* @return The IP packet when SLIP_END is received
*/
static struct pbuf *
slipif_input(struct netif *netif)
slipif_input(struct netif *netif, u8_t block)
{
struct slipif_priv *priv;
u8_t c;
/* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
struct pbuf *p, *q;
u16_t recved;
u16_t i;
struct pbuf *t;
LWIP_ASSERT("netif != NULL", (netif != NULL));
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
q = p = NULL;
recved = i = 0;
c = 0;
priv = netif->state;
while (1) {
c = sio_recv(netif->state);
switch (c) {
case SLIP_END:
if (recved > 0) {
/* Received whole packet. */
/* Trim the pbuf to the size of the received packet. */
pbuf_realloc(q, recved);
LINK_STATS_INC(link.recv);
LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
return q;
while (slip_sio_read(priv->sd, &c, 1, block) > 0) {
switch (priv->state) {
case SLIP_RECV_NORMAL:
switch (c) {
case SLIP_END:
if (priv->recved > 0) {
/* Received whole packet. */
/* Trim the pbuf to the size of the received packet. */
pbuf_realloc(priv->q, priv->recved);
LINK_STATS_INC(link.recv);
LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
t = priv->q;
priv->p = priv->q = NULL;
priv->i = priv->recved = 0;
return t;
}
continue;
case SLIP_ESC:
priv->state = SLIP_RECV_ESCAPE;
continue;
}
break;
case SLIP_ESC:
c = sio_recv(netif->state);
case SLIP_RECV_ESCAPE:
switch (c) {
case SLIP_ESC_END:
c = SLIP_END;
@@ -159,52 +204,52 @@ slipif_input(struct netif *netif)
c = SLIP_ESC;
break;
}
priv->state = SLIP_RECV_NORMAL;
/* FALLTHROUGH */
}
default:
/* byte received, packet not yet completely received */
if (p == NULL) {
/* allocate a new pbuf */
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);
/* byte received, packet not yet completely received */
if (priv->p == NULL) {
/* allocate a new pbuf */
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL);
if (p == NULL) {
LINK_STATS_INC(link.drop);
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
/* don't process any further since we got no pbuf to receive to */
break;
}
if (priv->p == NULL) {
LINK_STATS_INC(link.drop);
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
/* don't process any further since we got no pbuf to receive to */
break;
}
if (q != NULL) {
/* 'chain' the pbuf to the existing chain */
pbuf_cat(q, p);
if (priv->q != NULL) {
/* 'chain' the pbuf to the existing chain */
pbuf_cat(priv->q, priv->p);
} else {
/* p is the first pbuf in the chain */
priv->q = priv->p;
}
}
/* this automatically drops bytes if > SLIP_MAX_SIZE */
if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
((u8_t *)priv->p->payload)[priv->i] = c;
priv->recved++;
priv->i++;
if (priv->i >= priv->p->len) {
/* on to the next pbuf */
priv->i = 0;
if (priv->p->next != NULL && priv->p->next->len > 0) {
/* p is a chain, on to the next in the chain */
priv->p = priv->p->next;
} else {
/* p is the first pbuf in the chain */
q = p;
/* p is a single pbuf, set it to NULL so next time a new
* pbuf is allocated */
priv->p = NULL;
}
}
/* this automatically drops bytes if > MAX_SIZE */
if ((p != NULL) && (recved <= MAX_SIZE)) {
((u8_t *)p->payload)[i] = c;
recved++;
i++;
if (i >= p->len) {
/* on to the next pbuf */
i = 0;
if (p->next != NULL && p->next->len > 0) {
/* p is a chain, on to the next in the chain */
p = p->next;
} else {
/* p is a single pbuf, set it to NULL so next time a new
* pbuf is allocated */
p = NULL;
}
}
}
break;
}
}
return NULL;
}
@@ -217,13 +262,13 @@ slipif_input(struct netif *netif)
* @param nf the lwip network interface structure for this slipif
*/
static void
slipif_loop(void *nf)
slipif_loop_thread(void *nf)
{
struct pbuf *p;
struct netif *netif = (struct netif *)nf;
while (1) {
p = slipif_input(netif);
p = slipif_input(netif, SLIP_BLOCK);
if (p != NULL) {
if (netif->input(p, netif) != ERR_OK) {
pbuf_free(p);
@@ -242,6 +287,7 @@ slipif_loop(void *nf)
*
* @param netif the lwip network interface structure for this slipif
* @return ERR_OK if serial line could be opened,
* ERR_MEM if no memory could be allocated,
* ERR_IF is serial line couldn't be opened
*
* @note netif->num must contain the number of the serial port to open
@@ -250,22 +296,39 @@ slipif_loop(void *nf)
err_t
slipif_init(struct netif *netif)
{
struct slipif_priv *priv;
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
/* Allocate private data */
priv = mem_malloc(sizeof(struct slipif_priv));
if (!priv) {
return ERR_MEM;
}
netif->name[0] = 's';
netif->name[1] = 'l';
netif->output = slipif_output;
netif->mtu = MAX_SIZE;
netif->flags = NETIF_FLAG_POINTTOPOINT;
netif->mtu = SLIP_MAX_SIZE;
netif->flags |= NETIF_FLAG_POINTTOPOINT;
/* Try to open the serial port (netif->num contains the port number). */
netif->state = sio_open(netif->num);
if (!netif->state) {
priv->sd = sio_open(netif->num);
if (!priv->sd) {
/* Opening the serial port failed. */
mem_free(priv);
return ERR_IF;
}
/* Initialize private data */
priv->p = NULL;
priv->q = NULL;
priv->state = SLIP_RECV_NORMAL;
priv->i = 0;
priv->recved = 0;
netif->state = priv;
/* initialize the snmp variables and counters inside the struct netif
* ifSpeed: no assumption can be made without knowing more about the
* serial line!
@@ -273,7 +336,32 @@ slipif_init(struct netif *netif)
NETIF_INIT_SNMP(netif, snmp_ifType_slip, 0);
/* Create a thread to poll the serial line. */
sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop, netif, SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
return ERR_OK;
}
/**
* Polls the serial device and feeds the IP layer with incoming packets.
*
* @param netif The lwip network interface structure for this slipif
*/
void
slipif_poll(struct netif *netif)
{
struct pbuf *p;
struct slipif_priv *priv;
LWIP_ASSERT("netif != NULL", (netif != NULL));
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
priv = netif->state;
while ((p = slipif_input(netif, SLIP_DONTBLOCK)) != NULL) {
if (netif->input(p, netif) != ERR_OK) {
pbuf_free(p);
}
}
}
#endif /* LWIP_HAVE_SLIPIF */