diff --git a/ChangeLog b/ChangeLog
index 3c3207b6f0cca63808394db5ff3108e5c94047fe..8f6203a60a1b630cade6100a8c59c5444d0764e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -215,7 +215,7 @@
 	* Added listen() and accept()
 	* Added DM90x0 ethernet driver
 	* ARP timer is now built into the network layer
-	* Basic client functionality verified: socket(), bind(), connect(), recv(), send().
+	* Basic client functionality verified: TCP socket(), bind(), connect(), recv(), send().
 
 0.3.1 2007-11-19 Gregory Nutt <spudmonkey@racsa.co.cr>
 
@@ -223,12 +223,12 @@
 	* Corrected a TCP problem where packets were dropped because there was no
 	  recv() in place but the packet was being ACKed.  There are still TCP
 	  recv buffering issues, but this is part of a larger buffering issue.
-	* Basic server functionality verified: listen(), accept()
+	* Basic server functionality verified: TCP listen(), accept()
 	* Fix DM90x0 driver problem that caused TX overruns
 	* Add strncmp()
 	* Added TCP/IP read-ahead buffer to minimize failed ACKs and packet loss.
 
-0.3.2 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
+0.3.2 2007-11-23 Gregory Nutt <spudmonkey@racsa.co.cr>
 
 	* Add strcat() and strncat()
 	* Integrated uIP micro webserver
@@ -239,4 +239,10 @@
 	* Moved urgent data info into device structure.
 	* TCP and ICMP protocols can now be disabled.
 	* Added UDP test in examples/udp
-	* Verified/debugged UDP send logic using examples/udp
+	* Verified/debugged UDP socket(), bind(), sendto() and recvfrom() logic
+	  using examples/udp
+	* recvfrom() and accept() now correctly return the remote address.
+	* Fixed computation error in ntohl().
+
+0.3.3 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
+
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index 1b74db8090270c52f2430063ba82dd7f1774db1e..eb8f7dfac677604996055e4cd09dc0facabfa33a 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -8,7 +8,7 @@
   <tr align="center" bgcolor="#e4e4e4">
     <td>
       <h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
-      <p>Last Updated: November 20, 2007</p>
+      <p>Last Updated: November 23, 2007</p>
     </td>
   </tr>
 </table>
@@ -183,27 +183,36 @@
 </table>
 
 <p>
-   The 13th release of NuttX (nuttx-0.3.0) is available for download
-   from the <a href="http://sourceforge.net/project/showfiles.php?group_id=189573">SourceForge</a>
-   website.
-   The change log associated with the release is available <a href="#currentrelease">here</a>.
-   Unreleased changes after this release are avalable in CVS.
-   These unreleased changes are listed <a href="#pendingchanges">here</a>.
+  The 14th release of NuttX (nuttx-0.3.2) is available for download
+  from the <a href="http://sourceforge.net/project/showfiles.php?group_id=189573">SourceForge</a>
+  website.
+  The change log associated with the release is available <a href="#currentrelease">here</a>.
+  Unreleased changes after this release are avalable in CVS.
+  These unreleased changes are listed <a href="#pendingchanges">here</a>.
 </p>
 <p>
-  NuttX 0.3.1 is the second release containing the integration of a network
+  NuttX 0.3.2 is the 3rd release containing the integration of a network
   subsystem and the uIP TCP/IP, UDP, and ICMP stacks based on
   <a href="http://www.sics.se/~adam/uip/index.php/Main_Page">uIP</a>
   into NuttX.
 </p>
 <p>
-  Many network-related problems have been fixed from version 0.3.0
+  Many network-related problems have been fixed from version 0.3.1
   and the implementation has matured significantly.
