diff --git a/ChangeLog b/ChangeLog
index b4c345e501802b062db95941f69c01e97b8d5247..2541ff5da9b5f047e7a6d2d5aaa6b2c9e1a73188 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -205,4 +205,5 @@
 	   http://www.sics.se/~adam/uip/index.php/Main_Page)
 	* Adding socket(), bind(), connect()
 	* Added snprintf()
-
+	* Added send() and sendto(); integrate write() and close() with socket descriptors.
+        * Added recv() and recvfrom().
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index ef9aa49f7de02fdcd79b40124ba34de385966c99..e42714ad255fc3379cbb0589ade5ec894d266e52 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -639,6 +639,8 @@ Other memory:
 	   http://www.sics.se/~adam/uip/index.php/Main_Page)
 	* Adding socket(), bind(), connect()
 	* Added snprintf()
+        * Added send() and sendto(); integrate write() and close() with socket descriptors.
+        * Added recv() and recvfrom().
 </pre></ul>
 
 <table width ="100%">
diff --git a/examples/uip/main.c b/examples/uip/main.c
index 367e7e1c190bed0be4ae1e0db8348c12bcf285ef..d7cfc6bb224d3454b31a5d5d2a4a847bf364c0e8 100644
--- a/examples/uip/main.c
+++ b/examples/uip/main.c
@@ -31,7 +31,7 @@
  *
  * This file is part of the uIP TCP/IP stack.
  *
- * $Id: main.c,v 1.3 2007-09-01 18:06:12 patacongo Exp $
+ * $Id: main.c,v 1.4 2007-09-03 20:34:43 patacongo Exp $
  *
  */
 
@@ -84,6 +84,7 @@ int user_start(int argc, char *argv[])
 #elif defined(CONFIG_EXAMPLE_UIP_TELNETD)
   telnetd_init();
 #elif defined(CONFIG_EXAMPLE_UIP_DHCPC)
+  resolv_init();
   handle = dhcpc_open(&mac, 6);
   if (handle)
     {
@@ -126,21 +127,6 @@ void uip_log(char *m)
   printf("uIP log message: %s\n", m);
 }
 
-void resolv_found(char *name, uint16 *ipaddr)
-{
-  if (ipaddr == NULL)
-    {
-      printf("Host '%s' not found.\n", name);
-    }
-  else
-    {
-      printf("Found name '%s' = %d.%d.%d.%d\n", name,
-      htons(ipaddr[0]) >> 8, htons(ipaddr[0]) & 0xff,
-      htons(ipaddr[1]) >> 8, htons(ipaddr[1]) & 0xff);
-      /* webclient_get("www.sics.se", 80, "/~adam/uip");*/
-    }
-}
-
 void webclient_closed(void)
 {
   printf("Webclient: connection closed\n");
diff --git a/fs/fs_close.c b/fs/fs_close.c
index a704d1d5ec67307ad3c56a61c2bfbf1db4d9ed98..5a63ba6a909a2aea88dac42e6646908b07d44a08 100644
--- a/fs/fs_close.c
+++ b/fs/fs_close.c
@@ -43,70 +43,120 @@
 #include <sched.h>
 #include <errno.h>
 #include <nuttx/fs.h>
+
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+# include <nuttx/net.h>
+#endif
+
 #include "fs_internal.h"
 
 /****************************************************************************
  * Global Functions
  ****************************************************************************/
 
+/****************************************************************************
+ * Function: close
+ *
+ * Description:
+ *   close() closes a file descriptor, so that it no longer refers to any
+ *   file and may be reused. Any record locks (see fcntl(2)) held on the file
+ *   it was associated with, and owned by the process, are removed (regardless
+ *   of the file descriptor that was used to obtain the lock).
+ *
+ *   If fd is the last copy of a particular file descriptor the resources
+ *   associated with it are freed; if the descriptor was the last reference
+ *   to a file which has been removed using unlink(2) the file is deleted.
+ *
+ * Parameters:
+ *   fd   file descriptor to close
+ *
+ * Returned Value:
+ *   0 on success; -1 on error with errno set appropriately.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
 int close(int fd)
 {
   FAR struct filelist *list;
+  FAR struct inode *inode;
+  int err;
+
+  /* Did we get a valid file descriptor? */
+
+  if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
+    {
+      /* Close a socket descriptor */
 
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+      if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
+        {
+          return net_close(fd);
+        }
+      else
+#endif
+        {
+          err = EBADF;
+          goto errout;
+        }
+    }
   /* Get the thread-specific file list */
 
   list = sched_getfiles();
   if (!list)
     {
-      *get_errno_ptr() = EMFILE;
-      return ERROR;
+      err = EMFILE;
+      goto errout;
     }
 
-  if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS)
+  /* If the file was properly opened, there should be an inode assigned */
+
+  inode = list->fl_files[fd].f_inode;
+  if (!inode)
+   {
+     err = EBADF;
+     goto errout;
+   }
+
+  /* Close the driver or mountpoint.  NOTES: (1) there is no
+   * exclusion mechanism here , the driver or mountpoint must be
+   * able to handle concurrent operations internally, (2) The driver
+   * may have been opened numerous times (for different file
+   * descriptors) and must also handle being closed numerous times.
+   * (3) for the case of the mountpoint, we depend on the close
+   * methods bing identical in signature and position in the operations
+   * vtable.
+   */
+
+  if (inode->u.i_ops && inode->u.i_ops->close)
     {
-      FAR struct inode *inode = list->fl_files[fd].f_inode;
-      if (inode)
+      /* Perform the close operation (by the driver) */
+
+      int ret = inode->u.i_ops->close(&list->fl_files[fd]);
+      if (ret < 0)
         {
-          int ret = OK;
-
-          /* Close the driver or mountpoint.  NOTES: (1) there is no
-           * exclusion mechanism here , the driver or mountpoint must be
-           * able to handle concurrent operations internally, (2) The driver
-           * may have been opened numerous times (for different file
-           * descriptors) and must also handle being closed numerous times.
-           * (3) for the case of the mountpoint, we depend on the close
-           *  methods bing identical in signature and position in the operations
-           * vtable.
-           */
-
-          if (inode->u.i_ops && inode->u.i_ops->close)
-            {
-              /* Perform the close operation (by the driver) */
-
-              int status = inode->u.i_ops->close(&list->fl_files[fd]);
-              if (status < 0)
-                {
-                  /* An error occurred while closing the driver */
-
-                  *get_errno_ptr() = -status;
-                  ret = ERROR;
-                }
-            }
-
-          /* Release the file descriptor */
-
-          files_release(fd);
-
-          /* Decrement the reference count on the inode. This may remove the inode and
-           * eliminate the name from the namespace
-           */
-
-          inode_release(inode);
-          return ret;
+          /* An error occurred while closing the driver */
+
+          err = -ret;
+          goto errout;
         }
     }
 
-  *get_errno_ptr() = EBADF;
+  /* Release the file descriptor */
+
+  files_release(fd);
+
+  /* Decrement the reference count on the inode. This may remove the inode and
+   * eliminate the name from the namespace
+   */
+
+  inode_release(inode);
+
+  return OK;
+
+errout:
+  *get_errno_ptr() = err;
   return ERROR;
 }
 
diff --git a/fs/fs_write.c b/fs/fs_write.c
index 60a6b829045f14b47dc4c93d517a11dfedb04159..7de7898f446a7380d87da7e27554f5fd4e9db6c9 100644
--- a/fs/fs_write.c
+++ b/fs/fs_write.c
@@ -47,48 +47,134 @@
 #include <fcntl.h>
 #include <sched.h>
 #include <errno.h>
+
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+# include <sys/socket.h>
+#endif
+
 #include "fs_internal.h"
 
 /************************************************************
  * Global Functions
  ************************************************************/
 
+/****************************************************************************
+ * Function: send
+ *
+ * Description:
+ *  write() writes up to nytes bytes to the file referenced by the file
+ *  descriptor fd from the buffer starting at buf.
+ *
+ * Parameters:
+ *   fd       file descriptor (or socket descriptor) to write to
+ *   buf      Data to write
+ *   nbytes   Length of data to write
+ *
+ * Returned Value:
+ *  On success, the number of bytes  written are returned (zero indicates
+ *  nothing was written). On error, -1 is returned, and errno is set appro‐
+ *  priately:
+ *
+ *  EAGAIN
+ *    Non-blocking I/O has been selected using O_NONBLOCK and the write
+ *    would block.
+ *  EBADF
+ *    fd is not a valid file descriptor or is not open for writing.
+ *  EFAULT
+ *    buf is outside your accessible address space.
+ *  EFBIG
+ *    An attempt was made to write a file that exceeds the implementation
+ *    defined maximum file size or the process' file size limit, or
+ *    to write at a position past the maximum allowed offset.
+ *  EINTR
+ *    The call was interrupted by a signal before any data was written.
+ *  EINVAL
+ *    fd is attached to an object which is unsuitable for writing; or
+ *    the file was opened with the O_DIRECT flag, and either the address
+ *    specified in buf, the value specified in count, or the current
+ *     file offset is not suitably aligned.
+ *  EIO
+ *    A low-level I/O error occurred while modifying the inode.
+ *  ENOSPC
+ *    The device containing the file referred to by fd has no room for
+ *    the data.
+ *  EPIPE
+ *    fd is connected to a pipe or socket whose reading end is closed.
+ *    When this happens the writing process will also receive a SIGPIPE
+ *    signal. (Thus, the write return value is seen only if the program
+ *    catches, blocks or ignores this signal.)
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
 int write(int fd, const void *buf, unsigned int nbytes)
 {
   FAR struct filelist *list;
-  int ret = EBADF;
+  FAR struct file *this_file;
+  FAR struct inode *inode;
+  int err;
+  int ret;
+
+  /* Did we get a valid file descriptor? */
+
+  if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
+    {
+      /* Write to a socket descriptor is equivalent to send with flags == 0 */
+
+#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
+      if ((unsigned int)fd < (CONFIG_NFILE_DESCRIPTORS+CONFIG_NSOCKET_DESCRIPTORS))
+        {
+          return send(fd, buf, nbytes, 0);
+        }
+      else
+#endif
+        {
+          err = EBADF;
+          goto errout;
+        }
+    }
 
   /* Get the thread-specific file list */
 
   list = sched_getfiles();
   if (!list)
     {
-      *get_errno_ptr() = EMFILE;
-      return ERROR;
+      err = EMFILE;
+      goto errout;
     }
 
-  /* Did we get a valid file descriptor? */
+  /* Was this file opened for write access? */
 
-  if ((unsigned int)fd < CONFIG_NFILE_DESCRIPTORS)
+  this_file = &list->fl_files[fd];
+  if ((this_file->f_oflags & O_WROK) == 0)
     {
-      FAR struct file *this_file = &list->fl_files[fd];
-
-      /* Was this file opened for write access? */
+      err = EBADF;
+      goto errout;
+    }
 
