diff --git a/ChangeLog b/ChangeLog
index 41cdae75740f13eed775ab59cbe3b2b1ef6ce21f..6f7555625a29be204f1228dc540b050a74bba605 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -199,7 +199,7 @@
 	* examples/nsh/: Add cp, rm, rmdir, set, unset commands. echo will now print
 	  environment variables.
 
-0.2.9 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
+0.3.0 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 
 	* Imported uIP into the tree (see
 	   http://www.sics.se/~adam/uip/index.php/Main_Page)
@@ -209,4 +209,5 @@
         * Added recv() and recvfrom().
 	* Added getsockopt() and setsockopt()
 	* Documentation updated to address socket interfaces.
+	* Implemented receive timeouts via setsockopt(SO_RCVTIMEO).
 
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index bd511e94078f0c3d9fa131f795ea61157cb02632..5e997c711bab3e5e7ef555786f035bc3032fb662 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -632,7 +632,7 @@ Other memory:
 </table>
 
 <pre><ul>
-0.2.9 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
+0.3.0 2007-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
 
 	* Imported uIP into the tree (see
 	   http://www.sics.se/~adam/uip/index.php/Main_Page)
@@ -642,6 +642,7 @@ Other memory:
         * Added recv() and recvfrom().
 	* Added getsockopt() and setsockopt()
 	* Documentation updated to address socket interfaces.
+	* Implemented receive timeouts via setsockopt(SO_RCVTIMEO).
 </pre></ul>
 
 <table width ="100%">
diff --git a/include/net/uip/dhcpc.h b/include/net/uip/dhcpc.h
index d1950c9b8051855cc638c29ba09aebdb5b7c6930..13b717e439e2d868f4395b036259e8bd55e77af9 100644
--- a/include/net/uip/dhcpc.h
+++ b/include/net/uip/dhcpc.h
@@ -67,7 +67,7 @@ struct dhcpc_state
  ****************************************************************************/
 
 void *dhcpc_open(const void *mac_addr, int mac_len);
-int   dhcpc_request(void *handle, struct dhcpc_state *ds);
+int   dhcpc_request(void *handle, struct dhcpc_state *presult);
 void  dhcpc_close(void *handle);
 
 #endif /* NET_UIP_DHCP_H__ */
diff --git a/include/net/uip/resolv.h b/include/net/uip/resolv.h
index 1f22012b557ccde5b37a57127029a58a4666fbfb..c9547f13edc321e9389ff71982d37d9bcc2fa4dc 100644
--- a/include/net/uip/resolv.h
+++ b/include/net/uip/resolv.h
@@ -54,7 +54,7 @@ EXTERN void resolv_getserver(const struct sockaddr_in6 *dnsserver);
 EXTERN int  resolv_query(const char *name, struct sockaddr_in6 *addr);
 #else
 EXTERN void resolv_conf(const struct sockaddr_in *dnsserver);
-EXTERN void resolv_getserver(const struct sockaddr_in *dnsserver);
+EXTERN void resolv_getserver(struct sockaddr_in *dnsserver);
 EXTERN int  resolv_query(const char *name, struct sockaddr_in *addr);
 #endif
 
diff --git a/include/net/uip/uip.h b/include/net/uip/uip.h
index 004c0ec6e5ecf89a95f32b1f19792cc15c14969c..fe2088b2cad00e1f67b198216dad9314ff132cb6 100644
--- a/include/net/uip/uip.h
+++ b/include/net/uip/uip.h
@@ -1126,8 +1126,7 @@ extern int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *a
 
 /* This function is called user code to set up the wait */
 
-#define uip_event_wait(waitflags) uip_event_timedwait(waitflags,0)
-extern int uip_event_timedwait(uint16 waitflags, int timeout);
+extern int uip_event_wait(uint16 waitflags);
 
 /* This function is called from uip_interrupt() to wake up any
  * waiting threads/tasks.
diff --git a/net/recvfrom.c b/net/recvfrom.c
index d6d8b4aca3a3ebc1aea2635810bb75ea7dced075..d008262bf81b1a9350218d2028545a6811277092 100644
--- a/net/recvfrom.c
+++ b/net/recvfrom.c
@@ -58,9 +58,15 @@
 
 struct recvfrom_s
 {
-  sem_t   rf_sem;
-  uint16  rf_buflen;
-  char  * rf_buffer;
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+  FAR struct socket *rf_sock        /* The parent socket structure */
+#endif
+  sem_t              rf_sem;        /* Semaphore signals recv completion */
+  sint16             rf_buflen;     /* Length of receive buffer (error if <0) */
+  char              *rf_buffer;     /* Pointer to receive buffer */
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+  uint32             rf_starttime;  /* rcv start time for determining timeout */
+#endif
 };
 
 /****************************************************************************
@@ -72,38 +78,61 @@ void recvfrom_interrupt(void *private)
   struct recvfrom_s *pstate = (struct recvfrom_s *)private;
   size_t recvlen;
 
-  /* If new data is available and we are correctly intialized, then complete
-   * the read action.  We could also check for POLL events here in order to
-   * implement SO_RECVTIMEO.
-   */
+  /* 'private' might be null in some race conditions (?) */
 
-  if (uip_newdata() && private)
+  if (pstate)
     {
-      /* Get the length of the data to return */
-      if (uip_len > pstate-> rf_buflen)
-        {
-          recvlen = pstate-> rf_buflen;
-        }
-      else
+      /* If new data is available, then complete the read action. */
+
+      if (uip_newdata())
         {
-          recvlen = uip_len;
-        }
+          /* Get the length of the data to return */
+          if (uip_len > pstate-> rf_buflen)
+            {
+              recvlen = pstate-> rf_buflen;
+            }
+          else
+            {
+            recvlen = uip_len;
+            }
+
+          /* Copy the appdate into the user data and send it */
 
-      /* Copy the appdate into the user data and send it */
+          memcpy(pstate->rf_buffer, uip_appdata, recvlen);
 
-      memcpy(pstate->rf_buffer, uip_appdata, recvlen);
+          /* Don't allow any further call backs. */
 
-      /* Don't allow any further call backs. */
+          uip_conn->private = NULL;
+          uip_conn->callback = NULL;
 
-      uip_conn->private = NULL;
-      uip_conn->callback = NULL;
+          /* Wake up the waiting thread, returning the number of bytes
+           * actually read.
+           */
 
-      /* Wake up the waiting thread, returning the number of bytes
-       * actually read.
+          pstate->rf_buflen = recvlen;
+          sem_post(&pstate-> rf_sem);
+        }
+
+      /* No data has been received.  If this is a poll event, then check
+       * for a timeout.
        */
 
-      pstate->rf_buflen = recvlen;
-      sem_post(&pstate-> rf_sem);
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+      else if (uip_newdata() && pstate->rf_sock)
+        {
+          /* Check if SO_RCVTIMEO has been selected for this socket */
+
+          uint rcvtimeo = ;
+          if (pstate->rf_sock->s_rcvtimeo)
+            {
+              /* Yes.. Check if the timeout has elapsed */
+
+              if (net_timeo(pstate->rf_starttime, pstate->rf_sock->s_rcvtimeo))
+                {
+                }
+            }
+        }
+#endif
     }
 }
 
