mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-05 22:29:49 +00:00
Fixes wrongly cast LWIP_DEBUGF arguments (patch #1596 and more).
This commit is contained in:
parent
ba786dc49b
commit
93dfcdce93
125
src/core/dhcp.c
125
src/core/dhcp.c
@ -3,14 +3,14 @@
|
|||||||
*
|
*
|
||||||
* Dynamic Host Configuration Protocol client
|
* Dynamic Host Configuration Protocol client
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2003 Leon Woestenberg <leon.woestenberg@gmx.net>
|
* Copyright (c) 2001-2003 Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||||
* Copyright (c) 2001-2003 Axon Digital Design B.V., The Netherlands.
|
* Copyright (c) 2001-2003 Axon Digital Design B.V., The Netherlands.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
@ -19,26 +19,26 @@
|
|||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
* OF SUCH DAMAGE.
|
* OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is a contribution to the lwIP TCP/IP stack.
|
* This file is a contribution to the lwIP TCP/IP stack.
|
||||||
* The Swedish Institute of Computer Science and Adam Dunkels
|
* The Swedish Institute of Computer Science and Adam Dunkels
|
||||||
* are specifically granted permission to redistribute this
|
* are specifically granted permission to redistribute this
|
||||||
* source code.
|
* source code.
|
||||||
*
|
*
|
||||||
* Author: Leon Woestenberg <leon.woestenberg@gmx.net>
|
* Author: Leon Woestenberg <leon.woestenberg@gmx.net>
|
||||||
*
|
*
|
||||||
* This is a DHCP client for the lwIP TCP/IP stack. It aims to conform
|
* This is a DHCP client for the lwIP TCP/IP stack. It aims to conform
|
||||||
* with RFC 2131 and RFC 2132.
|
* with RFC 2131 and RFC 2132.
|
||||||
*
|
*
|
||||||
@ -135,11 +135,12 @@ static void dhcp_option_trailer(struct dhcp *dhcp);
|
|||||||
* We back-off and will end up restarting a fresh DHCP negotiation later.
|
* We back-off and will end up restarting a fresh DHCP negotiation later.
|
||||||
*
|
*
|
||||||
* @param state pointer to DHCP state structure
|
* @param state pointer to DHCP state structure
|
||||||
*/
|
*/
|
||||||
static void dhcp_handle_nak(struct netif *netif) {
|
static void dhcp_handle_nak(struct netif *netif) {
|
||||||
struct dhcp *dhcp = netif->dhcp;
|
struct dhcp *dhcp = netif->dhcp;
|
||||||
u16_t msecs = 10 * 1000;
|
u16_t msecs = 10 * 1000;
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_nak(netif=%p) %c%c%u\n", netif,
|
||||||
|
netif->name[0], netif->name[1], (unsigned int)netif->num));
|
||||||
dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
|
dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %u msecs\n", msecs));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_handle_nak(): set request timeout %u msecs\n", msecs));
|
||||||
dhcp_set_state(dhcp, DHCP_BACKING_OFF);
|
dhcp_set_state(dhcp, DHCP_BACKING_OFF);
|
||||||
@ -147,7 +148,7 @@ static void dhcp_handle_nak(struct netif *netif) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the offered IP address is already in use.
|
* Checks if the offered IP address is already in use.
|
||||||
*
|
*
|
||||||
* It does so by sending an ARP request for the offered address and
|
* It does so by sending an ARP request for the offered address and
|
||||||
* entering CHECKING state. If no ARP reply is received within a small
|
* entering CHECKING state. If no ARP reply is received within a small
|
||||||
* interval, the address is assumed to be free for use by us.
|
* interval, the address is assumed to be free for use by us.
|
||||||
@ -157,7 +158,8 @@ static void dhcp_check(struct netif *netif)
|
|||||||
struct dhcp *dhcp = netif->dhcp;
|
struct dhcp *dhcp = netif->dhcp;
|
||||||
err_t result;
|
err_t result;
|
||||||
u16_t msecs;
|
u16_t msecs;
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", netif, netif->name[0], netif->name[1]));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (unsigned int)netif->name[0],
|
||||||
|
(unsigned int)netif->name[1]));
|
||||||
/* create an ARP query for the offered IP address, expecting that no host
|
/* create an ARP query for the offered IP address, expecting that no host
|
||||||
responds, as the IP address should not be in use. */
|
responds, as the IP address should not be in use. */
|
||||||
result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
|
result = etharp_query(netif, &dhcp->offered_ip_addr, NULL);
|
||||||
@ -173,7 +175,7 @@ static void dhcp_check(struct netif *netif)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Remember the configuration offered by a DHCP server.
|
* Remember the configuration offered by a DHCP server.
|
||||||
*
|
*
|
||||||
* @param state pointer to DHCP state structure
|
* @param state pointer to DHCP state structure
|
||||||
*/
|
*/
|
||||||
static void dhcp_handle_offer(struct netif *netif)
|
static void dhcp_handle_offer(struct netif *netif)
|
||||||
@ -181,7 +183,8 @@ static void dhcp_handle_offer(struct netif *netif)
|
|||||||
struct dhcp *dhcp = netif->dhcp;
|
struct dhcp *dhcp = netif->dhcp;
|
||||||
/* obtain the server address */
|
/* obtain the server address */
|
||||||
u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);
|
u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID);
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_handle_offer(netif=%p) %c%c%u\n", netif,
|
||||||
|
netif->name[0], netif->name[1], netif->num));
|
||||||
if (option_ptr != NULL)
|
if (option_ptr != NULL)
|
||||||
{
|
{
|
||||||
dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
|
dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2]));
|
||||||
@ -313,10 +316,10 @@ void dhcp_fine_tmr()
|
|||||||
* A DHCP negotiation transaction, or ARP request, has timed out.
|
* A DHCP negotiation transaction, or ARP request, has timed out.
|
||||||
*
|
*
|
||||||
* The timer that was started with the DHCP or ARP request has
|
* The timer that was started with the DHCP or ARP request has
|
||||||
* timed out, indicating no response was received in time.
|
* timed out, indicating no response was received in time.
|
||||||
*
|
*
|
||||||
* @param netif the netif under DHCP control
|
* @param netif the netif under DHCP control
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void dhcp_timeout(struct netif *netif)
|
static void dhcp_timeout(struct netif *netif)
|
||||||
{
|
{
|
||||||
@ -341,7 +344,7 @@ static void dhcp_timeout(struct netif *netif)
|
|||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n"));
|
||||||
if (dhcp->tries <= 1) {
|
if (dhcp->tries <= 1) {
|
||||||
dhcp_check(netif);
|
dhcp_check(netif);
|
||||||
/* no ARP replies on the offered address,
|
/* no ARP replies on the offered address,
|
||||||
looks like the IP address is indeed free */
|
looks like the IP address is indeed free */
|
||||||
} else {
|
} else {
|
||||||
/* bind the interface to the offered address */
|
/* bind the interface to the offered address */
|
||||||
@ -351,7 +354,7 @@ static void dhcp_timeout(struct netif *netif)
|
|||||||
/* did not get response to renew request? */
|
/* did not get response to renew request? */
|
||||||
else if (dhcp->state == DHCP_RENEWING) {
|
else if (dhcp->state == DHCP_RENEWING) {
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n"));
|
||||||
/* just retry renewal */
|
/* just retry renewal */
|
||||||
/* note that the rebind timer will eventually time-out if renew does not work */
|
/* note that the rebind timer will eventually time-out if renew does not work */
|
||||||
dhcp_renew(netif);
|
dhcp_renew(netif);
|
||||||
/* did not get response to rebind request? */
|
/* did not get response to rebind request? */
|
||||||
@ -483,7 +486,7 @@ static void dhcp_handle_ack(struct netif *netif)
|
|||||||
* a new client is created first. If a DHCP client instance
|
* a new client is created first. If a DHCP client instance
|
||||||
* was already present, it restarts negotiation.
|
* was already present, it restarts negotiation.
|
||||||
*
|
*
|
||||||
* @param netif The lwIP network interface
|
* @param netif The lwIP network interface
|
||||||
* @return lwIP error code
|
* @return lwIP error code
|
||||||
* - ERR_OK - No error
|
* - ERR_OK - No error
|
||||||
* - ERR_MEM - Out of memory
|
* - ERR_MEM - Out of memory
|
||||||
@ -534,14 +537,14 @@ err_t dhcp_start(struct netif *netif)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Inform a DHCP server of our manual configuration.
|
* Inform a DHCP server of our manual configuration.
|
||||||
*
|
*
|
||||||
* This informs DHCP servers of our fixed IP address configuration
|
* This informs DHCP servers of our fixed IP address configuration
|
||||||
* by sending an INFORM message. It does not involve DHCP address
|
* by sending an INFORM message. It does not involve DHCP address
|
||||||
* configuration, it is just here to be nice to the network.
|
* configuration, it is just here to be nice to the network.
|
||||||
*
|
*
|
||||||
* @param netif The lwIP network interface
|
* @param netif The lwIP network interface
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void dhcp_inform(struct netif *netif)
|
void dhcp_inform(struct netif *netif)
|
||||||
{
|
{
|
||||||
struct dhcp *dhcp;
|
struct dhcp *dhcp;
|
||||||
@ -550,7 +553,7 @@ void dhcp_inform(struct netif *netif)
|
|||||||
if (dhcp == NULL) {
|
if (dhcp == NULL) {
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_inform(): could not allocate dhcp\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
netif->dhcp = dhcp;
|
netif->dhcp = dhcp;
|
||||||
memset(dhcp, 0, sizeof(struct dhcp));
|
memset(dhcp, 0, sizeof(struct dhcp));
|
||||||
|
|
||||||
@ -619,7 +622,7 @@ void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decline an offered lease.
|
* Decline an offered lease.
|
||||||
*
|
*
|
||||||
* Tell the DHCP server we do not accept the offered address.
|
* Tell the DHCP server we do not accept the offered address.
|
||||||
@ -735,7 +738,7 @@ static void dhcp_bind(struct netif *netif)
|
|||||||
LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL);
|
LWIP_ASSERT("dhcp_bind: netif != NULL", netif != NULL);
|
||||||
LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL);
|
LWIP_ASSERT("dhcp_bind: dhcp != NULL", dhcp != NULL);
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 3, ("dhcp_bind(netif=%p) %c%c%u\n", netif, netif->name[0], netif->name[1], netif->num));
|
||||||
|
|
||||||
/* temporary DHCP lease? */
|
/* temporary DHCP lease? */
|
||||||
if (dhcp->offered_t1_renew != 0xffffffffUL) {
|
if (dhcp->offered_t1_renew != 0xffffffffUL) {
|
||||||
/* set renewal period timer */
|
/* set renewal period timer */
|
||||||
@ -785,7 +788,7 @@ static void dhcp_bind(struct netif *netif)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Renew an existing DHCP lease at the involved DHCP server.
|
* Renew an existing DHCP lease at the involved DHCP server.
|
||||||
*
|
*
|
||||||
* @param netif network interface which must renew its lease
|
* @param netif network interface which must renew its lease
|
||||||
*/
|
*/
|
||||||
err_t dhcp_renew(struct netif *netif)
|
err_t dhcp_renew(struct netif *netif)
|
||||||
@ -840,7 +843,7 @@ err_t dhcp_renew(struct netif *netif)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebind with a DHCP server for an existing DHCP lease.
|
* Rebind with a DHCP server for an existing DHCP lease.
|
||||||
*
|
*
|
||||||
* @param netif network interface which must rebind with a DHCP server
|
* @param netif network interface which must rebind with a DHCP server
|
||||||
*/
|
*/
|
||||||
static err_t dhcp_rebind(struct netif *netif)
|
static err_t dhcp_rebind(struct netif *netif)
|
||||||
@ -892,7 +895,7 @@ static err_t dhcp_rebind(struct netif *netif)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Release a DHCP lease.
|
* Release a DHCP lease.
|
||||||
*
|
*
|
||||||
* @param netif network interface which must release its lease
|
* @param netif network interface which must release its lease
|
||||||
*/
|
*/
|
||||||
static err_t dhcp_release(struct netif *netif)
|
static err_t dhcp_release(struct netif *netif)
|
||||||
@ -968,7 +971,7 @@ void dhcp_stop(struct netif *netif)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the DHCP state of a DHCP client.
|
* Set the DHCP state of a DHCP client.
|
||||||
*
|
*
|
||||||
* If the state changed, reset the number of tries.
|
* If the state changed, reset the number of tries.
|
||||||
*
|
*
|
||||||
* TODO: we might also want to reset the timeout here?
|
* TODO: we might also want to reset the timeout here?
|
||||||
@ -1001,7 +1004,7 @@ static void dhcp_option_byte(struct dhcp *dhcp, u8_t value)
|
|||||||
{
|
{
|
||||||
LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
|
LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN);
|
||||||
dhcp->msg_out->options[dhcp->options_out_len++] = value;
|
dhcp->msg_out->options[dhcp->options_out_len++] = value;
|
||||||
}
|
}
|
||||||
static void dhcp_option_short(struct dhcp *dhcp, u16_t value)
|
static void dhcp_option_short(struct dhcp *dhcp, u16_t value)
|
||||||
{
|
{
|
||||||
LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN);
|
LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN);
|
||||||
@ -1025,7 +1028,7 @@ static void dhcp_option_long(struct dhcp *dhcp, u32_t value)
|
|||||||
* and also allows overriding some fields for options, the easy approach
|
* and also allows overriding some fields for options, the easy approach
|
||||||
* is to first unfold the options into a conitguous piece of memory, and
|
* is to first unfold the options into a conitguous piece of memory, and
|
||||||
* use that further on.
|
* use that further on.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static err_t dhcp_unfold_reply(struct dhcp *dhcp)
|
static err_t dhcp_unfold_reply(struct dhcp *dhcp)
|
||||||
{
|
{
|
||||||
@ -1043,14 +1046,14 @@ static err_t dhcp_unfold_reply(struct dhcp *dhcp)
|
|||||||
dhcp->options_in = mem_malloc(dhcp->options_in_len);
|
dhcp->options_in = mem_malloc(dhcp->options_in_len);
|
||||||
if (dhcp->options_in == NULL)
|
if (dhcp->options_in == NULL)
|
||||||
{
|
{
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->options\n"));
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
|
dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN);
|
||||||
if (dhcp->msg_in == NULL)
|
if (dhcp->msg_in == NULL)
|
||||||
{
|
{
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n"));
|
||||||
mem_free((void *)dhcp->options_in);
|
mem_free((void *)dhcp->options_in);
|
||||||
dhcp->options_in = NULL;
|
dhcp->options_in = NULL;
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
@ -1069,7 +1072,7 @@ static err_t dhcp_unfold_reply(struct dhcp *dhcp)
|
|||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes into dhcp->msg_in[]\n", i));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes into dhcp->msg_in[]\n", i));
|
||||||
if (dhcp->options_in != NULL) {
|
if (dhcp->options_in != NULL) {
|
||||||
ptr = (u8_t *)dhcp->options_in;
|
ptr = (u8_t *)dhcp->options_in;
|
||||||
/* proceed through options */
|
/* proceed through options */
|
||||||
@ -1082,13 +1085,13 @@ static err_t dhcp_unfold_reply(struct dhcp *dhcp)
|
|||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes to dhcp->options_in[]\n", i));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_unfold_reply(): copied %u bytes to dhcp->options_in[]\n", i));
|
||||||
}
|
}
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free the incoming DHCP message including contiguous copy of
|
* Free the incoming DHCP message including contiguous copy of
|
||||||
* its DHCP options.
|
* its DHCP options.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -1103,7 +1106,7 @@ static void dhcp_free_reply(struct dhcp *dhcp)
|
|||||||
dhcp->options_in = NULL;
|
dhcp->options_in = NULL;
|
||||||
dhcp->options_in_len = 0;
|
dhcp->options_in_len = 0;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));
|
LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1135,7 +1138,7 @@ static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_
|
|||||||
}
|
}
|
||||||
/* iterate through hardware address and match against DHCP message */
|
/* iterate through hardware address and match against DHCP message */
|
||||||
for (i = 0; i < netif->hwaddr_len; i++) {
|
for (i = 0; i < netif->hwaddr_len; i++) {
|
||||||
if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
|
if (netif->hwaddr[i] != reply_msg->chaddr[i]) {
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%u]==%02x != reply_msg->chaddr[%u]==%02x\n",
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 2, ("netif->hwaddr[%u]==%02x != reply_msg->chaddr[%u]==%02x\n",
|
||||||
i, netif->hwaddr[i], i, reply_msg->chaddr[i]));
|
i, netif->hwaddr[i], i, reply_msg->chaddr[i]));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
@ -1157,22 +1160,22 @@ static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_
|
|||||||
dhcp->p = NULL;
|
dhcp->p = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n"));
|
||||||
/* obtain pointer to DHCP message type */
|
/* obtain pointer to DHCP message type */
|
||||||
options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);
|
options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE);
|
||||||
if (options_ptr == NULL) {
|
if (options_ptr == NULL) {
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OPTION_MESSAGE_TYPE option not found\n"));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
dhcp->p = NULL;
|
dhcp->p = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read DHCP message type */
|
/* read DHCP message type */
|
||||||
msg_type = dhcp_get_option_byte(options_ptr + 2);
|
msg_type = dhcp_get_option_byte(options_ptr + 2);
|
||||||
/* message type is DHCP ACK? */
|
/* message type is DHCP ACK? */
|
||||||
if (msg_type == DHCP_ACK) {
|
if (msg_type == DHCP_ACK) {
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_ACK received\n"));
|
||||||
/* in requesting state? */
|
/* in requesting state? */
|
||||||
if (dhcp->state == DHCP_REQUESTING) {
|
if (dhcp->state == DHCP_REQUESTING) {
|
||||||
dhcp_handle_ack(netif);
|
dhcp_handle_ack(netif);
|
||||||
@ -1193,15 +1196,15 @@ static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_
|
|||||||
}
|
}
|
||||||
/* received a DHCP_NAK in appropriate state? */
|
/* received a DHCP_NAK in appropriate state? */
|
||||||
else if ((msg_type == DHCP_NAK) &&
|
else if ((msg_type == DHCP_NAK) &&
|
||||||
((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
|
((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) ||
|
||||||
(dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) {
|
(dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) {
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_NAK received\n"));
|
||||||
dhcp->request_timeout = 0;
|
dhcp->request_timeout = 0;
|
||||||
dhcp_handle_nak(netif);
|
dhcp_handle_nak(netif);
|
||||||
}
|
}
|
||||||
/* received a DHCP_OFFER in DHCP_SELECTING state? */
|
/* received a DHCP_OFFER in DHCP_SELECTING state? */
|
||||||
else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
|
else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) {
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | 1, ("DHCP_OFFER received in DHCP_SELECTING state\n"));
|
||||||
dhcp->request_timeout = 0;
|
dhcp->request_timeout = 0;
|
||||||
/* remember offered lease */
|
/* remember offered lease */
|
||||||
dhcp_handle_offer(netif);
|
dhcp_handle_offer(netif);
|
||||||
@ -1223,17 +1226,17 @@ static err_t dhcp_create_request(struct netif *netif)
|
|||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
/* give unique transaction identifier to this request */
|
/* give unique transaction identifier to this request */
|
||||||
dhcp->xid = xid++;
|
dhcp->xid = xid++;
|
||||||
|
|
||||||
dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;
|
dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload;
|
||||||
|
|
||||||
dhcp->msg_out->op = DHCP_BOOTREQUEST;
|
dhcp->msg_out->op = DHCP_BOOTREQUEST;
|
||||||
/* TODO: make link layer independent */
|
/* TODO: make link layer independent */
|
||||||
dhcp->msg_out->htype = DHCP_HTYPE_ETH;
|
dhcp->msg_out->htype = DHCP_HTYPE_ETH;
|
||||||
/* TODO: make link layer independent */
|
/* TODO: make link layer independent */
|
||||||
dhcp->msg_out->hlen = DHCP_HLEN_ETH;
|
dhcp->msg_out->hlen = DHCP_HLEN_ETH;
|
||||||
dhcp->msg_out->hops = 0;
|
dhcp->msg_out->hops = 0;
|
||||||
dhcp->msg_out->xid = htonl(dhcp->xid);
|
dhcp->msg_out->xid = htonl(dhcp->xid);
|
||||||
dhcp->msg_out->secs = 0;
|
dhcp->msg_out->secs = 0;
|
||||||
dhcp->msg_out->flags = 0;
|
dhcp->msg_out->flags = 0;
|
||||||
dhcp->msg_out->ciaddr = netif->ip_addr.addr;
|
dhcp->msg_out->ciaddr = netif->ip_addr.addr;
|
||||||
@ -1374,7 +1377,7 @@ static u8_t dhcp_get_option_byte(u8_t *ptr)
|
|||||||
{
|
{
|
||||||
LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%u\n", *ptr));
|
LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%u\n", *ptr));
|
||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the 16-bit value of DHCP option data.
|
* Return the 16-bit value of DHCP option data.
|
||||||
@ -1391,7 +1394,7 @@ static u16_t dhcp_get_option_short(u8_t *ptr)
|
|||||||
value |= *ptr;
|
value |= *ptr;
|
||||||
LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%u\n", value));
|
LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%u\n", value));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the 32-bit value of DHCP option data.
|
* Return the 32-bit value of DHCP option data.
|
||||||
@ -1410,4 +1413,4 @@ static u32_t dhcp_get_option_long(u8_t *ptr)
|
|||||||
value |= (u32_t)(*ptr++);
|
value |= (u32_t)(*ptr++);
|
||||||
LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value));
|
LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
@ -11,21 +11,21 @@
|
|||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
* OF SUCH DAMAGE.
|
* OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is part of the lwIP TCP/IP stack.
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -52,8 +52,8 @@ static u16_t
|
|||||||
lwip_chksum(void *dataptr, int len)
|
lwip_chksum(void *dataptr, int len)
|
||||||
{
|
{
|
||||||
u32_t acc;
|
u32_t acc;
|
||||||
|
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", dataptr, len));
|
LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", (void *)dataptr, len));
|
||||||
for(acc = 0; len > 1; len -= 2) {
|
for(acc = 0; len > 1; len -= 2) {
|
||||||
/* acc = acc + *((u16_t *)dataptr)++;*/
|
/* acc = acc + *((u16_t *)dataptr)++;*/
|
||||||
acc += *(u16_t *)dataptr;
|
acc += *(u16_t *)dataptr;
|
||||||
@ -63,7 +63,7 @@ lwip_chksum(void *dataptr, int len)
|
|||||||
/* add up any odd byte */
|
/* add up any odd byte */
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
|
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8);
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", *(u8_t *)dataptr));
|
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", (unsigned int)(*(u8_t *)dataptr)));
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));
|
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n"));
|
||||||
}
|
}
|
||||||
@ -93,8 +93,9 @@ inet_chksum_pseudo(struct pbuf *p,
|
|||||||
acc = 0;
|
acc = 0;
|
||||||
swapped = 0;
|
swapped = 0;
|
||||||
/* iterate through all pbuf in chain */
|
/* iterate through all pbuf in chain */
|
||||||
for(q = p; q != NULL; q = q->next) {
|
for(q = p; q != NULL; q = q->next) {
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", (void *) q, (void *)q->next));
|
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
|
||||||
|
(void *)q, (void *)q->next));
|
||||||
acc += lwip_chksum(q->payload, q->len);
|
acc += lwip_chksum(q->payload, q->len);
|
||||||
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));*/
|
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));*/
|
||||||
while (acc >> 16) {
|
while (acc >> 16) {
|
||||||
@ -115,11 +116,11 @@ inet_chksum_pseudo(struct pbuf *p,
|
|||||||
acc += (dest->addr & 0xffffUL);
|
acc += (dest->addr & 0xffffUL);
|
||||||
acc += ((dest->addr >> 16) & 0xffffUL);
|
acc += ((dest->addr >> 16) & 0xffffUL);
|
||||||
acc += (u32_t)htons((u16_t)proto);
|
acc += (u32_t)htons((u16_t)proto);
|
||||||
acc += (u32_t)htons(proto_len);
|
acc += (u32_t)htons(proto_len);
|
||||||
|
|
||||||
while (acc >> 16) {
|
while (acc >> 16) {
|
||||||
acc = (acc & 0xffffUL) + (acc >> 16);
|
acc = (acc & 0xffffUL) + (acc >> 16);
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%lx\n", acc));
|
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%lx\n", acc));
|
||||||
return ~(acc & 0xffffUL);
|
return ~(acc & 0xffffUL);
|
||||||
}
|
}
|
||||||
@ -138,7 +139,7 @@ inet_chksum(void *dataptr, u16_t len)
|
|||||||
acc = lwip_chksum(dataptr, len);
|
acc = lwip_chksum(dataptr, len);
|
||||||
while (acc >> 16) {
|
while (acc >> 16) {
|
||||||
acc = (acc & 0xffff) + (acc >> 16);
|
acc = (acc & 0xffff) + (acc >> 16);
|
||||||
}
|
}
|
||||||
return ~(acc & 0xffff);
|
return ~(acc & 0xffff);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -148,20 +149,20 @@ inet_chksum_pbuf(struct pbuf *p)
|
|||||||
u32_t acc;
|
u32_t acc;
|
||||||
struct pbuf *q;
|
struct pbuf *q;
|
||||||
u8_t swapped;
|
u8_t swapped;
|
||||||
|
|
||||||
acc = 0;
|
acc = 0;
|
||||||
swapped = 0;
|
swapped = 0;
|
||||||
for(q = p; q != NULL; q = q->next) {
|
for(q = p; q != NULL; q = q->next) {
|
||||||
acc += lwip_chksum(q->payload, q->len);
|
acc += lwip_chksum(q->payload, q->len);
|
||||||
while (acc >> 16) {
|
while (acc >> 16) {
|
||||||
acc = (acc & 0xffffUL) + (acc >> 16);
|
acc = (acc & 0xffffUL) + (acc >> 16);
|
||||||
}
|
}
|
||||||
if (q->len % 2 != 0) {
|
if (q->len % 2 != 0) {
|
||||||
swapped = 1 - swapped;
|
swapped = 1 - swapped;
|
||||||
acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8);
|
acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swapped) {
|
if (swapped) {
|
||||||
acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);
|
acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8);
|
||||||
}
|
}
|
||||||
@ -173,20 +174,20 @@ inet_chksum_pbuf(struct pbuf *p)
|
|||||||
* Ascii internet address interpretation routine.
|
* Ascii internet address interpretation routine.
|
||||||
* The value returned is in network order.
|
* The value returned is in network order.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
/* inet_addr */
|
/* inet_addr */
|
||||||
u32_t inet_addr(const char *cp)
|
u32_t inet_addr(const char *cp)
|
||||||
{
|
{
|
||||||
struct in_addr val;
|
struct in_addr val;
|
||||||
|
|
||||||
if (inet_aton(cp, &val)) {
|
if (inet_aton(cp, &val)) {
|
||||||
return (val.s_addr);
|
return (val.s_addr);
|
||||||
}
|
}
|
||||||
return (INADDR_NONE);
|
return (INADDR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether "cp" is a valid ascii representation
|
* Check whether "cp" is a valid ascii representation
|
||||||
* of an Internet address and convert to a binary address.
|
* of an Internet address and convert to a binary address.
|
||||||
* Returns 1 if the address is valid, 0 if not.
|
* Returns 1 if the address is valid, 0 if not.
|
||||||
@ -202,7 +203,7 @@ inet_chksum_pbuf(struct pbuf *p)
|
|||||||
char c;
|
char c;
|
||||||
u32_t parts[4];
|
u32_t parts[4];
|
||||||
u32_t* pp = parts;
|
u32_t* pp = parts;
|
||||||
|
|
||||||
c = *cp;
|
c = *cp;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/*
|
/*
|
||||||
@ -256,25 +257,25 @@ inet_chksum_pbuf(struct pbuf *p)
|
|||||||
*/
|
*/
|
||||||
n = pp - parts + 1;
|
n = pp - parts + 1;
|
||||||
switch (n) {
|
switch (n) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
return (0); /* initial nondigit */
|
return (0); /* initial nondigit */
|
||||||
|
|
||||||
case 1: /* a -- 32 bits */
|
case 1: /* a -- 32 bits */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* a.b -- 8.24 bits */
|
case 2: /* a.b -- 8.24 bits */
|
||||||
if (val > 0xffffff)
|
if (val > 0xffffff)
|
||||||
return (0);
|
return (0);
|
||||||
val |= parts[0] << 24;
|
val |= parts[0] << 24;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* a.b.c -- 8.8.16 bits */
|
case 3: /* a.b.c -- 8.8.16 bits */
|
||||||
if (val > 0xffff)
|
if (val > 0xffff)
|
||||||
return (0);
|
return (0);
|
||||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||||
if (val > 0xff)
|
if (val > 0xff)
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
@ -11,21 +11,21 @@
|
|||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
* OF SUCH DAMAGE.
|
* OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is part of the lwIP TCP/IP stack.
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -36,7 +36,7 @@
|
|||||||
*
|
*
|
||||||
* This is the code for the IP layer.
|
* This is the code for the IP layer.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
@ -104,13 +104,13 @@ ip_lookup(void *header, struct netif *inp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* IP_OPTIONS == 0 */
|
#endif /* IP_OPTIONS == 0 */
|
||||||
|
|
||||||
switch (IPH_PROTO(iphdr)) {
|
switch (IPH_PROTO(iphdr)) {
|
||||||
#if LWIP_UDP > 0
|
#if LWIP_UDP > 0
|
||||||
case IP_PROTO_UDP:
|
case IP_PROTO_UDP:
|
||||||
return udp_lookup(iphdr, inp);
|
return udp_lookup(iphdr, inp);
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP > 0
|
#if LWIP_TCP > 0
|
||||||
case IP_PROTO_TCP:
|
case IP_PROTO_TCP:
|
||||||
return 1;
|
return 1;
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
@ -135,7 +135,7 @@ ip_route(struct ip_addr *dest)
|
|||||||
{
|
{
|
||||||
struct netif *netif;
|
struct netif *netif;
|
||||||
|
|
||||||
/* iterate through netifs */
|
/* iterate through netifs */
|
||||||
for(netif = netif_list; netif != NULL; netif = netif->next) {
|
for(netif = netif_list; netif != NULL; netif = netif->next) {
|
||||||
/* network mask matches? */
|
/* network mask matches? */
|
||||||
if (ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
|
if (ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
|
||||||
@ -159,7 +159,7 @@ static void
|
|||||||
ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||||
{
|
{
|
||||||
struct netif *netif;
|
struct netif *netif;
|
||||||
|
|
||||||
PERF_START;
|
PERF_START;
|
||||||
/* Find network interface where to forward this IP packet to. */
|
/* Find network interface where to forward this IP packet to. */
|
||||||
netif = ip_route((struct ip_addr *)&(iphdr->dest));
|
netif = ip_route((struct ip_addr *)&(iphdr->dest));
|
||||||
@ -176,7 +176,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||||||
snmp_inc_ipnoroutes();
|
snmp_inc_ipnoroutes();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decrement TTL */
|
/* decrement TTL */
|
||||||
IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
|
IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
|
||||||
/* send ICMP if TTL == 0 */
|
/* send ICMP if TTL == 0 */
|
||||||
@ -186,9 +186,9 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||||||
icmp_time_exceeded(p, ICMP_TE_TTL);
|
icmp_time_exceeded(p, ICMP_TE_TTL);
|
||||||
snmp_inc_icmpouttimeexcds();
|
snmp_inc_icmpouttimeexcds();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Incrementally update the IP checksum. */
|
/* Incrementally update the IP checksum. */
|
||||||
if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
|
if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) {
|
||||||
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
|
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1);
|
||||||
@ -227,7 +227,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
static struct ip_hdr *iphdr;
|
static struct ip_hdr *iphdr;
|
||||||
static struct netif *netif;
|
static struct netif *netif;
|
||||||
static u16_t iphdrlen;
|
static u16_t iphdrlen;
|
||||||
|
|
||||||
#ifdef IP_STATS
|
#ifdef IP_STATS
|
||||||
++lwip_stats.ip.recv;
|
++lwip_stats.ip.recv;
|
||||||
#endif /* IP_STATS */
|
#endif /* IP_STATS */
|
||||||
@ -236,7 +236,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
/* identify the IP header */
|
/* identify the IP header */
|
||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
if (IPH_V(iphdr) != 4) {
|
if (IPH_V(iphdr) != 4) {
|
||||||
LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %d\n", IPH_V(iphdr)));
|
LWIP_DEBUGF(IP_DEBUG | 1, ("IP packet dropped due to bad version number %u\n", IPH_V(iphdr)));
|
||||||
#if IP_DEBUG
|
#if IP_DEBUG
|
||||||
ip_debug_print(p);
|
ip_debug_print(p);
|
||||||
#endif /* IP_DEBUG */
|
#endif /* IP_DEBUG */
|
||||||
@ -253,7 +253,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
/* calculate IP header length in bytes */
|
/* calculate IP header length in bytes */
|
||||||
iphdrlen *= 4;
|
iphdrlen *= 4;
|
||||||
|
|
||||||
/* header length exceeds first pbuf length? */
|
/* header length exceeds first pbuf length? */
|
||||||
if (iphdrlen > p->len) {
|
if (iphdrlen > p->len) {
|
||||||
LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
|
LWIP_DEBUGF(IP_DEBUG | 2, ("IP header (len %u) does not fit in first pbuf (len %u), IP packet droppped.\n",
|
||||||
iphdrlen, p->len));
|
iphdrlen, p->len));
|
||||||
@ -282,7 +282,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
snmp_inc_ipindiscards();
|
snmp_inc_ipindiscards();
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trim pbuf. This should have been done at the netif layer,
|
/* Trim pbuf. This should have been done at the netif layer,
|
||||||
but we'll do it anyway just to be sure that its done. */
|
but we'll do it anyway just to be sure that its done. */
|
||||||
pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
|
pbuf_realloc(p, ntohs(IPH_LEN(iphdr)));
|
||||||
@ -329,7 +329,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* LWIP_DHCP */
|
#endif /* LWIP_DHCP */
|
||||||
/* packet not for us? */
|
/* packet not for us? */
|
||||||
if (netif == NULL) {
|
if (netif == NULL) {
|
||||||
/* packet not for us, route or discard */
|
/* packet not for us, route or discard */
|
||||||
LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
|
LWIP_DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
|
||||||
@ -350,7 +350,8 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
|
|
||||||
#if IP_REASSEMBLY
|
#if IP_REASSEMBLY
|
||||||
if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
|
if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
|
LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u),
|
||||||
|
calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
|
||||||
p = ip_reass(p);
|
p = ip_reass(p);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
@ -370,18 +371,18 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
#endif /* IP_REASSEMBLY */
|
#endif /* IP_REASSEMBLY */
|
||||||
|
|
||||||
#if IP_OPTIONS == 0
|
#if IP_OPTIONS == 0
|
||||||
if (iphdrlen > IP_HLEN) {
|
if (iphdrlen > IP_HLEN) {
|
||||||
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
|
LWIP_DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
#ifdef IP_STATS
|
#ifdef IP_STATS
|
||||||
++lwip_stats.ip.opterr;
|
++lwip_stats.ip.opterr;
|
||||||
++lwip_stats.ip.drop;
|
++lwip_stats.ip.drop;
|
||||||
#endif /* IP_STATS */
|
#endif /* IP_STATS */
|
||||||
snmp_inc_ipunknownprotos();
|
snmp_inc_ipunknownprotos();
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
#endif /* IP_OPTIONS == 0 */
|
#endif /* IP_OPTIONS == 0 */
|
||||||
|
|
||||||
/* send to upper layers */
|
/* send to upper layers */
|
||||||
@ -389,16 +390,16 @@ ip_input(struct pbuf *p, struct netif *inp) {
|
|||||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
|
LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
|
||||||
ip_debug_print(p);
|
ip_debug_print(p);
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
|
LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
|
||||||
#endif /* IP_DEBUG */
|
#endif /* IP_DEBUG */
|
||||||
|
|
||||||
switch (IPH_PROTO(iphdr)) {
|
switch (IPH_PROTO(iphdr)) {
|
||||||
#if LWIP_UDP > 0
|
#if LWIP_UDP > 0
|
||||||
case IP_PROTO_UDP:
|
case IP_PROTO_UDP:
|
||||||
snmp_inc_ipindelivers();
|
snmp_inc_ipindelivers();
|
||||||
udp_input(p, inp);
|
udp_input(p, inp);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP > 0
|
#if LWIP_TCP > 0
|
||||||
case IP_PROTO_TCP:
|
case IP_PROTO_TCP:
|
||||||
snmp_inc_ipindelivers();
|
snmp_inc_ipindelivers();
|
||||||
tcp_input(p, inp);
|
tcp_input(p, inp);
|
||||||
@ -447,23 +448,23 @@ ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
|||||||
static u16_t ip_id = 0;
|
static u16_t ip_id = 0;
|
||||||
|
|
||||||
snmp_inc_ipoutrequests();
|
snmp_inc_ipoutrequests();
|
||||||
|
|
||||||
if (dest != IP_HDRINCL) {
|
if (dest != IP_HDRINCL) {
|
||||||
if (pbuf_header(p, IP_HLEN)) {
|
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 | 2, ("ip_output: not enough room for IP header in pbuf\n"));
|
||||||
|
|
||||||
#ifdef IP_STATS
|
#ifdef IP_STATS
|
||||||
++lwip_stats.ip.err;
|
++lwip_stats.ip.err;
|
||||||
#endif /* IP_STATS */
|
#endif /* IP_STATS */
|
||||||
snmp_inc_ipoutdiscards();
|
snmp_inc_ipoutdiscards();
|
||||||
return ERR_BUF;
|
return ERR_BUF;
|
||||||
}
|
}
|
||||||
|
|
||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
|
|
||||||
IPH_TTL_SET(iphdr, ttl);
|
IPH_TTL_SET(iphdr, ttl);
|
||||||
IPH_PROTO_SET(iphdr, proto);
|
IPH_PROTO_SET(iphdr, proto);
|
||||||
|
|
||||||
ip_addr_set(&(iphdr->dest), dest);
|
ip_addr_set(&(iphdr->dest), dest);
|
||||||
|
|
||||||
IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
|
IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
|
||||||
@ -485,12 +486,12 @@ ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
|||||||
dest = &(iphdr->dest);
|
dest = &(iphdr->dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IP_FRAG
|
#if IP_FRAG
|
||||||
/* don't fragment if interface has mtu set to 0 [loopif] */
|
/* don't fragment if interface has mtu set to 0 [loopif] */
|
||||||
if (netif->mtu && (p->tot_len > netif->mtu))
|
if (netif->mtu && (p->tot_len > netif->mtu))
|
||||||
return ip_frag(p,netif,dest);
|
return ip_frag(p,netif,dest);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IP_STATS
|
#ifdef IP_STATS
|
||||||
lwip_stats.ip.xmit++;
|
lwip_stats.ip.xmit++;
|
||||||
#endif /* IP_STATS */
|
#endif /* IP_STATS */
|
||||||
@ -501,7 +502,7 @@ ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
|||||||
|
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
|
LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
|
||||||
|
|
||||||
return netif->output(netif, p, dest);
|
return netif->output(netif, p, dest);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* ip_output:
|
/* ip_output:
|
||||||
@ -515,7 +516,7 @@ ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
|
|||||||
u8_t ttl, u8_t proto)
|
u8_t ttl, u8_t proto)
|
||||||
{
|
{
|
||||||
struct netif *netif;
|
struct netif *netif;
|
||||||
|
|
||||||
if ((netif = ip_route(dest)) == NULL) {
|
if ((netif = ip_route(dest)) == NULL) {
|
||||||
LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
|
LWIP_DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
|
||||||
|
|
||||||
@ -537,7 +538,7 @@ ip_debug_print(struct pbuf *p)
|
|||||||
u8_t *payload;
|
u8_t *payload;
|
||||||
|
|
||||||
payload = (u8_t *)iphdr + IP_HLEN;
|
payload = (u8_t *)iphdr + IP_HLEN;
|
||||||
|
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
|
LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
|
LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
|
||||||
LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d | 0x%02x | %5u | (v, hl, tos, len)\n",
|
LWIP_DEBUGF(IP_DEBUG, ("|%2d |%2d | 0x%02x | %5u | (v, hl, tos, len)\n",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
@ -11,21 +11,21 @@
|
|||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
* OF SUCH DAMAGE.
|
* OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is part of the lwIP TCP/IP stack.
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -50,7 +50,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
struct icmp_echo_hdr *iecho;
|
struct icmp_echo_hdr *iecho;
|
||||||
struct ip_hdr *iphdr;
|
struct ip_hdr *iphdr;
|
||||||
struct ip_addr tmpaddr;
|
struct ip_addr tmpaddr;
|
||||||
|
|
||||||
#ifdef ICMP_STATS
|
#ifdef ICMP_STATS
|
||||||
++lwip_stats.icmp.recv;
|
++lwip_stats.icmp.recv;
|
||||||
#endif /* ICMP_STATS */
|
#endif /* ICMP_STATS */
|
||||||
@ -71,7 +71,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
++lwip_stats.icmp.lenerr;
|
++lwip_stats.icmp.lenerr;
|
||||||
#endif /* ICMP_STATS */
|
#endif /* ICMP_STATS */
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iecho = p->payload;
|
iecho = p->payload;
|
||||||
iphdr = (struct ip_hdr *)((char *)p->payload - IP_HLEN);
|
iphdr = (struct ip_hdr *)((char *)p->payload - IP_HLEN);
|
||||||
@ -99,10 +99,10 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||||||
++lwip_stats.icmp.xmit;
|
++lwip_stats.icmp.xmit;
|
||||||
#endif /* ICMP_STATS */
|
#endif /* ICMP_STATS */
|
||||||
|
|
||||||
/* LWIP_DEBUGF("icmp: p->len %d p->tot_len %d\n", p->len, p->tot_len);*/
|
/* LWIP_DEBUGF("icmp: p->len %u p->tot_len %u\n", p->len, p->tot_len);*/
|
||||||
ip_output_if (p, &(iphdr->src), IP_HDRINCL,
|
ip_output_if (p, &(iphdr->src), IP_HDRINCL,
|
||||||
iphdr->hoplim, IP_PROTO_ICMP, inp);
|
iphdr->hoplim, IP_PROTO_ICMP, inp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d not supported.\n", (int)type));
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %d not supported.\n", (int)type));
|
||||||
#ifdef ICMP_STATS
|
#ifdef ICMP_STATS
|
||||||
@ -120,18 +120,18 @@ icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
|
|||||||
struct pbuf *q;
|
struct pbuf *q;
|
||||||
struct ip_hdr *iphdr;
|
struct ip_hdr *iphdr;
|
||||||
struct icmp_dur_hdr *idur;
|
struct icmp_dur_hdr *idur;
|
||||||
|
|
||||||
q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
|
q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
|
||||||
/* ICMP header + IP header + 8 bytes of data */
|
/* ICMP header + IP header + 8 bytes of data */
|
||||||
|
|
||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
|
|
||||||
idur = q->payload;
|
idur = q->payload;
|
||||||
idur->type = (char)ICMP6_DUR;
|
idur->type = (char)ICMP6_DUR;
|
||||||
idur->icode = (char)t;
|
idur->icode = (char)t;
|
||||||
|
|
||||||
memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8);
|
memcpy((char *)q->payload + 8, p->payload, IP_HLEN + 8);
|
||||||
|
|
||||||
/* calculate checksum */
|
/* calculate checksum */
|
||||||
idur->chksum = 0;
|
idur->chksum = 0;
|
||||||
idur->chksum = inet_chksum(idur, q->len);
|
idur->chksum = inet_chksum(idur, q->len);
|
||||||
@ -152,25 +152,25 @@ icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
|
|||||||
struct icmp_te_hdr *tehdr;
|
struct icmp_te_hdr *tehdr;
|
||||||
|
|
||||||
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));
|
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n"));
|
||||||
|
|
||||||
q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
|
q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM);
|
||||||
|
|
||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
|
|
||||||
tehdr = q->payload;
|
tehdr = q->payload;
|
||||||
tehdr->type = (char)ICMP6_TE;
|
tehdr->type = (char)ICMP6_TE;
|
||||||
tehdr->icode = (char)t;
|
tehdr->icode = (char)t;
|
||||||
|
|
||||||
/* copy fields from original packet */
|
/* copy fields from original packet */
|
||||||
memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8);
|
memcpy((char *)q->payload + 8, (char *)p->payload, IP_HLEN + 8);
|
||||||
|
|
||||||
/* calculate checksum */
|
/* calculate checksum */
|
||||||
tehdr->chksum = 0;
|
tehdr->chksum = 0;
|
||||||
tehdr->chksum = inet_chksum(tehdr, q->len);
|
tehdr->chksum = inet_chksum(tehdr, q->len);
|
||||||
#ifdef ICMP_STATS
|
#ifdef ICMP_STATS
|
||||||
++lwip_stats.icmp.xmit;
|
++lwip_stats.icmp.xmit;
|
||||||
#endif /* ICMP_STATS */
|
#endif /* ICMP_STATS */
|
||||||
ip_output(q, NULL,
|
ip_output(q, NULL,
|
||||||
(struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
|
(struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP);
|
||||||
pbuf_free(q);
|
pbuf_free(q);
|
||||||
}
|
}
|
||||||
|
133
src/core/pbuf.c
133
src/core/pbuf.c
@ -29,9 +29,9 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
@ -40,21 +40,21 @@
|
|||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
* OF SUCH DAMAGE.
|
* OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is part of the lwIP TCP/IP stack.
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -101,14 +101,14 @@ pbuf_init(void)
|
|||||||
|
|
||||||
pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
|
pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
|
||||||
LWIP_ASSERT("pbuf_init: pool aligned", (long)pbuf_pool % MEM_ALIGNMENT == 0);
|
LWIP_ASSERT("pbuf_init: pool aligned", (long)pbuf_pool % MEM_ALIGNMENT == 0);
|
||||||
|
|
||||||
#ifdef PBUF_STATS
|
#ifdef PBUF_STATS
|
||||||
lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
|
lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
|
||||||
#endif /* PBUF_STATS */
|
#endif /* PBUF_STATS */
|
||||||
|
|
||||||
/* Set up ->next pointers to link the pbufs of the pool together */
|
/* Set up ->next pointers to link the pbufs of the pool together */
|
||||||
p = pbuf_pool;
|
p = pbuf_pool;
|
||||||
|
|
||||||
for(i = 0; i < PBUF_POOL_SIZE; ++i) {
|
for(i = 0; i < PBUF_POOL_SIZE; ++i) {
|
||||||
p->next = (struct pbuf *)((u8_t *)p + PBUF_POOL_BUFSIZE + sizeof(struct pbuf));
|
p->next = (struct pbuf *)((u8_t *)p + PBUF_POOL_BUFSIZE + sizeof(struct pbuf));
|
||||||
p->len = p->tot_len = PBUF_POOL_BUFSIZE;
|
p->len = p->tot_len = PBUF_POOL_BUFSIZE;
|
||||||
@ -116,16 +116,16 @@ pbuf_init(void)
|
|||||||
q = p;
|
q = p;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The ->next pointer of last pbuf is NULL to indicate that there
|
/* The ->next pointer of last pbuf is NULL to indicate that there
|
||||||
are no more pbufs in the pool */
|
are no more pbufs in the pool */
|
||||||
q->next = NULL;
|
q->next = NULL;
|
||||||
|
|
||||||
#if !SYS_LIGHTWEIGHT_PROT
|
#if !SYS_LIGHTWEIGHT_PROT
|
||||||
pbuf_pool_alloc_lock = 0;
|
pbuf_pool_alloc_lock = 0;
|
||||||
pbuf_pool_free_lock = 0;
|
pbuf_pool_free_lock = 0;
|
||||||
pbuf_pool_free_sem = sys_sem_new(1);
|
pbuf_pool_free_sem = sys_sem_new(1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,8 +138,8 @@ pbuf_pool_alloc(void)
|
|||||||
|
|
||||||
SYS_ARCH_DECL_PROTECT(old_level);
|
SYS_ARCH_DECL_PROTECT(old_level);
|
||||||
SYS_ARCH_PROTECT(old_level);
|
SYS_ARCH_PROTECT(old_level);
|
||||||
|
|
||||||
#if !SYS_LIGHTWEIGHT_PROT
|
#if !SYS_LIGHTWEIGHT_PROT
|
||||||
/* Next, check the actual pbuf pool, but if the pool is locked, we
|
/* Next, check the actual pbuf pool, but if the pool is locked, we
|
||||||
pretend to be out of buffers and return NULL. */
|
pretend to be out of buffers and return NULL. */
|
||||||
if (pbuf_pool_free_lock) {
|
if (pbuf_pool_free_lock) {
|
||||||
@ -150,22 +150,22 @@ pbuf_pool_alloc(void)
|
|||||||
}
|
}
|
||||||
pbuf_pool_alloc_lock = 1;
|
pbuf_pool_alloc_lock = 1;
|
||||||
if (!pbuf_pool_free_lock) {
|
if (!pbuf_pool_free_lock) {
|
||||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||||
p = pbuf_pool;
|
p = pbuf_pool;
|
||||||
if (p) {
|
if (p) {
|
||||||
pbuf_pool = p->next;
|
pbuf_pool = p->next;
|
||||||
}
|
}
|
||||||
#if !SYS_LIGHTWEIGHT_PROT
|
#if !SYS_LIGHTWEIGHT_PROT
|
||||||
#ifdef PBUF_STATS
|
#ifdef PBUF_STATS
|
||||||
} else {
|
} else {
|
||||||
++lwip_stats.pbuf.alloc_locked;
|
++lwip_stats.pbuf.alloc_locked;
|
||||||
#endif /* PBUF_STATS */
|
#endif /* PBUF_STATS */
|
||||||
}
|
}
|
||||||
pbuf_pool_alloc_lock = 0;
|
pbuf_pool_alloc_lock = 0;
|
||||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||||
|
|
||||||
#ifdef PBUF_STATS
|
#ifdef PBUF_STATS
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
++lwip_stats.pbuf.used;
|
++lwip_stats.pbuf.used;
|
||||||
if (lwip_stats.pbuf.used > lwip_stats.pbuf.max) {
|
if (lwip_stats.pbuf.used > lwip_stats.pbuf.max) {
|
||||||
lwip_stats.pbuf.max = lwip_stats.pbuf.used;
|
lwip_stats.pbuf.max = lwip_stats.pbuf.used;
|
||||||
@ -174,7 +174,7 @@ pbuf_pool_alloc(void)
|
|||||||
#endif /* PBUF_STATS */
|
#endif /* PBUF_STATS */
|
||||||
|
|
||||||
SYS_ARCH_UNPROTECT(old_level);
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -187,9 +187,9 @@ pbuf_pool_alloc(void)
|
|||||||
*
|
*
|
||||||
* @param flag this parameter decides how and where the pbuf
|
* @param flag this parameter decides how and where the pbuf
|
||||||
* should be allocated as follows:
|
* should be allocated as follows:
|
||||||
*
|
*
|
||||||
* - PBUF_RAM: buffer memory for pbuf is allocated as one large
|
* - PBUF_RAM: buffer memory for pbuf is allocated as one large
|
||||||
* chunk. This includes protocol headers as well.
|
* chunk. This includes protocol headers as well.
|
||||||
* - PBUF_ROM: no buffer memory is allocated for the pbuf, even for
|
* - PBUF_ROM: no buffer memory is allocated for the pbuf, even for
|
||||||
* protocol headers. Additional headers must be prepended
|
* protocol headers. Additional headers must be prepended
|
||||||
* by allocating another pbuf and chain in to the front of
|
* by allocating another pbuf and chain in to the front of
|
||||||
@ -205,7 +205,7 @@ pbuf_pool_alloc(void)
|
|||||||
* the pbuf pool that is allocated during pbuf_init().
|
* the pbuf pool that is allocated during pbuf_init().
|
||||||
*
|
*
|
||||||
* @return the allocated pbuf. If multiple pbufs where allocated, this
|
* @return the allocated pbuf. If multiple pbufs where allocated, this
|
||||||
* is the first pbuf of a pbuf chain.
|
* is the first pbuf of a pbuf chain.
|
||||||
*/
|
*/
|
||||||
struct pbuf *
|
struct pbuf *
|
||||||
pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
||||||
@ -241,7 +241,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
|||||||
case PBUF_POOL:
|
case PBUF_POOL:
|
||||||
/* allocate head of pbuf chain into p */
|
/* allocate head of pbuf chain into p */
|
||||||
p = pbuf_pool_alloc();
|
p = pbuf_pool_alloc();
|
||||||
LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", p));
|
LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
#ifdef PBUF_STATS
|
#ifdef PBUF_STATS
|
||||||
++lwip_stats.pbuf.err;
|
++lwip_stats.pbuf.err;
|
||||||
@ -249,7 +249,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
p->next = NULL;
|
p->next = NULL;
|
||||||
|
|
||||||
/* make the payload pointer point 'offset' bytes into pbuf data memory */
|
/* make the payload pointer point 'offset' bytes into pbuf data memory */
|
||||||
p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
|
p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
|
||||||
LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
|
LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
|
||||||
@ -262,15 +262,15 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
|||||||
p->flags = PBUF_FLAG_POOL;
|
p->flags = PBUF_FLAG_POOL;
|
||||||
/* set reference count (needed here in case we fail) */
|
/* set reference count (needed here in case we fail) */
|
||||||
p->ref = 1;
|
p->ref = 1;
|
||||||
|
|
||||||
/* now allocate the tail of the pbuf chain */
|
/* now allocate the tail of the pbuf chain */
|
||||||
|
|
||||||
/* remember first pbuf for linkage in next iteration */
|
/* remember first pbuf for linkage in next iteration */
|
||||||
r = p;
|
r = p;
|
||||||
/* remaining length to be allocated */
|
/* remaining length to be allocated */
|
||||||
rem_len = length - p->len;
|
rem_len = length - p->len;
|
||||||
/* any remaining pbufs to be allocated? */
|
/* any remaining pbufs to be allocated? */
|
||||||
while (rem_len > 0) {
|
while (rem_len > 0) {
|
||||||
q = pbuf_pool_alloc();
|
q = pbuf_pool_alloc();
|
||||||
if (q == NULL) {
|
if (q == NULL) {
|
||||||
LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_alloc: Out of pbufs in pool.\n"));
|
LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_alloc: Out of pbufs in pool.\n"));
|
||||||
@ -381,7 +381,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
|
|||||||
* Depending on the desired length, the first few pbufs in a chain might
|
* Depending on the desired length, the first few pbufs in a chain might
|
||||||
* be skipped and left unchanged. The new last pbuf in the chain will be
|
* be skipped and left unchanged. The new last pbuf in the chain will be
|
||||||
* resized, and any remaining pbufs will be freed.
|
* resized, and any remaining pbufs will be freed.
|
||||||
*
|
*
|
||||||
* @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
|
* @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
|
||||||
* @note May not be called on a packet queue.
|
* @note May not be called on a packet queue.
|
||||||
*
|
*
|
||||||
@ -404,14 +404,14 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
|
|||||||
/* enlarging not yet supported */
|
/* enlarging not yet supported */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the pbuf chain grows by (new_len - p->tot_len) bytes
|
/* the pbuf chain grows by (new_len - p->tot_len) bytes
|
||||||
* (which may be negative in case of shrinking) */
|
* (which may be negative in case of shrinking) */
|
||||||
grow = new_len - p->tot_len;
|
grow = new_len - p->tot_len;
|
||||||
|
|
||||||
/* first, step over any pbufs that should remain in the chain */
|
/* first, step over any pbufs that should remain in the chain */
|
||||||
rem_len = new_len;
|
rem_len = new_len;
|
||||||
q = p;
|
q = p;
|
||||||
/* this pbuf should be kept? */
|
/* this pbuf should be kept? */
|
||||||
while (rem_len > q->len) {
|
while (rem_len > q->len) {
|
||||||
/* decrease remaining length by pbuf length */
|
/* decrease remaining length by pbuf length */
|
||||||
@ -422,7 +422,7 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
|
|||||||
q = q->next;
|
q = q->next;
|
||||||
}
|
}
|
||||||
/* we have now reached the new last pbuf (in q) */
|
/* we have now reached the new last pbuf (in q) */
|
||||||
/* rem_len == desired length for pbuf q */
|
/* rem_len == desired length for pbuf q */
|
||||||
|
|
||||||
/* shrink allocated memory for PBUF_RAM */
|
/* shrink allocated memory for PBUF_RAM */
|
||||||
/* (other types merely adjust their length fields */
|
/* (other types merely adjust their length fields */
|
||||||
@ -446,7 +446,7 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjusts the payload pointer to hide or reveal headers in the payload.
|
* Adjusts the payload pointer to hide or reveal headers in the payload.
|
||||||
*
|
*
|
||||||
* Adjusts the ->payload pointer so that space for a header
|
* Adjusts the ->payload pointer so that space for a header
|
||||||
* (dis)appears in the pbuf payload.
|
* (dis)appears in the pbuf payload.
|
||||||
*
|
*
|
||||||
@ -458,7 +458,7 @@ pbuf_realloc(struct pbuf *p, u16_t new_len)
|
|||||||
*
|
*
|
||||||
* PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
|
* PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
|
||||||
* the call will fail. A check is made that the increase in header size does
|
* the call will fail. A check is made that the increase in header size does
|
||||||
* not move the payload pointer in front of the start of the buffer.
|
* not move the payload pointer in front of the start of the buffer.
|
||||||
* @return 1 on failure, 0 on success.
|
* @return 1 on failure, 0 on success.
|
||||||
*
|
*
|
||||||
* @note May not be called on a packet queue.
|
* @note May not be called on a packet queue.
|
||||||
@ -497,7 +497,7 @@ pbuf_header(struct pbuf *p, s16_t header_size)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%d)\n", payload, p->payload, header_size) );
|
LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%d)\n", (void *)payload, (void *)p->payload, header_size) );
|
||||||
/* modify pbuf length fields */
|
/* modify pbuf length fields */
|
||||||
p->len += header_size;
|
p->len += header_size;
|
||||||
p->tot_len += header_size;
|
p->tot_len += header_size;
|
||||||
@ -513,11 +513,11 @@ pbuf_header(struct pbuf *p, s16_t header_size)
|
|||||||
*
|
*
|
||||||
* For a pbuf chain, this is repeated for each pbuf in the chain, until
|
* For a pbuf chain, this is repeated for each pbuf in the chain, until
|
||||||
* a non-zero reference count is encountered, or the end of the chain is
|
* a non-zero reference count is encountered, or the end of the chain is
|
||||||
* reached.
|
* reached.
|
||||||
*
|
*
|
||||||
* @param pbuf pbuf (chain) to be freed from one user.
|
* @param pbuf pbuf (chain) to be freed from one user.
|
||||||
*
|
*
|
||||||
* @return the number of unreferenced pbufs that were de-allocated
|
* @return the number of unreferenced pbufs that were de-allocated
|
||||||
* from the head of the chain.
|
* from the head of the chain.
|
||||||
*
|
*
|
||||||
* @note May not be called on a packet queue.
|
* @note May not be called on a packet queue.
|
||||||
@ -531,8 +531,8 @@ pbuf_header(struct pbuf *p, s16_t header_size)
|
|||||||
* 1->1->2 becomes ....->1
|
* 1->1->2 becomes ....->1
|
||||||
* 2->1->1 becomes 1->1->1
|
* 2->1->1 becomes 1->1->1
|
||||||
* 1->1->1 becomes .......
|
* 1->1->1 becomes .......
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
u8_t
|
u8_t
|
||||||
pbuf_free(struct pbuf *p)
|
pbuf_free(struct pbuf *p)
|
||||||
{
|
{
|
||||||
@ -587,7 +587,7 @@ pbuf_free(struct pbuf *p)
|
|||||||
/* p->ref > 0, this pbuf is still referenced to */
|
/* p->ref > 0, this pbuf is still referenced to */
|
||||||
/* (and so the remaining pbufs in chain as well) */
|
/* (and so the remaining pbufs in chain as well) */
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %u, ending here.\n", (void *)p, p->ref));
|
LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %u, ending here.\n", (void *)p, (unsigned int)p->ref));
|
||||||
/* stop walking through chain */
|
/* stop walking through chain */
|
||||||
p = NULL;
|
p = NULL;
|
||||||
}
|
}
|
||||||
@ -610,7 +610,7 @@ pbuf_clen(struct pbuf *p)
|
|||||||
{
|
{
|
||||||
u8_t len;
|
u8_t len;
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
while (p != NULL) {
|
while (p != NULL) {
|
||||||
++len;
|
++len;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
@ -629,7 +629,7 @@ void
|
|||||||
pbuf_ref(struct pbuf *p)
|
pbuf_ref(struct pbuf *p)
|
||||||
{
|
{
|
||||||
SYS_ARCH_DECL_PROTECT(old_level);
|
SYS_ARCH_DECL_PROTECT(old_level);
|
||||||
/* pbuf given? */
|
/* pbuf given? */
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
SYS_ARCH_PROTECT(old_level);
|
SYS_ARCH_PROTECT(old_level);
|
||||||
++(p->ref);
|
++(p->ref);
|
||||||
@ -644,11 +644,11 @@ pbuf_ref(struct pbuf *p)
|
|||||||
* @param h head pbuf (chain)
|
* @param h head pbuf (chain)
|
||||||
* @param t tail pbuf (chain)
|
* @param t tail pbuf (chain)
|
||||||
* @note May not be called on a packet queue.
|
* @note May not be called on a packet queue.
|
||||||
*
|
*
|
||||||
* The ->tot_len fields of all pbufs of the head chain are adjusted.
|
* The ->tot_len fields of all pbufs of the head chain are adjusted.
|
||||||
* The ->next field of the last pbuf of the head chain is adjusted.
|
* The ->next field of the last pbuf of the head chain is adjusted.
|
||||||
* The ->ref field of the first pbuf of the tail chain is adjusted.
|
* The ->ref field of the first pbuf of the tail chain is adjusted.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
pbuf_chain(struct pbuf *h, struct pbuf *t)
|
pbuf_chain(struct pbuf *h, struct pbuf *t)
|
||||||
@ -660,7 +660,7 @@ pbuf_chain(struct pbuf *h, struct pbuf *t)
|
|||||||
|
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* proceed to last pbuf of chain */
|
/* proceed to last pbuf of chain */
|
||||||
for (p = h; p->next != NULL; p = p->next) {
|
for (p = h; p->next != NULL; p = p->next) {
|
||||||
/* add total length of second chain to all totals of first chain */
|
/* add total length of second chain to all totals of first chain */
|
||||||
@ -685,7 +685,7 @@ pbuf_chain(struct pbuf *h, struct pbuf *t)
|
|||||||
*
|
*
|
||||||
* @param q pointer to first packet on the queue
|
* @param q pointer to first packet on the queue
|
||||||
* @param n packet to be queued
|
* @param n packet to be queued
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
pbuf_queue(struct pbuf *p, struct pbuf *n)
|
pbuf_queue(struct pbuf *p, struct pbuf *n)
|
||||||
@ -710,7 +710,7 @@ pbuf_queue(struct pbuf *p, struct pbuf *n)
|
|||||||
/* now p->tot_len == p->len */
|
/* now p->tot_len == p->len */
|
||||||
/* proceed to next packet on queue */
|
/* proceed to next packet on queue */
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
/* chain last pbuf of h chain (p) with first of tail (t) */
|
/* chain last pbuf of h chain (p) with first of tail (t) */
|
||||||
p->next = n;
|
p->next = n;
|
||||||
/* t is now referenced to one more time */
|
/* t is now referenced to one more time */
|
||||||
@ -723,7 +723,7 @@ pbuf_queue(struct pbuf *p, struct pbuf *n)
|
|||||||
*
|
*
|
||||||
* @param p pointer to first packet on the queue which will be dequeued.
|
* @param p pointer to first packet on the queue which will be dequeued.
|
||||||
* @return first packet on the remaining queue (NULL if no further packets).
|
* @return first packet on the remaining queue (NULL if no further packets).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct pbuf *
|
struct pbuf *
|
||||||
pbuf_dequeue(struct pbuf *p)
|
pbuf_dequeue(struct pbuf *p)
|
||||||
@ -768,7 +768,7 @@ pbuf_dequeue(struct pbuf *p)
|
|||||||
*
|
*
|
||||||
* @param p Head of pbuf chain to process
|
* @param p Head of pbuf chain to process
|
||||||
*
|
*
|
||||||
* @return Pointer to head of pbuf chain
|
* @return Pointer to head of pbuf chain
|
||||||
*/
|
*/
|
||||||
struct pbuf *
|
struct pbuf *
|
||||||
pbuf_take(struct pbuf *p)
|
pbuf_take(struct pbuf *p)
|
||||||
@ -803,7 +803,7 @@ pbuf_take(struct pbuf *p)
|
|||||||
/* replacement pbuf could be allocated? */
|
/* replacement pbuf could be allocated? */
|
||||||
if (q != NULL)
|
if (q != NULL)
|
||||||
{
|
{
|
||||||
/* copy p to q */
|
/* copy p to q */
|
||||||
/* copy successor */
|
/* copy successor */
|
||||||
q->next = p->next;
|
q->next = p->next;
|
||||||
/* remove linkage from original pbuf */
|
/* remove linkage from original pbuf */
|
||||||
@ -849,7 +849,7 @@ pbuf_take(struct pbuf *p)
|
|||||||
p = p->next;
|
p = p->next;
|
||||||
} while (p);
|
} while (p);
|
||||||
LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: end of chain reached.\n"));
|
LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: end of chain reached.\n"));
|
||||||
|
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -867,7 +867,7 @@ pbuf_dechain(struct pbuf *p)
|
|||||||
{
|
{
|
||||||
struct pbuf *q;
|
struct pbuf *q;
|
||||||
u8_t tail_gone = 1;
|
u8_t tail_gone = 1;
|
||||||
/* tail */
|
/* tail */
|
||||||
q = p->next;
|
q = p->next;
|
||||||
/* pbuf has successor in chain? */
|
/* pbuf has successor in chain? */
|
||||||
if (q != NULL) {
|
if (q != NULL) {
|
||||||
@ -880,9 +880,10 @@ pbuf_dechain(struct pbuf *p)
|
|||||||
/* total length of pbuf p is its own length only */
|
/* total length of pbuf p is its own length only */
|
||||||
p->tot_len = p->len;
|
p->tot_len = p->len;
|
||||||
/* q is no longer referenced by p, free it */
|
/* q is no longer referenced by p, free it */
|
||||||
LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *) q));
|
LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *)q));
|
||||||
tail_gone = pbuf_free(q);
|
tail_gone = pbuf_free(q);
|
||||||
if (tail_gone > 0) LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *) q));
|
if (tail_gone > 0) LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE,
|
||||||
|
("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q));
|
||||||
/* return remaining tail or NULL if deallocated */
|
/* return remaining tail or NULL if deallocated */
|
||||||
}
|
}
|
||||||
/* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
|
/* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
|
||||||
@ -893,7 +894,7 @@ pbuf_dechain(struct pbuf *p)
|
|||||||
|
|
||||||
/* TODO: This function is unused in the lwIP stack and will be deprecated. This is due
|
/* TODO: This function is unused in the lwIP stack and will be deprecated. This is due
|
||||||
* to the new way chains are built. */
|
* to the new way chains are built. */
|
||||||
#if 0
|
#if 0
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Increment the reference count of all pbufs in a chain.
|
* Increment the reference count of all pbufs in a chain.
|
||||||
@ -906,7 +907,7 @@ pbuf_ref_chain(struct pbuf *p)
|
|||||||
{
|
{
|
||||||
SYS_ARCH_DECL_PROTECT(old_level);
|
SYS_ARCH_DECL_PROTECT(old_level);
|
||||||
SYS_ARCH_PROTECT(old_level);
|
SYS_ARCH_PROTECT(old_level);
|
||||||
|
|
||||||
while (p != NULL) {
|
while (p != NULL) {
|
||||||
++p->ref;
|
++p->ref;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
@ -11,21 +11,21 @@
|
|||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
* OF SUCH DAMAGE.
|
* OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is part of the lwIP TCP/IP stack.
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -54,10 +54,10 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
|
|||||||
sys_timeout_handler h;
|
sys_timeout_handler h;
|
||||||
void *arg;
|
void *arg;
|
||||||
|
|
||||||
|
|
||||||
again:
|
again:
|
||||||
timeouts = sys_arch_timeouts();
|
timeouts = sys_arch_timeouts();
|
||||||
|
|
||||||
if (!timeouts || !timeouts->next) {
|
if (!timeouts || !timeouts->next) {
|
||||||
sys_arch_mbox_fetch(mbox, msg, 0);
|
sys_arch_mbox_fetch(mbox, msg, 0);
|
||||||
} else {
|
} else {
|
||||||
@ -80,7 +80,7 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
|
|||||||
LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));
|
LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", (void *)h, (void *)arg));
|
||||||
h(arg);
|
h(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We try again to fetch a message from the mbox. */
|
/* We try again to fetch a message from the mbox. */
|
||||||
goto again;
|
goto again;
|
||||||
} else {
|
} else {
|
||||||
@ -93,7 +93,7 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg)
|
|||||||
timeouts->next->time = 0;
|
timeouts->next->time = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -105,14 +105,14 @@ sys_sem_wait(sys_sem_t sem)
|
|||||||
struct sys_timeout *tmptimeout;
|
struct sys_timeout *tmptimeout;
|
||||||
sys_timeout_handler h;
|
sys_timeout_handler h;
|
||||||
void *arg;
|
void *arg;
|
||||||
|
|
||||||
/* while (sys_arch_sem_wait(sem, 1000) == 0);
|
/* while (sys_arch_sem_wait(sem, 1000) == 0);
|
||||||
return;*/
|
return;*/
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
|
||||||
timeouts = sys_arch_timeouts();
|
timeouts = sys_arch_timeouts();
|
||||||
|
|
||||||
if (!timeouts || !timeouts->next) {
|
if (!timeouts || !timeouts->next) {
|
||||||
sys_arch_sem_wait(sem, 0);
|
sys_arch_sem_wait(sem, 0);
|
||||||
} else {
|
} else {
|
||||||
@ -135,8 +135,8 @@ sys_sem_wait(sys_sem_t sem)
|
|||||||
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);
|
h(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We try again to fetch a message from the mbox. */
|
/* We try again to fetch a message from the mbox. */
|
||||||
goto again;
|
goto again;
|
||||||
} else {
|
} else {
|
||||||
@ -149,7 +149,7 @@ sys_sem_wait(sys_sem_t sem)
|
|||||||
timeouts->next->time = 0;
|
timeouts->next->time = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -167,17 +167,18 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
|
|||||||
timeout->h = h;
|
timeout->h = h;
|
||||||
timeout->arg = arg;
|
timeout->arg = arg;
|
||||||
timeout->time = msecs;
|
timeout->time = msecs;
|
||||||
|
|
||||||
timeouts = sys_arch_timeouts();
|
timeouts = sys_arch_timeouts();
|
||||||
|
|
||||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%lu h=%p arg=%p\n", (void *)timeout, msecs, (void *)h, (void *)arg));
|
LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%lu h=%p arg=%p\n",
|
||||||
|
(void *)timeout, msecs, (void *)h, (void *)arg));
|
||||||
|
|
||||||
LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
|
LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
|
||||||
if (timeouts->next == NULL) {
|
if (timeouts->next == NULL) {
|
||||||
timeouts->next = timeout;
|
timeouts->next = timeout;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeouts->next->time > msecs) {
|
if (timeouts->next->time > msecs) {
|
||||||
timeouts->next->time -= msecs;
|
timeouts->next->time -= msecs;
|
||||||
timeout->next = timeouts->next;
|
timeout->next = timeouts->next;
|
||||||
@ -196,7 +197,7 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go through timeout list (for this task only) and remove the first matching entry,
|
/* Go through timeout list (for this task only) and remove the first matching entry,
|
||||||
@ -210,7 +211,7 @@ sys_untimeout(sys_timeout_handler h, void *arg)
|
|||||||
struct sys_timeout *prev_t, *t;
|
struct sys_timeout *prev_t, *t;
|
||||||
|
|
||||||
timeouts = sys_arch_timeouts();
|
timeouts = sys_arch_timeouts();
|
||||||
|
|
||||||
if (timeouts->next == NULL)
|
if (timeouts->next == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -234,15 +235,15 @@ sys_untimeout(sys_timeout_handler h, void *arg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
sswt_handler(void *arg)
|
sswt_handler(void *arg)
|
||||||
{
|
{
|
||||||
struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;
|
struct sswt_cb *sswt_cb = (struct sswt_cb *) arg;
|
||||||
|
|
||||||
/* Timeout. Set flag to TRUE and signal semaphore */
|
/* Timeout. Set flag to TRUE and signal semaphore */
|
||||||
sswt_cb->timeflag = 1;
|
sswt_cb->timeflag = 1;
|
||||||
sys_sem_signal(*(sswt_cb->psem));
|
sys_sem_signal(*(sswt_cb->psem));
|
||||||
@ -259,7 +260,7 @@ sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
|
|||||||
|
|
||||||
sswt_cb.psem = &sem;
|
sswt_cb.psem = &sem;
|
||||||
sswt_cb.timeflag = 0;
|
sswt_cb.timeflag = 0;
|
||||||
|
|
||||||
/* If timeout is zero, then just wait forever */
|
/* If timeout is zero, then just wait forever */
|
||||||
if (timeout > 0)
|
if (timeout > 0)
|
||||||
/* Create a timer and pass it the address of our flag */
|
/* Create a timer and pass it the address of our flag */
|
||||||
@ -275,7 +276,7 @@ sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout)
|
|||||||
sys_untimeout(sswt_handler, &sswt_cb);
|
sys_untimeout(sswt_handler, &sswt_cb);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
@ -17,21 +17,21 @@
|
|||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
* OF SUCH DAMAGE.
|
* OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is part of the lwIP TCP/IP stack.
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -105,7 +105,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
|
|
||||||
PERF_START;
|
PERF_START;
|
||||||
|
|
||||||
|
|
||||||
#ifdef TCP_STATS
|
#ifdef TCP_STATS
|
||||||
++lwip_stats.tcp.recv;
|
++lwip_stats.tcp.recv;
|
||||||
#endif /* TCP_STATS */
|
#endif /* TCP_STATS */
|
||||||
@ -113,7 +113,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
iphdr = p->payload;
|
iphdr = p->payload;
|
||||||
tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
|
||||||
|
|
||||||
/* remove header from payload */
|
/* remove header from payload */
|
||||||
if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
|
if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
|
||||||
/* drop short packets */
|
/* drop short packets */
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%u bytes) discarded\n", p->tot_len));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%u bytes) discarded\n", p->tot_len));
|
||||||
@ -124,7 +124,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't even process incoming broadcasts/multicasts. */
|
/* Don't even process incoming broadcasts/multicasts. */
|
||||||
if (ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||
|
if (ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||
|
||||||
ip_addr_ismulticast(&(iphdr->dest))) {
|
ip_addr_ismulticast(&(iphdr->dest))) {
|
||||||
@ -136,8 +136,8 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
||||||
(struct ip_addr *)&(iphdr->dest),
|
(struct ip_addr *)&(iphdr->dest),
|
||||||
IP_PROTO_TCP, p->tot_len) != 0) {
|
IP_PROTO_TCP, p->tot_len) != 0) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n", inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n",
|
||||||
(struct ip_addr *)&(iphdr->dest),
|
inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest),
|
||||||
IP_PROTO_TCP, p->tot_len)));
|
IP_PROTO_TCP, p->tot_len)));
|
||||||
#if TCP_DEBUG
|
#if TCP_DEBUG
|
||||||
tcp_debug_print(tcphdr);
|
tcp_debug_print(tcphdr);
|
||||||
@ -166,10 +166,10 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
|
|
||||||
flags = TCPH_FLAGS(tcphdr) & TCP_FLAGS;
|
flags = TCPH_FLAGS(tcphdr) & TCP_FLAGS;
|
||||||
tcplen = p->tot_len + ((flags & TCP_FIN || flags & TCP_SYN)? 1: 0);
|
tcplen = p->tot_len + ((flags & TCP_FIN || flags & TCP_SYN)? 1: 0);
|
||||||
|
|
||||||
/* Demultiplex an incoming segment. First, we check if it is destined
|
/* Demultiplex an incoming segment. First, we check if it is destined
|
||||||
for an active connection. */
|
for an active connection. */
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
|
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||||
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
|
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
|
||||||
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
|
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
|
||||||
@ -178,7 +178,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
pcb->local_port == tcphdr->dest &&
|
pcb->local_port == tcphdr->dest &&
|
||||||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
|
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
|
||||||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
|
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
|
||||||
|
|
||||||
/* Move this PCB to the front of the list so that subsequent
|
/* Move this PCB to the front of the list so that subsequent
|
||||||
lookups will be faster (we exploit locality in TCP segment
|
lookups will be faster (we exploit locality in TCP segment
|
||||||
arrivals). */
|
arrivals). */
|
||||||
@ -186,7 +186,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
if (prev != NULL) {
|
if (prev != NULL) {
|
||||||
prev->next = pcb->next;
|
prev->next = pcb->next;
|
||||||
pcb->next = tcp_active_pcbs;
|
pcb->next = tcp_active_pcbs;
|
||||||
tcp_active_pcbs = pcb;
|
tcp_active_pcbs = pcb;
|
||||||
}
|
}
|
||||||
LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
|
LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
|
||||||
break;
|
break;
|
||||||
@ -210,17 +210,17 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
|
||||||
tcp_timewait_input(pcb);
|
tcp_timewait_input(pcb);
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, if we still did not get a match, we check all PCBs that
|
/* Finally, if we still did not get a match, we check all PCBs that
|
||||||
are LISTENing for incoming connections. */
|
are LISTENing for incoming connections. */
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||||
if ((ip_addr_isany(&(lpcb->local_ip)) ||
|
if ((ip_addr_isany(&(lpcb->local_ip)) ||
|
||||||
ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
|
ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
|
||||||
lpcb->local_port == tcphdr->dest) {
|
lpcb->local_port == tcphdr->dest) {
|
||||||
/* Move this PCB to the front of the list so that subsequent
|
/* Move this PCB to the front of the list so that subsequent
|
||||||
lookups will be faster (we exploit locality in TCP segment
|
lookups will be faster (we exploit locality in TCP segment
|
||||||
arrivals). */
|
arrivals). */
|
||||||
@ -229,7 +229,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
/* our successor is the remainder of the listening list */
|
/* our successor is the remainder of the listening list */
|
||||||
lpcb->next = tcp_listen_pcbs;
|
lpcb->next = tcp_listen_pcbs;
|
||||||
/* put this listening pcb at the head of the listening list */
|
/* put this listening pcb at the head of the listening list */
|
||||||
tcp_listen_pcbs = lpcb;
|
tcp_listen_pcbs = lpcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
|
||||||
@ -240,14 +240,14 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
prev = (struct tcp_pcb *)lpcb;
|
prev = (struct tcp_pcb *)lpcb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TCP_INPUT_DEBUG
|
#if TCP_INPUT_DEBUG
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
|
||||||
tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
|
tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
|
||||||
#endif /* TCP_INPUT_DEBUG */
|
#endif /* TCP_INPUT_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
if (pcb != NULL) {
|
if (pcb != NULL) {
|
||||||
/* The incoming segment belongs to a connection. */
|
/* The incoming segment belongs to a connection. */
|
||||||
#if TCP_INPUT_DEBUG
|
#if TCP_INPUT_DEBUG
|
||||||
@ -255,14 +255,14 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
tcp_debug_print_state(pcb->state);
|
tcp_debug_print_state(pcb->state);
|
||||||
#endif /* TCP_DEBUG */
|
#endif /* TCP_DEBUG */
|
||||||
#endif /* TCP_INPUT_DEBUG */
|
#endif /* TCP_INPUT_DEBUG */
|
||||||
|
|
||||||
/* Set up a tcp_seg structure. */
|
/* Set up a tcp_seg structure. */
|
||||||
inseg.next = NULL;
|
inseg.next = NULL;
|
||||||
inseg.len = p->tot_len;
|
inseg.len = p->tot_len;
|
||||||
inseg.dataptr = p->payload;
|
inseg.dataptr = p->payload;
|
||||||
inseg.p = p;
|
inseg.p = p;
|
||||||
inseg.tcphdr = tcphdr;
|
inseg.tcphdr = tcphdr;
|
||||||
|
|
||||||
recv_data = NULL;
|
recv_data = NULL;
|
||||||
recv_flags = 0;
|
recv_flags = 0;
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
application that the connection is dead before we
|
application that the connection is dead before we
|
||||||
deallocate the PCB. */
|
deallocate the PCB. */
|
||||||
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
|
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
|
||||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||||
memp_free(MEMP_TCP_PCB, pcb);
|
memp_free(MEMP_TCP_PCB, pcb);
|
||||||
} else if (recv_flags & TF_CLOSED) {
|
} else if (recv_flags & TF_CLOSED) {
|
||||||
/* The connection has been closed and we will deallocate the
|
/* The connection has been closed and we will deallocate the
|
||||||
@ -298,7 +298,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
/* Notify application that data has been received. */
|
/* Notify application that data has been received. */
|
||||||
TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
|
TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a FIN segment was received, we call the callback
|
/* If a FIN segment was received, we call the callback
|
||||||
function with a NULL buffer to indicate EOF. */
|
function with a NULL buffer to indicate EOF. */
|
||||||
if (recv_flags & TF_GOT_FIN) {
|
if (recv_flags & TF_GOT_FIN) {
|
||||||
@ -310,7 +310,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We deallocate the incoming pbuf. If it was buffered by the
|
/* We deallocate the incoming pbuf. If it was buffered by the
|
||||||
application, the application should have called pbuf_ref() to
|
application, the application should have called pbuf_ref() to
|
||||||
@ -323,7 +323,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
tcp_debug_print_state(pcb->state);
|
tcp_debug_print_state(pcb->state);
|
||||||
#endif /* TCP_DEBUG */
|
#endif /* TCP_DEBUG */
|
||||||
#endif /* TCP_INPUT_DEBUG */
|
#endif /* TCP_INPUT_DEBUG */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* If no matching PCB was found, send a TCP RST (reset) to the
|
/* If no matching PCB was found, send a TCP RST (reset) to the
|
||||||
sender. */
|
sender. */
|
||||||
@ -332,7 +332,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
#ifdef TCP_STATS
|
#ifdef TCP_STATS
|
||||||
++lwip_stats.tcp.proterr;
|
++lwip_stats.tcp.proterr;
|
||||||
++lwip_stats.tcp.drop;
|
++lwip_stats.tcp.drop;
|
||||||
#endif /* TCP_STATS */
|
#endif /* TCP_STATS */
|
||||||
tcp_rst(ackno, seqno + tcplen,
|
tcp_rst(ackno, seqno + tcplen,
|
||||||
&(iphdr->dest), &(iphdr->src),
|
&(iphdr->dest), &(iphdr->src),
|
||||||
tcphdr->dest, tcphdr->src);
|
tcphdr->dest, tcphdr->src);
|
||||||
@ -340,7 +340,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
|
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
|
||||||
PERF_STOP("tcp_input");
|
PERF_STOP("tcp_input");
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -355,7 +355,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
|||||||
{
|
{
|
||||||
struct tcp_pcb *npcb;
|
struct tcp_pcb *npcb;
|
||||||
u32_t optdata;
|
u32_t optdata;
|
||||||
|
|
||||||
/* In the LISTEN state, we check for incoming SYN segments,
|
/* In the LISTEN state, we check for incoming SYN segments,
|
||||||
creates a new PCB, and responds with a SYN|ACK. */
|
creates a new PCB, and responds with a SYN|ACK. */
|
||||||
if (flags & TCP_ACK) {
|
if (flags & TCP_ACK) {
|
||||||
@ -366,7 +366,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
|||||||
&(iphdr->dest), &(iphdr->src),
|
&(iphdr->dest), &(iphdr->src),
|
||||||
tcphdr->dest, tcphdr->src);
|
tcphdr->dest, tcphdr->src);
|
||||||
} else if (flags & TCP_SYN) {
|
} else if (flags & TCP_SYN) {
|
||||||
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection request %d -> %d.\n", tcphdr->src, tcphdr->dest));
|
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection request %u -> %u.\n", tcphdr->src, tcphdr->dest));
|
||||||
npcb = tcp_alloc(pcb->prio);
|
npcb = tcp_alloc(pcb->prio);
|
||||||
/* If a new PCB could not be created (probably due to lack of memory),
|
/* If a new PCB could not be created (probably due to lack of memory),
|
||||||
we don't do anything, but rely on the sender will retransmit the
|
we don't do anything, but rely on the sender will retransmit the
|
||||||
@ -392,17 +392,17 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
|||||||
#if LWIP_CALLBACK_API
|
#if LWIP_CALLBACK_API
|
||||||
npcb->accept = pcb->accept;
|
npcb->accept = pcb->accept;
|
||||||
#endif /* LWIP_CALLBACK_API */
|
#endif /* LWIP_CALLBACK_API */
|
||||||
|
|
||||||
/* Register the new PCB so that we can begin receiving segments
|
/* Register the new PCB so that we can begin receiving segments
|
||||||
for it. */
|
for it. */
|
||||||
TCP_REG(&tcp_active_pcbs, npcb);
|
TCP_REG(&tcp_active_pcbs, npcb);
|
||||||
|
|
||||||
/* Parse any options in the SYN. */
|
/* Parse any options in the SYN. */
|
||||||
tcp_parseopt(npcb);
|
tcp_parseopt(npcb);
|
||||||
|
|
||||||
/* Build an MSS option. */
|
/* Build an MSS option. */
|
||||||
optdata = htonl(((u32_t)2 << 24) |
|
optdata = htonl(((u32_t)2 << 24) |
|
||||||
((u32_t)4 << 16) |
|
((u32_t)4 << 16) |
|
||||||
(((u32_t)npcb->mss / 256) << 8) |
|
(((u32_t)npcb->mss / 256) << 8) |
|
||||||
(npcb->mss & 255));
|
(npcb->mss & 255));
|
||||||
/* Send a SYN|ACK together with the MSS option. */
|
/* Send a SYN|ACK together with the MSS option. */
|
||||||
@ -444,10 +444,10 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
struct tcp_seg *rseg;
|
struct tcp_seg *rseg;
|
||||||
u8_t acceptable = 0;
|
u8_t acceptable = 0;
|
||||||
err_t err;
|
err_t err;
|
||||||
|
|
||||||
|
|
||||||
err = ERR_OK;
|
err = ERR_OK;
|
||||||
|
|
||||||
/* Process incoming RST segments. */
|
/* Process incoming RST segments. */
|
||||||
if (flags & TCP_RST) {
|
if (flags & TCP_RST) {
|
||||||
/* First, determine if the reset is acceptable. */
|
/* First, determine if the reset is acceptable. */
|
||||||
@ -461,7 +461,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
acceptable = 1;
|
acceptable = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acceptable) {
|
if (acceptable) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
|
||||||
LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
|
LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
|
||||||
@ -479,7 +479,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
|
|
||||||
/* Update the PCB (in)activity timer. */
|
/* Update the PCB (in)activity timer. */
|
||||||
pcb->tmr = tcp_ticks;
|
pcb->tmr = tcp_ticks;
|
||||||
|
|
||||||
/* Do different things depending on the TCP state. */
|
/* Do different things depending on the TCP state. */
|
||||||
switch (pcb->state) {
|
switch (pcb->state) {
|
||||||
case SYN_SENT:
|
case SYN_SENT:
|
||||||
@ -493,7 +493,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
pcb->state = ESTABLISHED;
|
pcb->state = ESTABLISHED;
|
||||||
pcb->cwnd = pcb->mss;
|
pcb->cwnd = pcb->mss;
|
||||||
--pcb->snd_queuelen;
|
--pcb->snd_queuelen;
|
||||||
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %d\n", pcb->snd_queuelen));
|
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %u\n", (unsigned int)pcb->snd_queuelen));
|
||||||
rseg = pcb->unacked;
|
rseg = pcb->unacked;
|
||||||
pcb->unacked = rseg->next;
|
pcb->unacked = rseg->next;
|
||||||
tcp_seg_free(rseg);
|
tcp_seg_free(rseg);
|
||||||
@ -505,7 +505,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
connected. */
|
connected. */
|
||||||
TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
|
TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
|
||||||
tcp_ack(pcb);
|
tcp_ack(pcb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SYN_RCVD:
|
case SYN_RCVD:
|
||||||
if (flags & TCP_ACK &&
|
if (flags & TCP_ACK &&
|
||||||
@ -513,7 +513,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
if (TCP_SEQ_LT(pcb->lastack, ackno) &&
|
if (TCP_SEQ_LT(pcb->lastack, ackno) &&
|
||||||
TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
|
TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
|
||||||
pcb->state = ESTABLISHED;
|
pcb->state = ESTABLISHED;
|
||||||
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection established %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||||
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
|
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
|
||||||
/* Call the accept function. */
|
/* Call the accept function. */
|
||||||
TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
|
TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
|
||||||
@ -522,18 +522,18 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
the connection. */
|
the connection. */
|
||||||
tcp_abort(pcb);
|
tcp_abort(pcb);
|
||||||
return ERR_ABRT;
|
return ERR_ABRT;
|
||||||
}
|
}
|
||||||
/* If there was any data contained within this ACK,
|
/* If there was any data contained within this ACK,
|
||||||
we'd better pass it on to the application as well. */
|
we'd better pass it on to the application as well. */
|
||||||
tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
pcb->cwnd = pcb->mss;
|
pcb->cwnd = pcb->mss;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLOSE_WAIT:
|
case CLOSE_WAIT:
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case ESTABLISHED:
|
case ESTABLISHED:
|
||||||
tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
if (flags & TCP_FIN) {
|
if (flags & TCP_FIN) {
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
pcb->state = CLOSE_WAIT;
|
pcb->state = CLOSE_WAIT;
|
||||||
@ -561,7 +561,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
case FIN_WAIT_2:
|
case FIN_WAIT_2:
|
||||||
tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
if (flags & TCP_FIN) {
|
if (flags & TCP_FIN) {
|
||||||
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
tcp_pcb_purge(pcb);
|
tcp_pcb_purge(pcb);
|
||||||
TCP_RMV(&tcp_active_pcbs, pcb);
|
TCP_RMV(&tcp_active_pcbs, pcb);
|
||||||
@ -572,7 +572,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
case CLOSING:
|
case CLOSING:
|
||||||
tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
||||||
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
tcp_pcb_purge(pcb);
|
tcp_pcb_purge(pcb);
|
||||||
TCP_RMV(&tcp_active_pcbs, pcb);
|
TCP_RMV(&tcp_active_pcbs, pcb);
|
||||||
@ -583,7 +583,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
case LAST_ACK:
|
case LAST_ACK:
|
||||||
tcp_receive(pcb);
|
tcp_receive(pcb);
|
||||||
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
|
||||||
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||||
pcb->state = CLOSED;
|
pcb->state = CLOSED;
|
||||||
recv_flags = TF_CLOSED;
|
recv_flags = TF_CLOSED;
|
||||||
}
|
}
|
||||||
@ -591,7 +591,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -619,7 +619,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
int m;
|
int m;
|
||||||
u32_t right_wnd_edge;
|
u32_t right_wnd_edge;
|
||||||
|
|
||||||
|
|
||||||
if (flags & TCP_ACK) {
|
if (flags & TCP_ACK) {
|
||||||
right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
|
right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;
|
||||||
|
|
||||||
@ -639,7 +639,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
#endif /* TCP_WND_DEBUG */
|
#endif /* TCP_WND_DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pcb->lastack == ackno) {
|
if (pcb->lastack == ackno) {
|
||||||
pcb->acked = 0;
|
pcb->acked = 0;
|
||||||
@ -649,17 +649,17 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
|
if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
|
||||||
if (!(pcb->flags & TF_INFR)) {
|
if (!(pcb->flags & TF_INFR)) {
|
||||||
/* This is fast retransmit. Retransmit the first unacked segment. */
|
/* This is fast retransmit. Retransmit the first unacked segment. */
|
||||||
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %d (%lu), fast retransmit %lu\n",
|
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %u (%lu), fast retransmit %lu\n",
|
||||||
pcb->dupacks, pcb->lastack,
|
(unsigned int)pcb->dupacks, pcb->lastack,
|
||||||
ntohl(pcb->unacked->tcphdr->seqno)));
|
ntohl(pcb->unacked->tcphdr->seqno)));
|
||||||
tcp_rexmit(pcb);
|
tcp_rexmit(pcb);
|
||||||
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
|
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
|
||||||
pcb->ssthresh = LWIP_MAX((pcb->snd_max -
|
pcb->ssthresh = LWIP_MAX((pcb->snd_max -
|
||||||
pcb->lastack) / 2,
|
pcb->lastack) / 2,
|
||||||
2 * pcb->mss);
|
2 * pcb->mss);
|
||||||
|
|
||||||
pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
|
pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
|
||||||
pcb->flags |= TF_INFR;
|
pcb->flags |= TF_INFR;
|
||||||
} else {
|
} else {
|
||||||
/* Inflate the congestion window, but not if it means that
|
/* Inflate the congestion window, but not if it means that
|
||||||
the value overflows. */
|
the value overflows. */
|
||||||
@ -670,7 +670,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
|
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
|
||||||
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
|
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
|
||||||
}
|
}
|
||||||
} else if (TCP_SEQ_LT(pcb->lastack, ackno) &&
|
} else if (TCP_SEQ_LT(pcb->lastack, ackno) &&
|
||||||
TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
|
TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
|
||||||
@ -686,10 +686,10 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
|
|
||||||
/* Reset the number of retransmissions. */
|
/* Reset the number of retransmissions. */
|
||||||
pcb->nrtx = 0;
|
pcb->nrtx = 0;
|
||||||
|
|
||||||
/* Reset the retransmission time-out. */
|
/* Reset the retransmission time-out. */
|
||||||
pcb->rto = (pcb->sa >> 3) + pcb->sv;
|
pcb->rto = (pcb->sa >> 3) + pcb->sv;
|
||||||
|
|
||||||
/* Update the send buffer space. */
|
/* Update the send buffer space. */
|
||||||
pcb->acked = ackno - pcb->lastack;
|
pcb->acked = ackno - pcb->lastack;
|
||||||
pcb->snd_buf += pcb->acked;
|
pcb->snd_buf += pcb->acked;
|
||||||
@ -697,7 +697,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
/* Reset the fast retransmit variables. */
|
/* Reset the fast retransmit variables. */
|
||||||
pcb->dupacks = 0;
|
pcb->dupacks = 0;
|
||||||
pcb->lastack = ackno;
|
pcb->lastack = ackno;
|
||||||
|
|
||||||
/* Update the congestion control variables (cwnd and
|
/* Update the congestion control variables (cwnd and
|
||||||
ssthresh). */
|
ssthresh). */
|
||||||
if (pcb->state >= ESTABLISHED) {
|
if (pcb->state >= ESTABLISHED) {
|
||||||
@ -711,7 +711,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
if (new_cwnd > pcb->cwnd) {
|
if (new_cwnd > pcb->cwnd) {
|
||||||
pcb->cwnd = new_cwnd;
|
pcb->cwnd = new_cwnd;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %u\n", pcb->cwnd));
|
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %u\n", pcb->cwnd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %lu, unacked->seqno %lu:%lu\n",
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %lu, unacked->seqno %lu:%lu\n",
|
||||||
@ -723,7 +723,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
|
|
||||||
/* Remove segment from the unacknowledged list if the incoming
|
/* Remove segment from the unacknowledged list if the incoming
|
||||||
ACK acknowlegdes them. */
|
ACK acknowlegdes them. */
|
||||||
while (pcb->unacked != NULL &&
|
while (pcb->unacked != NULL &&
|
||||||
TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
|
TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
|
||||||
TCP_TCPLEN(pcb->unacked), ackno)) {
|
TCP_TCPLEN(pcb->unacked), ackno)) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",
|
||||||
@ -733,15 +733,15 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
|
|
||||||
next = pcb->unacked;
|
next = pcb->unacked;
|
||||||
pcb->unacked = pcb->unacked->next;
|
pcb->unacked = pcb->unacked->next;
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %d ... ", pcb->snd_queuelen));
|
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen));
|
||||||
pcb->snd_queuelen -= pbuf_clen(next->p);
|
pcb->snd_queuelen -= pbuf_clen(next->p);
|
||||||
tcp_seg_free(next);
|
tcp_seg_free(next);
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unacked)\n", pcb->snd_queuelen));
|
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unacked)\n", (unsigned int)pcb->snd_queuelen));
|
||||||
if (pcb->snd_queuelen != 0) {
|
if (pcb->snd_queuelen != 0) {
|
||||||
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
|
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
|
||||||
pcb->unsent != NULL);
|
pcb->unsent != NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pcb->polltmr = 0;
|
pcb->polltmr = 0;
|
||||||
@ -753,7 +753,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
rationale is that lwIP puts all outstanding segments on the
|
rationale is that lwIP puts all outstanding segments on the
|
||||||
->unsent list after a retransmission, so these segments may
|
->unsent list after a retransmission, so these segments may
|
||||||
in fact have been sent once. */
|
in fact have been sent once. */
|
||||||
while (pcb->unsent != NULL &&
|
while (pcb->unsent != NULL &&
|
||||||
TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),
|
TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),
|
||||||
ackno) &&
|
ackno) &&
|
||||||
TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
|
TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
|
||||||
@ -764,35 +764,35 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
|
|
||||||
next = pcb->unsent;
|
next = pcb->unsent;
|
||||||
pcb->unsent = pcb->unsent->next;
|
pcb->unsent = pcb->unsent->next;
|
||||||
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %d ... ", pcb->snd_queuelen));
|
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen));
|
||||||
pcb->snd_queuelen -= pbuf_clen(next->p);
|
pcb->snd_queuelen -= pbuf_clen(next->p);
|
||||||
tcp_seg_free(next);
|
tcp_seg_free(next);
|
||||||
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%d (after freeing unsent)\n", pcb->snd_queuelen));
|
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unsent)\n", (unsigned int)pcb->snd_queuelen));
|
||||||
if (pcb->snd_queuelen != 0) {
|
if (pcb->snd_queuelen != 0) {
|
||||||
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
|
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
|
||||||
pcb->unsent != NULL);
|
pcb->unsent != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcb->unsent != NULL) {
|
if (pcb->unsent != NULL) {
|
||||||
pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
|
pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of ACK for new data processing. */
|
/* End of ACK for new data processing. */
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %d rtseq %lu ackno %lu\n",
|
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %u rtseq %lu ackno %lu\n",
|
||||||
pcb->rttest, pcb->rtseq, ackno));
|
pcb->rttest, pcb->rtseq, ackno));
|
||||||
|
|
||||||
/* RTT estimation calculations. This is done by checking if the
|
/* RTT estimation calculations. This is done by checking if the
|
||||||
incoming segment acknowledges the segment we use to take a
|
incoming segment acknowledges the segment we use to take a
|
||||||
round-trip time measurement. */
|
round-trip time measurement. */
|
||||||
if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
|
if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
|
||||||
m = tcp_ticks - pcb->rttest;
|
m = tcp_ticks - pcb->rttest;
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %d ticks (%d msec).\n",
|
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %u ticks (%u msec).\n",
|
||||||
m, m * TCP_SLOW_INTERVAL));
|
m, m * TCP_SLOW_INTERVAL));
|
||||||
|
|
||||||
/* This is taken directly from VJs original code in his paper */
|
/* This is taken directly from VJs original code in his paper */
|
||||||
m = m - (pcb->sa >> 3);
|
m = m - (pcb->sa >> 3);
|
||||||
pcb->sa += m;
|
pcb->sa += m;
|
||||||
if (m < 0) {
|
if (m < 0) {
|
||||||
@ -801,14 +801,14 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
m = m - (pcb->sv >> 2);
|
m = m - (pcb->sv >> 2);
|
||||||
pcb->sv += m;
|
pcb->sv += m;
|
||||||
pcb->rto = (pcb->sa >> 3) + pcb->sv;
|
pcb->rto = (pcb->sa >> 3) + pcb->sv;
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %d (%d miliseconds)\n",
|
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %u (%u miliseconds)\n",
|
||||||
pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
|
pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
|
||||||
|
|
||||||
pcb->rttest = 0;
|
pcb->rttest = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the incoming segment contains data, we must process it
|
/* If the incoming segment contains data, we must process it
|
||||||
further. */
|
further. */
|
||||||
if (tcplen > 0) {
|
if (tcplen > 0) {
|
||||||
@ -817,7 +817,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
+) If the incoming segment contains data that is the next
|
+) If the incoming segment contains data that is the next
|
||||||
in-sequence data, this data is passed to the application. This
|
in-sequence data, this data is passed to the application. This
|
||||||
might involve trimming the first edge of the data. The rcv_nxt
|
might involve trimming the first edge of the data. The rcv_nxt
|
||||||
variable and the advertised window are adjusted.
|
variable and the advertised window are adjusted.
|
||||||
|
|
||||||
+) If the incoming segment has data that is above the next
|
+) If the incoming segment has data that is above the next
|
||||||
sequence number expected (->rcv_nxt), the segment is placed on
|
sequence number expected (->rcv_nxt), the segment is placed on
|
||||||
@ -847,7 +847,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
we do not want to discard the full contents of the pbuf up to
|
we do not want to discard the full contents of the pbuf up to
|
||||||
the new starting point of the data since we have to keep the
|
the new starting point of the data since we have to keep the
|
||||||
TCP header which is present in the first pbuf in the chain.
|
TCP header which is present in the first pbuf in the chain.
|
||||||
|
|
||||||
What is done is really quite a nasty hack: the first pbuf in
|
What is done is really quite a nasty hack: the first pbuf in
|
||||||
the pbuf chain is pointed to by inseg.p. Since we need to be
|
the pbuf chain is pointed to by inseg.p. Since we need to be
|
||||||
able to deallocate the whole pbuf, we cannot change this
|
able to deallocate the whole pbuf, we cannot change this
|
||||||
@ -857,7 +857,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
inseg.data pointer to point to the right place. This way, the
|
inseg.data pointer to point to the right place. This way, the
|
||||||
->p pointer will still point to the first pbuf, but the
|
->p pointer will still point to the first pbuf, but the
|
||||||
->p->payload pointer will point to data in another pbuf.
|
->p->payload pointer will point to data in another pbuf.
|
||||||
|
|
||||||
After we are done with adjusting the pbuf pointers we must
|
After we are done with adjusting the pbuf pointers we must
|
||||||
adjust the ->data pointer in the seg and the segment
|
adjust the ->data pointer in the seg and the segment
|
||||||
length.*/
|
length.*/
|
||||||
@ -875,13 +875,13 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
pbuf_header(inseg.p, -off);
|
pbuf_header(inseg.p, -off);
|
||||||
}
|
}
|
||||||
inseg.dataptr = inseg.p->payload;
|
inseg.dataptr = inseg.p->payload;
|
||||||
inseg.len -= pcb->rcv_nxt - seqno;
|
inseg.len -= pcb->rcv_nxt - seqno;
|
||||||
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
|
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
/* the whole segment is < rcv_nxt */
|
/* the whole segment is < rcv_nxt */
|
||||||
/* must be a duplicate of a packet that has already been correctly handled */
|
/* must be a duplicate of a packet that has already been correctly handled */
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
}
|
}
|
||||||
@ -892,7 +892,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
processed. */
|
processed. */
|
||||||
if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
|
if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
|
||||||
TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
|
TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
|
||||||
if (pcb->rcv_nxt == seqno) {
|
if (pcb->rcv_nxt == seqno) {
|
||||||
/* The incoming segment is the next in sequence. We check if
|
/* The incoming segment is the next in sequence. We check if
|
||||||
we have to trim the end of the segment and update rcv_nxt
|
we have to trim the end of the segment and update rcv_nxt
|
||||||
and pass the data to the application. */
|
and pass the data to the application. */
|
||||||
@ -907,25 +907,25 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
#endif /* TCP_QUEUE_OOSEQ */
|
#endif /* TCP_QUEUE_OOSEQ */
|
||||||
|
|
||||||
tcplen = TCP_TCPLEN(&inseg);
|
tcplen = TCP_TCPLEN(&inseg);
|
||||||
|
|
||||||
pcb->rcv_nxt += tcplen;
|
pcb->rcv_nxt += tcplen;
|
||||||
|
|
||||||
/* Update the receiver's (our) window. */
|
/* Update the receiver's (our) window. */
|
||||||
if (pcb->rcv_wnd < tcplen) {
|
if (pcb->rcv_wnd < tcplen) {
|
||||||
pcb->rcv_wnd = 0;
|
pcb->rcv_wnd = 0;
|
||||||
} else {
|
} else {
|
||||||
pcb->rcv_wnd -= tcplen;
|
pcb->rcv_wnd -= tcplen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there is data in the segment, we make preparations to
|
/* If there is data in the segment, we make preparations to
|
||||||
pass this up to the application. The ->recv_data variable
|
pass this up to the application. The ->recv_data variable
|
||||||
is used for holding the pbuf that goes to the
|
is used for holding the pbuf that goes to the
|
||||||
application. The code for reassembling out-of-sequence data
|
application. The code for reassembling out-of-sequence data
|
||||||
chains its data on this pbuf as well.
|
chains its data on this pbuf as well.
|
||||||
|
|
||||||
If the segment was a FIN, we set the TF_GOT_FIN flag that will
|
If the segment was a FIN, we set the TF_GOT_FIN flag that will
|
||||||
be used to indicate to the application that the remote side has
|
be used to indicate to the application that the remote side has
|
||||||
closed its end of the connection. */
|
closed its end of the connection. */
|
||||||
if (inseg.p->tot_len > 0) {
|
if (inseg.p->tot_len > 0) {
|
||||||
recv_data = inseg.p;
|
recv_data = inseg.p;
|
||||||
/* Since this pbuf now is the responsibility of the
|
/* Since this pbuf now is the responsibility of the
|
||||||
@ -937,7 +937,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));
|
||||||
recv_flags = TF_GOT_FIN;
|
recv_flags = TF_GOT_FIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TCP_QUEUE_OOSEQ
|
#if TCP_QUEUE_OOSEQ
|
||||||
/* We now check if we have segments on the ->ooseq queue that
|
/* We now check if we have segments on the ->ooseq queue that
|
||||||
is now in sequence. */
|
is now in sequence. */
|
||||||
@ -946,7 +946,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
|
|
||||||
cseg = pcb->ooseq;
|
cseg = pcb->ooseq;
|
||||||
seqno = pcb->ooseq->tcphdr->seqno;
|
seqno = pcb->ooseq->tcphdr->seqno;
|
||||||
|
|
||||||
pcb->rcv_nxt += TCP_TCPLEN(cseg);
|
pcb->rcv_nxt += TCP_TCPLEN(cseg);
|
||||||
if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
|
if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
|
||||||
pcb->rcv_wnd = 0;
|
pcb->rcv_wnd = 0;
|
||||||
@ -967,8 +967,8 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
if (flags & TCP_FIN) {
|
if (flags & TCP_FIN) {
|
||||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));
|
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));
|
||||||
recv_flags = TF_GOT_FIN;
|
recv_flags = TF_GOT_FIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pcb->ooseq = cseg->next;
|
pcb->ooseq = cseg->next;
|
||||||
tcp_seg_free(cseg);
|
tcp_seg_free(cseg);
|
||||||
@ -1025,7 +1025,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
segment was smaller than the old one; in either
|
segment was smaller than the old one; in either
|
||||||
case, we ditch the incoming segment. */
|
case, we ditch the incoming segment. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (prev == NULL) {
|
if (prev == NULL) {
|
||||||
if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
|
if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
|
||||||
@ -1033,7 +1033,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
than the sequence number of the first segment on the
|
than the sequence number of the first segment on the
|
||||||
queue. We put the incoming segment first on the
|
queue. We put the incoming segment first on the
|
||||||
queue. */
|
queue. */
|
||||||
|
|
||||||
if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
|
if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
|
||||||
/* We need to trim the incoming segment. */
|
/* We need to trim the incoming segment. */
|
||||||
inseg.len = next->tcphdr->seqno - seqno;
|
inseg.len = next->tcphdr->seqno - seqno;
|
||||||
@ -1060,7 +1060,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cseg = tcp_seg_copy(&inseg);
|
cseg = tcp_seg_copy(&inseg);
|
||||||
if (cseg != NULL) {
|
if (cseg != NULL) {
|
||||||
cseg->next = next;
|
cseg->next = next;
|
||||||
prev->next = cseg;
|
prev->next = cseg;
|
||||||
if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
|
if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
|
||||||
@ -1077,7 +1077,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
if (next->next == NULL &&
|
if (next->next == NULL &&
|
||||||
TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
|
TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
|
||||||
next->next = tcp_seg_copy(&inseg);
|
next->next = tcp_seg_copy(&inseg);
|
||||||
if (next->next != NULL) {
|
if (next->next != NULL) {
|
||||||
if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
|
if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
|
||||||
/* We need to trim the last segment. */
|
/* We need to trim the last segment. */
|
||||||
next->len = seqno - next->tcphdr->seqno;
|
next->len = seqno - next->tcphdr->seqno;
|
||||||
@ -1088,11 +1088,11 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev = next;
|
prev = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* TCP_QUEUE_OOSEQ */
|
#endif /* TCP_QUEUE_OOSEQ */
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Segments with length 0 is taken care of here. Segments that
|
/* Segments with length 0 is taken care of here. Segments that
|
||||||
@ -1100,7 +1100,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
|
if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
|
||||||
TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
|
TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
|
||||||
tcp_ack_now(pcb);
|
tcp_ack_now(pcb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -1109,7 +1109,7 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||||||
*
|
*
|
||||||
* Parses the options contained in the incoming segment. (Code taken
|
* Parses the options contained in the incoming segment. (Code taken
|
||||||
* from uIP with only small changes.)
|
* from uIP with only small changes.)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
@ -1120,23 +1120,23 @@ tcp_parseopt(struct tcp_pcb *pcb)
|
|||||||
u16_t mss;
|
u16_t mss;
|
||||||
|
|
||||||
opts = (u8_t *)tcphdr + TCP_HLEN;
|
opts = (u8_t *)tcphdr + TCP_HLEN;
|
||||||
|
|
||||||
/* Parse the TCP MSS option, if present. */
|
/* Parse the TCP MSS option, if present. */
|
||||||
if ((TCPH_OFFSET(tcphdr) & 0xf0) > 0x50) {
|
if ((TCPH_OFFSET(tcphdr) & 0xf0) > 0x50) {
|
||||||
for(c = 0; c < ((TCPH_OFFSET(tcphdr) >> 4) - 5) << 2 ;) {
|
for(c = 0; c < ((TCPH_OFFSET(tcphdr) >> 4) - 5) << 2 ;) {
|
||||||
opt = opts[c];
|
opt = opts[c];
|
||||||
if (opt == 0x00) {
|
if (opt == 0x00) {
|
||||||
/* End of options. */
|
/* End of options. */
|
||||||
break;
|
break;
|
||||||
} else if (opt == 0x01) {
|
} else if (opt == 0x01) {
|
||||||
++c;
|
++c;
|
||||||
/* NOP option. */
|
/* NOP option. */
|
||||||
} else if (opt == 0x02 &&
|
} else if (opt == 0x02 &&
|
||||||
opts[c + 1] == 0x04) {
|
opts[c + 1] == 0x04) {
|
||||||
/* An MSS option with the right option length. */
|
/* An MSS option with the right option length. */
|
||||||
mss = (opts[c + 2] << 8) | opts[c + 3];
|
mss = (opts[c + 2] << 8) | opts[c + 3];
|
||||||
pcb->mss = mss > TCP_MSS? TCP_MSS: mss;
|
pcb->mss = mss > TCP_MSS? TCP_MSS: mss;
|
||||||
|
|
||||||
/* And we are done processing options. */
|
/* And we are done processing options. */
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -1148,10 +1148,10 @@ tcp_parseopt(struct tcp_pcb *pcb)
|
|||||||
/* All other options have a length field, so that we easily
|
/* All other options have a length field, so that we easily
|
||||||
can skip past them. */
|
can skip past them. */
|
||||||
c += opts[c + 1];
|
c += opts[c + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
* are permitted provided that the following conditions are met:
|
* are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
@ -16,21 +16,21 @@
|
|||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
* OF SUCH DAMAGE.
|
* OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is part of the lwIP TCP/IP stack.
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* Author: Adam Dunkels <adam@sics.se>
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -75,7 +75,8 @@ tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
|
|||||||
err_t
|
err_t
|
||||||
tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
|
tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
|
||||||
{
|
{
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, arg=%p, len=%u, copy=%d)\n", (void *)pcb, arg, len, copy));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, arg=%p, len=%u, copy=%d)\n", (void *)pcb,
|
||||||
|
arg, len, (unsigned int)copy));
|
||||||
if (pcb->state == SYN_SENT ||
|
if (pcb->state == SYN_SENT ||
|
||||||
pcb->state == SYN_RCVD ||
|
pcb->state == SYN_RCVD ||
|
||||||
pcb->state == ESTABLISHED ||
|
pcb->state == ESTABLISHED ||
|
||||||
@ -102,12 +103,13 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
u8_t queuelen;
|
u8_t queuelen;
|
||||||
|
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%u, flags=%x, copy=%d)\n", (void *)pcb, arg, len, flags, copy));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%u, flags=%x, copy=%u)\n",
|
||||||
|
(void *)pcb, arg, len, (unsigned int)flags, (unsigned int)copy));
|
||||||
left = len;
|
left = len;
|
||||||
ptr = arg;
|
ptr = arg;
|
||||||
/* fail on too much data */
|
/* fail on too much data */
|
||||||
if (len > pcb->snd_buf) {
|
if (len > pcb->snd_buf) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%d > snd_buf=%d)\n", len, pcb->snd_buf));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too much data (len=%u > snd_buf=%u)\n", len, pcb->snd_buf));
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,19 +118,19 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
seqno = pcb->snd_lbb;
|
seqno = pcb->snd_lbb;
|
||||||
|
|
||||||
queue = NULL;
|
queue = NULL;
|
||||||
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %d\n", pcb->snd_queuelen));
|
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %u\n", (unsigned int)pcb->snd_queuelen));
|
||||||
|
|
||||||
/* Check if the queue length exceeds the configured maximum queue
|
/* Check if the queue length exceeds the configured maximum queue
|
||||||
* length. If so, we return an error. */
|
* length. If so, we return an error. */
|
||||||
queuelen = pcb->snd_queuelen;
|
queuelen = pcb->snd_queuelen;
|
||||||
if (queuelen >= TCP_SND_QUEUELEN) {
|
if (queuelen >= TCP_SND_QUEUELEN) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %d (max %d)\n", queuelen, TCP_SND_QUEUELEN));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue: too long queue %u (max %u)\n", queuelen, TCP_SND_QUEUELEN));
|
||||||
goto memerr;
|
goto memerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcb->snd_queuelen != 0) {
|
if (pcb->snd_queuelen != 0) {
|
||||||
LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
|
LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
|
||||||
pcb->unsent != NULL);
|
pcb->unsent != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
seg = NULL;
|
seg = NULL;
|
||||||
@ -173,7 +175,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
}
|
}
|
||||||
else if (copy) {
|
else if (copy) {
|
||||||
if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
|
if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %u\n", seglen));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %u\n", seglen));
|
||||||
goto memerr;
|
goto memerr;
|
||||||
}
|
}
|
||||||
++queuelen;
|
++queuelen;
|
||||||
@ -191,7 +193,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
* instead of PBUF_REF here.
|
* instead of PBUF_REF here.
|
||||||
*/
|
*/
|
||||||
if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
|
if ((p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n"));
|
||||||
goto memerr;
|
goto memerr;
|
||||||
}
|
}
|
||||||
++queuelen;
|
++queuelen;
|
||||||
@ -203,7 +205,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
/* If allocation fails, we have to deallocate the data pbuf as
|
/* If allocation fails, we have to deallocate the data pbuf as
|
||||||
* well. */
|
* well. */
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: could not allocate memory for header pbuf\n"));
|
||||||
goto memerr;
|
goto memerr;
|
||||||
}
|
}
|
||||||
++queuelen;
|
++queuelen;
|
||||||
@ -217,13 +219,13 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
/* Now that there are more segments queued, we check again if the
|
/* Now that there are more segments queued, we check again if the
|
||||||
length of the queue exceeds the configured maximum. */
|
length of the queue exceeds the configured maximum. */
|
||||||
if (queuelen > TCP_SND_QUEUELEN) {
|
if (queuelen > TCP_SND_QUEUELEN) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %d (%d)\n", queuelen, TCP_SND_QUEUELEN));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue: queue too long %u (%u)\n", queuelen, TCP_SND_QUEUELEN));
|
||||||
goto memerr;
|
goto memerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
seg->len = seglen;
|
seg->len = seglen;
|
||||||
#if 0 /* Was commented out. TODO: can someone say why this is here? */
|
#if 0 /* Was commented out. TODO: can someone say why this is here? */
|
||||||
if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
|
if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
|
||||||
++seg->len;
|
++seg->len;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -300,7 +302,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
|||||||
}
|
}
|
||||||
memp_free(MEMP_TCP_SEG, queue);
|
memp_free(MEMP_TCP_SEG, queue);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (useg == NULL) {
|
if (useg == NULL) {
|
||||||
pcb->unsent = queue;
|
pcb->unsent = queue;
|
||||||
|
|
||||||
@ -365,10 +367,10 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
if (tcp_input_pcb == pcb) {
|
if (tcp_input_pcb == pcb) {
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
|
wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
|
||||||
|
|
||||||
|
|
||||||
seg = pcb->unsent;
|
seg = pcb->unsent;
|
||||||
|
|
||||||
/* If the TF_ACK_NOW flag is set, we check if there is data that is
|
/* If the TF_ACK_NOW flag is set, we check if there is data that is
|
||||||
@ -386,8 +388,8 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
|
||||||
return ERR_BUF;
|
return ERR_BUF;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %lu\n", pcb->rcv_nxt));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: sending ACK for %lu\n", pcb->rcv_nxt));
|
||||||
|
|
||||||
tcphdr = p->payload;
|
tcphdr = p->payload;
|
||||||
tcphdr->src = htons(pcb->local_port);
|
tcphdr->src = htons(pcb->local_port);
|
||||||
tcphdr->dest = htons(pcb->remote_port);
|
tcphdr->dest = htons(pcb->remote_port);
|
||||||
@ -397,7 +399,7 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
tcphdr->wnd = htons(pcb->rcv_wnd);
|
tcphdr->wnd = htons(pcb->rcv_wnd);
|
||||||
tcphdr->urgp = 0;
|
tcphdr->urgp = 0;
|
||||||
TCPH_OFFSET_SET(tcphdr, 5 << 4);
|
TCPH_OFFSET_SET(tcphdr, 5 << 4);
|
||||||
|
|
||||||
tcphdr->chksum = 0;
|
tcphdr->chksum = 0;
|
||||||
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
|
||||||
IP_PROTO_TCP, p->tot_len);
|
IP_PROTO_TCP, p->tot_len);
|
||||||
@ -407,8 +409,8 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TCP_OUTPUT_DEBUG
|
#if TCP_OUTPUT_DEBUG
|
||||||
if (seg == NULL) {
|
if (seg == NULL) {
|
||||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", pcb->unsent));
|
LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", pcb->unsent));
|
||||||
@ -426,7 +428,7 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
ntohl(seg->tcphdr->seqno), pcb->lastack));
|
ntohl(seg->tcphdr->seqno), pcb->lastack));
|
||||||
}
|
}
|
||||||
#endif /* TCP_CWND_DEBUG */
|
#endif /* TCP_CWND_DEBUG */
|
||||||
|
|
||||||
while (seg != NULL &&
|
while (seg != NULL &&
|
||||||
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
|
ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
|
||||||
#if TCP_CWND_DEBUG
|
#if TCP_CWND_DEBUG
|
||||||
@ -439,12 +441,12 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
#endif /* TCP_CWND_DEBUG */
|
#endif /* TCP_CWND_DEBUG */
|
||||||
|
|
||||||
pcb->unsent = seg->next;
|
pcb->unsent = seg->next;
|
||||||
|
|
||||||
if (pcb->state != SYN_SENT) {
|
if (pcb->state != SYN_SENT) {
|
||||||
TCPH_FLAGS_SET(seg->tcphdr, TCPH_FLAGS(seg->tcphdr) | TCP_ACK);
|
TCPH_FLAGS_SET(seg->tcphdr, TCPH_FLAGS(seg->tcphdr) | TCP_ACK);
|
||||||
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
|
pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp_output_segment(seg, pcb);
|
tcp_output_segment(seg, pcb);
|
||||||
pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
|
pcb->snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
|
||||||
if (TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {
|
if (TCP_SEQ_LT(pcb->snd_max, pcb->snd_nxt)) {
|
||||||
@ -455,8 +457,8 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
seg->next = NULL;
|
seg->next = NULL;
|
||||||
if (pcb->unacked == NULL) {
|
if (pcb->unacked == NULL) {
|
||||||
pcb->unacked = seg;
|
pcb->unacked = seg;
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (useg = pcb->unacked; useg->next != NULL; useg = useg->next);
|
for (useg = pcb->unacked; useg->next != NULL; useg = useg->next);
|
||||||
useg->next = seg;
|
useg->next = seg;
|
||||||
@ -465,7 +467,7 @@ tcp_output(struct tcp_pcb *pcb)
|
|||||||
tcp_seg_free(seg);
|
tcp_seg_free(seg);
|
||||||
}
|
}
|
||||||
seg = pcb->unsent;
|
seg = pcb->unsent;
|
||||||
}
|
}
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -498,7 +500,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pcb->rtime = 0;
|
pcb->rtime = 0;
|
||||||
|
|
||||||
if (pcb->rttest == 0) {
|
if (pcb->rttest == 0) {
|
||||||
pcb->rttest = tcp_ticks;
|
pcb->rttest = tcp_ticks;
|
||||||
pcb->rtseq = ntohl(seg->tcphdr->seqno);
|
pcb->rtseq = ntohl(seg->tcphdr->seqno);
|
||||||
@ -510,12 +512,12 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
|||||||
seg->len));
|
seg->len));
|
||||||
|
|
||||||
len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
|
len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload);
|
||||||
|
|
||||||
seg->p->len -= len;
|
seg->p->len -= len;
|
||||||
seg->p->tot_len -= len;
|
seg->p->tot_len -= len;
|
||||||
|
|
||||||
seg->p->payload = seg->tcphdr;
|
seg->p->payload = seg->tcphdr;
|
||||||
|
|
||||||
seg->tcphdr->chksum = 0;
|
seg->tcphdr->chksum = 0;
|
||||||
seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
|
seg->tcphdr->chksum = inet_chksum_pseudo(seg->p,
|
||||||
&(pcb->local_ip),
|
&(pcb->local_ip),
|
||||||
@ -551,7 +553,7 @@ tcp_rst(u32_t seqno, u32_t ackno,
|
|||||||
tcphdr->wnd = htons(TCP_WND);
|
tcphdr->wnd = htons(TCP_WND);
|
||||||
tcphdr->urgp = 0;
|
tcphdr->urgp = 0;
|
||||||
TCPH_OFFSET_SET(tcphdr, 5 << 4);
|
TCPH_OFFSET_SET(tcphdr, 5 << 4);
|
||||||
|
|
||||||
tcphdr->chksum = 0;
|
tcphdr->chksum = 0;
|
||||||
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
|
tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip,
|
||||||
IP_PROTO_TCP, p->tot_len);
|
IP_PROTO_TCP, p->tot_len);
|
||||||
@ -572,23 +574,23 @@ tcp_rexmit(struct tcp_pcb *pcb)
|
|||||||
if (pcb->unacked == NULL) {
|
if (pcb->unacked == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move all unacked segments to the unsent queue. */
|
/* Move all unacked segments to the unsent queue. */
|
||||||
for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
|
for (seg = pcb->unacked; seg->next != NULL; seg = seg->next);
|
||||||
|
|
||||||
seg->next = pcb->unsent;
|
seg->next = pcb->unsent;
|
||||||
pcb->unsent = pcb->unacked;
|
pcb->unsent = pcb->unacked;
|
||||||
|
|
||||||
pcb->unacked = NULL;
|
pcb->unacked = NULL;
|
||||||
|
|
||||||
|
|
||||||
pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
|
pcb->snd_nxt = ntohl(pcb->unsent->tcphdr->seqno);
|
||||||
|
|
||||||
++pcb->nrtx;
|
++pcb->nrtx;
|
||||||
|
|
||||||
/* Don't take any rtt measurements after retransmitting. */
|
/* Don't take any rtt measurements after retransmitting. */
|
||||||
pcb->rttest = 0;
|
pcb->rttest = 0;
|
||||||
|
|
||||||
/* Do the actual retransmission. */
|
/* Do the actual retransmission. */
|
||||||
tcp_output(pcb);
|
tcp_output(pcb);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user