Merge branch 'master' into ppp-new

This commit is contained in:
Sylvain Rochet
2014-02-21 00:39:29 +01:00
38 changed files with 1027 additions and 394 deletions

View File

@@ -74,9 +74,6 @@
#if (!LWIP_UDP && LWIP_UDPLITE)
#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_SNMP)
#error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_DHCP)
#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
@@ -143,7 +140,7 @@
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
#endif
#if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff))
#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)))
#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
#endif
#if (LWIP_NETIF_API && (NO_SYS==1))
@@ -185,7 +182,7 @@
#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT)))
#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
#endif
#if PPP_SUPPORT && !PPPOS_SUPPORT & !PPPOE_SUPPORT
#if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT
#error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on"
#endif
#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT)
@@ -236,9 +233,6 @@
#ifdef MEMP_NUM_TCPIP_MSG
#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef MEMP_NUM_API_MSG
#error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef TCP_REXMIT_DEBUG
#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h."
#endif

View File

@@ -696,12 +696,18 @@ static void
igmp_start_timer(struct igmp_group *group, u8_t max_time)
{
/* ensure the input value is > 0 */
#ifdef LWIP_RAND
if (max_time == 0) {
max_time = 1;
}
#ifdef LWIP_RAND
/* ensure the random value is > 0 */
group->timer = (LWIP_RAND() % max_time);
#else /* LWIP_RAND */
/* ATTENTION: use this only if absolutely necessary! */
group->timer = max_time / 2;
if (group->timer == 0) {
group->timer = 1;
}
#endif /* LWIP_RAND */
}

View File

@@ -48,6 +48,7 @@
#include "lwip/igmp.h"
#include "lwip/api.h"
#include "lwip/api_msg.h"
#include "lwip/sockets.h"
#include "lwip/tcpip.h"
#include "lwip/sys.h"
#include "lwip/timers.h"

View File

@@ -890,12 +890,12 @@ pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
if((p_from != NULL) && (p_from->len == p_from->tot_len)) {
/* don't copy more than one packet! */
LWIP_ERROR("pbuf_copy() does not allow packet queues!\n",
LWIP_ERROR("pbuf_copy() does not allow packet queues!",
(p_from->next == NULL), return ERR_VAL;);
}
if((p_to != NULL) && (p_to->len == p_to->tot_len)) {
/* don't copy more than one packet! */
LWIP_ERROR("pbuf_copy() does not allow packet queues!\n",
LWIP_ERROR("pbuf_copy() does not allow packet queues!",
(p_to->next == NULL), return ERR_VAL;);
}
} while (p_from);
@@ -952,6 +952,56 @@ pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
return copied_total;
}
#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
/**
* This method modifies a 'pbuf chain', so that its total length is
* smaller than 64K. The remainder of the original pbuf chain is stored
* in *rest.
* This function never creates new pbufs, but splits an existing chain
* in two parts. The tot_len of the modified packet queue will likely be
* smaller than 64K.
* 'packet queues' are not supported by this function.
*
* @param p the pbuf queue to be splitted
* @param rest pointer to store the remainder (after the first 64K)
*/
void pbuf_split_64k(struct pbuf *p, struct pbuf **rest)
{
*rest = NULL;
if ((p != NULL) && (p->next != NULL)) {
u16_t tot_len_front = p->len;
struct pbuf *i = p;
struct pbuf *r = p->next;
/* continue until the total length (summed up as u16_t) overflows */
while ((r != NULL) && ((u16_t)(tot_len_front + r->len) > tot_len_front)) {
tot_len_front += r->len;
i = r;
r = r->next;
}
/* i now points to last packet of the first segment. Set next
pointer to NULL */
i->next = NULL;
if (r != NULL) {
/* Update the tot_len field in the first part */
for (i = p; i != NULL; i = i->next) {
i->tot_len -= r->tot_len;
LWIP_ASSERT("tot_len/len mismatch in last pbuf",
(i->next != NULL) || (i->tot_len == i->len));
}
if (p->flags & PBUF_FLAG_TCP_FIN) {
r->flags |= PBUF_FLAG_TCP_FIN;
}
/* tot_len field in rest does not need modifications */
/* reference counters do not need modifications */
*rest = r;
}
}
}
#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
/**
* Copy application supplied data into a pbuf.
* This function can only be used to copy the equivalent of buf->tot_len data.

View File

@@ -51,6 +51,7 @@
#include "arch/perf.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/inet_chksum.h"
#include <string.h>
@@ -313,6 +314,16 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
src_ip = &pcb->local_ip;
}
#if LWIP_IPV6
/* If requested, based on the IPV6_CHECKSUM socket option per RFC3542,
compute the checksum and update the checksum in the payload. */
if (PCB_ISIPV6(pcb) && pcb->chksum_reqd) {
u16_t chksum;
chksum = ip6_chksum_pseudo(q, pcb->protocol, q->tot_len, ipX_2_ip6(src_ip), ipX_2_ip6(dst_ip));
*(u16_t *)(((u8_t *)q->payload) + pcb->chksum_offset) = chksum;
}
#endif
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
err = ipX_output_if(PCB_ISIPV6(pcb), q, ipX_2_ip(src_ip), ipX_2_ip(dst_ip), pcb->ttl, pcb->tos, pcb->protocol, netif);
NETIF_SET_HWADDRHINT(netif, NULL);