@@ -213,6 +242,12 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *
   state. rf_buflen = len;
   state. rf_buffer = buf;
 
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+  /* Set up the start time for the timeout */
+
+  state.rf_starttime = g_system_timer;
+#endif
+
   /* Setup the UDP socket */
 
   ret = uip_udpconnect(psock->s_conn, NULL);
@@ -244,6 +279,20 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *
   sem_destroy(&state. rf_sem);
   irqrestore(save);
 
+  /* Check for a timeout.  Errors are signaled by negative errno values
+   * for the rcv length
+   */
+
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+  if (state.rf_buflen < 0)
+    {
+      /* Return EGAIN on a timeout */
+
+      err = -state.rf_buflen;
+      goto errout;
+    }
+#endif
+
   /* If sem_wait failed, then we were probably reawakened by a signal. In
    * this case, sem_wait will have set errno appropriately.
    */
@@ -253,8 +302,9 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *
       return ERROR;
     }
 
-  return state.rf_buflen;
 #warning "Needs to return server address"
+  return state.rf_buflen;
+
 #else
   err = ENOSYS;
 #endif
diff --git a/net/sendto.c b/net/sendto.c
index 1917ebf58d8b434bab4db12191220beb344226de..eef1a31b4ed35afa87d488820dd8344eca9a8cc2 100644
--- a/net/sendto.c
+++ b/net/sendto.c
@@ -58,9 +58,9 @@
 
 struct sendto_s
 {
-  sem_t       st_sem;
-  uint16      st_buflen;
-  const char *st_buffer;
+  sem_t       st_sem;        /* Semaphore signals sendto completion */
+  uint16      st_buflen;     /* Length of send buffer (error if <0) */
+  const char *st_buffer;     /* Pointer to send buffer */
 };
 
 /****************************************************************************
diff --git a/net/uip/uip-wait.c b/net/uip/uip-wait.c
index c7bf0a1bb27e62cadc74f37b483d9038156dc696..14775f54e396f292b588925e49fe81ffa5dddf0f 100644
--- a/net/uip/uip-wait.c
+++ b/net/uip/uip-wait.c
@@ -39,7 +39,6 @@
 
 #include <nuttx/config.h>
 #include <semaphore.h>
-#include <wdog.h>
 #include <arch/irq.h>
 #include <net/uip/uip.h>
 
@@ -63,31 +62,18 @@ static uint16 uip_waitflags = 0;     /* UIP flags to wait for */
  * Private Functions
  ************************************************************/
 
