diff --git a/kernel/trunk/network/IPv4.inc b/kernel/trunk/network/IPv4.inc
index e58071dc8a..15c377f9ce 100644
--- a/kernel/trunk/network/IPv4.inc
+++ b/kernel/trunk/network/IPv4.inc
@@ -19,6 +19,13 @@
 $Revision: 3515 $
 
 IPv4_MAX_FRAGMENTS              = 64
+IPv4_MAX_ROUTES                 = 64
+
+IPv4_ROUTE_FLAG_UP              = 1 shl 0
+IPv4_ROUTE_FLAG_GATEWAY         = 1 shl 1
+IPv4_ROUTE_FLAG_HOST            = 1 shl 2
+IPv4_ROUTE_FLAG_D               = 1 shl 3       ; Route was created by a redirect
+IPv4_ROUTE_FLAG_M               = 1 shl 4       ; Route was modified by a redirect
 
 struct  IPv4_header
 
@@ -54,6 +61,16 @@ struct  IPv4_FRAGMENT_entry             ; This structure will replace the ethern
                                         ; Ip header begins here (we will need the IP header to re-construct the complete packet)
 ends
 
+struct  IPv4_ROUTE
+
+        Destination             dd ?
+        Gateway                 dd ?
+        Flags                   dd ?
+        Use                     dd ?
+        Interface               dd ?
+
+ends
+
 
 uglobal
 align 4
@@ -70,6 +87,8 @@ align 4
 
         IPv4_FRAGMENT_LIST      rb IPv4_MAX_FRAGMENTS * sizeof.IPv4_FRAGMENT_slot
 
+        IPv4_ROUTES             rd IPv4_MAX_ROUTES * sizeof.IPv4_ROUTE
+
 endg
 
 
diff --git a/kernel/trunk/network/stack.inc b/kernel/trunk/network/stack.inc
index a2fd1daa84..8fc5a570f3 100644
--- a/kernel/trunk/network/stack.inc
+++ b/kernel/trunk/network/stack.inc
@@ -29,7 +29,7 @@ uglobal
 endg
 
 DEBUG_NETWORK_ERROR     = 1
-DEBUG_NETWORK_VERBOSE   = 0
+DEBUG_NETWORK_VERBOSE   = 1
 
 NET_DEVICES_MAX         = 16
 ARP_BLOCK               = 1             ; true or false
@@ -152,7 +152,8 @@ NET_LINK_PPP            = 2     ; Point to Point Protocol (PPPoE, ...)
 NET_LINK_IEEE802.11     = 3     ; IEEE 802.11 (WiFi)
 
 ; Hardware acceleration bits
-HWACC_TCP_IPv4          = 1 shl 0
+NET_HWACC_TCP_IPv4_IN   = 1 shl 0
+NET_HWACC_TCP_IPv4_OUT  = 1 shl 1
 
 struct  NET_DEVICE
 
diff --git a/kernel/trunk/network/tcp.inc b/kernel/trunk/network/tcp.inc
index f174f3b3a6..66de25103a 100644
--- a/kernel/trunk/network/tcp.inc
+++ b/kernel/trunk/network/tcp.inc
@@ -143,6 +143,62 @@ align 4
         TCP_input_event         dd ?
 endg
 