-      if ((this_file->f_oflags & O_WROK) != 0)
-        {
-          struct inode *inode = this_file->f_inode;
+  /* Is a driver registered? Does it support the write method? */
 
-          /* Is a driver registered? Does it support the write method? */
+  inode = this_file->f_inode;
+  if (!inode || !inode->u.i_ops && inode->u.i_ops->write)
+    {
+      err = EBADF;
+      goto errout;
+    }
 
-          if (inode && inode->u.i_ops && inode->u.i_ops->write)
-            {
-              /* Yes, then let it perform the write */
+  /* Yes, then let the driver perform the write */
 
-              ret = inode->u.i_ops->write(this_file, buf, nbytes);
-            }
-        }
+  ret = inode->u.i_ops->write(this_file, buf, nbytes);
+  if (ret < 0)
+    {
+      err = -ret;
+      goto errout;
     }
+
   return ret;
+
+errout:
+  *get_errno_ptr() = err;
+  return ERROR;
 }
 
diff --git a/include/net/uip/resolv.h b/include/net/uip/resolv.h
index 3411966eae11a0c381923658c814a30982944fa9..9ab900978be10d1949a15f41c9635387609ab252 100644
--- a/include/net/uip/resolv.h
+++ b/include/net/uip/resolv.h
@@ -36,25 +36,31 @@
 #include <sys/types.h>
 #include <net/uip/uipopt.h>
 
-/* Callback function which is called when a hostname is found.
- *
- * This function must be implemented by the module that uses the DNS
- * resolver. It is called when a hostname is found, or when a hostname
- * was not found.
- *
- * name A pointer to the name that was looked up.  \param
- * ipaddr A pointer to a 4-byte array containing the IP address of the
- * hostname, or NULL if the hostname could not be found.
- */
-
-extern void resolv_found(char *name, uint16 *ipaddr);
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
 
 /* Functions. */
 
-extern void resolv_conf(uint16 *dnsserver);
-extern uint16 *resolv_getserver(void);
-extern void resolv_init(void);
-extern uint16 *resolv_lookup(char *name);
-extern void resolv_query(char *name);
+EXTERN int resolv_init(void);
+
+#ifdef CONFIG_NET_IPv6
+EXTERN void resolv_conf(const struct sockaddr_in6 *dnsserver);
+EXTERN void resolv_getserver(const struct sockaddr_in6 *dnsserver);
+EXTERN int  resolv_query(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 int  resolv_query(char *name, struct sockaddr_in *addr);
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
 
 #endif /* __UIP_RESOLV_H__ */
diff --git a/include/net/uip/uip.h b/include/net/uip/uip.h
index 65a772e60556cab99b97dbc86a4f18ba174db527..b03233ed35cc81d654d92695abdab728ca73d3f9 100644
--- a/include/net/uip/uip.h
+++ b/include/net/uip/uip.h
@@ -48,8 +48,9 @@
  * Included Files
  ****************************************************************************/
 
-#include <sys/types.h>
 #include <nuttx/config.h>
+#include <sys/types.h>
+#include <queue.h>
 #include <arpa/inet.h>
 #include <net/uip/uipopt.h>
 
@@ -158,12 +159,11 @@ typedef uip_ip4addr_t uip_ipaddr_t;
 
 struct uip_conn
 {
+  dq_entry_t node;        /* Implements a doubly linked list */
   uip_ipaddr_t ripaddr;   /* The IP address of the remote host. */
-
   uint16 lport;           /* The local TCP port, in network byte order. */
   uint16 rport;           /* The local remote TCP port, in network byte
                          order. */
-
   uint8 rcv_nxt[4];       /* The sequence number that we expect to
                          receive next. */
   uint8 snd_nxt[4];       /* The sequence number that was last sent by
@@ -188,6 +188,7 @@ struct uip_conn
    */
 
   void *private;
+  void (*callback)(void *private);
 };
 
 #ifdef CONFIG_NET_UDP
@@ -195,16 +196,16 @@ struct uip_conn
 
 struct uip_udp_conn
 {
+  dq_entry_t node;        /* Implements a doubly linked list */
   uip_ipaddr_t ripaddr;   /* The IP address of the remote peer. */
   uint16 lport;           /* The local port number in network byte order. */
   uint16 rport;           /* The remote port number in network byte order. */
   uint8  ttl;             /* Default time-to-live. */
 
-  /* Higher level logic can retain application specific information
-   * in the following:
-   */
+  /* Defines the UDP callback */
 
   void *private;
+  void (*callback)(void *private);
 };
 #endif  /* CONFIG_NET_UDP */
 
@@ -613,9 +614,6 @@ void uip_setipid(uint16 id);
  */
 
 extern void uip_interrupt_event(void);
-#ifdef CONFIG_NET_UDP
-extern void uip_interrupt_udp_event(void);
-#endif
 
 /* Find a free connection structure and allocate it for use. This is
  * normally something done by the implementation of the socket() API
@@ -635,6 +633,34 @@ extern void uip_tcpfree(struct uip_conn *conn);
 extern void uip_udpfree(struct uip_udp_conn *conn);
 #endif
 
+/* Bind a TCP connection to a local address */
+
+#ifdef CONFIG_NET_IPv6
+extern int uip_tcpbind(struct uip_conn *conn, const struct sockaddr_in6 *addr);
+#else
+extern int uip_tcpbind(struct uip_conn *conn, const struct sockaddr_in *addr);
+#endif
+
+/* This function implements the UIP specific parts of the standard
+ * TCP connect() operation:  It connects to a remote host using TCP.
+ *
+ * This function is used to start a new connection to the specified
+ * port on the specied host. It uses the connection structure that was
+ * allocated by a preceding socket() call.  It sets the connection to
+ * the SYN_SENT state and sets the retransmission timer to 0. This will
+ * cause a TCP SYN segment to be sent out the next time this connection
+ * is periodically processed, which usually is done within 0.5 seconds
+ * after the call to uip_tcpconnect().
+ *
+ * This function is called from normal user level code.
+ */
+
+#ifdef CONFIG_NET_IPv6
+extern int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in6 *addr);
+#else
+extern int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr);
+#endif
+
 /* Start listening to the specified port.
  *
  * Note: Since this function expects the port number in network byte
@@ -848,51 +874,31 @@ void uip_send(const void *data, int len);
 
 #define uip_mss()        (uip_conn->mss)
 
-/* Set up a new UDP connection.
- *
- * This function sets up a new UDP connection. The function will
+/* Bind a UDP connection to a local address */
+
+#ifdef CONFIG_NET_IPv6
+extern int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in6 *addr);
+#else
+extern int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr);
+#endif
+
+/* This function sets up a new UDP connection. The function will
  * automatically allocate an unused local port for the new
  * connection. However, another port can be chosen by using the
- * uip_udp_bind() call, after the uip_udp_new() function has been
+ * uip_udpbind() call, after the uip_udpconnect() function has been
  * called.
  *
- * Example:
+ * This function is called as part of the implementation of sendto
+ * and recvfrom.
  *
- *   uip_ipaddr_t addr;
- *   struct uip_udp_conn *c;
- * 
- *   uip_ipaddr(&addr, 192,168,2,1);
- *   c = uip_udp_new(&addr, HTONS(12345));
- *   if(c != NULL) {
- *     uip_udp_bind(c, HTONS(12344));
- *   }
- *
- * ripaddr The IP address of the remote host.
- *
- * rport The remote port number in network byte order.
- *
- * Return:  The uip_udp_conn structure for the new connection or NULL
- * if no connection could be allocated.
+ * addr The address of the remote host.
  */
 
-struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, uint16 rport);
-
-/* Removed a UDP connection.
- *
- * conn A pointer to the uip_udp_conn structure for the connection.
- */
-
-#define uip_udp_remove(conn) (conn)->lport = 0
-
-/* Bind a UDP connection to a local port.
- *
- * conn A pointer to the uip_udp_conn structure for the
- * connection.
- *
- * port The local port number, in network byte order.
- */
-
-#define uip_udp_bind(conn, port) (conn)->lport = port
+#ifdef CONFIG_NET_IPv6
+extern int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in6 *addr);
+#else
+extern int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr);
+#endif
 
 /* Send a UDP datagram of length len on the current connection.
  *
diff --git a/include/nuttx/net.h b/include/nuttx/net.h
index bb8ec8da311496e058d916851f6a8f763b9c2f55..ab6b4b93ae8d80017fe3c2ba0549d4978d50728c 100644
--- a/include/nuttx/net.h
+++ b/include/nuttx/net.h
@@ -106,6 +106,10 @@ EXTERN FAR struct socketlist *net_alloclist(void);
 EXTERN int net_addreflist(FAR struct socketlist *list);
 EXTERN int net_releaselist(FAR struct socketlist *list);
 
+/* net-close.c ***************************************************************/
+
+EXTERN int net_close(int sockfd);
+
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/include/sys/socket.h b/include/sys/socket.h
index 589fafe13423f44b16bf443ea825ee25a7e31491..e1204e68a044c5bc3f657c0295d273650b9f2bad 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -93,6 +93,28 @@
 #define SOCK_RDM       4 /* Provides a reliable datagram layer that does not guarantee ordering. */
 #define SOCK_PACKET    5 /* Obsolete and should not be used in new programs */
 
+
+/* Bits in the FLAGS argument to `send', `recv', et al. These are the bits
+ * recognized by Linus, not all are supported by NuttX.
+ */
+
+#define MSG_OOB        0x0001 /* Process out-of-band data.  */
+#define MSG_PEEK       0x0002 /* Peek at incoming messages.  */
+#define MSG_DONTROUTE  0x0004 /* Don't use local routing.  */
+#define MSG_CTRUNC     0x0008 /* Control data lost before delivery.  */
+#define MSG_PROXY      0x0010 /* Supply or ask second address.  */
+#define MSG_TRUNC      0x0020
+#define MSG_DONTWAIT   0x0040 /* Enable nonblocking IO.  */
+#define MSG_EOR        0x0080 /* End of record.  */
+#define MSG_WAITALL    0x0100 /* Wait for a full request.  */
+#define MSG_FIN        0x0200
+#define MSG_SYN        0x0400
+#define MSG_CONFIRM    0x0800 /* Confirm path validity.  */
+#define MSG_RST        0x1000
+#define MSG_ERRQUEUE   0x2000 /* Fetch message from error queue.  */
+#define MSG_NOSIGNAL   0x4000 /* Do not generate SIGPIPE.  */
+#define MSG_MORE       0x8000 /* Sender will send more.  */
+
 /****************************************************************************
  * Type Definitions
  ****************************************************************************/
@@ -119,9 +141,15 @@ EXTERN int socket(int domain, int type, int protocol);
 EXTERN int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
 EXTERN int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
 