-/* Called from the timer interrupt handler when a event wait
- * watchdog expires.
- */
-
-static void uip_event_timeout(int argc, uint32 itcb, ...)
-{
-  irqstate_t save = irqsave();  /* Should not be necessary */
-  uip_flags |= UIP_APPTIMEOUT;  /* Set software timeout event */
-  uip_event_signal();           /* Signal the waiting thread/task */
-  irqrestore(save);             /* Restore interrupts */
-}
-
 /************************************************************
  * Global Functions
  ************************************************************/
 
 /* This function is called user code to set up the wait */
 
-int uip_event_timedwait(uint16 waitflags, int timeout)
+int uip_event_wait(uint16 waitflags)
 {
   /* Prevent conflicts with the interrupt level operation of
    * uip_event_signal().
    */
   irqstate_t save = irqsave();
-  WDOG_ID wdog;
 
   /* At present, we support only a single waiter. If uip_waitflags
    * is non-zero on entry, then there is a problem.
@@ -111,52 +97,17 @@ int uip_event_timedwait(uint16 waitflags, int timeout)
 
       uip_waitflags = waitflags;
 
-      /* Was a timeut requested as well? */
-
-      if (timeout)
-        {
-          /* Yes, then set the application timeout event as well */
-
-          uip_waitflags |= UIP_APPTIMEOUT;
-
-          /* Create a watchdog */
-
-          wdog = wd_create();
-          if (!wdog)
-            {
-              goto errout_with_irqdisabled;
-            }
-
-          /* Start the watchdog */
-
-          wd_start(wdog, timeout, (wdentry_t)uip_event_timeout, 0);
-        }
-
-      /* Wait for the event (or timeout) to occur */
+      /* Wait for the event to occur */
 
       if (sem_wait(&uip_waitsem) != 0)
         {
-          goto errout_with_watchdog;
-        }
-
-      /* We no longer need the watchdog */
-
-      if (wdog)
-        {
-          wd_delete(wdog);
-          wdog = NULL;
+          goto errout_with_irqdisabled;
         }
     }
 
     irqrestore(save);
     return OK;
 
-errout_with_watchdog:
-  if (wdog)
-    {
-      wd_delete(wdog);
-    }
-
 errout_with_irqdisabled:
   irqrestore(save);
   return ERROR;
diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c
index 1e11ae079c0783853c1e6284ccb4c16cc771dd6c..9c90fb8a8c3dc54f3c47b66dd5c2ea3f662062b1 100644
--- a/netutils/dhcpc/dhcpc.c
+++ b/netutils/dhcpc/dhcpc.c
@@ -43,13 +43,14 @@
  ****************************************************************************/
 
 #include <sys/types.h>
+#include <sys/socket.h>
+
 #include <stdlib.h>
 #include <string.h>
-#include <pthread.h>
-#include <semaphore.h>
+#include <unistd.h>
 #include <time.h>
+#include <errno.h>
 #include <debug.h>
-#include <sys/socket.h>
 
 #include <net/uip/uip.h>
 #include <net/uip/dhcpc.h>
@@ -58,10 +59,6 @@
  * Definitions
  ****************************************************************************/
 
-/* CLK_TCK is the frequency of the system clock (typically 100Hz) */
-
-#define CLOCK_SECOND            CLK_TCK
-
 #define STATE_INITIAL           0
 #define STATE_SENDING           1
 #define STATE_OFFER_RECEIVED    2
