Merged from main.
diff --git a/doc/contrib.txt b/doc/contrib.txt
index 252724a..7c46561 100644
--- a/doc/contrib.txt
+++ b/doc/contrib.txt
@@ -1,4 +1,9 @@
-How to contribute to lwIP
+1 Introduction
+
+This document describes some guidelines for people participating
+in lwIP development.
+
+2 How to contribute to lwIP
 
 Here is a short list of suggestions to anybody working with lwIP and 
 trying to contribute bugreports, fixes, enhancements, platform ports etc.
@@ -6,53 +11,53 @@
 to fixes or questions might often come late. Hopefully the bug and patch tracking 
 features of Savannah help us not lose users' input.
 
-Source code style:
+2.1 Source code style:
 
-- do not use tabs.
-- indentation is two spaces per level.
-- end debug messages with a trailing newline (\n).
-- one space between keyword and opening bracket.
-- no space between function and opening bracket.
-- one space and no newline before opening curly braces of a block.
-- spaces surrounding assignment and comparisons.
-- use current source code style as further reference.
+1. do not use tabs.
+2. identation is two spaces per level.
+3. end debug messages with a trailing newline (\n).
+4. one space between keyword and opening bracket.
+5. no space between function and opening bracket.
+6. one space and no newline before opening curly braces of a block.
+7. spaces surrounding assignment and comparisons.
+8. use current source code style as further reference.
 
-Source code documentation style:
+2.2 Source code documentation style:
 
-- JavaDoc compliant and Doxygen compatible.
-- Function documentation above functions in .c files, not .h files.
-  (This forces you to synchronize documentation and behaviour.)
-- Use current documentation style as further reference.
+1. JavaDoc compliant and Doxygen compatible.
+2. Function documentation above functions in .c files, not .h files.
+   (This forces you to synchronize documentation and behaviour.)
+3. Use current documentation style as further reference.
  
-Bug reports and patches:
+2.3 Bug reports and patches:
 
-- Make sure you are reporting bugs or send patches against the latest
-  sources. (From the latest release and/or the current CVS sources.)
-- If you think you found a bug make sure it's not already filed in the
-  bugtracker at Savannah.
-- If you have a fix put the patch on Savannah. If it is a patch that affects
-  both core and arch specific stuff please separate them so that the core can
-  be applied separately while leaving the other patch 'open'. The prefered way
-  is to NOT touch archs you can't test and let maintainers take care of them.
-  This is a good way to see if they are used at all - the same goes for unix
-  netifs except tapif.
-- Do not file a bug and post a fix to it to the patch area. Either a bug report
-or a patch will be enough.
-If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area.
-- Trivial patches (compiler warning, indentation and spelling fixes or anything obvious which takes a line or two)
-can go to the lwip-users list. This is still the fastest way of interaction and the list is not so crowded
-as to allow for loss of fixes. Putting bugs on Savannah and subsequently closing them is too much an overhead
-for reporting a compiler warning fix.
-- Patches should be specific to a single change or to related changes.Do not mix bugfixes with spelling and other
-trivial fixes unless the bugfix is trivial too.Do not reorganize code and rename identifiers in the same patch you
-change behaviour if not necessary.A patch is easier to read and understand if it's to the point and short than
-if it's not to the point and long :) so the chances for it to be applied are greater. 
+1. Make sure you are reporting bugs or send patches against the latest
+   sources. (From the latest release and/or the current CVS sources.)
+2. If you think you found a bug make sure it's not already filed in the
+   bugtracker at Savannah.
+3. If you have a fix put the patch on Savannah. If it is a patch that affects
+   both core and arch specific stuff please separate them so that the core can
+   be applied separately while leaving the other patch 'open'. The prefered way
+   is to NOT touch archs you can't test and let maintainers take care of them.
+   This is a good way to see if they are used at all - the same goes for unix
+   netifs except tapif.
+4. Do not file a bug and post a fix to it to the patch area. Either a bug report
+   or a patch will be enough.
+   If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area.
+5. Trivial patches (compiler warning, indentation and spelling fixes or anything obvious which takes a line or two)
+   can go to the lwip-users list. This is still the fastest way of interaction and the list is not so crowded
+   as to allow for loss of fixes. Putting bugs on Savannah and subsequently closing them is too much an overhead
+   for reporting a compiler warning fix.
+6. Patches should be specific to a single change or to related changes.Do not mix bugfixes with spelling and other
+   trivial fixes unless the bugfix is trivial too.Do not reorganize code and rename identifiers in the same patch you
+   change behaviour if not necessary.A patch is easier to read and understand if it's to the point and short than
+   if it's not to the point and long :) so the chances for it to be applied are greater. 
 