-  However, the level of network reliability is probably still at the
-  pre-alpha or early level.
-  It is sufficiently complete that you may begin to perform some network
-  integration and is exepcted to achieve beta level of reliability over
-  the next few releases.
+  Changes in this release include:
+</p>
+<ul>
+<li>TCP-related bug-fixes,</li>
+<li>TCP performance improvements,</li>
+<li>Initial UDP integration, and</li>
+<li>Initial uIP micro webserver integration
+</ul>
+</p>
+  See the ChangeLog for a complete list of changes.
+</p>
+<p>
+  The level of network reliability is a a strong alpha level is expected to
+  achieve beta level of reliability over the next few releases.
 </p>
 <p>
   The baseline functionality of NuttX continues to mature and remains at
@@ -667,17 +676,7 @@ Other memory:
 	* Added DM90x0 ethernet driver
 	* ARP timer is now built into the network layer
 	* Basic client functionality verified: socket(), bind(), connect(), recv(), send().
-</pre></ul>
-
-<table width ="100%">
-  <tr bgcolor="#e4e4e4">
-  <td>
-    <a name="currentrelease">ChangeLog for Current Release</a>
-  </td>
-  </tr>
-</table>
 
-<pre><ul>
 0.3.1 2007-11-19 Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
 
 	* Separated net/uip/uip.c into several functions in several files.
@@ -693,7 +692,7 @@ Other memory:
 <table width ="100%">
   <tr bgcolor="#e4e4e4">
   <td>
-    <a name="pendingchanges">Unreleased Changes</a>
+    <a name="currentrelease">ChangeLog for Current Release</a>
   </td>
   </tr>
 </table>
@@ -710,7 +709,22 @@ Other memory:
 	* Moved urgent data info into device structure.
 	* TCP and ICMP protocols can now be disabled.
 	* Added UDP test in examples/udp
-	* Verified/debugged UDP send logic using examples/udp
+	* Verified/debugged UDP socket(), bind(), sendto() and recvfrom() logic
+	  using examples/udp
+	* recvfrom() and accept() now correctly return the remote address.
+	* Fixed computation error in ntohl().
+</pre></ul>
+
+<table width ="100%">
+  <tr bgcolor="#e4e4e4">
+  <td>
+    <a name="pendingchanges">Unreleased Changes</a>
+  </td>
+  </tr>
+</table>
+
+<pre><ul>
+0.3.3 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 </pre></ul>
 
 <table width ="100%">
diff --git a/ReleaseNotes b/ReleaseNotes
index 60ed3a9e719a3ada186b771bdf028aaf9cd639f1..7be29fc2c68f376f20c53453340e23ff1a3f0cd1 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -1,23 +1,27 @@
-nuttx-0.3.1
+nuttx-0.3.2
 ^^^^^^^^^^^
 
