mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-11-16 12:34:34 +00:00
Compare commits
64 Commits
STABLE-1_3
...
STABLE-1_3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d73f82f41 | ||
|
|
71ddff4964 | ||
|
|
af3b796488 | ||
|
|
e2de2c6bb2 | ||
|
|
2ff0ce2d0a | ||
|
|
b09b8a0ccc | ||
|
|
db259c3557 | ||
|
|
bcc87ef851 | ||
|
|
650f16b6d9 | ||
|
|
ae2dd38e0d | ||
|
|
0319c1cf90 | ||
|
|
81f9442ac7 | ||
|
|
18ab274af3 | ||
|
|
65d1f52423 | ||
|
|
f1b82e0e9a | ||
|
|
67411c4299 | ||
|
|
a37e62b7d0 | ||
|
|
e2c1f7d5b5 | ||
|
|
ec97fbd101 | ||
|
|
b7d7559cc9 | ||
|
|
b4404ff0c8 | ||
|
|
502e89f4ad | ||
|
|
d8d8cf7e98 | ||
|
|
d9a5094068 | ||
|
|
a9740c6a44 | ||
|
|
2dc027401f | ||
|
|
ac638c85f3 | ||
|
|
c0e22c255c | ||
|
|
1309e5e86f | ||
|
|
c34c024dd5 | ||
|
|
6ef69ece95 | ||
|
|
a9cbdc141b | ||
|
|
9e5cf1cf8e | ||
|
|
ddc783bee7 | ||
|
|
68f92050e9 | ||
|
|
bd2bc2ee14 | ||
|
|
8a7c1c4926 | ||
|
|
cff3e0cad2 | ||
|
|
b55cfbc342 | ||
|
|
3115087d26 | ||
|
|
057c51ff6d | ||
|
|
f2f20cf133 | ||
|
|
2c618705f0 | ||
|
|
bc10ad2356 | ||
|
|
857fac1168 | ||
|
|
103ba9b0fc | ||
|
|
d83fc6893b | ||
|
|
e7d5739ce7 | ||
|
|
8bf57c0e14 | ||
|
|
dea7255fc5 | ||
|
|
ce3082976c | ||
|
|
362a295e06 | ||
|
|
0e91e2adf2 | ||
|
|
4d49d952b6 | ||
|
|
ae7a7a0abf | ||
|
|
4f265dce60 | ||
|
|
bd96db8c9f | ||
|
|
0b75917121 | ||
|
|
fa2dbc2b1b | ||
|
|
3a6165f0b9 | ||
|
|
62c27f7fce | ||
|
|
7feb116bae | ||
|
|
730a938912 | ||
|
|
3553efb75e |
115
CHANGELOG
115
CHANGELOG
@@ -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
2
README
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
173
src/core/dhcp.c
173
src/core/dhcp.c
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, ðbroadcast,
|
||||
(struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero,
|
||||
&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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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) );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; \
|
||||
} \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
err_t slipif_init(struct netif * netif);
|
||||
void slipif_poll(struct netif *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
#include "cbcp.h"
|
||||
#endif /* CBCP_SUPPORT */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
/*************************/
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "chap.h"
|
||||
#include "chpms.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
|
||||
#include "fsm.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Message-digest routines: **
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
#include "auth.h"
|
||||
#include "pap.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/***********************************/
|
||||
/*** LOCAL FUNCTION DECLARATIONS ***/
|
||||
/***********************************/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user