-For platform porters:
+2.4 Platform porters:
 
-- If you've ported lwIP to a platform (an OS, a uC/processor or a combination of these) and you think it
-could benefit others[1] you might want to post an url to a tarball or zip from which it can be imported 
-to the contrib CVS module. Then you get CVS access and have to maintain your port :)
+1. If you've ported lwIP to a platform (an OS, a uC/processor or a combination of these) and you think it
+   could benefit others[1] you might want to post an url to a tarball or zip from which it can be imported 
+   to the contrib CVS module. Then you get CVS access and have to maintain your port :)
 
 [1] - lwIP CVS should not be just a place to keep your port so you don't have to set up your own CVS :)
 Especially welcome are ports to common enough OS/hardware that others can have access too.
diff --git a/src/core/pbuf.c b/src/core/pbuf.c
index 41da523..cc9019c 100644
--- a/src/core/pbuf.c
+++ b/src/core/pbuf.c
@@ -13,11 +13,18 @@
  * Multiple packets may be queued, also using this singly linked list.
  * This is called a "packet queue". So, a packet queue consists of one
  * or more pbuf chains, each of which consist of one or more pbufs.
+ * The differences between a pbuf chain and a packet queue are very
+ * subtle. Currently, queues are only supported in a limited section
+ * of lwIP, this is the etharp queueing code. Outside of this section
+ * no packet queues are supported as of yet.
  *
  * The last pbuf of a packet has a ->tot_len field that equals the
  * ->len field. It can be found by traversing the list. If the last
  * pbuf of a packet has a ->next field other than NULL, more packets
  * are on the queue.
+ *
+ * Therefore, looping through a pbuf of a single packet, has an
+ * loop end condition (tot_len == p->len), NOT (next == NULL).
  */
 
 /*
@@ -206,6 +213,7 @@
   struct pbuf *p, *q, *r;
   u16_t offset;
   s32_t rem_len; /* remaining length */
+  DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u)\n", length));
 
   /* determine header offset */
   offset = 0;
@@ -233,6 +241,7 @@
   case PBUF_POOL:
     /* allocate head of pbuf chain into p */
     p = pbuf_pool_alloc();
+    DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", p));
     if (p == NULL) {
 #ifdef PBUF_STATS
       ++lwip_stats.pbuf.err;
@@ -291,7 +300,7 @@
       r = q;
     }
     /* end of chain */
-    r->next = NULL;
+    //r->next = NULL;
 
     break;
   case PBUF_RAM:
@@ -331,6 +340,7 @@
   }
   /* set reference count */
   p->ref = 1;
+  DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u) == %p\n", length, (void *)p));
   return p;
 }
 
@@ -534,6 +544,7 @@
     DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.\n"));
     return 0;
   }
+  DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_free(%p)\n", (void *)p));
 
   PERF_START;
 
@@ -557,6 +568,7 @@
     if (p->ref == 0) {
       /* remember next pbuf in chain for next iteration */
       q = p->next;
+      DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: deallocating %p\n", (void *)p));
       /* is this a pbuf from the pool? */
       if (p->flags == PBUF_FLAG_POOL) {
         p->len = p->tot_len = PBUF_POOL_BUFSIZE;
@@ -575,6 +587,7 @@
     /* p->ref > 0, this pbuf is still referenced to */
     /* (and so the remaining pbufs in chain as well) */
     } else {
+      DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %u, ending here.\n", (void *)p, p->ref));
       /* stop walking through chain */
       p = NULL;
     }
@@ -661,7 +674,7 @@
   p->next = t;
   /* t is now referenced to one more time */
   pbuf_ref(t);
-  DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: referencing tail %p\n", (void *) t));
+  DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)p, (void *)t));
 }
 
 /* For packet queueing. Note that queued packets must be dequeued first
@@ -869,6 +882,7 @@
     /* q is no longer referenced by p, free it */
     DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *) q));
     tail_gone = pbuf_free(q);
+    if (tail_gone > 0) 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 */
   }
   /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */