From f9c30017b074f55c48b86ff562520f14537b975f Mon Sep 17 00:00:00 2001 From: goldsimon Date: Wed, 25 Jul 2007 18:53:45 +0000 Subject: [PATCH] Fixed bug #20429: use the new pbuf_copy_partial instead of the old copy_from_pbuf, which illegally modified the given pbuf; Introduced pbuf_copy_partial, making netbuf_copy_partial use this function. --- CHANGELOG | 8 +++++++ src/api/api_lib.c | 44 -------------------------------------- src/core/ipv4/ip_frag.c | 38 ++------------------------------- src/core/pbuf.c | 47 +++++++++++++++++++++++++++++++++++++++++ src/include/lwip/api.h | 4 ++-- src/include/lwip/pbuf.h | 1 + 6 files changed, 60 insertions(+), 82 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e7218952..26f7b303 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,10 @@ HISTORY ++ New features: + 2007-07-25 Simon Goldschmidt + * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, + making netbuf_copy_partial use this function. + 2007-07-25 Simon Goldschmidt * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and @@ -252,6 +256,10 @@ HISTORY ++ Bug fixes: + 2007-07-25 Simon Goldschmidt + * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old + copy_from_pbuf, which illegally modified the given pbuf. + 2007-07-25 Simon Goldschmidt * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). diff --git a/src/api/api_lib.c b/src/api/api_lib.c index 557aa4c0..33f4cb29 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -234,50 +234,6 @@ netbuf_first(struct netbuf *buf) buf->ptr = buf->p; } -/** - * Copy (part of) the contents of a packet buffer contained in a netbuf - * to an application supplied buffer. - * - * @param buf the netbuf from which to copy data - * @param dataptr the application supplied buffer - * @param len length of data to copy (dataptr must be big enough) - * @param offset offset into the packet buffer from where to begin copying len bytes - */ -void -netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset) -{ - struct pbuf *p; - u16_t left; - u16_t buf_copy_len; - - LWIP_ERROR("netbuf_copy_partial: invalid buf", (buf != NULL), return;); - LWIP_ERROR("netbuf_copy_partial: invalid dataptr", (dataptr != NULL), return;); - - left = 0; - - if(buf == NULL || dataptr == NULL) { - return; - } - - /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ - for(p = buf->p; len != 0 && p != NULL; p = p->next) { - if ((offset != 0) && (offset >= p->len)) { - /* don't copy from this buffer -> on to the next */ - offset -= p->len; - } else { - /* copy from this buffer. maybe only partially. */ - buf_copy_len = p->len - offset; - if (buf_copy_len > len) - buf_copy_len = len; - /* copy the necessary parts of the buffer */ - MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); - left += buf_copy_len; - len -= buf_copy_len; - offset = 0; - } - } -} - /** ********************************** * Netconn functions diff --git a/src/core/ipv4/ip_frag.c b/src/core/ipv4/ip_frag.c index e20f70bb..428e0697 100644 --- a/src/core/ipv4/ip_frag.c +++ b/src/core/ipv4/ip_frag.c @@ -59,40 +59,6 @@ static u8_t ip_reassflags; static u8_t ip_reasstmr; #endif /* IP_REASSEMBLY */ -#if IP_REASSEMBLY || (IP_FRAG && IP_FRAG_USES_STATIC_BUF) -/* - * Copy len bytes from offset in pbuf to buffer - * - * helper used by both ip_reass and ip_frag - * - * @param p pbuf chain to copy from - * @param offset offset in bytes into the pbuf chain which should be skipped - * before starting to copy - * @param buffer destination to copy the data - * @param len number of bytes to copy (starting from offset) - * @return pointer to one pbuf in the chain p from which copied last - */ -static struct pbuf * -copy_from_pbuf(struct pbuf *p, u16_t *offset, u8_t *buffer, u16_t len) -{ - u16_t l; - - p->payload = (u8_t *)p->payload + *offset; - p->len -= *offset; - while (len) { - l = len < p->len ? len : p->len; - MEMCPY(buffer, p->payload, l); - buffer += l; - len -= l; - if (len) - p = p->next; - else - *offset = l; - } - return p; -} -#endif /* IP_REASSEMBLY || IP_FRAG_USES_STATIC_BUF */ - #if IP_REASSEMBLY /** * Initializes IP reassembly states. @@ -187,7 +153,7 @@ ip_reass(struct pbuf *p) ("ip_reass: copying with offset %"S16_F" into %"S16_F":%"S16_F"\n", offset, IP_HLEN + offset, IP_HLEN + offset + len)); i = IPH_HL(fraghdr) * 4; - copy_from_pbuf(p, &i, &ip_reassbuf[IP_HLEN + offset], len); + pbuf_copy_partial(p, &ip_reassbuf[IP_HLEN + offset], len, i); /* Update the bitmap. */ if (offset / (8 * 8) == (offset + len) / (8 * 8)) { @@ -392,7 +358,7 @@ ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest) cop = last ? left : nfb * 8; #if IP_FRAG_USES_STATIC_BUF - p = copy_from_pbuf(p, &poff, (u8_t *) iphdr + IP_HLEN, cop); + poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff); #else /* IP_FRAG_USES_STATIC_BUF */ /* When not using a static buffer, create a chain of pbufs. * The first will be a PBUF_RAM holding the link and IP header. diff --git a/src/core/pbuf.c b/src/core/pbuf.c index 497db5fc..0c42b9e5 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -735,3 +735,50 @@ pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 1, ("pbuf_copy: end of chain reached.\n")); return ERR_OK; } + +/** + * Copy (part of) the contents of a packet buffer + * to an application supplied buffer. + * + * @param buf the pbuf from which to copy data + * @param dataptr the application supplied buffer + * @param len length of data to copy (dataptr must be big enough) + * @param offset offset into the packet buffer from where to begin copying len bytes + */ +u16_t +pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) +{ + struct pbuf *p; + u16_t left; + u16_t buf_copy_len; + u16_t copied_total = 0; + + LWIP_ERROR("netbuf_copy_partial: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("netbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); + + left = 0; + + if((buf == NULL) || (dataptr == NULL)) { + return 0; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; len != 0 && p != NULL; p = p->next) { + if ((offset != 0) && (offset >= p->len)) { + /* don't copy from this buffer -> on to the next */ + offset -= p->len; + } else { + /* copy from this buffer. maybe only partially. */ + buf_copy_len = p->len - offset; + if (buf_copy_len > len) + buf_copy_len = len; + /* copy the necessary parts of the buffer */ + MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); + copied_total += buf_copy_len; + left += buf_copy_len; + len -= buf_copy_len; + offset = 0; + } + } + return copied_total; +} diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index 6f3b585f..3ba0f3aa 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -149,9 +149,9 @@ err_t netbuf_data (struct netbuf *buf, s8_t netbuf_next (struct netbuf *buf); void netbuf_first (struct netbuf *buf); -void netbuf_copy_partial(struct netbuf *buf, void *dataptr, - u16_t len, u16_t offset); +#define netbuf_copy_partial(buf, dataptr, len, offset) \ + pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) #define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) #define netbuf_len(buf) ((buf)->p->tot_len) #define netbuf_fromaddr(buf) ((buf)->addr) diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h index 9c798ab0..578a5344 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -111,6 +111,7 @@ void pbuf_cat(struct pbuf *h, struct pbuf *t); void pbuf_chain(struct pbuf *h, struct pbuf *t); struct pbuf *pbuf_dechain(struct pbuf *p); err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); +u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset); #ifdef __cplusplus }