-EXTERN ssize_t send(int s, const void *buf, size_t len, int flags);
-EXTERN ssize_t sendto(int s, const void *buf, size_t len, int flags,
+EXTERN ssize_t send(int sockfd, const void *buf, size_t len, int flags);
+EXTERN ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                       const struct sockaddr *to, socklen_t tolen);
+
+EXTERN ssize_t recv(int sockfd, void *buf, size_t len, int flags);
+EXTERN ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
+                        struct sockaddr *from, socklen_t *fromlen);
+
+
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/net/Makefile b/net/Makefile
index 25b5c46df37ffbdd9ea15de531f89fb2595579b0..089d45513f082f36665a4340d0013ecaf4636e57 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -1,4 +1,4 @@
-############################################################
+############################################################################
 # Makefile
 #
 #   Copyright (C) 2007 Gregory Nutt. All rights reserved.
@@ -31,7 +31,7 @@
 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 #
-############################################################
+############################################################################
 
 -include $(TOPDIR)/Make.defs
 CFLAGS		+= -I./uip
@@ -40,7 +40,8 @@ MKDEP		= $(TOPDIR)/tools/mkdeps.sh
 
 ifeq ($(CONFIG_NET),y)
 STD_ASRCS	=
-STD_CSRCS	= socket.c bind.c connect.c net_sockets.c
+STD_CSRCS	= socket.c bind.c connect.c send.c sendto.c recv.c recvfrom.c \
+		  net_sockets.c net-close.c
 include uip/Make.defs
 endif
 
diff --git a/net/bind.c b/net/bind.c
index 332214d3355965d656e9b081ef3a1de8af0f16c7..97ff479b4e87da3e09b077e12d5f507724fcea19 100644
--- a/net/bind.c
+++ b/net/bind.c
@@ -61,7 +61,7 @@
  *
  * Parameters:
  *   sockfd   Socket descriptor from socket
- *   my_addr  Socket local address
+ *   addr     Socket local address
  *   addrlen  Length of my_addr
  *
  * Returned Value:
@@ -91,6 +91,7 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
   FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
 #endif
   int err;
+  int ret;
 
   /* Verify that the sockfd corresponds to valid, allocated socket */
 
@@ -113,24 +114,32 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
   }
 
   /* Perform the binding depending on the protocol type */
+
   switch (psock->s_type)
     {
       case SOCK_STREAM:
-#warning Put TCP/IP binding logic here
+        ret = uip_tcpbind(psock->s_conn, inaddr);
         break;
 
 #ifdef CONFIG_NET_UDP
       case SOCK_DGRAM:
-#warning Put UDP binding logic here
+        ret = uip_udpbind(psock->s_conn, inaddr);
         break;
 #endif
       default:
-        err = EBADF;
+        err = -EBADF;
         goto errout;
     }
 
-  err = ENOSYS;
-  /*return OK;*/
+  /* Was the bind successful */
+
+  if (ret < 0)
+    {
+      err = -ret;
+      goto errout;
+    }
+
+  return OK;
 
 errout:
   *get_errno_ptr() = err;
diff --git a/net/connect.c b/net/connect.c
index 2fcb8bc7912a879cb0e527f2074cac32a6d4cfc3..bbc112f19d86ea01b5b97e5f4d97bc2fcc1ba5c7 100644
--- a/net/connect.c
+++ b/net/connect.c
@@ -149,7 +149,8 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
       goto errout;
   }
 
-  /* Perform the binding depending on the protocol type */
+  /* Perform the connection depending on the protocol type */
+
   switch (psock->s_type)
     {
       case SOCK_STREAM:
diff --git a/net/net-close.c b/net/net-close.c
new file mode 100644
index 0000000000000000000000000000000000000000..294a4f7b7e78a9f8d50af1ecb9e74a25c7b85aba
--- /dev/null
+++ b/net/net-close.c
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * net/net-close.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#ifdef CONFIG_NET
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#include "net_internal.h"
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: net_close
+ *
+ * Description:
+ *   Performs the close operation on socket descriptors
+ *
+ * Parameters:
+ *   sockfd   Socket descriptor of socket
+ *
+ * Returned Value:
+ *   0 on success; -1 on error with errno set appropriately.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int net_close(int sockfd)
+{
+  FAR struct socket *psock = sockfd_socket(sockfd);
+  int err;
+
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  if (!psock || psock->s_crefs <= 0)
+    {
+      err = EBADF;
+      goto errout;
+    }
+
+  /* Perform the close depending on the protocol type */
+
+  switch (psock->s_type)
+    {
+      case SOCK_STREAM:
+        uip_tcpfree(psock->s_conn);
+        break;
+
+#ifdef CONFIG_NET_UDP
+      case SOCK_DGRAM:
+        uip_udpfree(psock->s_conn);
+        break;
+#endif
+      default:
+        err = -EBADF;
+        goto errout;
+    }
+
+  /* Save the protocol type */
+
+  psock->s_type = 0;
+  psock->s_conn = NULL;
+
+  return OK;
+
+errout:
+  *get_errno_ptr() = err;
+  return ERROR;
+}
+
+#endif /* CONFIG_NET */
diff --git a/net/net_sockets.c b/net/net_sockets.c
index d2be221a8758bf5a85dabefe7038aa6d01f37418..bed48ffe3ab4c9ee692fbe5b0b9b3691e8d1b1bb 100644
--- a/net/net_sockets.c
+++ b/net/net_sockets.c
@@ -251,4 +251,4 @@ FAR struct socket *sockfd_socket(int sockfd)
         }
     }
   return NULL;
