提交 a27f7c67 编写于 作者: B bernard.xiong

update lwip to 1.3.2

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@297 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 ce10330d
......@@ -19,8 +19,179 @@ HISTORY
++ New features:
++ Bugfixes:
(STABLE-1.3.2)
++ 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-12-24: Kieran Mansley
* tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing
(BUG#28241)
2009-12-06: Simon Goldschmidt
* ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can
be statically allocated (like in ucip)
2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev)
* pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT
2009-12-03: Simon Goldschmidt
* tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit
could have non-zero length
2009-12-02: Simon Goldschmidt
* tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting
tcp_input_pcb until after calling the pcb's callbacks
2009-11-29: Simon Goldschmidt
* tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of-
sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code
2009-11-29: Simon Goldschmidt
* pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by
queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty
2009-11-26: Simon Goldschmidt
* tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending
segment
2009-11-26: Simon Goldschmidt
* tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle
algorithm at PCB level
2009-11-22: Simon Goldschmidt
* tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent
2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach)
* tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when
reusing time-wait pcb
2009-11-20: Simon Goldschmidt (patch by Albert Bartel)
* sockets.c: Fixed bug #28062: Data received directly after accepting
does not wake up select
2009-11-11: Simon Goldschmidt
* netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo)
2009-10-30: Simon Goldschmidt
* opt.h: Increased default value for TCP_MSS to 536, updated default
value for TCP_WND to 4*TCP_MSS to keep delayed ACK working.
2009-10-28: Kieran Mansley
* tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code
to follow algorithm from TCP/IP Illustrated
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_lib.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 (Jrg 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)
......
......@@ -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
......
......@@ -16,7 +16,7 @@ src/arch/sys_arch_init.c
src/core/dhcp.c
src/core/dns.c
src/core/init.c
src/core/memp_tiny.c
src/core/memp.c
src/core/netif.c
src/core/pbuf.c
src/core/raw.c
......
......@@ -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;
}
}
......@@ -1149,7 +1160,7 @@ do_close(struct api_msg_msg *msg)
#endif /* LWIP_TCP */
{
msg->conn->err = ERR_VAL;
TCPIP_APIMSG_ACK(msg);
sys_sem_signal(msg->conn->op_completed);
}
}
......
......@@ -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;
......
......@@ -116,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));
......@@ -126,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 */
......@@ -234,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;
......@@ -274,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;
......@@ -300,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));
if (ai == NULL) {
goto memerr;
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;
}
memset(ai, 0, sizeof(struct addrinfo));
sa = mem_malloc(sizeof(struct sockaddr_in));
if (sa == NULL) {
ai = mem_malloc(total_size);
if (ai == 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;
......@@ -328,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;
}
......@@ -347,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.
......
......@@ -494,7 +494,7 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
buf = sock->lastdata;
} else {
/* If this is non-blocking call, then check first */
if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) &&
if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) &&
(sock->rcvevent <= 0)) {
if (off > 0) {
/* already received data, return that */
......@@ -546,9 +546,9 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
if (netconn_type(sock->conn) == NETCONN_TCP) {
LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen);
len -= copylen;
if ( (len <= 0) ||
(buf->p->flags & PBUF_FLAG_PUSH) ||
(sock->rcvevent <= 0) ||
if ( (len <= 0) ||
(buf->p->flags & PBUF_FLAG_PUSH) ||
(sock->rcvevent <= 0) ||
((flags & MSG_PEEK)!=0)) {
done = 1;
}
......@@ -702,16 +702,16 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
#if LWIP_TCPIP_CORE_LOCKING
/* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */
{ struct pbuf* p;
p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
if (p == NULL) {
err = ERR_MEM;
} else {
p->payload = (void*)data;
p->len = p->tot_len = short_size;
remote_addr.addr = ((const struct sockaddr_in *)to)->sin_addr.s_addr;
LOCK_TCPIP_CORE();
if (sock->conn->type==NETCONN_RAW) {
err = sock->conn->err = raw_sendto(sock->conn->pcb.raw, p, &remote_addr);
......@@ -719,7 +719,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
err = sock->conn->err = udp_sendto(sock->conn->pcb.udp, p, &remote_addr, ntohs(((const struct sockaddr_in *)to)->sin_port));
}
UNLOCK_TCPIP_CORE();
pbuf_free(p);
}
}
......@@ -845,11 +845,11 @@ lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
int i, nready = 0;
fd_set lreadset, lwriteset, lexceptset;
struct lwip_socket *p_sock;
FD_ZERO(&lreadset);
FD_ZERO(&lwriteset);
FD_ZERO(&lexceptset);
/* Go through each socket in each list to count number of sockets which
currently match */
for(i = 0; i < maxfdp1; i++) {
......@@ -875,7 +875,7 @@ lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset)
*readset = lreadset;
*writeset = lwriteset;
FD_ZERO(exceptset);
return nready;
}
......@@ -935,27 +935,27 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
FD_ZERO(writeset);
if (exceptset)
FD_ZERO(exceptset);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n"));
set_errno(0);
return 0;
}
/* add our semaphore to list */
/* We don't actually need any dynamic memory. Our entry on the
* list is only valid while we are in this function, so it's ok
* to use local variables */
select_cb.sem = sys_sem_new(0);
/* Note that we are still protected */
/* Put this select_cb on top of list */
select_cb.next = select_cb_list;
select_cb_list = &select_cb;
/* Now we can safely unprotect */
sys_sem_signal(selectsem);
/* Now just wait to be woken */
if (timeout == 0)
/* Wait forever */
......@@ -965,7 +965,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
if(msectimeout == 0)
msectimeout = 1;
}
if (sys_arch_timeouts() == NULL){
/* it's not a lwip thread, use os semaphore with timeout to handle it */
i = sys_arch_sem_wait(select_cb.sem, msectimeout);
......@@ -976,7 +976,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
/* it's a lwip thread, use os semaphore with timeout to handle it */
i = sys_sem_wait_timeout(select_cb.sem, msectimeout);
}
/* Take us off the list */
sys_sem_wait(selectsem);
if (select_cb_list == &select_cb)
......@@ -988,9 +988,9 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
break;
}
}
sys_sem_signal(selectsem);
sys_sem_free(select_cb.sem);
if (i == 0) {
/* Timeout */
......@@ -1000,13 +1000,13 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
FD_ZERO(writeset);
if (exceptset)
FD_ZERO(exceptset);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
set_errno(0);
return 0;
}
if (readset)
lreadset = *readset;
else
......@@ -1019,22 +1019,22 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
lexceptset = *exceptset;
else
FD_ZERO(&lexceptset);
/* See what's set */
nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
} else
sys_sem_signal(selectsem);
if (readset)
*readset = lreadset;
if (writeset)
*writeset = lwriteset;
if (exceptset)
*exceptset = lexceptset;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
set_errno(0);
return nready;
}
......@@ -1068,6 +1068,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
sys_sem_signal(socksem);
return;
}
s = conn->socket;
sys_sem_signal(socksem);
}
......@@ -1205,11 +1206,11 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
/* Do length and type checks for the various options first, to keep it readable. */
switch (level) {
/* Level: SOL_SOCKET */
case SOL_SOCKET:
switch (optname) {
case SO_ACCEPTCONN:
case SO_BROADCAST:
/* UNIMPL case SO_DEBUG: */
......@@ -1258,7 +1259,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT;
} /* switch (optname) */
break;
/* Level: IPPROTO_IP */
case IPPROTO_IP:
switch (optname) {
......@@ -1290,7 +1291,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT;
} /* switch (optname) */
break;
#if LWIP_TCP
/* Level: IPPROTO_TCP */
case IPPROTO_TCP:
......@@ -1298,7 +1299,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = EINVAL;
break;
}
/* If this is no TCP socket, ignore any options. */
if (sock->conn->type != NETCONN_TCP)
return 0;
......@@ -1312,7 +1313,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
case TCP_KEEPCNT:
#endif /* LWIP_TCP_KEEPALIVE */
break;
default:
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n",
s, optname));
......@@ -1327,7 +1328,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = EINVAL;
break;
}
/* If this is no UDP lite socket, ignore any options. */
if (sock->conn->type != NETCONN_UDPLITE)
return 0;
......@@ -1336,7 +1337,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
case UDPLITE_SEND_CSCOV:
case UDPLITE_RECV_CSCOV:
break;
default:
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n",
s, optname));
......@@ -1351,7 +1352,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = ENOPROTOOPT;
} /* switch */
if (err != ERR_OK) {
sock_set_errno(sock, err);
return -1;
......@@ -1396,7 +1397,7 @@ lwip_getsockopt_internal(void *arg)
optval = data->optval;
switch (level) {
/* Level: SOL_SOCKET */
case SOL_SOCKET:
switch (optname) {
......@@ -1442,7 +1443,7 @@ lwip_getsockopt_internal(void *arg)
case SO_ERROR:
if (sock->err == 0) {
sock_set_errno(sock, err_to_errno(sock->conn->err));
}
}
*(int *)optval = sock->err;
sock->err = 0;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n",
......@@ -1500,7 +1501,7 @@ lwip_getsockopt_internal(void *arg)
case IPPROTO_TCP:
switch (optname) {
case TCP_NODELAY:
*(int*)optval = (sock->conn->pcb.tcp->flags & TF_NODELAY);
*(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n",
s, (*(int*)optval)?"on":"off") );
break;
......@@ -1861,9 +1862,9 @@ lwip_setsockopt_internal(void *arg)
switch (optname) {
case TCP_NODELAY:
if (*(int*)optval) {
sock->conn->pcb.tcp->flags |= TF_NODELAY;
tcp_nagle_disable(sock->conn->pcb.tcp);
} else {
sock->conn->pcb.tcp->flags &= ~TF_NODELAY;
tcp_nagle_enable(sock->conn->pcb.tcp);
}
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n",
s, (*(int *)optval)?"on":"off") );
......
此差异已折叠。
......@@ -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 */
......
......@@ -168,6 +168,9 @@
#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT)))
#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
#endif
#if PPP_SUPPORT && !PPPOS_SUPPORT & !PPPOE_SUPPORT
#error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on"
#endif
/* Compile-time checks for deprecated options.
......@@ -208,6 +211,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,13 +119,16 @@ 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
*/
void
autoip_init(void)
{
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_init()\n"));
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_init()\n"));
}
/**
......@@ -139,19 +145,19 @@ autoip_handle_arp_conflict(struct netif *netif)
/* retreat, there was a conflicting ARP in the last
* DEFEND_INTERVAL seconds
*/
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 1,
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
/* TODO: close all TCP sessions */
autoip_start(netif);
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 1,
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
autoip_arp_announce(netif);
netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 1,
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we do not defend, retreating\n"));
/* TODO: close all TCP sessions */
autoip_start(netif);
......@@ -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,
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_create_addr(): tried_llipaddr=%"U16_F", 0x%08"X32_F"\n",
(u16_t)(netif->autoip->tried_llipaddr), (u32_t)(IPAddr->addr)));
(u16_t)(netif->autoip->tried_llipaddr), (u32_t)(ipaddr->addr)));
}
/**
* Sends an ARP probe from a network interface
*
* @param netif network interface used to send the probe
*/
static err_t
autoip_arp_probe(struct netif *netif)
{
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, &ethbroadcast,
(struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, &ethzero,
&netif->autoip->llipaddr, ARP_REQUEST);
}
/**
......@@ -215,7 +234,7 @@ autoip_bind(struct netif *netif)
struct autoip *autoip = netif->autoip;
struct ip_addr sn_mask, gw_addr;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_bind(netif=%p) %c%c%"U16_F" 0x%08"X32_F"\n",
(void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, autoip->llipaddr.addr));
......@@ -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,13 +381,13 @@ 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));
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() PROBING Sent Probe\n"));
netif->autoip->sent_num++;
/* calculate time to wait to next probe */
......@@ -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,
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("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;
......@@ -397,7 +441,7 @@ autoip_tmr()
void
autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
{
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3, ("autoip_arp_reply()\n"));
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) {
/* when ip.src == llipaddr && hw.src != netif->hwaddr
*
......@@ -431,7 +475,7 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) ||
(ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 1,
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Probe Conflict detected\n"));
autoip_start(netif);
}
......@@ -442,7 +486,7 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
*/
if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 1,
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
autoip_handle_arp_conflict(netif);
}
......
......@@ -62,40 +62,12 @@
* 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
......@@ -122,7 +94,7 @@ ip_route(struct ip_addr *dest)
}
}
if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
LWIP_DEBUGF(IP_DEBUG | 2, ("ip_route: No route to 0x%"X32_F"\n", dest->addr));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to 0x%"X32_F"\n", dest->addr));
IP_STATS_INC(ip.rterr);
snmp_inc_ipoutnoroutes();
return NULL;
......@@ -230,7 +202,7 @@ ip_input(struct pbuf *p, struct netif *inp)
/* identify the IP header */
iphdr = p->payload;
if (IPH_V(iphdr) != 4) {
LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
ip_debug_print(p);
pbuf_free(p);
IP_STATS_INC(ip.err);
......@@ -248,13 +220,16 @@ ip_input(struct pbuf *p, struct netif *inp)
/* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) {
if (iphdr_hlen > p->len)
LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
iphdr_hlen, p->len));
if (iphdr_len > p->tot_len)
LWIP_DEBUGF(IP_DEBUG | 2, ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), "
"IP packet dropped.\n",
iphdr_len, p->tot_len));
if (iphdr_hlen > p->len) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
iphdr_hlen, p->len));
}
if (iphdr_len > p->tot_len) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
iphdr_len, p->tot_len));
}
/* free (drop) packet pbufs */
pbuf_free(p);
IP_STATS_INC(ip.lenerr);
......@@ -267,7 +242,8 @@ ip_input(struct pbuf *p, struct netif *inp)
#if CHECKSUM_CHECK_IP
if (inet_chksum(iphdr, iphdr_hlen) != 0) {
LWIP_DEBUGF(IP_DEBUG | 2, ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
ip_debug_print(p);
pbuf_free(p);
IP_STATS_INC(ip.chkerr);
......@@ -336,10 +312,10 @@ ip_input(struct pbuf *p, struct netif *inp)
if (netif == NULL) {
/* remote port is DHCP server? */
if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen))->dest)));
if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen))->dest) == DHCP_CLIENT_PORT) {
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n"));
netif = inp;
check_ip_src = 0;
}
......@@ -349,12 +325,13 @@ 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)))) {
/* packet source is not valid */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, ("ip_input: packet source is not valid.\n"));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
/* free (drop) packet pbufs */
pbuf_free(p);
IP_STATS_INC(ip.drop);
......@@ -367,7 +344,7 @@ ip_input(struct pbuf *p, struct netif *inp)
/* packet not for us? */
if (netif == NULL) {
/* packet not for us, route or discard */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
#if IP_FORWARD
/* non-broadcast packet? */
if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {
......@@ -396,7 +373,7 @@ ip_input(struct pbuf *p, struct netif *inp)
iphdr = p->payload;
#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
pbuf_free(p);
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
ntohs(IPH_OFFSET(iphdr))));
IP_STATS_INC(ip.opterr);
IP_STATS_INC(ip.drop);
......@@ -414,7 +391,7 @@ ip_input(struct pbuf *p, struct netif *inp)
#else
if (iphdr_hlen > IP_HLEN) {
#endif /* LWIP_IGMP */
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
pbuf_free(p);
IP_STATS_INC(ip.opterr);
IP_STATS_INC(ip.drop);
......@@ -476,7 +453,7 @@ ip_input(struct pbuf *p, struct netif *inp)
#endif /* LWIP_ICMP */
pbuf_free(p);
LWIP_DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
IP_STATS_INC(ip.proterr);
IP_STATS_INC(ip.drop);
......@@ -551,7 +528,7 @@ err_t ip_output_if_opt(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest
ip_hlen += optlen_aligned;
/* First write in the IP options */
if (pbuf_header(p, optlen_aligned)) {
LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));
IP_STATS_INC(ip.err);
snmp_inc_ipoutdiscards();
return ERR_BUF;
......@@ -565,7 +542,7 @@ err_t ip_output_if_opt(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest
#endif /* IP_OPTIONS_SEND */
/* generate IP header */
if (pbuf_header(p, IP_HLEN)) {
LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n"));
IP_STATS_INC(ip.err);
snmp_inc_ipoutdiscards();
......@@ -603,30 +580,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);
}
/**
......
......@@ -300,7 +300,7 @@ mem_free(void *rmem)
LWIP_MEM_FREE_DECL_PROTECT();
if (rmem == NULL) {
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n"));
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n"));
return;
}
LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0);
......@@ -310,7 +310,7 @@ mem_free(void *rmem)
if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
SYS_ARCH_DECL_PROTECT(lev);
LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n"));
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n"));
/* protect mem stats from concurrent access */
SYS_ARCH_PROTECT(lev);
MEM_STATS_INC(illegal);
......@@ -380,7 +380,7 @@ mem_realloc(void *rmem, mem_size_t newsize)
if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
SYS_ARCH_DECL_PROTECT(lev);
LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n"));
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_realloc: illegal memory\n"));
/* protect mem stats from concurrent access */
SYS_ARCH_PROTECT(lev);
MEM_STATS_INC(illegal);
......@@ -599,7 +599,7 @@ mem_malloc(mem_size_t size)
/* if we got interrupted by a mem_free, try again */
} while(local_mem_free_count != 0);
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
MEM_STATS_INC(err);
LWIP_MEM_ALLOC_UNPROTECT();
sys_sem_signal(mem_sem);
......
......@@ -289,7 +289,11 @@ memp_init(void)
/* check everything a first time to see if it worked */
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK */
}
}
#else
/* fix time-wait tcp pcb issue */
static rt_uint16_t tcp_pcbs = 0;
#endif /* MEMP_MEM_MALLOC */
/**
* Get an element from a specific pool.
......@@ -308,7 +312,8 @@ memp_malloc(memp_t type)
#else
memp_malloc_fn(memp_t type, const char* file, const int line)
#endif
{
{
#if !MEMP_MEM_MALLOC
struct memp *memp;
SYS_ARCH_DECL_PROTECT(old_level);
......@@ -333,13 +338,41 @@ memp_malloc_fn(memp_t type, const char* file, const int line)
((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
memp = (struct memp*)((u8_t*)memp + MEMP_SIZE);
} else {
LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
MEMP_STATS_INC(err, type);
}
SYS_ARCH_UNPROTECT(old_level);
return memp;
#else
void* ptr;
rt_uint32_t size;
SYS_ARCH_DECL_PROTECT(old_level);
size = memp_sizes[type];
LWIP_DEBUGF(MEMP_DEBUG, ("memp malloc %s, size %d, ", memp_desc[type], memp_sizes[type]));
SYS_ARCH_PROTECT(old_level);
if (type == MEMP_TCP_PCB)
{
if (tcp_pcbs >= MEMP_NUM_TCP_PCB)
{
SYS_ARCH_UNPROTECT(old_level);
return NULL;
}
else
{
/* increased tcp pcb allocated number */
tcp_pcbs ++;
}
}
SYS_ARCH_UNPROTECT(old_level);
ptr = mem_malloc(size);
LWIP_DEBUGF(MEMP_DEBUG, ("mem 0x%x\n", ptr));
return ptr;
#endif /* MEMP_MEM_MALLOC */
}
/**
......@@ -351,6 +384,7 @@ memp_malloc_fn(memp_t type, const char* file, const int line)
void
memp_free(memp_t type, void *mem)
{
#if !MEMP_MEM_MALLOC
struct memp *memp;
SYS_ARCH_DECL_PROTECT(old_level);
......@@ -381,6 +415,19 @@ memp_free(memp_t type, void *mem)
#endif /* MEMP_SANITY_CHECK */
SYS_ARCH_UNPROTECT(old_level);
}
#else
SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
if (type == MEMP_TCP_PCB && mem)
{
tcp_pcbs --;
}
SYS_ARCH_UNPROTECT(old_level);
LWIP_DEBUGF(MEMP_DEBUG, ("memp free %s, mem 0x%x\n", memp_desc[type], mem));
/* release this memory */
mem_free(mem);
#endif /* MEMP_MEM_MALLOC */
}
#include "lwip/opt.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/raw.h"
#include "lwip/tcp.h"
#include "lwip/igmp.h"
#include "lwip/api.h"
#include "lwip/api_msg.h"
#include "lwip/tcpip.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "netif/etharp.h"
#include "lwip/ip_frag.h"
#include <string.h>
#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
/** This array holds the element sizes of each pool. */
static const u16_t memp_sizes[MEMP_MAX] = {
#define LWIP_MEMPOOL(name,num,size,desc) MEMP_ALIGN_SIZE(size),
#include "lwip/memp_std.h"
};
/** This array holds a textual description of each pool. */
#ifdef LWIP_DEBUG
static const char *memp_desc[MEMP_MAX] = {
#define LWIP_MEMPOOL(name,num,size,desc) (desc),
#include "lwip/memp_std.h"
};
#endif /* LWIP_DEBUG */
/* fix time-wait tcp pcb issue */
static rt_uint32_t tcp_pcbs = 0;
/**
* Initialize this module.
*
* Carves out memp_memory into linked lists for each pool-type.
*/
void
memp_init(void)
{
/* nothing */
}
/**
* Get an element from a specific pool.
*
* @param type the pool to get an element from
*
* the debug version has two more parameters:
* @param file file name calling this function
* @param line number of line where this function is called
*
* @return a pointer to the allocated memory or a NULL pointer on error
*/
void *
#if !MEMP_OVERFLOW_CHECK
memp_malloc(memp_t type)
#else
memp_malloc_fn(memp_t type, const char* file, const int line)
#endif
{
void* ptr;
rt_uint32_t size, level;
size = memp_sizes[type];
LWIP_DEBUGF(MEMP_DEBUG, ("memp malloc %s, size %d, ", memp_desc[type], memp_sizes[type]));
level = rt_hw_interrupt_disable();
if (type == MEMP_TCP_PCB)
{
if (tcp_pcbs >= MEMP_NUM_TCP_PCB)
{
rt_hw_interrupt_enable(level);
return RT_NULL;
}
else
{
/* increased tcp pcb allocated number */
tcp_pcbs ++;
}
}
rt_hw_interrupt_enable(level);
ptr = rt_malloc(size);
LWIP_DEBUGF(MEMP_DEBUG, ("mem 0x%x\n", ptr));
return ptr;
}
/**
* Put an element back into its pool.
*
* @param type the pool where to put mem
* @param mem the memp element to free
*/
void
memp_free(memp_t type, void *mem)
{
rt_uint32_t level;
level = rt_hw_interrupt_disable();
if (type == MEMP_TCP_PCB && mem)
{
tcp_pcbs --;
}
rt_hw_interrupt_enable(level);
LWIP_DEBUGF(MEMP_DEBUG, ("memp free %s, mem 0x%x\n", memp_desc[type], mem));
/* release this memory */
rt_free(mem);
}
......@@ -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
......@@ -271,14 +278,14 @@ netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
{
/* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
pcb = tcp_active_pcbs;
while (pcb != NULL) {
/* PCB bound to current local interface address? */
if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
/* this connection must be aborted */
struct tcp_pcb *next = pcb->next;
LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
tcp_abort(pcb);
pcb = next;
} else {
......@@ -303,7 +310,7 @@ netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
snmp_insert_ipaddridx_tree(netif);
snmp_insert_iprteidx_tree(0,netif);
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
netif->name[0], netif->name[1],
ip4_addr1(&netif->ip_addr),
ip4_addr2(&netif->ip_addr),
......@@ -323,7 +330,7 @@ void
netif_set_gw(struct netif *netif, struct ip_addr *gw)
{
ip_addr_set(&(netif->gw), gw);
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
netif->name[0], netif->name[1],
ip4_addr1(&netif->gw),
ip4_addr2(&netif->gw),
......@@ -347,7 +354,7 @@ netif_set_netmask(struct netif *netif, struct ip_addr *netmask)
/* set new netmask to netif */
ip_addr_set(&(netif->netmask), netmask);
snmp_insert_iprteidx_tree(0, netif);
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | 3, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
netif->name[0], netif->name[1],
ip4_addr1(&netif->netmask),
ip4_addr2(&netif->netmask),
......@@ -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);
}
......
......@@ -81,41 +81,71 @@
aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */
#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE)
#if TCP_QUEUE_OOSEQ
#define ALLOC_POOL_PBUF(p) do { (p) = alloc_pool_pbuf(); } while (0)
#else
#define ALLOC_POOL_PBUF(p) do { (p) = memp_malloc(MEMP_PBUF_POOL); } while (0)
#endif
#if TCP_QUEUE_OOSEQ
#if !TCP_QUEUE_OOSEQ || NO_SYS
#define PBUF_POOL_IS_EMPTY()
#else /* !TCP_QUEUE_OOSEQ || NO_SYS */
/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */
#ifndef PBUF_POOL_FREE_OOSEQ
#define PBUF_POOL_FREE_OOSEQ 1
#endif /* PBUF_POOL_FREE_OOSEQ */
#if PBUF_POOL_FREE_OOSEQ
#include "lwip/tcpip.h"
#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty()
static u8_t pbuf_free_ooseq_queued;
/**
* Attempt to reclaim some memory from queued out-of-sequence TCP segments
* if we run out of pool pbufs. It's better to give priority to new packets
* if we're running out.
*
* @return the allocated pbuf.
* This must be done in the correct thread context therefore this function
* can only be used with NO_SYS=0 and through tcpip_callback.
*/
static struct pbuf *
alloc_pool_pbuf(void)
static void
pbuf_free_ooseq(void* arg)
{
struct tcp_pcb *pcb;
struct pbuf *p;
struct tcp_pcb* pcb;
SYS_ARCH_DECL_PROTECT(old_level);
LWIP_UNUSED_ARG(arg);
SYS_ARCH_PROTECT(old_level);
pbuf_free_ooseq_queued = 0;
SYS_ARCH_UNPROTECT(old_level);
for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) {
if (NULL != pcb->ooseq) {
/** Free the ooseq pbufs of one PCB only */
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n"));
tcp_segs_free(pcb->ooseq);
pcb->ooseq = NULL;
return;
}
}
}
retry:
p = memp_malloc(MEMP_PBUF_POOL);
if (NULL == p) {
for (pcb=tcp_active_pcbs; NULL != pcb; pcb = pcb->next) {
if (NULL != pcb->ooseq) {
tcp_segs_free(pcb->ooseq);
pcb->ooseq = NULL;
goto retry;
}
/** Queue a call to pbuf_free_ooseq if not already queued. */
static void
pbuf_pool_is_empty(void)
{
u8_t queued;
SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
queued = pbuf_free_ooseq_queued;
pbuf_free_ooseq_queued = 1;
SYS_ARCH_UNPROTECT(old_level);
if(!queued) {
/* queue a call to pbuf_free_ooseq if not already queued */
if(tcpip_callback_with_block(pbuf_free_ooseq, NULL, 0) != ERR_OK) {
SYS_ARCH_PROTECT(old_level);
pbuf_free_ooseq_queued = 0;
SYS_ARCH_UNPROTECT(old_level);
}
}
return p;
}
#endif /* TCP_QUEUE_OOSEQ */
#endif /* PBUF_POOL_FREE_OOSEQ */
#endif /* !TCP_QUEUE_OOSEQ || NO_SYS */
/**
* Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
......@@ -154,7 +184,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
struct pbuf *p, *q, *r;
u16_t offset;
s32_t rem_len; /* remaining length */
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_alloc(length=%"U16_F")\n", length));
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length));
/* determine header offset */
offset = 0;
......@@ -181,9 +211,10 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
switch (type) {
case PBUF_POOL:
/* allocate head of pbuf chain into p */
ALLOC_POOL_PBUF(p);
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));
p = memp_malloc(MEMP_PBUF_POOL);
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));
if (p == NULL) {
PBUF_POOL_IS_EMPTY();
return NULL;
}
p->type = type;
......@@ -213,8 +244,9 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
rem_len = length - p->len;
/* any remaining pbufs to be allocated? */
while (rem_len > 0) {
ALLOC_POOL_PBUF(q);
q = memp_malloc(MEMP_PBUF_POOL);
if (q == NULL) {
PBUF_POOL_IS_EMPTY();
/* free chain so far allocated */
pbuf_free(p);
/* bail out unsuccesfully */
......@@ -268,7 +300,8 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
/* only allocate memory for the pbuf structure */
p = memp_malloc(MEMP_PBUF);
if (p == NULL) {
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 2, ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n",
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n",
(type == PBUF_ROM) ? "ROM" : "REF"));
return NULL;
}
......@@ -286,7 +319,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
p->ref = 1;
/* set flags */
p->flags = 0;
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
return p;
}
......@@ -426,9 +459,9 @@ pbuf_header(struct pbuf *p, s16_t header_size_increment)
p->payload = (u8_t *)p->payload - header_size_increment;
/* boundary check fails? */
if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) {
LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_header: failed as %p < %p (not enough space for new header size)\n",
(void *)p->payload,
(void *)(p + 1)));\
LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("pbuf_header: failed as %p < %p (not enough space for new header size)\n",
(void *)p->payload, (void *)(p + 1)));
/* restore old payload pointer */
p->payload = payload;
/* bail out unsuccesfully */
......@@ -455,7 +488,7 @@ pbuf_header(struct pbuf *p, s16_t header_size_increment)
p->len += header_size_increment;
p->tot_len += header_size_increment;
LWIP_DEBUGF(PBUF_DEBUG, ("pbuf_header: old %p new %p (%"S16_F")\n",
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n",
(void *)payload, (void *)p->payload, header_size_increment));
return 0;
......@@ -504,10 +537,11 @@ pbuf_free(struct pbuf *p)
if (p == NULL) {
LWIP_ASSERT("p != NULL", p != NULL);
/* if assertions are disabled, proceed with debug output */
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.\n"));
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("pbuf_free(p == NULL) was called.\n"));
return 0;
}
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_free(%p)\n", (void *)p));
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p));
PERF_START;
......@@ -534,7 +568,7 @@ pbuf_free(struct pbuf *p)
if (ref == 0) {
/* remember next pbuf in chain for next iteration */
q = p->next;
LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: deallocating %p\n", (void *)p));
LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p));
type = p->type;
/* is this a pbuf from the pool? */
if (type == PBUF_POOL) {
......@@ -552,7 +586,7 @@ pbuf_free(struct pbuf *p)
/* p->ref > 0, this pbuf is still referenced to */
/* (and so the remaining pbufs in chain as well) */
} else {
LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref));
LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref));
/* stop walking through the chain */
p = NULL;
}
......@@ -657,7 +691,7 @@ pbuf_chain(struct pbuf *h, struct pbuf *t)
pbuf_cat(h, t);
/* t is now referenced by h */
pbuf_ref(t);
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
}
/**
......@@ -686,10 +720,10 @@ pbuf_dechain(struct pbuf *p)
/* total length of pbuf p is its own length only */
p->tot_len = p->len;
/* q is no longer referenced by p, free it */
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *)q));
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q));
tail_gone = pbuf_free(q);
if (tail_gone > 0) {
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_STATE,
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE,
("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));
}
/* return remaining tail or NULL if deallocated */
......@@ -722,7 +756,7 @@ pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
{
u16_t offset_to=0, offset_from=0, len;
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_copy(%p, %p)\n",
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
(void*)p_to, (void*)p_from));
/* is the target big enough to hold the source? */
......@@ -768,7 +802,7 @@ pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
(p_to->next == NULL), return ERR_VAL;);
}
} while (p_from);
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 1, ("pbuf_copy: end of chain reached.\n"));
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n"));
return ERR_OK;
}
......
......@@ -210,7 +210,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
struct ip_addr *src_ip;
struct pbuf *q; /* q will be sent down the stack */
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | 3, ("raw_sendto\n"));
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
/* not enough space to add an IP header to first pbuf in given p chain? */
if (pbuf_header(p, IP_HLEN)) {
......@@ -218,7 +218,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | 2, ("raw_sendto: could not allocate header\n"));
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
return ERR_MEM;
}
/* chain header q in front of given pbuf p */
......@@ -235,7 +235,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
}
if ((netif = ip_route(ipaddr)) == NULL) {
LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_sendto: No route to 0x%"X32_F"\n", ipaddr->addr));
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to 0x%"X32_F"\n", ipaddr->addr));
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
......@@ -246,7 +246,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
#if IP_SOF_BROADCAST
/* broadcast filter? */
if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif) ) {
LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
......@@ -335,7 +335,7 @@ struct raw_pcb *
raw_new(u8_t proto) {
struct raw_pcb *pcb;
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | 3, ("raw_new\n"));
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n"));
pcb = memp_malloc(MEMP_RAW_PCB);
/* could allocate RAW PCB? */
......
......@@ -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)
{
......
......@@ -118,7 +118,7 @@ snmp_netiftoifindex(struct netif *netif, s32_t *ifidx)
u16_t i;
i = 0;
while (nif != netif)
while ((nif != NULL) && (nif != netif))
{
nif = nif->next;
i++;
......
......@@ -97,7 +97,7 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
arg = tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
if (h != NULL) {
LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void*)&h, arg));
LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", *(void**)&h, arg));
h(arg);
}
......@@ -154,7 +154,7 @@ sys_sem_wait(sys_sem_t sem)
arg = tmptimeout->arg;
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
if (h != NULL) {
LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", (void*)&h, (void *)arg));
LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", *(void**)&h, (void *)arg));
h(arg);
}
......@@ -203,7 +203,7 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
timeouts = sys_arch_timeouts();
LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" h=%p arg=%p\n",
(void *)timeout, msecs, (void*)&h, (void *)arg));
(void *)timeout, msecs, *(void**)&h, (void *)arg));
if (timeouts == NULL) {
LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
......@@ -264,13 +264,15 @@ sys_untimeout(sys_timeout_handler h, void *arg)
if ((t->h == h) && (t->arg == arg)) {
/* We have a match */
/* Unlink from previous in list */
if (prev_t == NULL)
if (prev_t == NULL) {
timeouts->next = t->next;
else
} else {
prev_t->next = t->next;
}
/* If not the last one, add time of this one back to next */
if (t->next != NULL)
if (t->next != NULL) {
t->next->time += t->time;
}
memp_free(MEMP_SYS_TIMEOUT, t);
return;
}
......
......@@ -50,9 +50,24 @@
#include "lwip/snmp.h"
#include "lwip/tcp.h"
#include "lwip/debug.h"
#include "lwip/stats.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] =
......@@ -394,7 +409,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;
......@@ -564,6 +579,7 @@ tcp_slowtmr(void)
struct tcp_pcb *pcb, *pcb2, *prev;
u16_t eff_wnd;
u8_t pcb_remove; /* flag if a PCB should be removed */
u8_t pcb_reset; /* flag if a RST should be sent when removing */
err_t err;
err = ERR_OK;
......@@ -583,6 +599,7 @@ tcp_slowtmr(void)
LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
pcb_remove = 0;
pcb_reset = 0;
if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
++pcb_remove;
......@@ -666,7 +683,8 @@ tcp_slowtmr(void)
ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip)));
tcp_abort(pcb);
++pcb_remove;
++pcb_reset;
}
#if LWIP_TCP_KEEPALIVE
else if((u32_t)(tcp_ticks - pcb->tmr) >
......@@ -726,6 +744,10 @@ tcp_slowtmr(void)
}
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
if (pcb_reset) {
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
pcb->local_port, pcb->remote_port);
}
pcb2 = pcb->next;
memp_free(MEMP_TCP_PCB, pcb);
......@@ -899,11 +921,12 @@ tcp_seg_copy(struct tcp_seg *seg)
* Default receive callback that is called if the user didn't register
* a recv callback for the pcb.
*/
static err_t
err_t
tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
arg = arg;
LWIP_UNUSED_ARG(arg);
if (p != NULL) {
tcp_recved(pcb, p->tot_len);
pbuf_free(p);
} else if (err == ERR_OK) {
return tcp_close(pcb);
......@@ -993,9 +1016,18 @@ tcp_alloc(u8_t prio)
pcb = memp_malloc(MEMP_TCP_PCB);
if (pcb == NULL) {
/* Try killing active connections with lower priority than the new one. */
LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio));
tcp_kill_prio(prio);
/* Try to allocate a tcp_pcb again. */
pcb = memp_malloc(MEMP_TCP_PCB);
if (pcb != NULL) {
/* adjust err stats: memp_malloc failed twice before */
MEMP_STATS_DEC(err, MEMP_TCP_PCB);
}
}
if (pcb != NULL) {
/* adjust err stats: timewait PCB was freed above */
MEMP_STATS_DEC(err, MEMP_TCP_PCB);
}
}
if (pcb != NULL) {
......@@ -1218,7 +1250,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
* Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first.
*
* @param pcblist PCB list to purge.
* @param pcb tcp_pcb to purge. The pcb itself is also deallocated!
* @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated!
*/
void
tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
......@@ -1288,6 +1320,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.
......@@ -1333,42 +1371,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]));
}
/**
......
此差异已折叠。
......@@ -132,7 +132,7 @@ tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags)
}
return ERR_OK;
} else {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | 3, ("tcp_write() called in invalid state\n"));
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n"));
return ERR_CONN;
}
}
......@@ -174,7 +174,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
/* fail on too much data */
if (len > pcb->snd_buf) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_WARNING,
("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf));
pcb->flags |= TF_NAGLEMEMERR;
return ERR_MEM;
}
......@@ -194,7 +195,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
queuelen = pcb->snd_queuelen;
/* check for configured max queuelen and possible overflow */
if ((queuelen >= TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_WARNING,
("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
TCP_STATS_INC(tcp.memerr);
pcb->flags |= TF_NAGLEMEMERR;
return ERR_MEM;
......@@ -218,7 +220,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
/* Allocate memory for tcp_seg, and fill in fields. */
seg = memp_malloc(MEMP_TCP_SEG);
if (seg == NULL) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("tcp_enqueue: could not allocate memory for tcp_seg\n"));
goto memerr;
}
......@@ -243,7 +245,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
* ROM or other static memory, and need not be copied. */
if (apiflags & TCP_WRITE_FLAG_COPY) {
if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen + optlen, PBUF_RAM)) == NULL) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen));
goto memerr;
}
......@@ -259,7 +261,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
else {
/* First, allocate a pbuf for the headers. */
if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("tcp_enqueue: could not allocate memory for header pbuf\n"));
goto memerr;
}
......@@ -275,7 +277,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
/* If allocation fails, we have to deallocate the header pbuf as well. */
pbuf_free(seg->p);
seg->p = NULL;
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2,
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
goto memerr;
}
......@@ -293,7 +295,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
/* Now that there are more segments queued, we check again if the
length of the queue exceeds the configured maximum or overflows. */
if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
goto memerr;
}
......@@ -301,7 +304,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
/* build TCP header */
if (pbuf_header(seg->p, TCP_HLEN)) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_enqueue: no room for TCP header in pbuf.\n"));
TCP_STATS_INC(tcp.err);
goto memerr;
}
......@@ -343,11 +346,13 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
if (useg != NULL &&
TCP_TCPLEN(useg) != 0 &&
!(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
!(flags & (TCP_SYN | TCP_FIN)) &&
(!(flags & (TCP_SYN | TCP_FIN)) || (flags == TCP_FIN)) &&
/* 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 */
......@@ -363,10 +368,16 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
queuelen--;
pbuf_free(old_q);
}
LWIP_ASSERT("zero-length pbuf", (queue->p != NULL) && (queue->p->len > 0));
pbuf_cat(useg->p, queue->p);
useg->len += queue->len;
useg->next = queue->next;
if (flags & TCP_FIN) {
/* the new segment contains only FIN, no data -> put the FIN into the last segment */
LWIP_ASSERT("FIN enqueued together with data", queue->p == NULL && queue->len == 0);
TCPH_SET_FLAG(useg->tcphdr, TCP_FIN);
} else {
LWIP_ASSERT("zero-length pbuf", (queue->p != NULL) && (queue->p->len > 0));
pbuf_cat(useg->p, queue->p);
useg->len += queue->len;
useg->next = queue->next;
}
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));
if (seg == queue) {
......@@ -443,6 +454,58 @@ tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
}
#endif
/** Send an ACK without data.
*
* @param pcb Protocol control block for the TCP connection to send the ACK
*/
err_t
tcp_send_empty_ack(struct tcp_pcb *pcb)
{
struct pbuf *p;
struct tcp_hdr *tcphdr;
u8_t optlen = 0;
#if LWIP_TCP_TIMESTAMPS
if (pcb->flags & TF_TIMESTAMP) {
optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
}
#endif
p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen, PBUF_RAM);
if (p == NULL) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
return ERR_BUF;
}
LWIP_DEBUGF(TCP_OUTPUT_DEBUG,
("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
/* remove ACK flags from the PCB, as we send an empty ACK now */
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
tcphdr = tcp_output_set_header(pcb, p, optlen, htonl(pcb->snd_nxt));
/* NB. MSS option is only sent on SYNs, so ignore it here */
#if LWIP_TCP_TIMESTAMPS
pcb->ts_lastacksent = pcb->rcv_nxt;
if (pcb->flags & TF_TIMESTAMP) {
tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
}
#endif
#if CHECKSUM_GEN_TCP
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
IP_PROTO_TCP, p->tot_len);
#endif
#if LWIP_NETIF_HWADDRHINT
ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
IP_PROTO_TCP, &(pcb->addr_hint));
#else /* LWIP_NETIF_HWADDRHINT*/
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
IP_PROTO_TCP);
#endif /* LWIP_NETIF_HWADDRHINT*/
pbuf_free(p);
return ERR_OK;
}
/**
* Find out what we can send and send it
......@@ -454,14 +517,11 @@ tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
err_t
tcp_output(struct tcp_pcb *pcb)
{
struct pbuf *p;
struct tcp_hdr *tcphdr;
struct tcp_seg *seg, *useg;
u32_t wnd, snd_nxt;
#if TCP_CWND_DEBUG
s16_t i = 0;
#endif /* TCP_CWND_DEBUG */
u8_t optlen = 0;
/* First, check if we are invoked by the TCP input processing
code. If so, we do not output anything. Instead, we rely on the
......@@ -475,12 +535,6 @@ tcp_output(struct tcp_pcb *pcb)
seg = pcb->unsent;
/* useg should point to last segment on unacked queue */
useg = pcb->unacked;
if (useg != NULL) {
for (; useg->next != NULL; useg = useg->next);
}
/* If the TF_ACK_NOW flag is set and no data will be sent (either
* because the ->unsent queue is empty or because the window does
* not allow it), construct an empty ACK segment and send it.
......@@ -490,44 +544,13 @@ tcp_output(struct tcp_pcb *pcb)
if (pcb->flags & TF_ACK_NOW &&
(seg == NULL ||
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
#if LWIP_TCP_TIMESTAMPS
if (pcb->flags & TF_TIMESTAMP)
optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
#endif
p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen, PBUF_RAM);
if (p == NULL) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
return ERR_BUF;
}
LWIP_DEBUGF(TCP_OUTPUT_DEBUG,
("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
/* remove ACK flags from the PCB, as we send an empty ACK now */
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
tcphdr = tcp_output_set_header(pcb, p, optlen, htonl(pcb->snd_nxt));
/* NB. MSS option is only sent on SYNs, so ignore it here */
#if LWIP_TCP_TIMESTAMPS
pcb->ts_lastacksent = pcb->rcv_nxt;
if (pcb->flags & TF_TIMESTAMP)
tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
#endif
#if CHECKSUM_GEN_TCP
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
IP_PROTO_TCP, p->tot_len);
#endif
#if LWIP_NETIF_HWADDRHINT
ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
IP_PROTO_TCP, &(pcb->addr_hint));
#else /* LWIP_NETIF_HWADDRHINT*/
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
IP_PROTO_TCP);
#endif /* LWIP_NETIF_HWADDRHINT*/
pbuf_free(p);
return tcp_send_empty_ack(pcb);
}
return ERR_OK;
/* useg should point to last segment on unacked queue */
useg = pcb->unacked;
if (useg != NULL) {
for (; useg->next != NULL; useg = useg->next);
}
#if TCP_OUTPUT_DEBUG
......@@ -853,9 +876,50 @@ tcp_rexmit(struct tcp_pcb *pcb)
/* Do the actual retransmission. */
snmp_inc_tcpretranssegs();
tcp_output(pcb);
/* No need to call tcp_output: we are always called from tcp_input()
and thus tcp_output directly returns. */
}
/**
* Handle retransmission after three dupacks received
*
* @param pcb the tcp_pcb for which to retransmit the first unacked segment
*/
void
tcp_rexmit_fast(struct tcp_pcb *pcb)
{
if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) {
/* 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,
ntohl(pcb->unacked->tcphdr->seqno)));
tcp_rexmit(pcb);
/* 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;
}
}
/**
* Send keepalive packets to keep a connection active although
* no data is sent over it.
......@@ -924,6 +988,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 +1010,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 +1023,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,
......
......@@ -241,8 +241,8 @@ udp_input(struct pbuf *p, struct netif *inp)
if (inet_chksum_pseudo_partial(p, (struct ip_addr *)&(iphdr->src),
(struct ip_addr *)&(iphdr->dest),
IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) {
LWIP_DEBUGF(UDP_DEBUG | 2,
("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
UDP_STATS_INC(udp.chkerr);
UDP_STATS_INC(udp.drop);
snmp_inc_udpinerrors();
......@@ -258,7 +258,7 @@ udp_input(struct pbuf *p, struct netif *inp)
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
(struct ip_addr *)&(iphdr->dest),
IP_PROTO_UDP, p->tot_len) != 0) {
LWIP_DEBUGF(UDP_DEBUG | 2,
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("udp_input: UDP datagram discarded due to failing checksum\n"));
UDP_STATS_INC(udp.chkerr);
UDP_STATS_INC(udp.drop);
......@@ -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);
......@@ -362,7 +362,7 @@ udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
{
struct netif *netif;
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 3, ("udp_send\n"));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));
/* find the outgoing network interface for this packet */
#if LWIP_IGMP
......@@ -373,7 +373,7 @@ udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
/* no outgoing network interface could be found? */
if (netif == NULL) {
LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%"X32_F"\n", dst_ip->addr));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to 0x%"X32_F"\n", dst_ip->addr));
UDP_STATS_INC(udp.rterr);
return ERR_RTE;
}
......@@ -411,17 +411,18 @@ udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
#if IP_SOF_BROADCAST
/* broadcast filter? */
if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(dst_ip, netif) ) {
LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
return ERR_VAL;
}
#endif /* IP_SOF_BROADCAST */
/* if the PCB is not yet bound to a port, bind it here */
if (pcb->local_port == 0) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 2, ("udp_send: not yet bound to a port, binding now\n"));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
if (err != ERR_OK) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 2, ("udp_send: forced port bind failed\n"));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
return err;
}
}
......@@ -432,7 +433,7 @@ udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 2, ("udp_send: could not allocate header\n"));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
return ERR_MEM;
}
/* chain header q in front of given pbuf p */
......@@ -580,9 +581,9 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
struct udp_pcb *ipcb;
u8_t rebind;
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 3, ("udp_bind(ipaddr = "));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = "));
ip_addr_debug_print(UDP_DEBUG, ipaddr);
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 3, (", port = %"U16_F")\n", port));
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port));
rebind = 0;
/* Check for double bind and rebind of the same pcb */
......
......@@ -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__ */
......@@ -33,9 +33,6 @@
#define __LWIP_ICMP_H__
#include "lwip/opt.h"
#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
......@@ -70,11 +67,6 @@ enum icmp_te_type {
ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
};
void icmp_input(struct pbuf *p, struct netif *inp);
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
......@@ -103,10 +95,17 @@ PACK_STRUCT_END
#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t))
#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c))
#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
void icmp_input(struct pbuf *p, struct netif *inp);
void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
#endif /* LWIP_ICMP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ICMP */
#endif /* __LWIP_ICMP_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;
......
......@@ -35,12 +35,13 @@
#include "lwip/arch.h"
/** lower two bits indicate debug level
* - 0 off
* - 0 all
* - 1 warning
* - 2 serious
* - 3 severe
*/
#define LWIP_DBG_LEVEL_OFF 0x00
#define LWIP_DBG_LEVEL_ALL 0x00
#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */
#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */
#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */
#define LWIP_DBG_LEVEL_SEVERE 0x03
......
......@@ -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,7 +43,7 @@ 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) */
......
......@@ -84,8 +84,6 @@ extern const u16_t memp_sizes[MEMP_MAX];
#include "mem.h"
#define memp_init()
#define memp_malloc(type) mem_malloc(memp_sizes[type])
#define memp_free(type, mem) mem_free(mem)
#else /* MEMP_MEM_MALLOC */
......@@ -98,6 +96,7 @@ struct memp_malloc_helper
#endif /* MEM_USE_POOLS */
void memp_init(void);
#endif /* MEMP_MEM_MALLOC */
#if MEMP_OVERFLOW_CHECK
void *memp_malloc_fn(memp_t type, const char* file, const int line);
......@@ -107,8 +106,6 @@ void *memp_malloc(memp_t type);
#endif
void memp_free(memp_t type, void *mem);
#endif /* MEMP_MEM_MALLOC */
#ifdef __cplusplus
}
#endif
......
......@@ -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
}
......
......@@ -103,7 +103,7 @@ int lwip_getaddrinfo(const char *nodename,
#define gethostbyname(name) lwip_gethostbyname(name)
#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \
lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop)
#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(a)
#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo)
#define getaddrinfo(nodname, servname, hints, res) \
lwip_getaddrinfo(nodname, servname, hints, res)
#endif /* LWIP_COMPAT_SOCKETS */
......
......@@ -131,12 +131,12 @@ struct netif {
/* the hostname for this netif, NULL is a valid value */
char* hostname;
#endif /* LWIP_NETIF_HOSTNAME */
/** maximum transfer unit (in bytes) */
u16_t mtu;
/** number of bytes used in hwaddr */
u8_t hwaddr_len;
/** link level hardware address of this interface */
u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
/** maximum transfer unit (in bytes) */
u16_t mtu;
/** flags (see NETIF_FLAG_ above) */
u8_t flags;
/** descriptive abbreviation */
......
......@@ -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 ----------
......@@ -742,7 +759,7 @@
* (2 * TCP_MSS) for things to work well
*/
#ifndef TCP_WND
#define TCP_WND 2048
#define TCP_WND (4 * TCP_MSS)
#endif
/**
......@@ -768,14 +785,14 @@
#endif
/**
* TCP_MSS: TCP Maximum segment size. (default is 128, a *very*
* conservative default.)
* TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default,
* you might want to increase this.)
* For the receive side, this MSS is advertised to the remote side
* when opening a connection. For the transmit size, this MSS sets
* an upper limit on the MSS advertised by the remote host.
*/
#ifndef TCP_MSS
#define TCP_MSS 128
#define TCP_MSS 536
#endif
/**
......@@ -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
......@@ -1510,9 +1527,12 @@
#endif
#define PPP_MINMRU 128 /* No MRUs below this */
#ifndef MAXNAMELEN
#define MAXNAMELEN 256 /* max length of hostname or name for auth */
#endif
#ifndef MAXSECRETLEN
#define MAXSECRETLEN 256 /* max length of password or secret */
#endif
#endif /* PPP_SUPPORT */
......@@ -1574,7 +1594,7 @@
* messages are written.
*/
#ifndef LWIP_DBG_MIN_LEVEL
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#endif
/**
......
......@@ -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
......
......@@ -78,6 +78,9 @@ void tcp_err (struct tcp_pcb *pcb,
#define tcp_mss(pcb) ((pcb)->mss)
#define tcp_sndbuf(pcb) ((pcb)->snd_buf)
#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY)
#define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY)
#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0)
#if TCP_LISTEN_BACKLOG
#define tcp_accepted(pcb) (((struct tcp_pcb_listen *)(pcb))->accepts_pending--)
......@@ -122,9 +125,11 @@ void tcp_fasttmr (void);
/* Only used by IP to pass a TCP segment to TCP: */
void tcp_input (struct pbuf *p, struct netif *inp);
/* Used within the TCP code only: */
err_t tcp_send_empty_ack(struct tcp_pcb *pcb);
err_t tcp_output (struct tcp_pcb *pcb);
void tcp_rexmit (struct tcp_pcb *pcb);
void tcp_rexmit_rto (struct tcp_pcb *pcb);
void tcp_rexmit_fast (struct tcp_pcb *pcb);
u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
/**
......@@ -134,9 +139,10 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb);
* - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or
* - the only unsent segment is at least pcb->mss bytes long (or there is more
* than one unsent segment - with lwIP, this can happen although unsent->len < mss)
* - or if we are in fast-retransmit (TF_INFR)
*/
#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
((tpcb)->flags & TF_NODELAY) || \
((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
(((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
((tpcb)->unsent->len >= (tpcb)->mss))) \
) ? 1 : 0)
......@@ -230,12 +236,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,
......@@ -489,9 +494,7 @@ err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb,
if((pcb)->recv != NULL) { \
(ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); \
} else { \
(ret) = ERR_OK; \
if (p != NULL) \
pbuf_free(p); \
(ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \
} \
} while (0)
......@@ -585,9 +588,14 @@ void tcp_zero_window_probe(struct tcp_pcb *pcb);
u16_t tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr);
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
#if LWIP_CALLBACK_API
err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
#endif /* LWIP_CALLBACK_API */
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 +659,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 +687,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
}
......
......@@ -89,7 +89,13 @@
#define MEM_LIBC_MALLOC 1
#define mem_malloc rt_malloc
#define mem_free rt_free
#define mem_calloc rt_calloc
#define mem_calloc rt_calloc
#ifdef RT_LWIP_USING_RT_MEM
#define MEMP_MEM_MALLOC 1
#else
#define MEMP_MEM_MALLOC 0
#endif
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
......
......@@ -23,3 +23,7 @@ slipif.c
protocol. It requires a sio (serial I/O) module to work.
ppp/ Point-to-Point Protocol stack
The PPP stack has been ported from ucip (http://ucip.sourceforge.net).
It matches quite well to pppd 2.3.1 (http://ppp.samba.org), although
compared to that, it has some modifications for embedded systems and
the source code has been reordered a bit.
\ No newline at end of file
......@@ -468,7 +468,7 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
{
s8_t i;
u8_t k;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 3, ("update_arp_entry()\n"));
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry()\n"));
LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),
......@@ -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,32 @@ 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 | LWIP_DBG_LEVEL_WARNING,
("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))) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 1,
(ethhdr->type != htons(ETHTYPE_ARP))) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("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 +736,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
......@@ -788,7 +805,8 @@ etharp_output(struct netif *netif, struct pbuf *q, struct ip_addr *ipaddr)
/* make room for Ethernet header - should not fail */
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
/* bail out */
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("etharp_output: could not allocate room for header.\n"));
LINK_STATS_INC(link.lenerr);
return ERR_BUF;
}
......@@ -1034,23 +1052,26 @@ 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"));
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("etharp_raw: could not allocate pbuf for ARP request.\n"));
ETHARP_STATS_INC(etharp.memerr);
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 +1091,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 +1105,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 +1147,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 +1159,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 +1182,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;
......
......@@ -301,26 +301,18 @@ FINSH_FUNCTION_EXPORT(set_dns, set DNS server address);
void list_if()
{
struct ip_addr ip_addr;
struct _ip_addr
{
rt_uint8_t addr0, addr1, addr2, addr3;
} *addr;
rt_kprintf("Default network interface: %c%c\n", netif_default->name[0], netif_default->name[1]);
addr = (struct _ip_addr*)&netif_default->ip_addr.addr;
rt_kprintf("ip address: %d.%d.%d.%d\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
addr = (struct _ip_addr*)&netif_default->gw.addr;
rt_kprintf("gw address: %d.%d.%d.%d\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
addr = (struct _ip_addr*)&netif_default->netmask.addr;
rt_kprintf("net mask : %d.%d.%d.%d\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
rt_kprintf("ip address: %s\n", ip_ntoa(&(netif_default->ip_addr.addr)));
rt_kprintf("gw address: %s\n", ip_ntoa(&(netif_default->ip_addr.addr)));
rt_kprintf("net mask : %s\n", ip_ntoa(&(netif_default->ip_addr.addr)));
#if LWIP_DNS
ip_addr = dns_getserver(0);
addr = (struct _ip_addr*)&ip_addr;
rt_kprintf("dns server: %d.%d.%d.%d\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
{
struct ip_addr ip_addr;
ip_addr = dns_getserver(0);
rt_kprintf("dns server: %d.%d.%d.%d\n", ip_ntoa(&ip_addr));
}
#endif
}
FINSH_FUNCTION_EXPORT(list_if, list network interface information);
......
......@@ -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 ***/
......
/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/
/*** The original PPPD code is written in a way to require either the UNIX DES
encryption functions encrypt(3) and setkey(3) or the DES library libdes.
Since both is not included in lwIP, MSCHAP currently does not work! */
/*****************************************************************************
* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file.
*
......
......@@ -64,6 +64,8 @@
#include "fsm.h"
#include <string.h>
/*************************/
/*** LOCAL DEFINITIONS ***/
......@@ -551,7 +553,7 @@ fsm_timeout(void *arg)
break;
default:
FSMDEBUG((LOG_INFO, "%s: Timeout event in state %d (%s)!\n",
FSMDEBUG((LOG_INFO, "%s: UNHANDLED timeout event in state %d (%s)!\n",
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
}
}
......
......@@ -183,20 +183,7 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
/*** LOCAL FUNCTION DEFINITIONS ***/
/**********************************/
/*
* Non-standard inet_ntoa left here for compat with original ppp
* sources. Assumes u32_t instead of struct in_addr.
*/
char *
_inet_ntoa(u32_t n)
{
struct in_addr ia;
ia.s_addr = n;
return inet_ntoa(ia);
}
#define inet_ntoa _inet_ntoa
#define inet_ntoa(addr) ip_ntoa(((struct ip_addr*)&(addr)))
/*
* ipcp_init - Initialize IPCP.
......
......@@ -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 ***/
/***********************************/
......@@ -490,6 +492,7 @@ upap_rauthack(upap_state *u, u_char *inp, int id, int len)
msg = (char *) inp;
PRINTMSG(msg, msglen);
UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
u->us_clientstate = UPAPCS_OPEN;
auth_withpeer_success(u->us_unit, PPP_PAP);
......
......@@ -166,7 +166,7 @@ typedef struct PPPControl_s {
ext_accm outACCM; /* Async-Ctl-Char-Map for output. */
#if PPPOS_SUPPORT && VJ_SUPPORT
int vjEnabled; /* Flag indicating VJ compression enabled. */
struct vjcompress vjComp; /* Van Jabobsen compression header. */
struct vjcompress vjComp; /* Van Jacobson compression header. */
#endif /* PPPOS_SUPPORT && VJ_SUPPORT */
struct netif netif;
......@@ -235,7 +235,7 @@ struct protent *ppp_protocols[] = {
* Buffers for outgoing packets. This must be accessed only from the appropriate
* PPP task so that it doesn't need to be protected to avoid collisions.
*/
u_char *outpacket_buf[NUM_PPP];
u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];
/*****************************/
......@@ -306,13 +306,11 @@ pppMainWakeup(int pd)
void
pppLinkTerminated(int pd)
{
PPPControl *pc = &pppControl[pd];
PPPDEBUG((LOG_DEBUG, "pppLinkTerminated: unit %d\n", pd));
#if PPPOE_SUPPORT
if(pc->ethif) {
pppoe_disconnect(pc->pppoe_sc);
if(pppControl[pd].ethif) {
pppoe_disconnect(pppControl[pd].pppoe_sc);
} else
#endif /* PPPOE_SUPPORT */
{
......@@ -325,13 +323,11 @@ pppLinkTerminated(int pd)
void
pppLinkDown(int pd)
{
PPPControl *pc = &pppControl[pd];
PPPDEBUG((LOG_DEBUG, "pppLinkDown: unit %d\n", pd));
#if PPPOE_SUPPORT
if(pc->ethif) {
pppoe_disconnect(pc->pppoe_sc);
if(pppControl[pd].ethif) {
pppoe_disconnect(pppControl[pd].pppoe_sc);
} else
#endif /* PPPOE_SUPPORT */
{
......@@ -383,7 +379,7 @@ pppHupCB(void *arg)
struct ppp_settings ppp_settings;
err_t
void
pppInit(void)
{
struct protent *protp;
......@@ -395,16 +391,11 @@ 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]) {
return ERR_MEM;
}
/*
* Initialize to the standard option set.
*/
......@@ -413,17 +404,9 @@ pppInit(void)
}
}
#if LINK_STATS
/** @todo already done in stats_init (in fact, zeroed at boot). So, remove it? */
/* Clear the statistics. */
memset(&lwip_stats.link, 0, sizeof(lwip_stats.link));
#endif /* LINK_STATS */
#if PPPOE_SUPPORT
pppoe_init();
#endif /* PPPOE_SUPPORT */
return ERR_OK;
}
void
......@@ -601,7 +584,7 @@ int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const cha
pppControl[pd].openFlag = !0;
}
/* Launch a deamon thread. */
/* PPP session descriptor found, start PPPoE */
if (pd >= 0) {
pppControl[pd].openFlag = 1;
......@@ -824,9 +807,9 @@ static err_t
pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr)
{
int pd = (int)netif->state;
u_short protocol = PPP_IP;
PPPControl *pc = &pppControl[pd];
#if PPPOS_SUPPORT
u_short protocol = PPP_IP;
u_int fcsOut = PPP_INITFCS;
struct pbuf *headMB = NULL, *tailMB = NULL, *p;
u_char c;
......@@ -839,7 +822,7 @@ pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr)
* and the peer will just drop it if it's not accepting it. */
if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) {
PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad parms prot=%d pb=%p\n",
pd, protocol, pb));
pd, PPP_IP, pb));
LINK_STATS_INC(link.opterr);
LINK_STATS_INC(link.drop);
return ERR_ARG;
......@@ -1294,7 +1277,7 @@ GetMask(u32_t addr)
* sifvjcomp - config tcp header compression
*/
int
sifvjcomp( int pd, int vjcomp, int cidcomp, int maxcid)
sifvjcomp(int pd, int vjcomp, int cidcomp, int maxcid)
{
#if PPPOS_SUPPORT && VJ_SUPPORT
PPPControl *pc = &pppControl[pd];
......@@ -1304,6 +1287,11 @@ sifvjcomp( int pd, int vjcomp, int cidcomp, int maxcid)
pc->vjComp.maxSlotIndex = maxcid;
PPPDEBUG((LOG_INFO, "sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n",
vjcomp, cidcomp, maxcid));
#else /* PPPOS_SUPPORT && VJ_SUPPORT */
LWIP_UNUSED_ARG(pd);
LWIP_UNUSED_ARG(vjcomp);
LWIP_UNUSED_ARG(cidcomp);
LWIP_UNUSED_ARG(maxcid);
#endif /* PPPOS_SUPPORT && VJ_SUPPORT */
return 0;
......@@ -1381,6 +1369,8 @@ sifdown(int pd)
PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd));
} else {
pc->if_up = 0;
/* make sure the netif status callback is called */
netif_set_down(&pc->netif);
netif_remove(&pc->netif);
PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
if(pc->linkStatusCB) {
......@@ -1537,8 +1527,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);
}
}
}
......@@ -1658,7 +1648,7 @@ pppInput(void *arg)
switch(protocol) {
case PPP_VJC_COMP: /* VJ compressed TCP */
#if VJ_SUPPORT
#if PPPOS_SUPPORT && VJ_SUPPORT
PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len));
/*
* Clip off the VJ header and prepend the rebuilt TCP/IP header and
......@@ -1670,14 +1660,14 @@ pppInput(void *arg)
}
/* Something's wrong so drop it. */
PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ compressed\n", pd));
#else /* VJ_SUPPORT */
#else /* PPPOS_SUPPORT && VJ_SUPPORT */
/* No handler for this protocol so drop the packet. */
PPPDEBUG((LOG_INFO, "pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload));
#endif /* VJ_SUPPORT */
#endif /* PPPOS_SUPPORT && VJ_SUPPORT */
break;
case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */
#if VJ_SUPPORT
#if PPPOS_SUPPORT && VJ_SUPPORT
PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len));
/*
* Process the TCP/IP header for VJ header compression and then pass
......@@ -1689,12 +1679,12 @@ pppInput(void *arg)
}
/* Something's wrong so drop it. */
PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ uncompressed\n", pd));
#else /* VJ_SUPPORT */
#else /* PPPOS_SUPPORT && VJ_SUPPORT */
/* No handler for this protocol so drop the packet. */
PPPDEBUG((LOG_INFO,
"pppInput[%d]: drop VJ UnComp in %d:.*H\n",
pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload));
#endif /* VJ_SUPPORT */
#endif /* PPPOS_SUPPORT && VJ_SUPPORT */
break;
case PPP_IP: /* Internet Protocol */
......
......@@ -333,7 +333,7 @@ struct ppp_addrs {
*****************************/
/* Buffers for outgoing packets. */
extern u_char *outpacket_buf[NUM_PPP];
extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN];
extern struct ppp_settings ppp_settings;
......@@ -345,7 +345,7 @@ extern struct protent *ppp_protocols[]; /* Table of pointers to supported protoc
***********************/
/* Initialize the PPP subsystem. */
err_t pppInit(void);
void pppInit(void);
/* Warning: Using PPPAUTHTYPE_ANY might have security consequences.
* RFC 1994 says:
......
......@@ -398,7 +398,7 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb)
#endif
struct pppoehdr *ph;
struct pppoetag pt;
int off = 0, err, errortag;
int off, err, errortag;
struct eth_hdr *ethhdr;
pb = pppSingleBuf(pb);
......@@ -410,7 +410,7 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb)
goto done;
}
ethhdr = (struct eth_hdr *)pb->payload;
off += sizeof(*ethhdr);
off = sizeof(*ethhdr);
ac_cookie = NULL;
ac_cookie_len = 0;
......@@ -419,7 +419,7 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb)
hunique_len = 0;
#endif
session = 0;
if (pb->len - off <= PPPOE_HEADERLEN) {
if (pb->len - off < PPPOE_HEADERLEN) {
printf("pppoe: packet too short: %d\n", pb->len);
goto done;
}
......
......@@ -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. */
......
......@@ -136,7 +136,7 @@ vj_compress_init(struct vjcompress *comp)
}
/*
* vj_compress_tcp - Attempt to do Van Jacobsen header compression on a
* vj_compress_tcp - Attempt to do Van Jacobson header compression on a
* packet. This assumes that nb and comp are not null and that the first
* buffer of the chain contains a valid IP header.
* Return the VJ type code indicating whether or not the packet was
......
此差异已折叠。
#ifndef __LWIP_CHECK_H__
#define __LWIP_CHECK_H__
/* Common header file for lwIP unit tests using the check framework */
#include <config.h>
#include <check.h>
#include <stdlib.h>
#define FAIL_RET() do { fail(); return; } while(0)
#define EXPECT(x) fail_unless(x)
#define EXPECT_RET(x) do { fail_unless(x); if(!(x)) { return; }} while(0)
#define EXPECT_RETX(x, y) do { fail_unless(x); if(!(x)) { return y; }} while(0)
#define EXPECT_RETNULL(x) EXPECT_RETX(x, NULL)
/** typedef for a function returning a test suite */
typedef Suite* (suite_getter_fn)(void);
/** Create a test suite */
static Suite* create_suite(const char* name, TFun *tests, size_t num_tests, SFun setup, SFun teardown)
{
size_t i;
Suite *s = suite_create(name);
for(i = 0; i < num_tests; i++) {
// Core test case
TCase *tc_core = tcase_create("Core");
if ((setup != NULL) || (teardown != NULL)) {
tcase_add_checked_fixture(tc_core, setup, teardown);
}
tcase_add_test(tc_core, tests[i]);
suite_add_tcase(s, tc_core);
}
return s;
}
#endif /* __LWIP_CHECK_H__ */
#include "lwip_check.h"
#include "udp/test_udp.h"
#include "tcp/test_tcp.h"
#include "tcp/test_tcp_oos.h"
#include "lwip/init.h"
int main()
{
int number_failed;
SRunner *sr;
size_t i;
suite_getter_fn* suites[] = {
udp_suite,
tcp_suite,
tcp_oos_suite,
};
size_t num = sizeof(suites)/sizeof(void*);
LWIP_ASSERT("No suites defined", num > 0);
lwip_init();
sr = srunner_create((suites[0])());
for(i = 1; i < num; i++) {
srunner_add_suite(sr, ((suite_getter_fn*)suites[i])());
}
#ifdef LWIP_UNITTESTS_NOFORK
srunner_set_fork_status(sr, CK_NOFORK);
#endif
#ifdef LWIP_UNITTESTS_FORK
srunner_set_fork_status(sr, CK_FORK);
#endif
srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
#ifndef __TEST_TCP_H__
#define __TEST_TCP_H__
#include "../lwip_check.h"
Suite *tcp_suite(void);
#endif
此差异已折叠。
#ifndef __TEST_TCP_OOS_H__
#define __TEST_TCP_OOS_H__
#include "../lwip_check.h"
Suite *tcp_oos_suite(void);
#endif
此差异已折叠。
#ifndef __TEST_UDP_H__
#define __TEST_UDP_H__
#include "../lwip_check.h"
Suite* udp_suite(void);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册