View File

@@ -51,6 +51,8 @@
#include "lwip/sys.h"
#include "netif/etharp.h"
#include <string.h>
/**
* IANA assigned enterprise ID for lwIP is 26381
* @see http://www.iana.org/assignments/enterprise-numbers
@@ -763,7 +765,8 @@ const struct mib_array_node internet = {
#endif
/** mib-2.system.sysObjectID */
static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID};
static const struct snmp_obj_id sysobjid_default = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID};
static const struct snmp_obj_id* sysobjid_ptr = &sysobjid_default;
/** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */
static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}};
/** mib-2.system.sysServices */
@@ -893,40 +896,6 @@ static u32_t snmpinpkts = 0,
snmpouttraps = 0;
/* prototypes of the following functions are in lwip/src/include/lwip/snmp.h */
/**
* Copy octet string.
*
* @param dst points to destination
* @param src points to source
* @param n number of octets to copy.
*/
static void ocstrncpy(u8_t *dst, const u8_t *src, u16_t n)
{
u16_t i = n;
while (i > 0) {
i--;
*dst++ = *src++;
}
}
/**
* Copy object identifier (s32_t) array.
*
* @param dst points to destination
* @param src points to source
* @param n number of sub identifiers to copy.
*/
void objectidncpy(s32_t *dst, const s32_t *src, u8_t n)
{
u8_t i = n;
while(i > 0) {
i--;
*dst++ = *src++;
}
}
/**
* Initializes sysDescr pointers.
*
@@ -942,9 +911,9 @@ void snmp_set_sysdescr(const u8_t *str, const u8_t *len)
}
}
void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid)
void snmp_get_sysobjid_ptr(const struct snmp_obj_id **oid)
{
*oid = &sysobjid;
*oid = sysobjid_ptr;
}
/**
@@ -952,9 +921,9 @@ void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid)
*
* @param oid points to stuct snmp_obj_id to copy
*/
void snmp_set_sysobjid(struct snmp_obj_id *oid)
void snmp_set_sysobjid(const struct snmp_obj_id *oid)
{
sysobjid = *oid;
sysobjid_ptr = oid;
}
/**
@@ -2141,7 +2110,7 @@ system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
od->instance = MIB_OBJECT_SCALAR;
od->access = MIB_OBJECT_READ_ONLY;
od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
od->v_len = sysobjid.len * sizeof(s32_t);
od->v_len = sysobjid_ptr->len * sizeof(s32_t);
break;
case 3: /* sysUpTime */
od->instance = MIB_OBJECT_SCALAR;
@@ -2204,10 +2173,10 @@ system_get_value(struct obj_def *od, u16_t len, void *value)
switch (id)
{
case 1: /* sysDescr */
ocstrncpy((u8_t*)value, sysdescr_ptr, len);
MEMCPY(value, sysdescr_ptr, len);
break;
case 2: /* sysObjectID */
objectidncpy((s32_t*)value, (s32_t*)sysobjid.id, (u8_t)(len / sizeof(s32_t)));
MEMCPY(value, sysobjid_ptr->id, len);
break;
case 3: /* sysUpTime */
{
@@ -2215,13 +2184,13 @@ system_get_value(struct obj_def *od, u16_t len, void *value)
}
break;
case 4: /* sysContact */
ocstrncpy((u8_t*)value, syscontact_ptr, len);
MEMCPY(value, syscontact_ptr, len);
break;
case 5: /* sysName */
ocstrncpy((u8_t*)value, sysname_ptr, len);
MEMCPY(value, sysname_ptr, len);
break;
case 6: /* sysLocation */
ocstrncpy((u8_t*)value, syslocation_ptr, len);
MEMCPY(value, syslocation_ptr, len);
break;
case 7: /* sysServices */
{
@@ -2279,15 +2248,15 @@ system_set_value(struct obj_def *od, u16_t len, void *value)
switch (id)
{
case 4: /* sysContact */
ocstrncpy(syscontact_ptr, (u8_t*)value, len);
MEMCPY(syscontact_ptr, value, len);
*syscontact_len_ptr = (u8_t)len;
break;
case 5: /* sysName */
ocstrncpy(sysname_ptr, (u8_t*)value, len);
MEMCPY(sysname_ptr, value, len);
*sysname_len_ptr = (u8_t)len;
break;
case 6: /* sysLocation */
ocstrncpy(syslocation_ptr, (u8_t*)value, len);
MEMCPY(syslocation_ptr, value, len);
*syslocation_len_ptr = (u8_t)len;
break;
};
@@ -2475,7 +2444,7 @@ ifentry_get_value(struct obj_def *od, u16_t len, void *value)
}
break;
case 2: /* ifDescr */
ocstrncpy((u8_t*)value, (u8_t*)netif->name, len);
MEMCPY(value, netif->name, len);
break;
case 3: /* ifType */
{
@@ -2496,7 +2465,7 @@ ifentry_get_value(struct obj_def *od, u16_t len, void *value)
}
break;
case 6: /* ifPhysAddress */
ocstrncpy((u8_t*)value, netif->hwaddr, len);
MEMCPY(value, netif->hwaddr, len);
break;
case 7: /* ifAdminStatus */
{
@@ -2608,7 +2577,7 @@ ifentry_get_value(struct obj_def *od, u16_t len, void *value)
}
break;
case 22: /* ifSpecific */
objectidncpy((s32_t*)value, (s32_t*)ifspecific.id, (u8_t)(len / sizeof(s32_t)));
MEMCPY(value, ifspecific.id, len);
break;
};
}
@@ -3352,7 +3321,7 @@ ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value)
}
break;
case 13: /* ipRouteInfo */
objectidncpy((s32_t*)value, (s32_t*)iprouteinfo.id, (u8_t)(len / sizeof(s32_t)));
MEMCPY(value, iprouteinfo.id, len);
break;
}
}

