Index: src/core/pbuf.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/pbuf.c,v
retrieving revision 1.87
diff -u -r1.87 pbuf.c
--- src/core/pbuf.c	21 Mar 2007 12:55:00 -0000	1.87
+++ src/core/pbuf.c	21 Mar 2007 21:34:08 -0000
@@ -841,114 +841,53 @@
 }
 #endif
 
+#if ARP_QUEUEING
 /**
  *
- * Create PBUF_POOL (or PBUF_RAM) copies of PBUF_REF pbufs.
+ * Create PBUF_RAM copies of pbufs.
  *
  * Used to queue packets on behalf of the lwIP stack, such as
  * ARP based queueing.
  *
- * Go through a pbuf chain and replace any PBUF_REF buffers
- * with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of
- * the referenced data.
- *
  * @note You MUST explicitly use p = pbuf_take(p);
- * The pbuf you give as argument, may have been replaced
- * by a (differently located) copy through pbuf_take()!
  *
- * @note Any replaced pbufs will be freed through pbuf_free().
- * This may deallocate them if they become no longer referenced.
+ * @note Only one packet is copied, no packet queue!
  *
  * @param p Head of pbuf chain to process
  *
  * @return Pointer to head of pbuf chain
  */
 struct pbuf *
-pbuf_take(struct pbuf *p)
+pbuf_copy(struct pbuf *p)
 {
-  struct pbuf *q , *prev, *head;
-  LWIP_ASSERT("pbuf_take: p != NULL\n", p != NULL);
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_take(%p)\n", (void*)p));
+  u16_t count=0;
+  struct pbuf *q;
+  LWIP_ASSERT("pbuf_copy: p != NULL\n", p != NULL);
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_copy(%p)\n", (void*)p));
+
+  /* allocate one pbuf to hold the complete packet */
+  q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
+  if(q == NULL) {
+    /* out of memory */
+    return NULL;
+  }
 
-  prev = NULL;
-  head = p;
   /* iterate through pbuf chain */
   do
   {
-    /* pbuf is of type PBUF_REF? */
-    if (p->flags == PBUF_FLAG_REF) {
-      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE, ("pbuf_take: encountered PBUF_REF %p\n", (void *)p));
-      /* allocate a pbuf (w/ payload) fully in RAM */
-      /* PBUF_POOL buffers are faster if we can use them */
-      if (p->len <= PBUF_POOL_BUFSIZE) {
-        q = pbuf_alloc(PBUF_RAW, p->len, PBUF_POOL);
-        if (q == NULL) {
-          LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_POOL\n"));
-        }
-      } else {
-        /* no replacement pbuf yet */
-        q = NULL;
-        LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: PBUF_POOL too small to replace PBUF_REF\n"));
-      }
-      /* no (large enough) PBUF_POOL was available? retry with PBUF_RAM */
-      if (q == NULL) {
-        q = pbuf_alloc(PBUF_RAW, p->len, PBUF_RAM);
-        if (q == NULL) {
-          LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_RAM\n"));
-        }
-      }
-      /* replacement pbuf could be allocated? */
-      if (q != NULL)
-      {
-        /* copy p to q */
-        /* copy successor */
-        q->next = p->next;
-        /* remove linkage from original pbuf */
-        p->next = NULL;
-        /* remove linkage to original pbuf */
-        if (prev != NULL) {
-          /* prev->next == p at this point */
-          LWIP_ASSERT("prev->next == p", prev->next == p);
-          /* break chain and insert new pbuf instead */
-          prev->next = q;
-        /* prev == NULL, so we replaced the head pbuf of the chain */
-        } else {
-          head = q;
-        }
-        /* copy pbuf payload */
-        memcpy(q->payload, p->payload, p->len);
-        q->tot_len = p->tot_len;
-        q->len = p->len;
-        /* in case p was the first pbuf, it is no longer refered to by
-         * our caller, as the caller MUST do p = pbuf_take(p);
-         * in case p was not the first pbuf, it is no longer refered to
-         * by prev. we can safely free the pbuf here.
-         * (note that we have set p->next to NULL already so that
-         * we will not free the rest of the chain by accident.)
-         */
-        pbuf_free(p);
-        /* do not copy ref, since someone else might be using the old buffer */
-        LWIP_DEBUGF(PBUF_DEBUG, ("pbuf_take: replaced PBUF_REF %p with %p\n", (void *)p, (void *)q));
-        p = q;
-      } else {
-        /* deallocate chain */
-        pbuf_free(head);
-        LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_take: failed to allocate replacement pbuf for %p\n", (void *)p));
-        return NULL;
-      }
-    /* p->flags != PBUF_FLAG_REF */
-    } else {
-      LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: skipping pbuf not of type PBUF_REF\n"));
-    }
-    /* remember this pbuf */
-    prev = p;
+    /* copy pbuf payload */
+    memcpy((char*)q->payload + count, p->payload, p->len);
+    LWIP_DEBUGF(PBUF_DEBUG, ("pbuf_copy: copied pbuf %p\n", (void *)p, (void *)q));
+    count += p->len;
+
     /* proceed to next pbuf in original chain */
     p = p->next;
-  } while (p);
-  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: end of chain reached.\n"));
+  } while ((p->next) && (p->len != p->tot_len));
+  LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_copy: end of chain reached.\n"));
 
-  return head;
+  return q;
 }
+#endif /* ARP_QUEUEING */
 
 /**
  * Dechains the first pbuf from its succeeding pbufs in the chain.
Index: src/include/lwip/pbuf.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/pbuf.h,v
retrieving revision 1.19
diff -u -r1.19 pbuf.h
--- src/include/lwip/pbuf.h	5 May 2004 14:12:28 -0000	1.19
+++ src/include/lwip/pbuf.h	21 Mar 2007 21:24:18 -0000
@@ -105,7 +105,9 @@
 u8_t pbuf_clen(struct pbuf *p);  
 void pbuf_cat(struct pbuf *h, struct pbuf *t);
 void pbuf_chain(struct pbuf *h, struct pbuf *t);
-struct pbuf *pbuf_take(struct pbuf *f);
+#if ARP_QUEUEING
+struct pbuf *pbuf_copy(struct pbuf *f);
+#endif
 struct pbuf *pbuf_dechain(struct pbuf *p);
 void pbuf_queue(struct pbuf *p, struct pbuf *n);
 struct pbuf * pbuf_dequeue(struct pbuf *p);
Index: src/netif/etharp.c
===================================================================
RCS file: /sources/lwip/lwip/src/netif/etharp.c,v
retrieving revision 1.102
diff -u -r1.102 etharp.c
--- src/netif/etharp.c	4 Mar 2007 12:12:42 -0000	1.102
+++ src/netif/etharp.c	21 Mar 2007 21:25:15 -0000
@@ -832,7 +832,7 @@
       /* (the caller of lwIP assumes the referenced payload can be
        * freed after it returns from the lwIP call that brought us here) */
       /* @todo: if q->type == PBUF_REF, do we have a memory leak (since we call pbuf_ref(p) later)? */
-      p = pbuf_take(q);
+      p = pbuf_copy(q);
       /* packet could be taken over? */
       if (p != NULL) {
         /* queue packet ... */
@@ -842,7 +842,6 @@
         LWIP_ASSERT("newEntry != NULL", newEntry != NULL);
         newEntry->next = 0;
         newEntry->p = p;
-        pbuf_ref(p);
         if(arp_table[i].q != NULL) {
           /* queue was already existent, append the new entry to the end */
           struct etharp_q_entry *r;