-}
\ No newline at end of file
+}
diff --git a/net/recv.c b/net/recv.c
new file mode 100644
index 0000000000000000000000000000000000000000..70cd4d995b479d2da281927156973ec547c21a5b
--- /dev/null
+++ b/net/recv.c
@@ -0,0 +1,77 @@
+/****************************************************************************
+ * net/recv.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#ifdef CONFIG_NET
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#include "net_internal.h"
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: recv
+ *
+ * Description:
+ *   The recv() call is identical to recvfrom() with a NULL from parameter.
+ *
+ * Parameters:
+ *   sockfd   Socket descriptor of socket
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags
+ *
+ * Returned Value:
+ *  (see recvfrom)
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+ssize_t recv(int sockfd, void *buf, size_t len, int flags)
+{
+  return recvfrom(sockfd, buf, len, flags, NULL, 0);
+}
+
+#endif /* CONFIG_NET */
diff --git a/net/recvfrom.c b/net/recvfrom.c
new file mode 100644
index 0000000000000000000000000000000000000000..9632b5ca030f7580d7afa6d95ee0be05e6d3794a
--- /dev/null
+++ b/net/recvfrom.c
@@ -0,0 +1,239 @@
+/****************************************************************************
+ * net/recvfrom.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#ifdef CONFIG_NET
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <errno.h>
+#include <arch/irq.h>
+
+#include "net_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct recvfrom_s
+{
+  sem_t   rf_sem;
+  uint16  rf_buflen;
+  char  * rf_buffer;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+void recvfrom_interrupt(void *private)
+{
+  struct recvfrom_s *pstate = (struct recvfrom_s *)private;
+  size_t recvlen;
+
+  if (uip_newdata() && private)
+    {
+      /* 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 */
+
+      memcpy(pstate->rf_buffer, uip_appdata, recvlen);
+
+      /* Don't allow any furhter call backs. */
+
+      uip_conn->private = NULL;
+      uip_conn->callback = NULL;
+
+      /* Wake up the waiting thread */
+
+      pstate->rf_buflen = recvlen;
+      sem_post(&pstate-> rf_sem);
+    }
+}
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: recvfrom
+ *
+ * Description:
+ *   recvfrom() receives messages from a socket, and may be used to receive
+ *   data on a socket whether or not it is connection-oriented.
+ *
+ *   If from is not NULL, and the underlying protocol provides the source
+ *   address, this source address is filled in. The argument fromlen
+ *   initialized to the size of the buffer associated with from, and modified
+ *   on return to indicate the actual size of the address stored there.
+ *
+ * Parameters:
+ *   sockfd   Socket descriptor of socket
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags
+ *   from     Address of source
+ *   fromlen  The length of the address structure
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error,
+ *   -1 is returned, and errno is set appropriately:
+ *
+ *   EAGAIN
+ *     The socket is marked non-blocking and the receive operation would block,
+ *     or a receive timeout had been set and the timeout expired before data
+ *     was received.
+ *   EBADF
+ *     The argument sockfd is an invalid descriptor.
+ *   ECONNREFUSED
+ *     A remote host refused to allow the network connection (typically because
+ *     it is not running the requested service).
+ *   EFAULT
+ *     The receive buffer pointer(s) point outside the process's address space.
+ *   EINTR
+ *     The receive was interrupted by delivery of a signal before any data were
+ *     available.
+ *   EINVAL
+ *     Invalid argument passed.
+ *   ENOMEM
+ *     Could not allocate memory for recvmsg().
+ *   ENOTCONN
+ *     The socket is associated with a connection-oriented protocol and has
+ *     not been connected.
+ *   ENOTSOCK
+ *     The argument sockfd does not refer to a socket.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *from,
+                 socklen_t *fromlen)
+{
+  FAR struct socket *psock;
+#ifdef CONFIG_NET_IPv6
+  FAR const struct sockaddr_in6 *infrom = (const struct sockaddr_in6 *)from;
+#else
+  FAR const struct sockaddr_in *infrom = (const struct sockaddr_in *)from;
+#endif
+#ifdef CONFIG_NET_UDP
+  struct uip_udp_conn *udp_conn;
+  struct recvfrom_s state;
+  irqstate_t save;
+#endif
+  int err;
+  int ret;
+
+  /* Get the underlying socket structure */
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  psock = sockfd_socket(sockfd);
+  if (!psock || psock->s_crefs <= 0)
+    {
+      err = EBADF;
+      goto errout;
+    }
+
+  /* Perform the TCP/IP recv() operation */
+
+  if (psock->s_type == SOCK_STREAM)
+    {
+#warning "TCP/IP recv not implemented"
+      err = ENOSYS;
+      goto errout;
+    }
+
+  /* Perform the UDP recvfrom() operation */
+
+#ifdef CONFIG_NET_UDP
+  /* Initialize the state structure.  This is done with interrupts
+   * disabled because we don't want anything to happen until we
+   * are ready.
+   */
+
+  save = irqsave();
+  memset(&state, 0, sizeof(struct recvfrom_s));
+  sem_init(&state. rf_sem, 0, 0);
+  state. rf_buflen = len;
+  state. rf_buffer = buf;
+
+  /* Setup the UDP socket */
+
+  ret = uip_udpconnect(psock->s_conn, NULL);
+  if (ret < 0)
+    {
+      irqrestore(save);
+      err = -ret;
+      goto errout;
+    }
+
+  /* Set up the callback in the connection */
+
+  udp_conn = (struct uip_udp_conn *)psock->s_conn;
+  udp_conn->private  = (void*)&state;
+  udp_conn->callback = recvfrom_interrupt;
+  irqrestore(save);
+
+  sem_wait(&state. rf_sem);
+  sem_destroy(&state. rf_sem);
+  return state.rf_buflen;
+#warning "Needs to return server address"
+#else
+  err = ENOSYS;
+#endif
+
+errout:
+  *get_errno_ptr() = err;
+  return ERROR;
+}
+
+#endif /* CONFIG_NET */
diff --git a/net/send.c b/net/send.c
new file mode 100644
index 0000000000000000000000000000000000000000..cb93995a7ccd8ea2df314854b9afb6acc0a538a9
--- /dev/null
+++ b/net/send.c
@@ -0,0 +1,150 @@
+/****************************************************************************
+ * net/send.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#ifdef CONFIG_NET
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#include "net_internal.h"
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: send
+ *
+ * Description:
+ *   The send() call may be used only when the socket is in a connected state
+ *   (so that the intended recipient is known). The only difference between
+ *   send() and write() is the presence of flags. With zero flags parameter,
+ *   send() is equivalent to write(). Also, send(s,buf,len,flags) is
+ *   equivalent to sendto(s,buf,len,flags,NULL,0).
+ *
+ * Parameters:
+ *   sockfd   Socket descriptor of socket
+ *   buf      Data to send
+ *   len      Length of data to send
+ *   flags    Send flags
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error,
+ *   -1 is returned, and errno is set appropriately:
+ *
+ *   EAGAIN or EWOULDBLOCK
+ *     The socket is marked non-blocking and the requested operation
+ *     would block.
+ *   EBADF
+ *     An invalid descriptor was specified.
+ *   ECONNRESET
+ *     Connection reset by peer.
+ *   EDESTADDRREQ
+ *     The socket is not connection-mode, and no peer address is set.
+ *   EFAULT
+ *      An invalid user space address was specified for a parameter.
+ *   EINTR
+ *      A signal occurred before any data was transmitted.
+ *   EINVAL
+ *      Invalid argument passed.
+ *   EISCONN
+ *     The connection-mode socket was connected already but a recipient
+ *     was specified. (Now either this error is returned, or the recipient
+ *     specification is ignored.)
+ *   EMSGSIZE
+ *     The socket type requires that message be sent atomically, and the
+ *     size of the message to be sent made this impossible.
+ *   ENOBUFS
+ *     The output queue for a network interface was full. This generally
+ *     indicates that the interface has stopped sending, but may be
+ *     caused by transient congestion.
+ *   ENOMEM
+ *     No memory available.
+ *   ENOTCONN
+ *     The socket is not connected, and no target has been given.
+ *   ENOTSOCK
+ *     The argument s is not a socket.
+ *   EOPNOTSUPP
+ *     Some bit in the flags argument is inappropriate for the socket
+ *     type.
+ *   EPIPE
+ *     The local end has been shut down on a connection oriented socket.
+ *     In this case the process will also receive a SIGPIPE unless
+ *     MSG_NOSIGNAL is set.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+ssize_t send(int sockfd, const void *buf, size_t len, int flags)
+{
+  FAR struct socket *psock = sockfd_socket(sockfd);
+  int err;
+
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  if (!psock || psock->s_crefs <= 0)
+    {
+      err = EBADF;
+      goto errout;
+    }
+
+  /* If this is a connected socket, then return ENOTCONN */
+
+  if (psock->s_type != SOCK_STREAM)
+    {
+      err = ENOTCONN;
+      goto errout;
+    }
+
+  /* Perform the TCP send operation */
+
+#warning "send() not implemented"
+  err = ENOSYS;
+
+errout:
+  *get_errno_ptr() = ENOSYS;
+  return ERROR;
+  *get_errno_ptr() = ENOSYS;
+  return ERROR;
+}
+
+#endif /* CONFIG_NET */
diff --git a/net/sendto.c b/net/sendto.c
new file mode 100644
index 0000000000000000000000000000000000000000..86be9968bf6f8999b03426971b839c49ce3ca055
--- /dev/null
+++ b/net/sendto.c
@@ -0,0 +1,257 @@
+/****************************************************************************
+ * net/sendto.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#ifdef CONFIG_NET
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <errno.h>
+#include <arch/irq.h>
+
+#include "net_internal.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct sendto_s
+{
+  sem_t       st_sem;
+  uint16      st_buflen;
+  const char *st_buffer;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+void sendto_interrupt(void *private)
+{
+  struct sendto_s *pstate = (struct sendto_s *)private;
+  if (private)
+    {
+      /* Copy the user data into appdata and send it */
+
+      memcpy(uip_appdata, pstate->st_buffer, pstate->st_buflen);
+      uip_udp_send(pstate->st_buflen);
+
+      /* Don't allow any furhter call backs. */
+
+      uip_conn->private = NULL;
+      uip_conn->callback = NULL;
+
+      /* Wake up the waiting thread */
+
+      sem_post(&pstate->st_sem);
+    }
+}
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: sendto
+ *
+ * Description:
+ *   If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
+ *   socket, the parameters to and tolen are ignored (and the error EISCONN
+ *   may be returned when they are not NULL and 0), and the error ENOTCONN is
+ *   returned when the socket was not actually connected.
+ *
+ * Parameters:
+ *   sockfd   Socket descriptor of socket
+ *   buf      Data to send
+ *   len      Length of data to send
+ *   flags    Send flags
+ *   to       Address of recipient
+ *   tolen    The length of the address structure
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error,
+ *   -1 is returned, and errno is set appropriately:
+ *
+ *   EAGAIN or EWOULDBLOCK
+ *     The socket is marked non-blocking and the requested operation
+ *     would block.
+ *   EBADF
+ *     An invalid descriptor was specified.
+ *   ECONNRESET
+ *     Connection reset by peer.
+ *   EDESTADDRREQ
+ *     The socket is not connection-mode, and no peer address is set.
+ *   EFAULT
+ *      An invalid user space address was specified for a parameter.
+ *   EINTR
+ *      A signal occurred before any data was transmitted.
+ *   EINVAL
+ *      Invalid argument passed.
+ *   EISCONN
+ *     The connection-mode socket was connected already but a recipient
+ *     was specified. (Now either this error is returned, or the recipient
+ *     specification is ignored.)
+ *   EMSGSIZE
+ *     The socket type requires that message be sent atomically, and the
+ *     size of the message to be sent made this impossible.
+ *   ENOBUFS
+ *     The output queue for a network interface was full. This generally
+ *     indicates that the interface has stopped sending, but may be
+ *     caused by transient congestion.
+ *   ENOMEM
+ *     No memory available.
+ *   ENOTCONN
+ *     The socket is not connected, and no target has been given.
+ *   ENOTSOCK
+ *     The argument s is not a socket.
+ *   EOPNOTSUPP
+ *     Some bit in the flags argument is inappropriate for the socket
+ *     type.
+ *   EPIPE
+ *     The local end has been shut down on a connection oriented socket.
+ *     In this case the process will also receive a SIGPIPE unless
+ *     MSG_NOSIGNAL is set.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
+               const struct sockaddr *to, socklen_t tolen)
+{
+  FAR struct socket *psock;
+#ifdef CONFIG_NET_IPv6
+  FAR const struct sockaddr_in6 *into = (const struct sockaddr_in6 *)to;
+#else
+  FAR const struct sockaddr_in *into = (const struct sockaddr_in *)to;
+#endif
+#ifdef CONFIG_NET_UDP
+  struct uip_udp_conn *udp_conn;
+  struct sendto_s state;
+  irqstate_t save;
+#endif
+  int err;
+  int ret;
+
+  /* If to is NULL or tolen is zero, then this function is same as send */
+
+  if (!to || !tolen)
+    {
+      return send(sockfd, buf, len, flags);
+    }
+
+  /* Verify that a valid address has been provided */
+
+#ifdef CONFIG_NET_IPv6
+  if (to->sa_family != AF_INET6 || tolen < sizeof(struct sockaddr_in6))
+#else
+  if (to->sa_family != AF_INET || tolen < sizeof(struct sockaddr_in))
+#endif
+  {
+      err = EBADF;
+      goto errout;
+  }
+
+  /* Get the underlying socket structure */
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  psock = sockfd_socket(sockfd);
+  if (!psock || psock->s_crefs <= 0)
+    {
+      err = EBADF;
+      goto errout;
+    }
+
+  /* If this is a connected socket, then return EISCONN */
+
+  if (psock->s_type != SOCK_DGRAM)
+    {
+      err = EISCONN;
+      goto errout;
+    }
+
+  /* Perform the UDP sendto operation */
+
+#ifdef CONFIG_NET_UDP
+  /* Initialize the state structure.  This is done with interrupts
+   * disabled because we don't want anything to happen until we
+   * are ready.
+   */
+
+  save = irqsave();
+  memset(&state, 0, sizeof(struct sendto_s));
+  sem_init(&state.st_sem, 0, 0);
+  state.st_buflen = len;
+  state.st_buffer = buf;
+
+  /* Setup the UDP socket */
+
+  ret = uip_udpconnect(psock->s_conn, into);
+  if (ret < 0)
+    {
+      irqrestore(save);
+      err = -ret;
+      goto errout;
+    }
+
+  /* Set up the callback in the connection */
+
+  udp_conn = (struct uip_udp_conn *)psock->s_conn;
+  udp_conn->private  = (void*)&state;
+  udp_conn->callback = sendto_interrupt;
+  irqrestore(save);
+
+  sem_wait(&state.st_sem);
+  sem_destroy(&state.st_sem);
+  return len;
+#else
+  err = ENOSYS;
+#endif
+
+errout:
+  *get_errno_ptr() = err;
+  return ERROR;
+}
+
+#endif /* CONFIG_NET */
diff --git a/net/socket.c b/net/socket.c
index ad3ef1e9279580e2d67c605d09f2216edfe14ae8..43d4645fd28fe66a2a9bffc666ea9454fce93719 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -135,10 +135,27 @@ int socket(int domain, int type, int protocol)
       /* Save the protocol type */
 
       psock->s_type = type;
+      psock->s_conn = NULL;
 
-      /* Allocate a TCP connection structure */
+      /* Allocate the appropriate connection structure */
+
+      switch (type)
+        {
+          case SOCK_STREAM:
+            psock->s_conn = uip_tcpalloc();
+            break;
+
+#ifdef CONFIG_NET_UDP
+          case SOCK_DGRAM:
+            psock->s_conn = uip_udpalloc();
+            break;
+#endif
+          default:
+            break;
+        }
+
+      /* Did we succesfully allocate some kind of connection structure? */
 