View File

@@ -737,13 +737,13 @@ snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snm
}
else
{
u8_t j;
u16_t j;
struct nse cur_node;
LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
/* non-leaf, store right child ptr and id */
LWIP_ASSERT("i < 0xff", i < 0xff);
j = (u8_t)i + 1;
j = i + 1;
while ((j < an->maxlength) && (empty_table(an->nptr[j])))
{
j++;
@@ -781,7 +781,7 @@ snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snm
}
else
{
u8_t j;
u16_t j;
/* ident_len == 0, complete with leftmost '.thing' */
j = 0;
while ((j < an->maxlength) && empty_table(an->nptr[j]))
@@ -980,13 +980,13 @@ snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snm
}
else
{
u8_t j;
u16_t j;
struct nse cur_node;
LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
/* non-leaf, store right child ptr and id */
LWIP_ASSERT("i < 0xff", i < 0xff);
j = (u8_t)i + 1;
j = i + 1;
if (j < len)
{
/* right node is the current external node */

View File

@@ -1124,37 +1124,58 @@ tcp_fasttmr_start:
err_t
tcp_process_refused_data(struct tcp_pcb *pcb)
{
err_t err;
u8_t refused_flags = pcb->refused_data->flags;
/* set pcb->refused_data to NULL in case the callback frees it and then
closes the pcb */
struct pbuf *refused_data = pcb->refused_data;
pcb->refused_data = NULL;
/* Notify again application with data previously received. */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
if (err == ERR_OK) {
/* did refused_data include a FIN? */
if (refused_flags & PBUF_FLAG_TCP_FIN) {
/* correct rcv_wnd as the application won't call tcp_recved()
for the FIN's seqno */
if (pcb->rcv_wnd != TCP_WND) {
pcb->rcv_wnd++;
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
struct pbuf *rest;
while (pcb->refused_data != NULL)
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
{
err_t err;
u8_t refused_flags = pcb->refused_data->flags;
/* set pcb->refused_data to NULL in case the callback frees it and then
closes the pcb */
struct pbuf *refused_data = pcb->refused_data;
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
pbuf_split_64k(refused_data, &rest);
pcb->refused_data = rest;
#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
pcb->refused_data = NULL;
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
/* Notify again application with data previously received. */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
if (err == ERR_OK) {
/* did refused_data include a FIN? */
if (refused_flags & PBUF_FLAG_TCP_FIN
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
&& (rest == NULL)
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
) {
/* correct rcv_wnd as the application won't call tcp_recved()
for the FIN's seqno */
if (pcb->rcv_wnd != TCP_WND) {
pcb->rcv_wnd++;
}
TCP_EVENT_CLOSED(pcb, err);
if (err == ERR_ABRT) {
return ERR_ABRT;
}
}
TCP_EVENT_CLOSED(pcb, err);
if (err == ERR_ABRT) {
return ERR_ABRT;
} else if (err == ERR_ABRT) {
/* if err == ERR_ABRT, 'pcb' is already deallocated */
/* Drop incoming packets because pcb is "full" (only if the incoming
segment contains data). */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
return ERR_ABRT;
} else {
/* data is still refused, pbuf is still valid (go on for ACK-only packets) */
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
if (rest != NULL) {
pbuf_cat(refused_data, rest);
}
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
pcb->refused_data = refused_data;
return ERR_INPROGRESS;
}
} else if (err == ERR_ABRT) {
/* if err == ERR_ABRT, 'pcb' is already deallocated */
/* Drop incoming packets because pcb is "full" (only if the incoming
segment contains data). */
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
return ERR_ABRT;
} else {
/* data is still refused, pbuf is still valid (go on for ACK-only packets) */
pcb->refused_data = refused_data;
}
return ERR_OK;
}

View File

@@ -348,7 +348,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
u16_t acked;
#if LWIP_WND_SCALE
/* pcb->acked is u32_t but the sent callback only takes a u16_t,
so we might have to call it multiple timess. */
so we might have to call it multiple times. */
u32_t pcb_acked = pcb->acked;
while(pcb_acked > 0) {
acked = (u16_t)LWIP_MIN(pcb_acked, 0xffffu);
@@ -364,12 +364,24 @@ tcp_input(struct pbuf *p, struct netif *inp)
}
}
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
while (recv_data != NULL) {
struct pbuf *rest = NULL;
pbuf_split_64k(recv_data, &rest);
#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
if (recv_data != NULL) {
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
if (pcb->flags & TF_RXCLOSED) {
/* received data although already closed -> abort (send RST) to
notify the remote host that not all data has been processed */
pbuf_free(recv_data);
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
if (rest != NULL) {
pbuf_free(rest);
}
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
tcp_abort(pcb);
goto aborted;
}
@@ -377,13 +389,29 @@ tcp_input(struct pbuf *p, struct netif *inp)
/* Notify application that data has been received. */
TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
if (err == ERR_ABRT) {
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
if (rest != NULL) {
pbuf_free(rest);
}
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
goto aborted;
}
/* If the upper layer can't receive this data, store it */
if (err != ERR_OK) {
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
if (rest != NULL) {
pbuf_cat(recv_data, rest);
}
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
pcb->refused_data = recv_data;
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
break;
} else {
/* Upper layer received the data, go on with the rest if > 64K */
recv_data = rest;
#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */
}
}
@@ -1382,6 +1410,9 @@ tcp_receive(struct tcp_pcb *pcb)
if (cseg->p->tot_len > 0) {
/* Chain this pbuf onto the pbuf that we will pass to
the application. */
/* With window scaling, this can overflow recv_data->tot_len, but
that's not a problem since we explicitly fix that before passing
recv_data to the application. */
if (recv_data) {
pbuf_cat(recv_data, cseg->p);
} else {

View File

@@ -789,7 +789,7 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
TCP_STATS_INC(tcp.memerr);
return ERR_MEM;
}
LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % 4) == 0);
LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,