@@ -96,6 +93,8 @@
 #define DHCP_OPTION_REQ_LIST    55
 #define DHCP_OPTION_END         255
 
+#define BUFFER_SIZE             256
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -103,12 +102,10 @@
 struct dhcpc_state_internal
 {
   struct uip_udp_conn *conn;
-  struct dhcpc_state  *result;
   const void            *mac_addr;
   int                    mac_len;
   int                    sockfd;
-  uint16                 ticks;
-  char                   state;
+  char                   buffer[256];
 };
 
 struct dhcp_msg
@@ -183,28 +180,28 @@ static uint8 *add_end(uint8 *optptr)
   return optptr;
 }
 
-static void create_msg(struct dhcpc_state_internal *pdhcpc, struct dhcp_msg *m)
+static void create_msg(struct dhcpc_state_internal *pdhcpc, struct dhcp_msg *pmsg)
 {
-  m->op    = DHCP_REQUEST;
-  m->htype = DHCP_HTYPE_ETHERNET;
-  m->hlen  = pdhcpc->mac_len;
-  m->hops  = 0;
-  memcpy(m->xid, xid, sizeof(m->xid));
-  m->secs  = 0;
-  m->flags = HTONS(BOOTP_BROADCAST); /*  Broadcast bit. */
-  /*  uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/
-  memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr));
-  memset(m->yiaddr, 0, sizeof(m->yiaddr));
-  memset(m->siaddr, 0, sizeof(m->siaddr));
-  memset(m->giaddr, 0, sizeof(m->giaddr));
-  memcpy(m->chaddr, pdhcpc->mac_addr, pdhcpc->mac_len);
-  memset(&m->chaddr[pdhcpc->mac_len], 0, sizeof(m->chaddr) - pdhcpc->mac_len);
+  pmsg->op    = DHCP_REQUEST;
+  pmsg->htype = DHCP_HTYPE_ETHERNET;
+  pmsg->hlen  = pdhcpc->mac_len;
+  pmsg->hops  = 0;
+  memcpy(pmsg->xid, xid, sizeof(pmsg->xid));
+  pmsg->secs  = 0;
+  pmsg->flags = HTONS(BOOTP_BROADCAST); /*  Broadcast bit. */
+  /*  uip_ipaddr_copy(pmsg->ciaddr, uip_hostaddr);*/
+  memcpy(pmsg->ciaddr, uip_hostaddr, sizeof(pmsg->ciaddr));
+  memset(pmsg->yiaddr, 0, sizeof(pmsg->yiaddr));
+  memset(pmsg->siaddr, 0, sizeof(pmsg->siaddr));
+  memset(pmsg->giaddr, 0, sizeof(pmsg->giaddr));
+  memcpy(pmsg->chaddr, pdhcpc->mac_addr, pdhcpc->mac_len);
+  memset(&pmsg->chaddr[pdhcpc->mac_len], 0, sizeof(pmsg->chaddr) - pdhcpc->mac_len);
 #ifndef CONFIG_NET_DHCP_LIGHT
-  memset(m->sname, 0, sizeof(m->sname));
-  memset(m->file, 0, sizeof(m->file));
+  memset(pmsg->sname, 0, sizeof(pmsg->sname));
+  memset(pmsg->file, 0, sizeof(pmsg->file));
 #endif
 
-  memcpy(m->options, magic_cookie, sizeof(magic_cookie));
+  memcpy(pmsg->options, magic_cookie, sizeof(magic_cookie));
 }
 
 static int send_discover(struct dhcpc_state_internal *pdhcpc)
@@ -228,7 +225,7 @@ static int send_discover(struct dhcpc_state_internal *pdhcpc)
                 (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
 }
 
-static int send_request(struct dhcpc_state_internal *pdhcpc)
+static int send_request(struct dhcpc_state_internal *pdhcpc, struct dhcpc_state *presult)
 {
   struct dhcp_msg msg;
   struct sockaddr_in addr;
@@ -237,8 +234,8 @@ static int send_request(struct dhcpc_state_internal *pdhcpc)
 
   create_msg(pdhcpc, &msg);
   pend = add_msg_type(&msg.options[4], DHCPREQUEST);
-  pend = add_server_id(pdhcpc->result, pend);
-  pend = add_req_ipaddr(pdhcpc->result, pend);
+  pend = add_server_id(presult, pend);
+  pend = add_req_ipaddr(presult, pend);
   pend = add_end(pend);
   len  = pend - (uint8*)&msg;
 
@@ -286,105 +283,20 @@ static uint8 parse_options(struct dhcpc_state *presult, uint8 *optptr, int len)
   return type;
 }
 