-      psock->s_conn = uip_tcpalloc();
       if (!psock->s_conn)
         {
           /* Failed to reserve a connection structure */
diff --git a/net/uip/uip-internal.h b/net/uip/uip-internal.h
index 0f47fbc52d5403f36373ae1d5256c01bf6e60133..f8613c63a0eca76ad06a881078f2cebfced738d1 100644
--- a/net/uip/uip-internal.h
+++ b/net/uip/uip-internal.h
@@ -57,10 +57,6 @@
  * Public Data
  ****************************************************************************/
 
-/* g_tcp_sequence[] is used to generate TCP sequence numbers */
-
-extern uint8 g_tcp_sequence[4];
-
 extern const uip_ipaddr_t all_ones_addr;
 extern const uip_ipaddr_t all_zeroes_addr;
 
@@ -79,6 +75,7 @@ extern "C" {
 
 EXTERN void uip_tcpinit(void);
 EXTERN struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf);
+EXTERN struct uip_conn *uip_tcplistener(struct uip_tcpip_hdr *buf);
 EXTERN void uip_tcpnextsequence(void);
 
 /* Defined in uip_udpconn.c *************************************************/
diff --git a/net/uip/uip-tcpconn.c b/net/uip/uip-tcpconn.c
index 2c6d0cd023466b05adf272ed672c8315eb691254..9d1380f6bc9eb645ee4324142572e80a26df1932 100644
--- a/net/uip/uip-tcpconn.c
+++ b/net/uip/uip-tcpconn.c
@@ -62,10 +62,6 @@
  * Public Data
  ****************************************************************************/
 
-/* g_tcp_sequence[] is used to generate TCP sequence numbers */
-
-uint8 g_tcp_sequence[4];
-
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -74,17 +70,34 @@ uint8 g_tcp_sequence[4];
 
 static struct uip_conn g_tcp_connections[UIP_CONNS];
 
+/* A list of all free TCP connections */
+
+static dq_queue_t g_free_tcp_connections;
+
+/* A list of all connected TCP connections */
+
+static dq_queue_t g_active_tcp_connections;
+
 /* Last port used by a TCP connection connection. */
 
 static uint16 g_last_tcp_port;
 
+/* g_tcp_sequence[] is used to generate TCP sequence numbers */
+
+static uint8 g_tcp_sequence[4];
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
-/* Given a port number, find the socket bound to the port number.
- * Primary use: to determine if a port number is available.
- */
+/****************************************************************************
+ * Name: uip_find_conn()
+ *
+ * Description:
+ *   Given a port number, find the socket bound to the port number.
+ *   Primary use: to determine if a port number is available.
+ *
+ ****************************************************************************/
 
 static struct uip_conn *uip_find_conn(uint16 portno)
 {
@@ -118,16 +131,27 @@ static struct uip_conn *uip_find_conn(uint16 portno)
  *
  * Description:
  *   Initialize the TCP/IP connection structures.  Called only once and only
- *   from the UIP layer.
+ *   from the UIP layer at startup in normal user mode.
  *
  ****************************************************************************/
 
 void uip_tcpinit(void)
 {
   int i;
+
+  /* Initialize the queues */
+
+  dq_init(&g_free_tcp_connections);
+  dq_init(&g_active_tcp_connections);
+
+  /* Now initialize each connection structure */
+
   for (i = 0; i < UIP_CONNS; i++)
     {
+      /* Mark the connection closed and move it to the free list */
+
       g_tcp_connections[i].tcpstateflags = UIP_CLOSED;
+      dq_addlast(&g_tcp_connections[i].node, &g_free_tcp_connections);
     }
 
   g_last_tcp_port = 1024;
@@ -146,60 +170,67 @@ void uip_tcpinit(void)
 
 struct uip_conn *uip_tcpalloc(void)
 {
-#if 0 /* Revisit */
-  struct uip_conn *oldest = NULL;
-#endif
+  struct uip_conn *conn;
   irqstate_t flags;
-  unsigned int i;
 
   /* Because this routine is called from both interrupt level and
    * and from user level, we have not option but to disable interrupts
-   * while accessing g_tcp_connections[];
+   * while accessing g_free_tcp_connections[];
    */
 
   flags = irqsave();
 
-  /* Check if there are any available connections. */
-
-  for (i = 0; i < UIP_CONNS; i++)
-    {
-      /* First, check if any connections structures are marked as
-       * CLOSED in the table of pre-allocated connection structures.
-       */
-
-      if (g_tcp_connections[i].tcpstateflags == UIP_CLOSED)
-        {
-          /* We found an unused structure. Mark as allocated, but not
-           * initialized.
-           */
+  /* Return the entry from the head of the free list */
 
-          memset(&g_tcp_connections[i], 0, sizeof(struct uip_conn));
-          g_tcp_connections[i].tcpstateflags = UIP_ALLOCATED;
-
-          irqrestore(flags);
-          return &g_tcp_connections[i];
-        }
+  conn = (struct uip_conn *)dq_remfirst(&g_free_tcp_connections);
 
 #if 0 /* Revisit */
+  /* Is the free list empty? */
+
+  if (!conn)
+    {
       /* As a fallback, check for connection structures in the TIME_WAIT
        * state.  If no CLOSED connections are found, then take the oldest
        */
 
-      if (g_tcp_connections[i].tcpstateflags == UIP_TIME_WAIT)
+      struct uip_conn *tmp = g_active_tcp_connections.head;
+      while (tmp)
         {
-          if (!oldest || g_tcp_connections[i].timer > oldest->timer)
+          /* Is this connectin in the UIP_TIME_WAIT state? */
+
+          if (tmp->tcpstateflags == UIP_TIME_WAIT)
             {
-              oldest = &g_tcp_connections[i];
+              /* Is it the oldest one we have seen so far? */
+
+              if (!conn || tmp->timer > conn->timer)
+                {
+                  /* Yes.. remember it */
+
+                  conn = tmp;
+                }
             }
+
+          /* Look at the next active connection */
+
+          tmp = tmp->node.flink;
         }
+
+      /* If we found one, remove it from the active connection list */
+
+      dq_rem(&conn->node, &g_active_tcp_connections);
     }
-  return oldest;
-#else
-    }
+#endif
 
   irqrestore(flags);
-  return NULL;
-#endif
+
+  /* Mark the connection allocated */
+
+  if (conn)
+    {
+      conn->tcpstateflags = UIP_ALLOCATED;
+    }
+
+  return conn;
 }
 
 /****************************************************************************
@@ -213,9 +244,31 @@ struct uip_conn *uip_tcpalloc(void)
 
 void uip_tcpfree(struct uip_conn *conn)
 {
-  /* this action is atomic and should require no special protetion */
+  irqstate_t flags;
+
+  /* Because g_free_tcp_connections is accessed from user level and interrupt
+   * level, code, it is necessary to keep interrupts disabled during this
+   * operation.
+   */
+
+  flags = irqsave();
+
+  /* UIP_ALLOCATED means that that the connection is not in the active list
+   * yet.
+   */
+
+  if (conn->tcpstateflags != UIP_ALLOCATED)
+    {
+      /* Remove the connection from the active list */
+
+      dq_rem(&conn->node, &g_free_tcp_connections);
+    }
+
+  /* Mark the connection available and put it into the free list */
 
   conn->tcpstateflags = UIP_CLOSED;
+  dq_addlast(&conn->node, &g_free_tcp_connections);
+  irqrestore(flags);
 }
 
 /****************************************************************************
@@ -232,8 +285,8 @@ void uip_tcpfree(struct uip_conn *conn)
 
 struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf)
 {
-  struct uip_conn *conn;
-  for (conn = g_tcp_connections; conn <= &g_tcp_connections[UIP_CONNS - 1]; conn++)
+  struct uip_conn *conn = (struct uip_conn *)g_active_tcp_connections.head;
+  while (conn)
     {
       /* Find an open connection matching the tcp input */
 
@@ -241,15 +294,64 @@ struct uip_conn *uip_tcpactive(struct uip_tcpip_hdr *buf)
            buf->destport == conn->lport && buf->srcport == conn->rport &&
            uip_ipaddr_cmp(buf->srcipaddr, conn->ripaddr))
         {
-          /* Matching connection found.. return a reference to it */
+          /* Matching connection found.. break out of the loop and return a
+           * reference to it.
+           */
 
-          return conn;
+          break;
         }
+
+      /* Look at the next active connection */
+
+      conn = (struct uip_conn *)conn->node.flink;
     }
 
-  /* No match found */
+  return conn;
+}
 
-  return NULL;
+/****************************************************************************
+ * Name: uip_tcpactive()
+ *
+ * Description:
+ *    Called when uip_interupt matches the incoming packet with a connection
+ *    in LISTEN. In that case, this function will create a new connection and
+ *    initialize it to send a SYNACK in return.
+ *
+ * Assumptions:
+ *   This function is called from UIP logic at interrupt level
+ *
+ ****************************************************************************/
+
+struct uip_conn *uip_tcplistener(struct uip_tcpip_hdr *buf)
+{
+  struct uip_conn *conn = uip_tcpalloc();
+  if (conn)
+    {
+      /* Fill in the necessary fields for the new connection. */
+
+      conn->rto   = conn->timer = UIP_RTO;
+      conn->sa    = 0;
+      conn->sv    = 4;
+      conn->nrtx  = 0;
+      conn->lport = buf->destport;
+      conn->rport = buf->srcport;
+      uip_ipaddr_copy(conn->ripaddr, buf->srcipaddr);
+      conn->tcpstateflags = UIP_SYN_RCVD;
+
+      conn->snd_nxt[0] = g_tcp_sequence[0];
+      conn->snd_nxt[1] = g_tcp_sequence[1];
+      conn->snd_nxt[2] = g_tcp_sequence[2];
+      conn->snd_nxt[3] = g_tcp_sequence[3];
+      conn->len = 1;
+
+      /* rcv_nxt should be the seqno from the incoming packet + 1. */
+
+      conn->rcv_nxt[3] = buf->seqno[3];
+      conn->rcv_nxt[2] = buf->seqno[2];
+      conn->rcv_nxt[1] = buf->seqno[1];
+      conn->rcv_nxt[0] = buf->seqno[0];
+  }
+  return conn;
 }
 
 /****************************************************************************
@@ -345,13 +447,24 @@ int uip_tcpbind(struct uip_conn *conn, const struct sockaddr_in *addr)
  ****************************************************************************/
 
 #ifdef CONFIG_NET_IPv6
-int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in6 *addr )
+int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in6 *addr)
 #else