-This is the 13th release of NuttX and the second release containing
+This is the 14th release of NuttX and the 3rd release containing
 the integration of a network subsystem and the uIP TCP/IP, UDP, and
 ICMP stacks into NuttX (see http://www.sics.se/~adam/uip/index.php/Main_Page).
 
 Many network-related problems have been fixed and the implementation
-has matured significantly.  However, the level of network reliability
-is probably still at the pre-alpha or early level.  It is sufficiently
-complete that you may begin to perform some network integration and
-is exepcted to achieve beta level of reliability over the next few
-releases.
+has matured significantly.  This release consists of:
 
-The baseline functionality of NuttX continues to mature and remains at
-post-beta (as long as the network is not used).
+o TCP-related bug-fixes
+o TCP performance improvements
+o Initial UDP integration
+o Initial uIP micro webserver integration
 
 See the ChangeLog for a complete list of changes.
 
+The level of network reliability is at alpha level is expected to
+achieve beta level of reliability over the next few releases.
+
+The baseline functionality of NuttX continues to mature and remains at
+post-beta.
+
 This release has been verified only on the Neuros OSD (DM320 ARM9)
 platform using the DM90x0 driver.
 
-This tarball contains a complete CVS snapshot from November 19, 2007.
+This tarball contains a complete CVS snapshot from November 23, 2007.
diff --git a/TODO b/TODO
index 90c9d123bdc63e73bb9fe1cf294abe79e086e3dd..fe9b5385cd1a3bcc5f35bec6683b89d93f7cb5ec 100644
--- a/TODO
+++ b/TODO
@@ -29,7 +29,6 @@ o C++ Support
 - Need to call static constructors
 
 o Network
-- UDP is untested.
 - Did not implement send() and sendto() timeouts.  Option is setable via setsockopt,
   but is not implemented.
 - uIP's netutils/telnetd (and maybe others) are seriously broken.
@@ -37,7 +36,6 @@ o Network
 - uIP's netutils/webserver hangs
 - uIP's netutils/smtp, dpcpc, resolv, webclient -- untested
 - Should implement SOCK_RAW
-- accept() and recvfrom() need to return connection address
 - Performance Improvements (uIP is not very fast):
   Need to extend logic so that uIP can have more than on packet in flight and to
   handle deferred acknowledgements.
diff --git a/examples/udp/udp-server.c b/examples/udp/udp-server.c
index 839cd10a900dc25f632e6be2f14d84b48453c047..d833a254f184419f1c470a1e04cd384f2cf062b2 100644
--- a/examples/udp/udp-server.c
+++ b/examples/udp/udp-server.c
@@ -83,6 +83,7 @@ void recv_server(void)
 {
   struct sockaddr_in server;
   struct sockaddr_in client;
+  uint32 tmpaddr;
   unsigned char inbuf[1024];
   int sockfd;
   int nbytes;
@@ -128,7 +129,13 @@ void recv_server(void)
       addrlen = sizeof(struct sockaddr_in);
       nbytes = recvfrom(sockfd, inbuf, 1024, 0, 
                         (struct sockaddr*)&client, &addrlen);
-      message("server: %d. Recieved %d bytes\n", offset, nbytes);
+
+      tmpaddr = ntohl(client.sin_addr.s_addr);
+      message("server: %d. Received %d bytes from %d.%d.%d.%d:%d\n",
+              offset, nbytes, 
+              tmpaddr >> 24, (tmpaddr >> 16) & 0xff, 
+              (tmpaddr >> 8) & 0xff, tmpaddr & 0xff, 
+              ntohs(client.sin_port));
 
       if (nbytes < 0)
         {
diff --git a/fs/fs_open.c b/fs/fs_open.c
index 71fc8d0c42e8adca927e172089d7584afde3e083..d07b734169c2e683b6441dbb87a9da00eaf90d8e 100644
--- a/fs/fs_open.c
+++ b/fs/fs_open.c
@@ -74,7 +74,7 @@ int open(const char *path, int oflags, ...)
   struct filelist  *list;
   FAR struct inode *inode;
   const char       *relpath = NULL;
-#ifdef CONFIG_FILE_MODE
+#if defined(CONFIG_FILE_MODE) || !defined(CONFIG_DISABLE_MOUNTPOINT)
   mode_t            mode = 0666;
 #endif
   int               ret;
diff --git a/lib/lib_htonl.c b/lib/lib_htonl.c
index 1cc5b6bcf5f57832db7b42ef03cb5228df0a863f..0f6cbf2242dbc651f02a6978c8ae7476f0b726e8 100644
--- a/lib/lib_htonl.c
+++ b/lib/lib_htonl.c
@@ -53,7 +53,10 @@ uint32 htonl(uint32 hl)
 #ifdef CONFIG_ENDIAN_BIG
   return hl;
 #else
-  return (uint32)htons((uint16)((hl) << 16)) | (uint32)htons((uint16)((hl) & 0xffff));
+  return (( (hl) >> 24) |
+          (((hl) >>  8) & 0x0000ff00) |
+          (((hl) <<  8) & 0x00ff0000) |
+	  ( (hl) << 24));
 #endif
 }
 
diff --git a/net/accept.c b/net/accept.c
index a348953f6e55e53b585fab0ea627b0f70772feb0..8c32eac3a888cc146e8a91f0bb5ffecc34ce18bb 100644
--- a/net/accept.c
+++ b/net/accept.c
@@ -52,6 +52,10 @@
 
 #include "net-internal.h"
 
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -76,6 +80,47 @@ struct accept_s
  * Private Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Function: accept_tcpsender
+ *
+ * Description:
+ *   Getting the sender's address from the UDP packet
+ *
+ * Parameters:
+ *   conn   - The newly accepted TCP connection
+ *   pstate - the recvfrom state structure 
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Running at the interrupt level
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_TCP
+static inline void accept_tcpsender(struct uip_conn *conn, struct accept_s *pstate)
+{
+ #ifdef CONFIG_NET_IPv6
+  FAR struct sockaddr_in6 *addr = pstate->acpt_addr;
+#else
+  FAR struct sockaddr_in *addr  = pstate->acpt_addr;
+#endif
+
+  if (addr)
+    {
+      addr->sin_family = AF_INET;
+      addr->sin_port   = conn->rport;
+
+#ifdef CONFIG_NET_IPv6
+      uip_ipaddr_copy(addr->sin_addr.s_addr, conn->ripaddr);
+#else
+      uip_ipaddr_copy(addr->sin_addr.s_addr, conn->ripaddr);
+#endif
+    }
+}
+#endif
+
 /****************************************************************************
  * Function: accept_interrupt
  *
@@ -102,7 +147,8 @@ static int accept_interrupt(struct uip_conn *listener, struct uip_conn *conn)
   if (pstate)
     {
       /* Get the connection address */
-#warning "need to return the address of the connection"
+
+      accept_tcpsender(conn, pstate);
 
       /* Save the connection structure */
 
diff --git a/net/recvfrom.c b/net/recvfrom.c
index 0d4e1bf30afcabf0e838ba935e410b1953b7eaf8..70a989c28d842bdbc00e6ea191259a1573ea64d5 100644
--- a/net/recvfrom.c
+++ b/net/recvfrom.c
@@ -59,6 +59,9 @@
 
 #define TCP_TIMEO 10  /* Deciseconds after data received before recv() returns */
 
+#define UDPBUF ((struct uip_udpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
+#define TCPBUF ((struct uip_tcpip_hdr *)&dev->d_buf[UIP_LLH_LEN])
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -67,14 +70,19 @@
 struct recvfrom_s
 {
 #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
-  FAR struct socket *rf_sock;       /* The parent socket structure */
-  uint32             rf_starttime;  /* rcv start time for determining timeout */
+  FAR struct socket       *rf_sock;      /* The parent socket structure */
+  uint32                   rf_starttime; /* rcv start time for determining timeout */
 #endif
-  sem_t              rf_sem;        /* Semaphore signals recv completion */
-  size_t             rf_buflen;     /* Length of receive buffer */
-  char              *rf_buffer;     /* Pointer to receive buffer */
-  size_t             rf_recvlen;    /* The received length */
-  int                rf_result;     /* OK on success, otherwise a negated errno. */
+  sem_t                    rf_sem;       /* Semaphore signals recv completion */
+  size_t                   rf_buflen;    /* Length of receive buffer */
+  char                    *rf_buffer;    /* Pointer to receive buffer */
+#ifdef CONFIG_NET_IPv6
+  FAR struct sockaddr_in6 *rf_from;      /* Address of sender */
+#else
+  FAR struct sockaddr_in  *rf_from;      /* Address of sender */
+#endif
+  size_t                   rf_recvlen;   /* The received length */
+  int                      rf_result;    /* OK:success, failure:negated errno */
 };
 #endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
 
@@ -286,6 +294,47 @@ static int recvfrom_timeout(struct recvfrom_s *pstate)
 #endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
 #endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
 
+/****************************************************************************
+ * Function: recvfrom_tcpsender
+ *
+ * Description:
+ *   Getting the sender's address from the UDP packet
+ *
+ * Parameters:
+ *   dev    - The device driver data structure
+ *   pstate - the recvfrom state structure 
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Running at the interrupt level
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_TCP
+static inline void recvfrom_tcpsender(struct uip_driver_s *dev, struct recvfrom_s *pstate)
+{
+#ifdef CONFIG_NET_IPv6
+  FAR struct sockaddr_in6 *infrom = pstate->rf_from;
+#else
+  FAR struct sockaddr_in *infrom  = pstate->rf_from;
+#endif
+
+  if (infrom)
+    {
+      infrom->sin_family = AF_INET;
+      infrom->sin_port   = TCPBUF->srcport;
+
+#ifdef CONFIG_NET_IPv6
+      uip_ipaddr_copy(infrom->sin_addr.s_addr, TCPBUF->srcipaddr);
+#else
+      uip_ipaddr_copy(infrom->sin_addr.s_addr, uip_ip4addr_conv(TCPBUF->srcipaddr));
+#endif
+    }
+}
+#endif
+
 /****************************************************************************
  * Function: recvfrom_tcpinterrupt
  *
@@ -326,6 +375,10 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev,
 
           recvfrom_newdata(dev, pstate);
 
+          /* Save the sender's address in the caller's 'from' location */
+
+          recvfrom_tcpsender(dev, pstate);
+
           /* If the user buffer has been filled, then we are finished. */
 
           if (pstate->rf_buflen == 0)
@@ -415,6 +468,47 @@ static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev,
 }
 #endif /* CONFIG_NET_TCP */
 
+/****************************************************************************
+ * Function: recvfrom_udpsender
+ *
+ * Description:
+ *   Getting the sender's address from the UDP packet
+ *
+ * Parameters:
+ *   dev    - The device driver data structure
+ *   pstate - the recvfrom state structure 
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Running at the interrupt level
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_UDP
+static inline void recvfrom_udpsender(struct uip_driver_s *dev, struct recvfrom_s *pstate)
+{
+#ifdef CONFIG_NET_IPv6
+  FAR struct sockaddr_in6 *infrom = pstate->rf_from;
+#else
+  FAR struct sockaddr_in *infrom  = pstate->rf_from;
+#endif
+
+  if (infrom)
+    {
+      infrom->sin_family = AF_INET;
+      infrom->sin_port   = UDPBUF->srcport;
+
+#ifdef CONFIG_NET_IPv6
+      uip_ipaddr_copy(infrom->sin_addr.s_addr, UDPBUF->srcipaddr);
+#else
+      uip_ipaddr_copy(infrom->sin_addr.s_addr, uip_ip4addr_conv(UDPBUF->srcipaddr));
+#endif
+    }
+}
+#endif
+
 /****************************************************************************
  * Function: recvfrom_udpinterrupt
  *
@@ -457,13 +551,17 @@ static void recvfrom_udpinterrupt(struct uip_driver_s *dev,
 
           /* We are finished. */
 
-          vdbg("UDP resume\n");
+          vdbg("UDP done\n");
 
           /* Don't allow any further UDP call backs. */
 
           conn->private = NULL;
           conn->event   = NULL;
 
+          /* Save the sender's address in the caller's 'from' location */
+
+          recvfrom_udpsender(dev, pstate);
+
           /* Wake up the waiting thread, returning the number of bytes
            * actually read.
            */
@@ -539,6 +637,11 @@ static void recvfrom_udpinterrupt(struct uip_driver_s *dev,
 
 #if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
 static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len,
+#ifdef CONFIG_NET_IPv6
+                          FAR struct sockaddr_in6 *infrom,
+#else
+                          FAR struct sockaddr_in *infrom,
+#endif
                           struct recvfrom_s *pstate)
 {
   /* Initialize the state structure. */
@@ -547,6 +650,7 @@ static void recvfrom_init(FAR struct socket *psock, FAR void *buf, size_t len,
   (void)sem_init(&pstate->rf_sem, 0, 0); /* Doesn't really fail */
   pstate->rf_buflen    = len;
   pstate->rf_buffer    = buf;
+  pstate->rf_from      = infrom;
 
 #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
   /* Set up the start time for the timeout */
@@ -630,13 +734,13 @@ static ssize_t recvfrom_result(int result, struct recvfrom_s *pstate)
 #ifdef CONFIG_NET_UDP
 #ifdef CONFIG_NET_IPv6
 static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
-                            FAR const struct sockaddr_in6 *infrom )
+                            FAR struct sockaddr_in6 *infrom )
 #else
 static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
-                            FAR const struct sockaddr_in *infrom )
+                            FAR struct sockaddr_in *infrom )
 #endif
 {
-  struct uip_udp_conn *udp_conn;
+  struct uip_udp_conn *udp_conn = (struct uip_udp_conn *)psock->s_conn;
   struct recvfrom_s    state;
   irqstate_t           save;
   int                  ret;
@@ -649,11 +753,11 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
    */
 
   save = irqsave();
-  recvfrom_init(psock, buf, len, &state);
+  recvfrom_init(psock, buf, len, infrom, &state);
 
-  /* Setup the UDP socket */
+  /* Setup the UDP remote connection */
 
-  ret = uip_udpconnect(psock->s_conn, NULL);
+  ret = uip_udpconnect(udp_conn, infrom);
   if (ret < 0)
     {
       irqrestore(save);
@@ -662,13 +766,12 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 
   /* Set up the callback in the connection */
 
-  udp_conn          = (struct uip_udp_conn *)psock->s_conn;
   udp_conn->private = (void*)&state;
   udp_conn->event   = recvfrom_udpinterrupt;
 
   /* Enable the UDP socket */
 
-  uip_udpenable(psock->s_conn);
+  uip_udpenable(udp_conn);
 
   /* Wait for either the receive to complete or for an error/timeout to occur.
    * NOTES:  (1) sem_wait will also terminate if a signal is received, (2)
@@ -680,12 +783,11 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 
   /* Make sure that no further interrupts are processed */
 
-  uip_udpdisable(psock->s_conn);
+  uip_udpdisable(udp_conn);
   udp_conn->private = NULL;
   udp_conn->event   = NULL;
   irqrestore(save);
 
-#warning "Needs to return server address"
   return recvfrom_result(ret, &state);
 }
 #endif /* CONFIG_NET_UDP */
@@ -713,10 +815,10 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 #ifdef CONFIG_NET_TCP
 #ifdef CONFIG_NET_IPv6
 static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
-                            FAR const struct sockaddr_in6 *infrom )
+                            FAR struct sockaddr_in6 *infrom )
 #else
 static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