-static uint8 parse_msg(struct dhcpc_state_internal *pdhcpc)
+static uint8 parse_msg(struct dhcpc_state_internal *pdhcpc, int buflen, struct dhcpc_state *presult)
 {
-  struct dhcpc_state *presult = pdhcpc->result;
-  struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+  struct dhcp_msg *pbuffer = (struct dhcp_msg *)pdhcpc->buffer;
 
-  if (m->op == DHCP_REPLY &&
-      memcmp(m->xid, xid, sizeof(xid)) == 0 &&
-      memcmp(m->chaddr, pdhcpc->mac_addr, pdhcpc->mac_len) == 0)
+  if (pbuffer->op == DHCP_REPLY &&
+      memcmp(pbuffer->xid, xid, sizeof(xid)) == 0 &&
+      memcmp(pbuffer->chaddr, pdhcpc->mac_addr, pdhcpc->mac_len) == 0)
     {
-      memcpy(presult->ipaddr, m->yiaddr, 4);
-      return parse_options(presult, &m->options[4], uip_datalen());
+      memcpy(presult->ipaddr, pbuffer->yiaddr, 4);
+      return parse_options(presult, &pbuffer->options[4], buflen);
     }
   return 0;
 }
 
-static int handle_dhcp(struct dhcpc_state_internal *pdhcpc)
-{
-  struct dhcpc_state *presult = pdhcpc->result;
-
-restart:
-  pdhcpc->state = STATE_SENDING;
-  pdhcpc->ticks = CLOCK_SECOND;
-
-  do
-    {
-      /* Send the command */
-
-      send_discover(pdhcpc);
-
-      /* Set up a watchdog to timeout the recvfrom */
-#warning need to implement timeout;
-
-      /* Wait for the response */
-#warning need to use recvfrom
-      uip_event_timedwait(UIP_NEWDATA, CLOCK_SECOND);
-
-      if (uip_newdata() && parse_msg(pdhcpc) == DHCPOFFER)
-        {
-          pdhcpc->state = STATE_OFFER_RECEIVED;
-          break;
-        }
-
-      if (pdhcpc->ticks < CLOCK_SECOND * 60)
-        {
-          pdhcpc->ticks *= 2;
-        }
-    }
-  while(pdhcpc->state != STATE_OFFER_RECEIVED);
-
-  pdhcpc->ticks = CLOCK_SECOND;
-
-  do
-    {
-      /* Send the request */
-
-      send_request(pdhcpc);
-
-      /* Set up a watchdog to timeout the recvfrom */
-#warning need to implement timeout;
-
-      /* Then wait to received the response */
-#warning need to use recvfrom
-
-      uip_event_timedwait(UIP_NEWDATA, CLOCK_SECOND);
-
-      if (uip_newdata() && parse_msg(pdhcpc) == DHCPACK)
-        {
-          pdhcpc->state = STATE_CONFIG_RECEIVED;
-          break;
-        }
-
-      if (pdhcpc->ticks <= CLOCK_SECOND * 10)
-        {
-          pdhcpc->ticks += CLOCK_SECOND;
-        }
-      else
-        {
-          goto restart;
-        }
-    }
-  while(pdhcpc->state != STATE_CONFIG_RECEIVED);
-
-  dbg("Got IP address %d.%d.%d.%d\n",
-      uip_ipaddr1(presult->ipaddr), uip_ipaddr2(presult->ipaddr),
-      uip_ipaddr3(presult->ipaddr), uip_ipaddr4(presult->ipaddr));
-  dbg("Got netmask %d.%d.%d.%d\n",
-      uip_ipaddr1(presult->netmask), uip_ipaddr2(presult->netmask),
-      uip_ipaddr3(presult->netmask), uip_ipaddr4(presult->netmask));
-  dbg("Got DNS server %d.%d.%d.%d\n",
-      uip_ipaddr1(presult->dnsaddr), uip_ipaddr2(presult->dnsaddr),
-      uip_ipaddr3(presult->dnsaddr), uip_ipaddr4(presult->dnsaddr));
-  dbg("Got default router %d.%d.%d.%d\n",
-      uip_ipaddr1(presult->default_router), uip_ipaddr2(presult->default_router),
-      uip_ipaddr3(presult->default_router), uip_ipaddr4(presult->default_router));
-  dbg("Lease expires in %ld seconds\n",
-      ntohs(presult->lease_time[0])*65536ul + ntohs(presult->lease_time[1]));
-  return OK;
-}
-
 /****************************************************************************
  * Global Functions
  ****************************************************************************/