-int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr )
+int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr)
 #endif
 {
+  irqstate_t flags;
   uint16 port;
 
+  /* The connection is expected to be in the UIP_ALLOCATED state.. i.e., 
+   * allocated via up_tcpalloc(), but not yet put into the active connections
+   * list.
+   */
+
+  if (!conn || conn->tcpstateflags != UIP_ALLOCATED)
+    {
+      return -EISCONN;
+    }
+
   /* If the TCP port has not alread been bound to a local port, then select
    * one now.
    */
@@ -407,6 +520,17 @@ int uip_tcpconnect(struct uip_conn *conn, const struct sockaddr_in *addr )
   /* The sockaddr address is 32-bits in network order. */
 
   uip_ipaddr_copy(&conn->ripaddr, addr->sin_addr.s_addr);
+
+  /* And, finally, put the connection structure into the active
+   * list. Because g_active_tcp_connections is accessed from user level and
+   * interrupt level, code, it is necessary to keep interrupts disabled during
+   * this operation.
+   */
+
+  flags = irqsave();
+  dq_addlast(&conn->node, &g_active_tcp_connections);
+  irqrestore(flags);
+
   return OK;
 }
 
diff --git a/net/uip/uip-udpconn.c b/net/uip/uip-udpconn.c
index 1738e5d5a45d2897e7cb2520e289ec35a0583a13..24739bee1dfd7f2d0b3c075e4290a5137c7d6205 100644
--- a/net/uip/uip-udpconn.c
+++ b/net/uip/uip-udpconn.c
@@ -1,4 +1,4 @@
-/************************************************************
+/****************************************************************************
  * uip-udpconn.c
  *
  *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
@@ -34,21 +34,23 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- ************************************************************/
+ ****************************************************************************/
 
-/************************************************************
+/****************************************************************************
  * Compilation Switches
- ************************************************************/
+ ****************************************************************************/
 
-/************************************************************
+/****************************************************************************
  * Included Files
- ************************************************************/
+ ****************************************************************************/
 
 #include <nuttx/config.h>
 #if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)
 
 #include <sys/types.h>
 #include <string.h>
+#include <semaphore.h>
+#include <assert.h>
 #include <errno.h>
 #include <arch/irq.h>
 
@@ -58,43 +60,93 @@
 
 #include "uip-internal.h"
 
-/************************************************************
+/****************************************************************************
  * Private Data
- ************************************************************/
+ ****************************************************************************/
 
 /* The array containing all uIP UDP connections. */
 
-struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
+struct uip_udp_conn g_udp_connections[UIP_UDP_CONNS];
+
+/* A list of all free UDP connections */
+
+static dq_queue_t g_free_udp_connections;
+static sem_t g_free_sem;
+
+/* A list of all allocated UDP connections */
+
+static dq_queue_t g_active_udp_connections;
 
 /* Last port used by a UDP connection connection. */
 
 static uint16 g_last_udp_port;
 
-/************************************************************
+/****************************************************************************
  * Private Functions
- ************************************************************/
+ ****************************************************************************/
 
-#ifdef CONFIG_NET_UDP
-struct uip_udp_conn *uip_find_udp_conn( uint16 portno )
+/****************************************************************************
+ * Name: _uip_semtake() and _uip_semgive()
+ *
+ * Description:
+ *   Take/give semaphore
+ *
+ ****************************************************************************/
+
+static inline void _uip_semtake(sem_t *sem)
+{
+  /* Take the semaphore (perhaps waiting) */
+
+  while (sem_wait(sem) != 0)
+    {
+      /* The only case that an error should occr here is if
+       * the wait was awakened by a signal.
+       */
+
+      ASSERT(*get_errno_ptr() == EINTR);
+    }
+}
+
+#define _uip_semgive(sem) sem_post(sem)
+
+/****************************************************************************
+ * Name: uip_find_conn()
+ *
+ * Description:
+ *   Find the UDP connection that uses this local port number.  Called only
+ *   from user, non-interrupt level logic.
+ *
+ ****************************************************************************/
+
+struct uip_udp_conn *uip_find_conn( uint16 portno )
 {
   struct uip_udp_conn *conn;
-  int i;
+  uint16 nlastport = htons(g_last_udp_port);
+  irqstate_t flags;
 
-  for (i = 0; i < UIP_UDP_CONNS; i++)
+  /* Now search each active connection structure.  This list is modifiable
+   * from interrupt level, we we must diable interrupts to access it safely.
+   */
+
+  flags = irqsave();
+  conn = (struct uip_udp_conn *)g_active_udp_connections.head;
+  while (conn)
     {
-      if (uip_udp_conns[i].lport == htons(g_last_udp_port))
+      if (conn->lport == nlastport)
         {
-          return conn;
+          break;
         }
+
+      conn = (struct uip_udp_conn *)conn->node.flink;
     }
 
-  return NULL;
+  irqrestore(flags);
+  return conn;
 }
-#endif   /* CONFIG_NET_UDP */
 
-/************************************************************
+/****************************************************************************
  * Public Functions
- ************************************************************/
+ ****************************************************************************/
 
 /****************************************************************************
  * Name: uip_udpinit()
@@ -108,9 +160,19 @@ struct uip_udp_conn *uip_find_udp_conn( uint16 portno )
 void uip_udpinit(void)
 {
   int i;
+
+  /* Initialize the queues */
+
+  dq_init(&g_free_udp_connections);
+  dq_init(&g_active_udp_connections);
+  sem_init(&g_free_sem, 0, 1);
+
   for (i = 0; i < UIP_UDP_CONNS; i++)
     {
-      uip_udp_conns[i].lport = 0;
+      /* Mark the connection closed and move it to the free list */
+
+      g_udp_connections[i].lport = 0;
+      dq_addlast(&g_udp_connections[i].node, &g_free_udp_connections);
     }
 
   g_last_udp_port = 1024;
@@ -120,15 +182,28 @@ void uip_udpinit(void)
  * Name: uip_udpalloc()
  *
  * Description:
- *   Find a free UDP connection structure and allocate it for use.  This is
- *   normally something done by the implementation of the socket() API.
+ *   Alloc a new, uninitialized UDP connection structure.
  *
  ****************************************************************************/
 
 struct uip_udp_conn *uip_udpalloc(void)
 {
-#warning "Need to implement allocation logic"
-  return NULL;
+  struct uip_udp_conn *conn;
+
+  /* The free list is only accessed from user, non-interrupt level and
+   * is protected by a semaphore (that behaves like a mutex).
+   */
+
+  _uip_semtake(&g_free_sem);
+  conn = (struct uip_udp_conn *)dq_remfirst(&g_free_udp_connections);
+  if (conn)
+    {
+      /* Make sure that the connectin is marked as uninitialized */
+
+      conn->lport = 0;
+    }
+  _uip_semgive(&g_free_sem);
+  return conn;
 }
 
 /****************************************************************************
@@ -142,7 +217,27 @@ struct uip_udp_conn *uip_udpalloc(void)
 
 void uip_udpfree(struct uip_udp_conn *conn)
 {
-#warning "Need to implement release logic"
+  irqstate_t flags;
+
+  /* The active list is accessed from the interrupt level and me must be
+   * certain that no interrupts occur while the active list is modified.
+   */
+
+  flags = irqsave();
+  if (conn->lport != 0)
+    {
+      dq_rem(&conn->node, &g_active_udp_connections);
+    }
+  irqrestore(flags);
+
+  /* The free list is only accessed from user, non-interrupt level and
+   * is protected by a semaphore (that behaves like a mutex).
+   */
+
+  _uip_semtake(&g_free_sem);
+  conn->lport = 0;
+  dq_addlast(&conn->node, &g_free_udp_connections);
+  _uip_semgive(&g_free_sem);
 }
 
 /****************************************************************************
@@ -159,8 +254,8 @@ void uip_udpfree(struct uip_udp_conn *conn)
 
 struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
 {
-  struct uip_udp_conn *conn;
-  for (conn = &uip_udp_conns[0]; conn < &uip_udp_conns[UIP_UDP_CONNS]; conn++)
+  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
        * to be used. If so, the local port number is checked against the
@@ -179,11 +274,13 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
         {
           /* Matching connection found.. return a reference to it */
 
-          return conn;
+          break;
         }
-    }
 
-  /* No match found */
+      /* Look at the next active connection */
+
+      conn = (struct uip_udp_conn *)conn->node.flink;
+    }
 
   return NULL;
 }
@@ -207,63 +304,26 @@ struct uip_udp_conn *uip_udpactive(struct uip_udpip_hdr *buf)
 
 void uip_udppoll(unsigned int conn)
 {
-  uip_udp_conn = &uip_udp_conns[conn];
+  uip_udp_conn = &g_udp_connections[conn];
   uip_interrupt(UIP_UDP_TIMER);
 }
 
-/****************************************************************************
- * Name: uip_tcpbind()
- *
- * Description:
- *   This function implements the UIP specific parts of the standard TCP
- *   bind() operation.
- *
- * Assumptions:
- *   This function is called from normal user level code.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IPv6
-int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in6 *addr)
-#else
-int uip_udpbind(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
-#endif
-{
-#warning "Need to implement bind logic"
-  return -ENOSYS;
-}
-
-/* Set up a new UDP connection.
- *
- * This function sets up a new UDP connection. The function will
+/* This function sets up a new UDP connection. The function will
  * automatically allocate an unused local port for the new
  * connection. However, another port can be chosen by using the
- * uip_udp_bind() call, after the uip_udp_new() function has been
+ * uip_udpbind() call, after the uip_udpconnect() function has been
  * called.
  *
- * Example:
- *
- *   uip_ipaddr_t addr;
- *   struct uip_udp_conn *c;
- * 
- *   uip_ipaddr(&addr, 192,168,2,1);
- *   c = uip_udp_new(&addr, HTONS(12345));
- *   if(c != NULL) {
- *     uip_udp_bind(c, HTONS(12344));
- *   }
- *
- * ripaddr The IP address of the remote host.
- *
- * rport The remote port number in network byte order.
- *
- * Return:  The uip_udp_conn structure for the new connection or NULL
- * if no connection could be allocated.
+ * addr The address of the remote host.
  */
 
-struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, uint16 rport)
+#ifdef CONFIG_NET_IPv6
+int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in6 *addr)
+#else
+int uip_udpconnect(struct uip_udp_conn *conn, const struct sockaddr_in *addr)
+#endif
 {
-  struct uip_udp_conn *conn;
-  int i;
+  irqstate_t flags;
 
   /* Find an unused local port number.  Loop until we find a valid listen port
    * number that is not being used by any other connection.
@@ -283,42 +343,32 @@ struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, uint16 rport)
           g_last_udp_port = 4096;
         }
     }
-  while (uip_find_udp_conn(g_last_udp_port));
-
-  /* Now find an available UDP connection structure */
-
-  conn = 0;
-  for (i = 0; i < UIP_UDP_CONNS; i++)
-    {
-      if (uip_udp_conns[i].lport == 0)
-        {
-          conn = &uip_udp_conns[i];
-          break;
-        }
-    }
-
-  /* Return an error if no connection is available */
-
-  if (conn == 0)
-    {
-      return 0;
-    }
+  while (uip_find_conn(g_last_udp_port));
 
   /* Initialize and return the connection structure, bind it to the port number */
 
   conn->lport = HTONS(g_last_udp_port);
-  conn->rport = rport;
 
-  if (ripaddr == NULL)
+  if (addr)
     {
-      memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t));
+      conn->rport = addr->sin_port;
+      uip_ipaddr_copy(&conn->ripaddr, &addr->sin_addr.s_addr);
     }
   else
     {
-      uip_ipaddr_copy(&conn->ripaddr, ripaddr);
-    }
+       conn->rport = 0;
+       uip_ipaddr_copy(&conn->ripaddr, &all_zeroes_addr);
+   }
+  conn->ttl   = UIP_TTL;
+
+  /* Now add the connection structure to the active connectionlist. This list
+   * is modifiable from interrupt level, we we must diable interrupts to
+   * access it safely.
+   */
 