+uglobal
+align 4
+
+        TCPS_accepts            dd ?    ; #SYNs received in LISTEN state
+        TCPS_closed             dd ?    ; #connections closed (includes drops)
+        TCPS_connattempt        dd ?    ; #connections initiated (calls to connect)
+        TCPS_conndrops          dd ?    ; #embryonic connections dropped (before SYN received)
+        TCPS_connects           dd ?    ; #connections established actively or passively
+        TCPS_delack             dd ?    ; #delayed ACKs sent
+        TCPS_drops              dd ?    ; #connections dropped (after SYN received)
+        TCPS_keepdrops          dd ?    ; #connections dropped in keepalive (established or awaiting SYN)
+        TCPS_keepprobe          dd ?    ; #keepalive probes sent
+        TCPS_keeptimeo          dd ?    ; #times keepalive timer or connections-establishment timer expire
+        TCPS_pawsdrop           dd ?    ; #segments dropped due to PAWS
+        TCPS_pcbcachemiss       dd ?    ; #times PCB cache comparison fails
+        TCPS_persisttimeo       dd ?    ; #times persist timer expires
+        TCPS_predack            dd ?    ; #times header prediction correct for ACKs
+        TCPS_preddat            dd ?    ; #times header prediction correct for data packets
+        TCPS_rcvackbyte         dd ?    ; #bytes ACKed by received ACKs
+        TCPS_rcvackpack         dd ?    ; #received ACK packets
+        TCPS_rcvacktoomuch      dd ?    ; #received ACKs for unsent data
+        TCPS_rcvafterclose      dd ?    ; #packets received after connection closed
+        TCPS_rcvbadoff          dd ?    ; #packets received with invalid header length
+        TCPS_rcvbadsum          dd ?    ; #packets received with checksum errors
+        TCPS_rcvbyte            dd ?    ; #bytes received in sequence
+        TCPS_rcvbyteafterwin    dd ?    ; #bytes received beyond advertised window
+        TCPS_rcvdupack          dd ?    ; #duplicate ACKs received
+        TCPS_rcvdupbyte         dd ?    ; #bytes receivedin completely duplicate packets
+        TCPS_rcvduppack         dd ?    ; #packets received with completely duplicate bytes
+        TCPS_rcvoobyte          dd ?    ; #out-of-order bytes received
+        TCPS_rcvoopack          dd ?    ; #out-of-order packets received
+        TCPS_rcvpack            dd ?    ; #packets received in sequence
+        TCPS_rcvpackafterwin    dd ?    ; #packets with some data beyond advertised window
+        TCPS_rcvpartdupbyte     dd ?    ; #duplicate bytes in part-duplicate packets
+        TCPS_rcvpartduppack     dd ?    ; #packets with some duplicate data
+        TCPS_rcvshort           dd ?    ; #packets received too short
+        TCPS_rcvtotal           dd ?    ; #total packets received
+        TCPS_rcvwinprobe        dd ?    ; #window probe packets received
+        TCPS_rcvwinupd          dd ?    ; #received window update packets
+        TCPS_rexmttimeo         dd ?    ; #retransmission timeouts
+        TCPS_rttupdated         dd ?    ; #times RTT estimators updated
+        TCPS_segstimed          dd ?    ; #segments for which TCP tried to measure RTT
+        TCPS_sndacks            dd ?    ; #ACK-only packets sent (data length = 0)
+        TCPS_sndbyte            dd ?    ; #data bytes sent
+        TCPS_sndctrl            dd ?    ; #control (SYN, FIN, RST) packets sent (data length = 0)
+        TCPS_sndpack            dd ?    ; #data packets sent (data length > 0)
+        TCPS_sndprobe           dd ?    ; #window probes sent (1 byte of data forced by persist timer)
+        TCPS_sndrexmitbyte      dd ?    ; #data bytes retransmitted
+        TCPS_sndrexmitpack      dd ?    ; #data packets retransmitted
+        TCPS_sndtotal           dd ?    ; total #packets sent
+        TCPS_sndurg             dd ?    ; #packets sent with URG-only (data length=0)
+        TCPS_sndwinup           dd ?    ; #window update-only packets sent (data length=0)
+        TCPS_timeoutdrop        dd ?    ; #connections dropped in retransmission timeout
+
+endg
+
 
 ;-----------------------------------------------------------------
 ;
diff --git a/kernel/trunk/network/tcp_input.inc b/kernel/trunk/network/tcp_input.inc
index 773119412e..1f0f3e4e5c 100644
--- a/kernel/trunk/network/tcp_input.inc
+++ b/kernel/trunk/network/tcp_input.inc
@@ -643,7 +643,7 @@ endl
 ; Remove duplicate data and update urgent offset
 
   .duplicate:
-        DEBUGF  1,  "TCP_input: trimming duplicate data\n"
+        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_input: trimming duplicate data\n"
 
 ; Trim data from left side of window
         add     [dataoffset], eax
diff --git a/kernel/trunk/network/tcp_output.inc b/kernel/trunk/network/tcp_output.inc
index 1ae7e9266f..1d64570a1a 100644
--- a/kernel/trunk/network/tcp_output.inc
+++ b/kernel/trunk/network/tcp_output.inc
@@ -21,8 +21,7 @@ $Revision: 3289 $
 ; TCP_output
 ;
 ; IN:  eax = socket pointer