@@ -393,6 +305,7 @@ void *dhcpc_open(const void *mac_addr, int mac_len)
 {
   struct dhcpc_state_internal *pdhcpc;
   struct sockaddr_in addr;
+  struct timeval tv;
 
   /* Allocate an internal DHCP structure */
 
@@ -404,7 +317,6 @@ void *dhcpc_open(const void *mac_addr, int mac_len)
       memset(pdhcpc, 0, sizeof(struct dhcpc_state_internal));
       pdhcpc->mac_addr = mac_addr;
       pdhcpc->mac_len  = mac_len;
-      pdhcpc->state    = STATE_INITIAL;
 
       /* Create a UDP socket */
 
@@ -412,23 +324,34 @@ void *dhcpc_open(const void *mac_addr, int mac_len)
       if (pdhcpc->sockfd < 0)
         {
           free(pdhcpc);
-          pdhcpc = NULL;
+          return NULL;
         }
-      else
+
+      /* bind the socket */
+
+      addr.sin_family      = AF_INET;
+      addr.sin_port        = HTONS(DHCPC_CLIENT_PORT);
+      addr.sin_addr.s_addr = INADDR_ANY;
+
+      if (bind(pdhcpc->sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0)
         {
-          /* bind the socket */
+          close(pdhcpc->sockfd);
+          free(pdhcpc);
+          return NULL;
+        }
 
-          addr.sin_family      = AF_INET;
-          addr.sin_port        = HTONS(DHCPC_CLIENT_PORT);
-          addr.sin_addr.s_addr = INADDR_ANY;
+      /* Configure for read timeouts */
 
-          if (bind(pdhcpc->sockfd, &addr, sizeof(struct sockaddr_in)) < 0)
-            {
-              free(pdhcpc);
-              pdhcpc = NULL;
-            }
+      tv.tv_sec  = 30;
+      tv.tv_usec = 0;
+      if (setsockopt(pdhcpc->sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0)
+        {
+          close(pdhcpc->sockfd);
+          free(pdhcpc);
+          return NULL;
         }
     }
+
   return (void*)pdhcpc;
 }
 
@@ -441,17 +364,89 @@ void dhcpc_close(void *handle)
     }
 }
 