-  conn->ttl = UIP_TTL;
+  flags = irqsave();
+  dq_addlast(&conn->node, &g_active_udp_connections);
+  irqrestore(flags);
 
   return conn;
 }
diff --git a/net/uip/uip.c b/net/uip/uip.c
index e45e0e560fa15f73c475f230197802ff4674386b..44403af84876f8d12c8d7977b49d350540d02d11 100644
--- a/net/uip/uip.c
+++ b/net/uip/uip.c
@@ -17,6 +17,7 @@
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
+ *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
@@ -587,6 +588,18 @@ static void uip_add_rcv_nxt(uint16 n)
   uip_conn->rcv_nxt[3] = uip_acc32[3];
 }
 
+static uip_udp_callback(void)
+{
+  /* Some sanity checking */
+
+  if (uip_udp_conn && uip_udp_conn->callback)
+    {
+      /* Perform the callback */
+
+      uip_udp_conn->callback(uip_udp_conn->private);
+    }
+}
+
 void uip_interrupt(uint8 flag)
 {
   register struct uip_conn *uip_connr = uip_conn;
@@ -759,7 +772,7 @@ void uip_interrupt(uint8 flag)
           uip_len = uip_slen = 0;
           uip_flags = UIP_POLL;
           uip_event_signal();
-          uip_interrupt_udp_event();
+          up_udp_callback();
           goto udp_send;
         }
       else
@@ -1099,7 +1112,7 @@ void uip_interrupt(uint8 flag)
     uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
     uip_slen = 0;
     uip_event_signal();
-    uip_interrupt_udp_event();
+    up_udp_callback();
 
  udp_send:
     if (uip_slen == 0)
@@ -1256,7 +1269,7 @@ found_listen:
 
     /* First allocate a new connection structure */
 
