Index: trunk/kernel/syscalls/sys_socket.c
===================================================================
--- trunk/kernel/syscalls/sys_socket.c	(revision 670)
+++ trunk/kernel/syscalls/sys_socket.c	(revision 683)
@@ -45,5 +45,5 @@
 
 #if DEBUG_SYS_SOCKET
-static char* socket_cmd_type_str( uint32_t type )
+static char* socket_user_cmd_str( uint32_t type )
 {
     if     ( type == SOCK_CREATE      ) return "CREATE"; 
@@ -54,4 +54,6 @@
     else if( type == SOCK_SEND        ) return "SEND"; 
     else if( type == SOCK_RECV        ) return "RECV"; 
+    else if( type == SOCK_SENDTO      ) return "SENDTO"; 
+    else if( type == SOCK_RECVFROM    ) return "RECVFROM"; 
     else                                return "undefined";
 }
@@ -79,7 +81,8 @@
 
 #if DEBUG_SYS_SOCKET
+char kbuf[64];
 if( DEBUG_SYS_SOCKET < (uint32_t)tm_start )
-printk("\n[%s] thread[%x,%x] enter / %s / a1 %x / a2 %x / a3 %x / cycle %d\n",
-__FUNCTION__, process->pid, this->trdid, socket_cmd_type_str(cmd), 
+printk("\n[%s] thread[%x,%x] enter for %s / a1 %x / a2 %x / a3 %x / cycle %d\n",
+__FUNCTION__, process->pid, this->trdid, socket_user_cmd_str(cmd), 
 arg1, arg2, arg3, (uint32_t)tm_start );
 #endif
@@ -97,7 +100,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / domain %d =! AF_INET\n",
-__FUNCTION__ , process->pid , this->trdid , domain );
+printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / domain %d =! AF_INET / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , domain , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -110,7 +112,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / illegal socket type\n",
-__FUNCTION__ , process->pid , this->trdid );
+printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / illegal socket type / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid  , (uint32_t)tm_start);
 #endif
                 this->errno = EINVAL;
@@ -126,7 +127,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / cannot create socket\n",
-__FUNCTION__ , process->pid , this->trdid );
+printk("\n[ERROR] in %s : thread[%x,%x] / CREATE / cannot create socket / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid  , (uint32_t)tm_start);
 #endif
                 this->errno = EINVAL;
@@ -148,7 +148,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / BIND / socket address %x unmapped\n",
-__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
+printk("\n[ERROR] in %s : thread[%x,%x] / BIND / socket address %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -171,7 +170,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / BIND / cannot access socket[%x,%d]\n",
-__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid );
+printk("\n[ERROR] in %s : thread[%x,%x] / BIND / cannot access socket[%x,%d] / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -195,7 +193,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / LISTEN / cannot access socket[%x,%d]\n",
-__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid );
+printk("\n[ERROR] in %s : thread[%x,%x] / LISTEN / cannot access socket[%x,%d] / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -217,7 +214,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / CONNECT / server address %x unmapped\n",
-__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
+printk("\n[ERROR] in %s : thread[%x,%x] / CONNECT / server address %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -239,7 +235,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / LISTEN / cannot access socket[%x,%d]\n",
-__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid );
+printk("\n[ERROR] in %s : thread[%x,%x] / LISTEN / cannot access socket[%x,%d] / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid ,  process->pid, fdid , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -261,7 +256,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / CONNECT / server address %x unmapped\n",
-__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
+printk("\n[ERROR] in %s : thread[%x,%x] / CONNECT / server address %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -275,11 +269,10 @@
                                  &k_sockaddr.sin_port );
 
-            if( ret )
-            {
-
-#if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / ACCEPT / cannot access socket[%x,%d]\n",
-__FUNCTION__ , process->pid , this->trdid , process->pid, fdid );
+            if( ret < 0 )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / ACCEPT / cannot access socket[%x,%d] / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , process->pid, fdid , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -305,40 +298,47 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / SEND / buffer %x unmapped\n",
-__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
-#endif
-                this->errno = EINVAL;
-                ret = -1;
-                break;
-            }
-
-            // check length
-            if( length == 0 )
-            {
-
-#if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / SEND / buffer length is 0\n",
-__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
-#endif
-                this->errno = EINVAL;
-                ret = -1;
-                break;
-            }
-
-            // cal relevant relevant socket function
-            ret = socket_send( fdid , u_buf , length );
-
-            if( ret < 0 )
-            {
-
-#if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / SEND / cannot access socket[%x,%d] \n",
-__FUNCTION__ , process->pid , this->trdid , process->pid, fdid );
-#endif
-                this->errno = EINVAL;
-            }
+printk("\n[ERROR] in %s : thread[%x,%x] / SEND / u_buf %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // check length argument
+            if( (length == 0) || (length > (1<<CONFIG_SOCK_TX_BUF_ORDER)) )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / SEND / bad buffer length %d / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , length , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // cal relevant socket function
+            ret = socket_send( fdid,
+                               u_buf,
+                               length );
+            if( ret < 0 )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / SEND / cannot access socket[%x,%d] / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , process->pid, fdid , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+            }
+
+#if DEBUG_SYS_SOCKET
+if( DEBUG_SYS_SOCKET < (uint32_t)tm_start )
+{
+    hal_copy_from_uspace( XPTR( local_cxy , &kbuf ) , u_buf , ret );
+    printk("\n[%s] thread[%x,%x] send %d bytes <%s>\n",
+    __FUNCTION__, process->pid, this->trdid , ret, kbuf );
+}
+#endif
             break;
         }