-int dhcpc_request(void *handle, struct dhcpc_state *ds)
+int dhcpc_request(void *handle, struct dhcpc_state *presult)
 {
   struct dhcpc_state_internal *pdhcpc = (struct dhcpc_state_internal *)handle;
-  uint16 ipaddr[2];
+  ssize_t result;
+  int state;
 
-  if (pdhcpc->state == STATE_INITIAL)
+  /* Loop until we receive the offer */
+
+  do
     {
-      uip_ipaddr(ipaddr, 0,0,0,0);
-      uip_sethostaddr(ipaddr);
+      state = STATE_SENDING;
+
+      do
+        {
+          /* Send the command */
+
+          if (send_discover(pdhcpc) < 0)
+            {
+              return ERROR;
+            }
+
+          /* Get the response */
+
+          result = recv(pdhcpc->sockfd, pdhcpc->buffer, BUFFER_SIZE, 0);
+          if (result >= 0)
+            {
+              if (parse_msg(pdhcpc, result, presult) == DHCPOFFER)
+                {
+                  state = STATE_OFFER_RECEIVED;
+                }
+            }
+          else if (*get_errno_ptr() != EAGAIN)
+            {
+              /* An error other than a timeout was received */
+
+              return ERROR;
+            }
+        }
+      while (state != STATE_OFFER_RECEIVED);
+
+      do
+        {
+          /* Send the request */
+
+          if (send_request(pdhcpc, presult) < 0)
+            {
+              return ERROR;
+            }
+
+          /* Get the response */
+
+          result = recv(pdhcpc->sockfd, pdhcpc->buffer, BUFFER_SIZE, 0);
+          if (result >= 0)
+            {
+              if (parse_msg(pdhcpc, result, presult) == DHCPACK)
+                {
+                  state = STATE_CONFIG_RECEIVED;
+                }
+            }
+          else if (*get_errno_ptr() != EAGAIN)
+            {
+              /* An error other than a timeout was received */
+
+              return ERROR;
+            }
+        }
+      while (state != STATE_CONFIG_RECEIVED);
     }
+  while(state != STATE_CONFIG_RECEIVED);
 
-  pdhcpc->result = ds;
-  return handle_dhcp(pdhcpc);
+  dbg("Got IP address %d.%d.%d.%d\n",
+      uip_ipaddr1(presult->ipaddr), uip_ipaddr2(presult->ipaddr),
+      uip_ipaddr3(presult->ipaddr), uip_ipaddr4(presult->ipaddr));
+  dbg("Got netmask %d.%d.%d.%d\n",
+      uip_ipaddr1(presult->netmask), uip_ipaddr2(presult->netmask),
+      uip_ipaddr3(presult->netmask), uip_ipaddr4(presult->netmask));
+  dbg("Got DNS server %d.%d.%d.%d\n",
+      uip_ipaddr1(presult->dnsaddr), uip_ipaddr2(presult->dnsaddr),
+      uip_ipaddr3(presult->dnsaddr), uip_ipaddr4(presult->dnsaddr));
+  dbg("Got default router %d.%d.%d.%d\n",
+      uip_ipaddr1(presult->default_router), uip_ipaddr2(presult->default_router),
+      uip_ipaddr3(presult->default_router), uip_ipaddr4(presult->default_router));
+  dbg("Lease expires in %ld seconds\n",
+      ntohs(presult->lease_time[0])*65536ul + ntohs(presult->lease_time[1]));
+  return OK;
 }
diff --git a/netutils/resolv/resolv.c b/netutils/resolv/resolv.c
index b6c861e517e314084b8bee319167d5e8b854c6c0..b318e551eea46e196c7240b6c165b5dd14d22b18 100644
--- a/netutils/resolv/resolv.c
+++ b/netutils/resolv/resolv.c
@@ -52,6 +52,9 @@
 
 #include <sys/types.h>
 #include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
 #include <debug.h>
 
 #include <sys/socket.h>
@@ -341,10 +344,29 @@ int resolv_query(const char *name, struct sockaddr_in6 *addr)
 int resolv_query(const char *name, struct sockaddr_in *addr)
 #endif
 {
-  int ret = send_query(name, addr);
-  if (ret == 0)
+  int retries;
+  int ret;
+
+  // Loop while receive timeout errors occur and there are remaining retries
+  for (retries = 0; retries < 3; retries++)
     {
+      if (send_query(name, addr) < 0)
+        {
+          return ERROR;
+        }
+
       ret = recv_response(addr);
+      if (ret >= 0)
+        {
+          /* Response received successfully */
+          return OK;
+        }
+
+      else if (*get_errno_ptr() != EAGAIN)
+        {
+          /* Some failure other than receive timeout occurred */
+          return ERROR;
+        }
     }
   return ret;
 }
@@ -352,9 +374,9 @@ int resolv_query(const char *name, struct sockaddr_in *addr)
 /* Obtain the currently configured DNS server. */
 
 #ifdef CONFIG_NET_IPv6
-void resolv_getserver(const struct sockaddr_in6 *dnsserver)
+void resolv_getserver(struct sockaddr_in6 *dnsserver)
 #else
-void resolv_getserver(const struct sockaddr_in *dnsserver)
+void resolv_getserver(struct sockaddr_in *dnsserver)
 #endif
 {
   memcpy(dnsserver, &g_dnsserver, ADDRLEN);
@@ -375,10 +397,23 @@ void resolv_conf(const struct sockaddr_in *dnsserver)
 
 int resolv_init(void)
 {
+  struct timeval tv;
   g_sockfd = socket(PF_INET, SOCK_DGRAM, 0);
   if (g_sockfd < 0)
     {
       return ERROR;
     }
+
+  /* Set up a receive timeout */
+
+  tv.tv_sec  = 30;
+  tv.tv_usec = 0;
+  if (setsockopt(g_sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0)
+    {
+      close(g_sockfd);
+      g_sockfd = -1;
+      return ERROR;
+    }
+
   return OK;
 }