-    uip_connr = uip_tcpalloc();
+    uip_connr = uip_tcplistener(BUF);
     if (!uip_connr)
       {
         /* All connections are used already, we drop packet and hope that
@@ -1268,33 +1281,12 @@ found_listen:
         UIP_LOG("tcp: found no unused connections.");
         goto drop;
       }
-    uip_conn = uip_connr;
 
-    /* Fill in the necessary fields for the new connection. */
-
-    uip_connr->rto   = uip_connr->timer = UIP_RTO;
-    uip_connr->sa    = 0;
-    uip_connr->sv    = 4;
-    uip_connr->nrtx  = 0;
-    uip_connr->lport = BUF->destport;
-    uip_connr->rport = BUF->srcport;
-    uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
-    uip_connr->tcpstateflags = UIP_SYN_RCVD;
-
-    uip_connr->snd_nxt[0] = g_tcp_sequence[0];
-    uip_connr->snd_nxt[1] = g_tcp_sequence[1];
-    uip_connr->snd_nxt[2] = g_tcp_sequence[2];
-    uip_connr->snd_nxt[3] = g_tcp_sequence[3];
-    uip_connr->len = 1;
-
-    /* rcv_nxt should be the seqno from the incoming packet + 1. */
-    uip_connr->rcv_nxt[3] = BUF->seqno[3];
-    uip_connr->rcv_nxt[2] = BUF->seqno[2];
-    uip_connr->rcv_nxt[1] = BUF->seqno[1];
-    uip_connr->rcv_nxt[0] = BUF->seqno[0];
     uip_add_rcv_nxt(1);
+    uip_conn = uip_connr;
 
     /* Parse the TCP MSS option, if present. */
+
     if ((BUF->tcpoffset & 0xf0) > 0x50)
       {
         for (c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;)
@@ -1338,7 +1330,7 @@ found_listen:
       }
 
     /* Our response will be a SYNACK. */
-    tcp_send_synack:
+tcp_send_synack:
     BUF->flags = TCP_ACK;
 
  tcp_send_syn:
diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c
index 1fc64cf1b234016c69a5b244d82c4e8884e11934..a2a233e937d7014c547bc23ac68970d7881c29e3 100644
--- a/netutils/dhcpc/dhcpc.c
+++ b/netutils/dhcpc/dhcpc.c
@@ -402,6 +402,7 @@ void dhcpc_close(void *handle)
 
 void uip_interrupt_udp_event(void)
 {
+#error OBSOLETE
   if (gpdhcpc)
     {
       sem_post(&gpdhcpc->sem);
diff --git a/netutils/resolv/resolv.c b/netutils/resolv/resolv.c
index f149c6a8028f2c96ecf9e74bff52c9a8f127fd3b..512f1ac5999c0f79601364b3bb634e411962d6e0 100644
--- a/netutils/resolv/resolv.c
+++ b/netutils/resolv/resolv.c
@@ -54,7 +54,7 @@
 #include <string.h>
 #include <debug.h>
 
-#include <net/uip/uip.h>
+#include <sys/socket.h>
 #include <net/uip/resolv.h>
 
 /****************************************************************************
@@ -87,11 +87,8 @@
 #define DNS_FLAG2_ERR_NONE        0x00
 #define DNS_FLAG2_ERR_NAME        0x03
 
-#define STATE_UNUSED 0
-#define STATE_NEW    1
-#define STATE_ASKING 2
-#define STATE_DONE   3
-#define STATE_ERROR  4
+#define SEND_BUFFER_SIZE 64
+#define RECV_BUFFER_SIZE 64
 
 /****************************************************************************
  * Private Types
@@ -140,8 +137,13 @@ struct namemap
  ****************************************************************************/
 
 static struct namemap names[RESOLV_ENTRIES];
-static uint8 seqno;
-static struct uip_udp_conn *resolv_conn = NULL;
+static uint8 gseqno;
+static int g_sockfd = -1;
+#ifdef CONFIG_NET_IPv6
+static struct sockaddr_in6 gdnsserver;
+#else
+static struct sockaddr_in gdnsserver;
+#endif
 
 /****************************************************************************
  * Private Functions
@@ -171,90 +173,76 @@ static unsigned char *parse_name(unsigned char *query)
  * not yet been queried and, if so, sends out a query.
  */
 
-static void check_entries(void)
+static int send_query(const char name)
 {
   register struct dns_hdr *hdr;
-  char *query, *nptr, *nameptr;
+  char *query;
+  char *nptr;
+  char **nameptr;
   static uint8 i;
   static uint8 n;
-  register struct namemap *namemapptr;
+  uint8 state = NEW_STATE;
+  uint8 seqno = gsegno++;
+  uint8 err;
+  static unsigned char endquery[] = {0,0,1,0,1};
+  char buffer[SEND_BUFFER_SIZE];
 
-  for(i = 0; i < RESOLV_ENTRIES; ++i)
-    {
-      namemapptr = &names[i];
-      if (namemapptr->state == STATE_NEW ||
-          namemapptr->state == STATE_ASKING)
-        {
-          if (namemapptr->state == STATE_ASKING)
-            {
-              if (--namemapptr->tmr == 0)
-                {
-                  if (++namemapptr->retries == MAX_RETRIES)
-                    {
-                      namemapptr->state = STATE_ERROR;
-                      resolv_found(namemapptr->name, NULL);
-                      continue;
-                    }
-                  namemapptr->tmr = namemapptr->retries;
-                }
-              else
-                {
-                  /* Its timer has not run out, so we move on to next entry. */
-                  continue;
-                }
-            }
-          else
-            {
-              namemapptr->state = STATE_ASKING;
-              namemapptr->tmr = 1;
-              namemapptr->retries = 0;
-            }
-          hdr = (struct dns_hdr *)uip_appdata;
-          memset(hdr, 0, sizeof(struct dns_hdr));
-          hdr->id = htons(i);
-          hdr->flags1 = DNS_FLAG1_RD;
-          hdr->numquestions = HTONS(1);
-          query = (char *)uip_appdata + 12;
-          nameptr = namemapptr->name;
-          --nameptr;
-
-          /* Convert hostname into suitable query format. */
-          do
-            {
-              ++nameptr;
-              nptr = query;
-              ++query;
-              for (n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr)
-                {
-                  *query = *nameptr;
-                  ++query;
-                  ++n;
-                }
-              *nptr = n;
-            }
-          while(*nameptr != 0);
-            {
-              static unsigned char endquery[] = {0,0,1,0,1};
-              memcpy(query, endquery, 5);
-            }
-          uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
-          break;
-        }
-    }
+  hdr               = (struct dns_hdr*)buffer;
+  memset(hdr, 0, sizeof(struct dns_hdr));
+  hdr->id           = htons(seqno);
+  hdr->flags1       = DNS_FLAG1_RD;
+  hdr->numquestions = HTONS(1);
+  query             = buffer + 12;
+
+  /* Convert hostname into suitable query format. */
+
+  nameptr = name - 1;
+  do
+   {
+     nameptr++;
+     nptr = query++;
+     for (n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr)
+       {
+         *query = *nameptr;
+         ++query;
+         ++n;
+       }
+     *nptr = n;
+   }
+  while(*nameptr != 0);
+
+  memcpy(query, endquery, 5);
+  return sendto(gsockfd, buffer, query + 5 - buffer);
 }
 
 /* Called when new UDP data arrives */
 
-static void newdata(void)
+#ifdef CONFIG_NET_IPv6
+#error "Not implemented
+#else
+int recv_response(struct sockaddr_in *addr)
+#endif
+
+hdr->flags2 & DNS_FLAG2_ERR_MASKstatic int (void)
 {
   unsigned char *nameptr;
+  char buffer[RECV_BUFFER_SIZE];
   struct dns_answer *ans;
   struct dns_hdr *hdr;
-  static uint8 nquestions, nanswers;
-  static uint8 i;
-  register struct namemap *namemapptr;
+  uint8 nquestions;
+  uint8 nanswers;
+  uint8 i;
+  int ret;
 
-  hdr = (struct dns_hdr *)uip_appdata;
+  /* Receive the response */
+
+  ret = recv(g_sockfd, buffer, RECV_BUFFER_SIZE);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  hdr = (struct dns_hdr *)b
 
   dbg( "ID %d\n", htons(hdr->id));
   dbg( "Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
@@ -263,226 +251,123 @@ static void newdata(void)
        htons(hdr->numquestions), htons(hdr->numanswers),
        htons(hdr->numauthrr), htons(hdr->numextrarr));
 
-  /* The ID in the DNS header should be our entry into the name
-   * table.
-   */
+  /* Check for error. If so, call callback to inform */
 
-  i = htons(hdr->id);
-  namemapptr = &names[i];
-  if (i < RESOLV_ENTRIES && namemapptr->state == STATE_ASKING)
+  if ((hdr->flags2 & DNS_FLAG2_ERR_MASK) != 0)
     {
-      /* This entry is now finished */
+      return ERROR;
+    }
 
-      namemapptr->state = STATE_DONE;
-      namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
+  /* We only care about the question(s) and the answers. The authrr
+   * and the extrarr are simply discarded.
+   */
 
-      /* Check for error. If so, call callback to inform */
+  nquestions = htons(hdr->numquestions);
+  nanswers   = htons(hdr->numanswers);
 
-      if (namemapptr->err != 0)
-        {
-          namemapptr->state = STATE_ERROR;
-          resolv_found(namemapptr->name, NULL);
-          return;
-        }
+  /* Skip the name in the question. XXX: This should really be
+   * checked agains the name in the question, to be sure that they
+   * match.
+    */
 
-      /* We only care about the question(s) and the answers. The authrr
-       * and the extrarr are simply discarded.
-       */
-
-      nquestions = htons(hdr->numquestions);
-      nanswers = htons(hdr->numanswers);
+  nameptr = parse_name((unsigned char *)buffer + 12) + 4;
 
-      /* Skip the name in the question. XXX: This should really be
-       * checked agains the name in the question, to be sure that they
-       * match.
+  for (; nanswers > 0; nanswers--)
+    {
+      /* The first byte in the answer resource record determines if it
+       * is a compressed record or a normal one.
        */
 
-      nameptr = parse_name((unsigned char *)uip_appdata + 12) + 4;
-
-      while(nanswers > 0)
+      if (*nameptr & 0xc0)
         {
-          /* The first byte in the answer resource record determines if it
-           * is a compressed record or a normal one.
-           */
-
-          if (*nameptr & 0xc0)
-            {
-              /* Compressed name. */
-
-              nameptr +=2;
-              dbg("Compressed anwser\n");
-            }
-          else
-            {
-              /* Not compressed name. */
-              nameptr = parse_name(nameptr);
-            }
-
-          ans = (struct dns_answer *)nameptr;
-          dbg("Answer: type %x, class %x, ttl %x, length %x\n",
-              htons(ans->type), htons(ans->class), (htons(ans->ttl[0]) << 16) | htons(ans->ttl[1]),
-              htons(ans->len));
-
-          /* Check for IP address type and Internet class. Others are discarded. */
-
-          if (ans->type == HTONS(1) && ans->class == HTONS(1) && ans->len == HTONS(4))
-            {
-              dbg("IP address %d.%d.%d.%d\n",
-                  htons(ans->ipaddr[0]) >> 8, htons(ans->ipaddr[0]) & 0xff,
-                  htons(ans->ipaddr[1]) >> 8, htons(ans->ipaddr[1]) & 0xff);
-
-              /* XXX: we should really check that this IP address is the one
-               * we want.
-               */
-
-              namemapptr->ipaddr[0] = ans->ipaddr[0];
-              namemapptr->ipaddr[1] = ans->ipaddr[1];
-
-              resolv_found(namemapptr->name, namemapptr->ipaddr);
-              return;
-            }
-          else
-            {
-              nameptr = nameptr + 10 + htons(ans->len);
-            }
-          --nanswers;
-        }
-    }
-}
+          /* Compressed name. */
 
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/* This function is called by the UIP interrupt handling logic whenevent an
- * event of interest occurs.
- */
-
-void uip_interrupt_udp_event(void)
-{
-  if (uip_udp_conn->rport == HTONS(53))
-    {
-      if (uip_poll())
-        {
-          check_entries();
+          nameptr +=2;
+          dbg("Compressed anwser\n");
         }
-      if (uip_newdata())
+      else
         {
-          newdata();
+          /* Not compressed name. */
+          nameptr = parse_name(nameptr);
         }
-    }
-}
-
-/* Queues a name so that a question for the name will be sent out. */
 
-void resolv_query(char *name)
-{
-  static uint8 i;
-  static uint8 lseq, lseqi;
-  register struct namemap *nameptr;
+      ans = (struct dns_answer *)nameptr;
+      dbg("Answer: type %x, class %x, ttl %x, length %x\n",
+          htons(ans->type), htons(ans->class), (htons(ans->ttl[0]) << 16) | htons(ans->ttl[1]),
+          htons(ans->len));
 
-  lseq = lseqi = 0;
+      /* Check for IP address type and Internet class. Others are discarded. */
 
-  for(i = 0; i < RESOLV_ENTRIES; ++i)
-    {
-      nameptr = &names[i];
-      if (nameptr->state == STATE_UNUSED)
+      if (ans->type == HTONS(1) && ans->class == HTONS(1) && ans->len == HTONS(4))
         {
-          break;
+          dbg("IP address %d.%d.%d.%d\n",
+              htons(ans->ipaddr[0]) >> 8, htons(ans->ipaddr[0]) & 0xff,
+              htons(ans->ipaddr[1]) >> 8, htons(ans->ipaddr[1]) & 0xff);
+
+           /* XXX: we should really check that this IP address is the one
+           * we want.
+           */
+
+          addr->sin_addr.s_addr = ((uint32)ans->ipaddr[0] << 16) | (uint32)ans->ipaddr[1];
+          return OK;
         }
-      if (seqno - nameptr->seqno > lseq)
+      else
         {
-          lseq = seqno - nameptr->seqno;
-          lseqi = i;
+          nameptr = nameptr + 10 + htons(ans->len);
         }
     }
-
-  if (i == RESOLV_ENTRIES)
-    {
-      i = lseqi;
-      nameptr = &names[i];
-    }
-
-  dbg("Using entry %d\n", i);
-
-  strcpy(nameptr->name, name);
-  nameptr->state = STATE_NEW;
-  nameptr->seqno = seqno;
-  ++seqno;
 }
 
-/* Look up a hostname in the array of known hostnames.
- *
- * Note: This function only looks in the internal array of known
- * hostnames, it does not send out a query for the hostname if none
- * was found. The function resolv_query() can be used to send a query
- * for a hostname.
- *
- * Return A pointer to a 4-byte representation of the hostname's IP
- * address, or NULL if the hostname was not found in the array of
- * hostnames.
- */
-
-uint16 *resolv_lookup(char *name)
-{
-  static uint8 i;
-  struct namemap *nameptr;
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
 
-  /* Walk through the list to see if the name is in there. If it is
-   * not, we return NULL.
-   */
+/* Get the binding for name. */
 
-  for(i = 0; i < RESOLV_ENTRIES; ++i)
+#ifdef CONFIG_NET_IPv6
+int resolv_query(char *name, struct sockaddr_in6 *addr)
+#else
+int resolv_query(char *name, struct sockaddr_in *addr)
+#endif
+{
+  int ret = send_query(name);
+  if (ret == 0)
     {
-      nameptr = &names[i];
-      if (nameptr->state == STATE_DONE && strcmp(name, nameptr->name) == 0)
-        {
-          return nameptr->ipaddr;
-        }
+      ret = recv_response(addr);
     }
-  return NULL;
+  return ret;
 }
 
-/* Obtain the currently configured DNS server.
- *
- * Return: A pointer to a 4-byte representation of the IP address of
- * the currently configured DNS server or NULL if no DNS server has
- * been configured.
- */
+/* Obtain the currently configured DNS server. */
 
-uint16 *resolv_getserver(void)
+#ifdef CONFIG_NET_IPv6
+void resolv_getserver(const struct sockaddr_in6 *dnsserver)
+#else
+void resolv_getserver(const struct sockaddr_in *dnsserver)
+#endif
 {
-  if (resolv_conn == NULL)
-    {
-      return NULL;
-    }
-  return resolv_conn->ripaddr;
+  memcpy(dnsserver, gdnsserver, sizeof(gdnsserver));
 }
 
-/* Configure which DNS server to use for queries.
- *
- * dnsserver A pointer to a 4-byte representation of the IP
- * address of the DNS server to be configured.
- */
+/* Configure which DNS server to use for queries */
 
-void resolv_conf(uint16 *dnsserver)
+#ifdef CONFIG_NET_IPv6
+void resolv_conf(const struct sockaddr_in6 *dnsserver)
+#else
+void resolv_conf(const struct sockaddr_in *dnsserver)
+#endif
 {
-  if (resolv_conn != NULL)
-    {
-      uip_udp_remove(resolv_conn);
-    }
-
-  resolv_conn = uip_udp_new(dnsserver, HTONS(53));
+  memcpy(&gdnsserver, dnsserver, sizeof(gdnsserver));
 }
 
 /* Initalize the resolver. */
 
-void resolv_init(void)
+int resolv_init(void)
 {
-  static uint8 i;
-
-  for(i = 0; i < RESOLV_ENTRIES; ++i)
+  g_sockfd = socket(PF_INET, SOCK_DGRAM, 0);
+  if (g_sockfd < 0)
     {
-      names[i].state = STATE_DONE;
+      return ERROR;
     }
+  return OK;
 }
diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c
index a89647ab5b0f1f22109e7e6ca0a028f3f7fc291e..6d0c0645b4bace26393cbcd3119f720ddf212fec 100644
--- a/netutils/webclient/webclient.c
+++ b/netutils/webclient/webclient.c
@@ -38,7 +38,7 @@
  *
  * This file is part of the uIP TCP/IP stack.
  *
- * $Id: webclient.c,v 1.2 2007-09-02 21:58:34 patacongo Exp $
+ * $Id: webclient.c,v 1.3 2007-09-03 20:34:44 patacongo Exp $
  *
  */
 
@@ -129,11 +129,10 @@ unsigned char webclient_get(char *host, uint16 port, char *file)
   ipaddr = &addr;
   if (uiplib_ipaddrconv(host, (unsigned char *)addr) == 0)
     {
-      ipaddr = (uip_ipaddr_t *)resolv_lookup(host);
-
-      if (ipaddr == NULL) {
-        return 0;
-      }
+      if (resolv_query(host, &ipaddr) < 0)
+        {
+          return ERROR;
+        }
   }
 
   /* Create a socket */
@@ -460,9 +459,14 @@ void uip_interrupt_event(void)
         }
       else
         {
-          if (resolv_lookup(s.host) == NULL)
+#ifdef CONFIG_NET_IPv6
+          struct sockaddr_in6 addr;
+#else
+          struct sockaddr_in addr;
+#endif
+          if (resolv_query(s.host, &addr) < 0)
             {
-              resolv_query(s.host);
+              return ERROR;
             }
           webclient_get(s.host, s.port, s.file);
         }