-                            FAR const struct sockaddr_in *infrom )
+                            FAR struct sockaddr_in *infrom )
 #endif
 {
   struct uip_conn        *conn;
@@ -740,7 +842,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
    */
 
   save = irqsave();
-  recvfrom_init(psock, buf, len, &state);
+  recvfrom_init(psock, buf, len, infrom, &state);
 
 #if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0
 
@@ -776,7 +878,6 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
     }
   irqrestore(save);
 
-#warning "Needs to return server address"
   return recvfrom_result(ret, &state);
 }
 #endif /* CONFIG_NET_TCP */
@@ -837,16 +938,16 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
  *
  ****************************************************************************/
 
-ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, FAR struct sockaddr *from,
-                 FAR socklen_t *fromlen)
+ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
+                 FAR struct sockaddr *from, FAR socklen_t *fromlen)
 {
   FAR struct socket *psock;
 
 #if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
 #ifdef CONFIG_NET_IPv6
-  FAR const struct sockaddr_in6 *infrom = (const struct sockaddr_in6 *)from;
+  FAR struct sockaddr_in6 *infrom = (struct sockaddr_in6 *)from;
 #else
-  FAR const struct sockaddr_in *infrom = (const struct sockaddr_in *)from;
+  FAR struct sockaddr_in *infrom = (struct sockaddr_in *)from;
 #endif
 #endif
 
@@ -871,17 +972,19 @@ ssize_t recvfrom(int sockfd, FAR void *buf, size_t len, int flags, FAR struct so
       goto errout;
     }
 
-  /* If a 'from' address has been provided, verify that it is valid */
+  /* If a 'from' address has been provided, verify that it is large
+   * enough to hold this address family.
+   */
 
   if (from)
     {
 #ifdef CONFIG_NET_IPv6
-      if (from->sa_family != AF_INET6 || *fromlen < sizeof(struct sockaddr_in6))
+      if (*fromlen < sizeof(struct sockaddr_in6))
 #else
-      if (from->sa_family != AF_INET || *fromlen < sizeof(struct sockaddr_in))
+      if (*fromlen < sizeof(struct sockaddr_in))
 #endif
         {
-          err = EBADF;
+          err = EINVAL;
           goto errout;
         }
     }
diff --git a/net/uip/uip-udpconn.c b/net/uip/uip-udpconn.c
index e8116d71af2c020af9d61bfdbafe7f53763f9fbe..88d41cdc4298c26d6b443be098fdd6c778d26a2e 100644
--- a/net/uip/uip-udpconn.c
+++ b/net/uip/uip-udpconn.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * uip-udpconn.c
+ * net/uip/uip-udpconn.c
  *
  *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@@ -52,6 +52,8 @@
 #include <semaphore.h>
 #include <assert.h>
 #include <errno.h>
+#include <debug.h>
+
 #include <arch/irq.h>
 
 #include <net/uip/uipopt.h>
@@ -118,7 +120,7 @@ static inline void _uip_semtake(sem_t *sem)
  *
  ****************************************************************************/
 
-static struct uip_udp_conn *uip_find_conn( uint16 portno )
+static struct uip_udp_conn *uip_find_conn(uint16 portno)
 {
   int i;
 
@@ -234,6 +236,7 @@ void uip_udpfree(struct uip_udp_conn *conn)
 struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
 {
   struct uip_udp_conn *conn = (struct uip_udp_conn *)g_active_udp_connections.head;
+
   while (conn)
     {
       /* If the local UDP port is non-zero, the connection is considered
@@ -252,7 +255,6 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
              uiphdr_ipaddr_cmp(buf->srcipaddr, &conn->ripaddr)))
         {
           /* Matching connection found.. return a reference to it */
-
           break;
         }
 
@@ -261,7 +263,7 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
       conn = (struct uip_udp_conn *)conn->node.flink;
     }
 
-  return NULL;
+  return conn;
 }
 
 /****************************************************************************
@@ -307,13 +309,29 @@ int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
 #endif
 {
   int ret = -EADDRINUSE;
-  irqstate_t flags = irqsave();
-  if (!uip_find_conn(g_last_udp_port))
+  irqstate_t flags;
+
+  /* Never set lport to zero! */
+
+  if (addr->sin_port)
     {
-      conn->lport = HTONS(g_last_udp_port);
-      ret = OK;
+      /* Interrupts must be disabled while access the UDP connection list */
+
+      flags = irqsave();
+
+      /* Is any other UDP connection bound to this port? */
+
+      if (!uip_find_conn(addr->sin_port))
+        {
+          /* No.. then bind the socket to the port */
+
+          conn->lport = addr->sin_port;
+          ret = OK;
+        }
+
+      irqrestore(flags);
     }
-  irqrestore(flags);
+
   return ret;
 }
 
@@ -367,7 +385,7 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
               g_last_udp_port = 4096;
             }
         }
-      while (uip_find_conn(g_last_udp_port));
+      while (uip_find_conn(htons(g_last_udp_port)));
 
       /* Initialize and return the connection structure, bind it to the
        * port number
@@ -406,7 +424,7 @@ int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
 void uip_udpenable(struct uip_udp_conn *conn)
 {
   /* Add the connection structure to the active connectionlist. This list
-   * is modifiable from interrupt level, we we must diable interrupts to
+   * is modifiable from interrupt level, we we must disable interrupts to
    * access it safely.
    */
 
@@ -417,8 +435,8 @@ void uip_udpenable(struct uip_udp_conn *conn)
 
 void uip_udpdisable(struct uip_udp_conn *conn)
 {
-  /* Remove the connection structure to the active connectionlist. This list
-   * is modifiable from interrupt level, we we must diable interrupts to
+  /* Remove the connection structure from the active connectionlist. This list
+   * is modifiable from interrupt level, we we must disable interrupts to
    * access it safely.
    */