提交 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;
......
......@@ -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.
......
......@@ -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);
}
......@@ -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
......@@ -184,11 +190,24 @@ autoip_create_addr(struct netif *netif, struct ip_addr *IPAddr)
}
LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
(addr <= AUTOIP_RANGE_END));
IPAddr->addr = htonl(addr);
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);
} else {
autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() ANNOUNCING Sent Announce\n"));
}
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
netif->autoip->sent_num++;
if(netif->autoip->sent_num == ANNOUNCE_NUM) {
if(netif->autoip->sent_num >= ANNOUNCE_NUM) {
netif->autoip->state = AUTOIP_STATE_BOUND;
netif->autoip->sent_num = 0;
netif->autoip->ttw = 0;
} else {
autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
("autoip_tmr() ANNOUNCING Sent Announce\n"));
netif->autoip->sent_num++;
netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
}
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",
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 | 2, ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), "
"IP packet dropped.\n",
}
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()"));
}
#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);
......
......@@ -290,6 +290,10 @@ memp_init(void)
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.
......@@ -309,6 +313,7 @@ memp_malloc(memp_t type)
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),
......@@ -407,6 +414,12 @@ void netif_set_up(struct netif *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) {
......@@ -472,7 +498,7 @@ void netif_set_link_up(struct netif *netif )
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);
retry:
p = memp_malloc(MEMP_PBUF_POOL);
if (NULL == p) {
for (pcb=tcp_active_pcbs; NULL != pcb; pcb = pcb->next) {
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;
goto retry;
return;
}
}
}
/** 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);
}
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,56 +454,21 @@ tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
}
#endif
/**
* Find out what we can send and send it
/** Send an ACK without data.
*
* @param pcb Protocol control block for the TCP connection to send data
* @return ERR_OK if data has been sent or nothing to send
* another err_t on error
* @param pcb Protocol control block for the TCP connection to send the ACK
*/
err_t
tcp_output(struct tcp_pcb *pcb)
tcp_send_empty_ack(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
input processing code to call us when input processing is done
with. */
if (tcp_input_pcb == pcb) {
return ERR_OK;
}
wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
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.
*
* If data is to be sent, we will just piggyback the ACK (see below).
*/
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)
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) {
......@@ -510,8 +486,9 @@ tcp_output(struct tcp_pcb *pcb)
#if LWIP_TCP_TIMESTAMPS
pcb->ts_lastacksent = pcb->rcv_nxt;
if (pcb->flags & TF_TIMESTAMP)
if (pcb->flags & TF_TIMESTAMP) {
tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
}
#endif
#if CHECKSUM_GEN_TCP
......@@ -527,9 +504,55 @@ tcp_output(struct tcp_pcb *pcb)
#endif /* LWIP_NETIF_HWADDRHINT*/
pbuf_free(p);
return ERR_OK;
}
/**
* Find out what we can send and send it
*
* @param pcb Protocol control block for the TCP connection to send data
* @return ERR_OK if data has been sent or nothing to send
* another err_t on error
*/
err_t
tcp_output(struct tcp_pcb *pcb)
{
struct tcp_seg *seg, *useg;
u32_t wnd, snd_nxt;
#if TCP_CWND_DEBUG
s16_t i = 0;
#endif /* TCP_CWND_DEBUG */
/* First, check if we are invoked by the TCP input processing
code. If so, we do not output anything. Instead, we rely on the
input processing code to call us when input processing is done
with. */
if (tcp_input_pcb == pcb) {
return ERR_OK;
}
wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
seg = pcb->unsent;
/* 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.
*
* If data is to be sent, we will just piggyback the ACK (see below).
*/
if (pcb->flags & TF_ACK_NOW &&
(seg == NULL ||
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
return tcp_send_empty_ack(pcb);
}
/* 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
if (seg == NULL) {
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
......@@ -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 */
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,7 +241,7 @@ 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,
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);
......@@ -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
}
......
......@@ -91,6 +91,12 @@
#define mem_free rt_free
#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
should be set high. */
......
......@@ -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
{
struct ip_addr ip_addr;
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);
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,15 +391,10 @@ pppInit(void)
magicInit();
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;
}
for (i = 0; i < NUM_PPP; i++) {
pppControl[i].openFlag = 0;
/*
* 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
......
......@@ -39,7 +39,7 @@
/*
* This is an arch independent SLIP netif. The specific serial hooks must be
* provided by another file. They are sio_open, sio_recv and sio_send
* provided by another file. They are sio_open, sio_read/sio_tryread and sio_send
*/
#include "netif/slipif.h"
......@@ -54,12 +54,28 @@
#include "lwip/snmp.h"
#include "lwip/sio.h"
#define SLIP_BLOCK 1
#define SLIP_DONTBLOCK 0
#define SLIP_END 0300 /* 0xC0 */
#define SLIP_ESC 0333 /* 0xDB */
#define SLIP_ESC_END 0334 /* 0xDC */
#define SLIP_ESC_ESC 0335 /* 0xDD */
#define MAX_SIZE 1500
#define SLIP_MAX_SIZE 1500
enum slipif_recv_state {
SLIP_RECV_NORMAL,
SLIP_RECV_ESCAPE,
};
struct slipif_priv {
sio_fd_t sd;
/* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
struct pbuf *p, *q;
enum slipif_recv_state state;
u16_t i, recved;
};
/**
* Send a pbuf doing the necessary SLIP encapsulation
......@@ -74,6 +90,7 @@
err_t
slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
struct slipif_priv *priv;
struct pbuf *q;
u16_t i;
u8_t c;
......@@ -84,73 +101,101 @@ slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
LWIP_UNUSED_ARG(ipaddr);
priv = netif->state;
/* Send pbuf out on the serial I/O device. */
sio_send(SLIP_END, netif->state);
sio_send(SLIP_END, priv->sd);
for (q = p; q != NULL; q = q->next) {
for (i = 0; i < q->len; i++) {
c = ((u8_t *)q->payload)[i];
switch (c) {
case SLIP_END:
sio_send(SLIP_ESC, netif->state);
sio_send(SLIP_ESC_END, netif->state);
sio_send(SLIP_ESC, priv->sd);
sio_send(SLIP_ESC_END, priv->sd);
break;
case SLIP_ESC:
sio_send(SLIP_ESC, netif->state);
sio_send(SLIP_ESC_ESC, netif->state);
sio_send(SLIP_ESC, priv->sd);
sio_send(SLIP_ESC_ESC, priv->sd);
break;
default:
sio_send(c, netif->state);
sio_send(c, priv->sd);
break;
}
}
}
sio_send(SLIP_END, netif->state);
sio_send(SLIP_END, priv->sd);
return ERR_OK;
}
/**
* Static function for easy use of blockig or non-blocking
* sio_read
*
* @param fd serial device handle
* @param data pointer to data buffer for receiving
* @param len maximum length (in bytes) of data to receive
* @param block if 1, call sio_read; if 0, call sio_tryread
* @return return value of sio_read of sio_tryread
*/
static u32_t
slip_sio_read(sio_fd_t fd, u8_t* data, u32_t len, u8_t block)
{
if (block) {
return sio_read(fd, data, len);
} else {
return sio_tryread(fd, data, len);
}
}
/**
* Handle the incoming SLIP stream character by character
*
* Poll the serial layer by calling sio_recv()
* Poll the serial layer by calling sio_read() or sio_tryread().
*
* @param netif the lwip network interface structure for this slipif
* @param block if 1, block until data is received; if 0, return when all data
* from the buffer is received (multiple calls to this function will
* return a complete packet, NULL is returned before - used for polling)
* @return The IP packet when SLIP_END is received
*/
static struct pbuf *
slipif_input(struct netif *netif)
slipif_input(struct netif *netif, u8_t block)
{
struct slipif_priv *priv;
u8_t c;
/* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
struct pbuf *p, *q;
u16_t recved;
u16_t i;
struct pbuf *t;
LWIP_ASSERT("netif != NULL", (netif != NULL));
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
q = p = NULL;
recved = i = 0;
c = 0;
priv = netif->state;
while (1) {
c = sio_recv(netif->state);
while (slip_sio_read(priv->sd, &c, 1, block) > 0) {
switch (priv->state) {
case SLIP_RECV_NORMAL:
switch (c) {
case SLIP_END:
if (recved > 0) {
if (priv->recved > 0) {
/* Received whole packet. */
/* Trim the pbuf to the size of the received packet. */
pbuf_realloc(q, recved);
pbuf_realloc(priv->q, priv->recved);
LINK_STATS_INC(link.recv);
LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
return q;
t = priv->q;
priv->p = priv->q = NULL;
priv->i = priv->recved = 0;
return t;
}
break;
continue;
case SLIP_ESC:
c = sio_recv(netif->state);
priv->state = SLIP_RECV_ESCAPE;
continue;
}
break;
case SLIP_RECV_ESCAPE:
switch (c) {
case SLIP_ESC_END:
c = SLIP_END;
......@@ -159,52 +204,52 @@ slipif_input(struct netif *netif)
c = SLIP_ESC;
break;
}
priv->state = SLIP_RECV_NORMAL;
/* FALLTHROUGH */
}
default:
/* byte received, packet not yet completely received */
if (p == NULL) {
if (priv->p == NULL) {
/* allocate a new pbuf */
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);
priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL);
if (p == NULL) {
if (priv->p == NULL) {
LINK_STATS_INC(link.drop);
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
/* don't process any further since we got no pbuf to receive to */
break;
}
if (q != NULL) {
if (priv->q != NULL) {
/* 'chain' the pbuf to the existing chain */
pbuf_cat(q, p);
pbuf_cat(priv->q, priv->p);
} else {
/* p is the first pbuf in the chain */
q = p;
priv->q = priv->p;
}
}
/* this automatically drops bytes if > MAX_SIZE */
if ((p != NULL) && (recved <= MAX_SIZE)) {
((u8_t *)p->payload)[i] = c;
recved++;
i++;
if (i >= p->len) {
/* this automatically drops bytes if > SLIP_MAX_SIZE */
if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
((u8_t *)priv->p->payload)[priv->i] = c;
priv->recved++;
priv->i++;
if (priv->i >= priv->p->len) {
/* on to the next pbuf */
i = 0;
if (p->next != NULL && p->next->len > 0) {
priv->i = 0;
if (priv->p->next != NULL && priv->p->next->len > 0) {
/* p is a chain, on to the next in the chain */
p = p->next;
priv->p = priv->p->next;
} else {
/* p is a single pbuf, set it to NULL so next time a new
* pbuf is allocated */
p = NULL;
priv->p = NULL;
}
}
}
break;
}
}
return NULL;
}
......@@ -217,13 +262,13 @@ slipif_input(struct netif *netif)
* @param nf the lwip network interface structure for this slipif
*/
static void
slipif_loop(void *nf)
slipif_loop_thread(void *nf)
{
struct pbuf *p;
struct netif *netif = (struct netif *)nf;
while (1) {
p = slipif_input(netif);
p = slipif_input(netif, SLIP_BLOCK);
if (p != NULL) {
if (netif->input(p, netif) != ERR_OK) {
pbuf_free(p);
......@@ -242,6 +287,7 @@ slipif_loop(void *nf)
*
* @param netif the lwip network interface structure for this slipif
* @return ERR_OK if serial line could be opened,
* ERR_MEM if no memory could be allocated,
* ERR_IF is serial line couldn't be opened
*
* @note netif->num must contain the number of the serial port to open
......@@ -250,22 +296,39 @@ slipif_loop(void *nf)
err_t
slipif_init(struct netif *netif)
{
struct slipif_priv *priv;
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
/* Allocate private data */
priv = mem_malloc(sizeof(struct slipif_priv));
if (!priv) {
return ERR_MEM;
}
netif->name[0] = 's';
netif->name[1] = 'l';
netif->output = slipif_output;
netif->mtu = MAX_SIZE;
netif->flags = NETIF_FLAG_POINTTOPOINT;
netif->mtu = SLIP_MAX_SIZE;
netif->flags |= NETIF_FLAG_POINTTOPOINT;
/* Try to open the serial port (netif->num contains the port number). */
netif->state = sio_open(netif->num);
if (!netif->state) {
priv->sd = sio_open(netif->num);
if (!priv->sd) {
/* Opening the serial port failed. */
mem_free(priv);
return ERR_IF;
}
/* Initialize private data */
priv->p = NULL;
priv->q = NULL;
priv->state = SLIP_RECV_NORMAL;
priv->i = 0;
priv->recved = 0;
netif->state = priv;
/* initialize the snmp variables and counters inside the struct netif
* ifSpeed: no assumption can be made without knowing more about the
* serial line!
......@@ -273,7 +336,32 @@ slipif_init(struct netif *netif)
NETIF_INIT_SNMP(netif, snmp_ifType_slip, 0);
/* Create a thread to poll the serial line. */
sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop, netif, SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
return ERR_OK;
}
/**
* Polls the serial device and feeds the IP layer with incoming packets.
*
* @param netif The lwip network interface structure for this slipif
*/
void
slipif_poll(struct netif *netif)
{
struct pbuf *p;
struct slipif_priv *priv;
LWIP_ASSERT("netif != NULL", (netif != NULL));
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
priv = netif->state;
while ((p = slipif_input(netif, SLIP_DONTBLOCK)) != NULL) {
if (netif->input(p, netif) != ERR_OK) {
pbuf_free(p);
}
}
}
#endif /* LWIP_HAVE_SLIPIF */
#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.
先完成此消息的编辑!
想要评论请 注册