@@ -355,21 +355,19 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / RECV / buffer %x unmapped\n",
-__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
-#endif
-                this->errno = EINVAL;
-                ret = -1;
-                break;
-            }
-
-            // check length
-            if( length == 0 )
-            {
-
-#if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / RECV / buffer length is 0\n",
-__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 );
+printk("\n[ERROR] in %s : thread[%x,%x] / RECV / u_buf %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // check length argument
+            if( (length == 0) || (length > (1<<CONFIG_SOCK_RX_BUF_ORDER)) )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / RECV / bad buffer length %d / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , length , (uint32_t)tm_start );
 #endif
                 this->errno = EINVAL;
@@ -379,16 +377,167 @@
 
             // cal relevant kernel socket function
-            ret =  socket_recv( fdid , u_buf , length );
-
-            if( ret < 0 )
-            {
-
-#if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / RECV / cannot access socket[%x,%d] \n",
-__FUNCTION__ , process->pid , this->trdid , process->pid, fdid );
-#endif
-                this->errno = EINVAL;
-            }
+            ret =  socket_recv( fdid, 
+                                u_buf,
+                                length );
+            if( ret < 0 )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / RECV / cannot access socket[%x,%d] / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , process->pid, fdid , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+            }
+
+#if DEBUG_SYS_SOCKET
+if( DEBUG_SYS_SOCKET < (uint32_t)tm_start )
+{
+    hal_copy_from_uspace( XPTR( local_cxy , &kbuf ) , u_buf , ret );
+    printk("\n[%s] thread[%x,%x] received %d bytes <%s>\n",
+    __FUNCTION__, process->pid, this->trdid , ret, kbuf );
+}
+#endif
+            break;
+        }
+        /////////////////
+        case SOCK_SENDTO:
+        {
+            sockaddr_in_t k_remote_addr;
+
+            uint32_t      fdid          = (uint32_t)arg1 & 0x0000FFFF;
+            uint32_t      length        = (uint32_t)arg1 >> 16;
+            uint8_t     * u_buf         = (uint8_t *)(intptr_t)arg2;
+            sockaddr_t  * u_remote_addr = (sockaddr_t *)(intptr_t)arg3;
+
+            // check u_buf mapped in user space
+            if( vmm_get_vseg( process , (intptr_t)arg2 , &vseg ) )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / SENDTO / u_buf %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // check u_remote_addr mapped in user space
+            if( vmm_get_vseg( process , (intptr_t)arg3 , &vseg ) )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / SENDTO / u_remote_addr %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg3 , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // check length argument
+            if( (length == 0) || (length > (1<<CONFIG_SOCK_TX_BUF_ORDER)) )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / SENDTO / bad length %d / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , length , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // make a kernel copy of the sockaddr_t structure
+            hal_copy_from_uspace( XPTR( local_cxy , &k_remote_addr ),
+                                  u_remote_addr, sizeof(sockaddr_t) );
+
+            // cal relevant socket function
+            ret = socket_sendto( fdid,
+                                 u_buf,
+                                 length,
+                                 k_remote_addr.sin_addr,
+                                 k_remote_addr.sin_port );
+            if( ret < 0 )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / SENDTO / cannot access socket[%x,%d] / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , process->pid, fdid , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+            }
+
+            break;
+        }
+        ///////////////////
+        case SOCK_RECVFROM:
+        {
+            sockaddr_in_t k_remote_addr;
+
+            uint32_t      fdid          = (uint32_t)arg1 & 0x0000FFFF;
+            uint32_t      length        = (uint32_t)arg1 >> 16;
+            uint8_t     * u_buf         = (uint8_t *)(intptr_t)arg2;
+            sockaddr_t  * u_remote_addr = (sockaddr_t *)(intptr_t)arg3;
+
+            // check buffer is mapped in user space
+            if( vmm_get_vseg( process , (intptr_t)arg2 , &vseg ) )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / RECVFROM / u_buf %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg2 , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // check u_remote_addr mapped in user space
+            if( vmm_get_vseg( process , (intptr_t)arg3 , &vseg ) )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / RECVFROM / u_remote_addr %x unmapped / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , (intptr_t)arg3 , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // check length argument
+            if( (length == 0) || (length > (1<<CONFIG_SOCK_RX_BUF_ORDER)) )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / RECVFROM / bad length %d / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , length , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+                ret = -1;
+                break;
+            }
+
+            // make a kernel copy of the sockaddr_t structure
+            hal_copy_from_uspace( XPTR( local_cxy , &k_remote_addr ),
+                                  u_remote_addr, sizeof(sockaddr_t) );
+
+            // cal relevant socket function
+            ret = socket_recvfrom( fdid,
+                                   u_buf,
+                                   length,
+                                   k_remote_addr.sin_addr,
+                                   k_remote_addr.sin_port );
+            if( ret < 0 )
+            {
+
+#if DEBUG_SYSCALLS_ERROR
+printk("\n[ERROR] in %s : thread[%x,%x] / RECVFROM / cannot access socket[%x,%d] / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , process->pid, fdid , (uint32_t)tm_start );
+#endif
+                this->errno = EINVAL;
+            }
+
             break;
         }
@@ -398,7 +547,6 @@
 
 #if DEBUG_SYSCALLS_ERROR
-if( DEBUG_SYSCALLS_ERROR < (uint32_t)tm_start )
-printk("\n[ERROR] in %s : thread[%x,%x] / undefined socket operation %d\n",
-__FUNCTION__ , process->pid , this->trdid , cmd );
+printk("\n[ERROR] in %s : thread[%x,%x] / undefined socket operation %d / cycle %d\n",
+__FUNCTION__ , process->pid , this->trdid , cmd , (uint32_t)tm_start );
 #endif
             this->errno = EINVAL;
@@ -413,7 +561,6 @@
 
 #if DEBUG_SYS_SOCKET
-if( DEBUG_SYS_SOCKET < tm_end )
-printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
-__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end );
+printk("\n[%s] thread[%x,%x] exit for %s / cycle %d\n",
+__FUNCTION__, process->pid, this->trdid, socket_user_cmd_str(cmd), (uint32_t)tm_end );
 #endif
 