-;
-; OUT: /
+; OUT: eax = 0 on success/errorcode
 ;
 ;-----------------------------------------------------------------
 align 4
@@ -177,31 +176,31 @@ endl
         jz      .len_zero
 
         cmp     esi, [eax + TCP_SOCKET.t_maxseg]
-        je      TCP_send
+        je      .send
 
         add     ebx, esi                                ; offset + length
         cmp     ebx, [eax + STREAM_SOCKET.snd.size]
         jb      @f
 
         test    [eax + TCP_SOCKET.t_flags], TF_NODELAY
-        jnz     TCP_send
+        jnz     .send
 
         mov     ebx, [eax + TCP_SOCKET.SND_MAX]
         cmp     ebx, [eax + TCP_SOCKET.SND_UNA]
-        je      TCP_send
+        je      .send
        @@:
 
         test    [eax + TCP_SOCKET.t_force], -1  ;;;
-        jnz     TCP_send
+        jnz     .send
 
         mov     ebx, [eax + TCP_SOCKET.max_sndwnd]
         shr     ebx, 1
         cmp     esi, ebx
-        jae     TCP_send
+        jae     .send
 
         mov     ebx, [eax + TCP_SOCKET.SND_NXT]
         cmp     ebx, [eax + TCP_SOCKET.SND_MAX]
-        jb      TCP_send
+        jb      .send
 
   .len_zero:
 
@@ -233,9 +232,10 @@ endl
         mov     edi, [eax + TCP_SOCKET.t_maxseg]
         shl     edi, 1
 
-;        cmp     ebx, edi
-;        jae     TCP_send
+        cmp     ebx, edi
+        jae     .send
 
+        shl     ebx, 1
 ;        cmp     ebx, [eax + TCP_SOCKET.]    ;;; TODO: check with receive buffer high water mark
 ;        jae     TCP_send
 
@@ -244,17 +244,15 @@ endl
 ;--------------------------
 ; Should a segment be sent? (174)
 
-        DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_output: 174\n"
-
         test    [eax + TCP_SOCKET.t_flags], TF_ACKNOW   ; we need to ACK
-        jnz     TCP_send
+        jnz     .send
 
         test    dl, TH_SYN + TH_RST                     ; we need to send a SYN or RST
-        jnz     TCP_send
+        jnz     .send
 
         mov     ebx, [eax + TCP_SOCKET.SND_UP]          ; when urgent pointer is beyond start of send bufer
         cmp     ebx, [eax + TCP_SOCKET.SND_UNA]
-        ja      TCP_send
+        ja      .send
 
         test    dl, TH_FIN
         jz      .enter_persist  ; no reason to send, enter persist state
@@ -262,11 +260,11 @@ endl
 ; FIN was set, only send if not already sent, or on retransmit
 
         test    [eax + TCP_SOCKET.t_flags], TF_SENTFIN
-        jz      TCP_send
+        jz      .send
 
         mov     ebx, [eax + TCP_SOCKET.SND_NXT]
         cmp     ebx, [eax + TCP_SOCKET.SND_UNA]
-        je      TCP_send
+        je      .send
 
 ;--------------------
 ; Enter persist state (191)
@@ -302,13 +300,6 @@ endl
         ret
 
 
-
-
-
-
-
-
-
 ;-----------------------------------------------
 ;
 ; Send a segment (222)
@@ -318,8 +309,7 @@ endl
 ;  dl = flags
 ;
 ;-----------------------------------------------
-align 4
-TCP_send:
+  .send:
 
         DEBUGF  DEBUG_NETWORK_VERBOSE, "TCP_send: socket=%x length=%u flags=%x\n", eax, esi, dl
 
@@ -570,7 +560,13 @@ TCP_send:
 ;--------------------
 ; Create the checksum
 
+        xor     dx, dx
+        test    [ebx + NET_DEVICE.hwacc], NET_HWACC_TCP_IPv4_OUT
+        jnz     .checksum_ok
+
         TCP_checksum (eax + IP_SOCKET.LocalIP), (eax + IP_SOCKET.RemoteIP)
+
+  .checksum_ok:
         mov     [esi + TCP_header.Checksum], dx
 
 ;----------------