Index: trunk/src/VBox/Devices/Network/slirp/bootp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/bootp.c	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/bootp.c	(revision 19839)
@@ -41,4 +41,7 @@
             bc->allocated = 1;
             paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR));
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
+            bc->addr.s_addr = paddr->s_addr;
+#endif
             return bc;
         }
@@ -127,5 +130,5 @@
 }
 
-#ifndef VBOX_WITH_NAT_SERVICE
+#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
 static void bootp_reply(PNATState pData, struct bootp_t *bp)
 #else
@@ -135,5 +138,5 @@
     BOOTPClient *bc;
     struct mbuf *m; /* XXX: @todo vasily - it'd be better to reuse this mbuf here */
-#ifdef VBOX_WITH_NAT_SERVICE
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     struct bootp_t *bp = mtod(m0, struct bootp_t *);
     struct ethhdr *eh;
@@ -189,5 +192,5 @@
         return;
 
-#ifndef VBOX_WITH_NAT_SERVICE
+#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     /* XXX: this is a hack to get the client mac address */
     memcpy(client_ethaddr, bp->bp_hwaddr, 6);
@@ -196,5 +199,5 @@
     if ((m = m_get(pData)) == NULL)
         return;
-#ifdef VBOX_WITH_NAT_SERVICE
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     eh = mtod(m, struct ethhdr *);
     memcpy(eh->h_source, bp->bp_hwaddr, ETH_ALEN); /* XXX: if_encap just swap source with dest*/
@@ -218,5 +221,5 @@
                 return;
             }
-#ifdef VBOX_WITH_NAT_SERVICE
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
             memcpy(bc->macaddr, bp->bp_hwaddr, 6);
 #else
@@ -242,5 +245,5 @@
 
     /* Address/port of the DHCP server. */
-#ifndef VBOX_WITH_NAT_SERVICE
+#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
 #else
@@ -398,5 +401,5 @@
 
     if (bp->bp_op == BOOTP_REQUEST)
-#ifndef VBOX_WITH_NAT_SERVICE
+#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
         bootp_reply(pData, bp);
 #else
Index: trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/ip_icmp.c	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/ip_icmp.c	(revision 19839)
@@ -539,15 +539,13 @@
     {
         int new_m_size;
-#ifdef VBOX_WITH_NAT_SERVICE
-        struct ethhdr *eh, *eh0;
-        eh0 = (struct ethhdr *)msrc->m_dat;
-        eh = (struct ethhdr *)m->m_dat;
-        memcpy(eh->h_source, eh0->h_source, ETH_ALEN);
-#endif
-        m->m_data += if_maxlinkhdr;
+        m_adj(m, if_maxlinkhdr);
         new_m_size = sizeof(struct ip) + ICMP_MINLEN + msrc->m_len + ICMP_MAXDATALEN;
         if (new_m_size>m->m_size)
             m_inc(m, new_m_size);
     }
+    /* XXX (vasily - r) not very safe code here add M_EXT assertion, 
+     * need replace code here with more safe constructions
+     */
+    Assert((m->m_flags & M_EXT) == 0 && (msrc->m_flags & M_EXT) == 0);
     memcpy(m->m_data, msrc->m_data, msrc->m_len);
     m->m_len = msrc->m_len;                /* copy msrc to m */
Index: trunk/src/VBox/Devices/Network/slirp/ip_output.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/ip_output.c	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/ip_output.c	(revision 19839)
@@ -45,4 +45,24 @@
 #include <slirp.h>
 
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
+char * rt_lookup_in_cache(PNATState pData, uint32_t dst)
+{
+    int i;
+   /* temporary do for dhcp client */ 
+    for(i = 0; i < NB_ADDR; i++)
+    {
+        if (    bootp_clients[i].allocated 
+            && bootp_clients[i].addr.s_addr == dst)
+        {
+            return &bootp_clients[i].macaddr[0];
+        }
+    }
+    if (dst != 0)
+    {
+        return pData->slirp_ethaddr;
+    }
+   return NULL; 
+}
+#endif
 
 /*
@@ -107,13 +127,21 @@
         ip->ip_sum = 0;
         ip->ip_sum = cksum(m, hlen);
-
-#ifdef VBOX_WITH_NAT_SERVICE
-        {
-            struct ethhdr *eh, *eh0;
-            eh = (struct ethhdr *)m->m_dat;
-            eh0 = (struct ethhdr *)m0->m_dat;
-            memcpy(eh->h_source, eh0->h_source, ETH_ALEN);
-        }
-#endif
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
+        /* Current TCP/IP stack hasn't routing information at 
+         * all so we need to calculate destination ethernet address 
+         */
+        {
+            extern uint8_t zerro_ethaddr[ETH_ALEN];
+            struct ethhdr *eh;
+            eh = (struct ethhdr *)MBUF_HEAD(m);
+            if (memcmp(eh->h_source, zerro_ethaddr, ETH_ALEN) == 0) {
+                char *dst = rt_lookup_in_cache(pData, ip->ip_dst.s_addr); 
+                if (dst != NULL) {
+                    memcpy(eh->h_source, dst, ETH_ALEN); 
+                }
+            }
+        }
+#endif
+
         if_output(pData, so, m);
         goto done;
@@ -150,5 +178,5 @@
         for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len)
         {
-#ifdef VBOX_WITH_NAT_SERVICE
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
             struct ethhdr *eh0;
             struct ethhdr *eh;
@@ -163,9 +191,9 @@
             }
 #ifdef VBOX_WITH_NAT_SERVICE
-            eh0 = (struct ethhdr *)m0->m_dat; 
-            eh = (struct ethhdr *)m->m_dat;
+            eh0 = (struct ethhdr *)MBUF_HEAD(m0);
+            eh = (struct ethhdr *)MBUF_HEAD(m);
             memcpy(eh->h_source, eh0->h_source, ETH_ALEN);
 #endif
-            m->m_data += if_maxlinkhdr;
+            m_adj(m, if_maxlinkhdr);
             mhip = mtod(m, struct ip *);
             *mhip = *ip;
Index: trunk/src/VBox/Devices/Network/slirp/slirp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 19839)
@@ -201,5 +201,5 @@
 };
 
-static const uint8_t zerro_ethaddr[6] =
+const uint8_t zerro_ethaddr[6] =
 {
     0x0, 0x0, 0x0, 0x0, 0x0, 0x0
@@ -660,4 +660,7 @@
 #else
     special_addr.s_addr = u32NetAddr;
+#endif
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
+    pData->slirp_ethaddr = &special_ethaddr;
 #endif
     alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
@@ -1399,5 +1402,5 @@
 }
 
-#ifndef VBOX_WITH_NAT_SERVICE
+#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
 #define ETH_ALEN        6
 #define ETH_HLEN        14
@@ -1450,10 +1453,9 @@
 
     mr = m_get(pData);
-#ifdef VBOX_WITH_NAT_SERVICE
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     reh = mtod(mr, struct ethhdr *);
     memcpy(reh->h_source, eh->h_source, ETH_ALEN); /* XXX: if_encap will swap src and dst*/ 
-    Log4(("NAT: arp:[%hhx:%hhx:%hhx:%hhx:%hhx:%hhx]->[%hhx:%hhx:%hhx:%hhx:%hhx:%hhx]\n",
-        reh->h_source[0], reh->h_source[1], reh->h_source[2], reh->h_source[3], reh->h_source[4], reh->h_source[5], 
-        reh->h_dest[0], reh->h_dest[1], reh->h_dest[2], reh->h_dest[3], reh->h_dest[4], reh->h_dest[5]));
+    Log4(("NAT: arp:%R[ether]->%R[ether]\n",
+        reh->h_source, reh->h_dest));
     Log4(("NAT: arp: %R[IP4]\n", &tip));
 #endif
@@ -1524,8 +1526,6 @@
         return;
     }
-    Log4(("NAT: in:[%hhx:%hhx:%hhx:%hhx:%hhx:%hhx]->[%hhx:%hhx:%hhx:%hhx:%hhx:%hhx]\n",
-        eh->h_source[0], eh->h_source[1], eh->h_source[2], eh->h_source[3], eh->h_source[4], eh->h_source[5], 
-        eh->h_dest[0], eh->h_dest[1], eh->h_dest[2], eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]));
-#ifdef VBOX_WITH_NAT_SERVICE
+    Log4(("NAT: in:%R[ether]->%R[ether]\n", eh->h_source, eh->h_dest));
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     if (memcmp(eh->h_source, special_ethaddr, ETH_ALEN) == 0) 
     {
@@ -1598,5 +1598,5 @@
     }
 
-#ifndef VBOX_WITH_NAT_SERVICE
+#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
     memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
@@ -1650,5 +1650,5 @@
 void slirp_set_ethaddr(PNATState pData, const uint8_t *ethaddr)
 {
-#ifndef VBOX_WITH_NAT_SERVICE
+#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     memcpy(client_ethaddr, ethaddr, ETH_ALEN);
 #endif
Index: trunk/src/VBox/Devices/Network/slirp/slirp.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.h	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.h	(revision 19839)
@@ -358,5 +358,5 @@
 
 
-# ifdef VBOX_WITH_NAT_SERVICE
+# ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
 #  define ETH_ALEN        6
 #  define ETH_HLEN        14
Index: trunk/src/VBox/Devices/Network/slirp/slirp_state.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 19839)
@@ -41,4 +41,7 @@
     bool allocated;
     uint8_t macaddr[6];
+#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
+    struct in_addr addr;
+#endif
 } BOOTPClient;
 
@@ -126,6 +129,8 @@
     struct in_addr loopback_addr;
     uint32_t netmask;
-#ifndef VBOX_WITH_NAT_SERVICE
+#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
     uint8_t client_ethaddr[6];
+#else
+    uint8_t *slirp_ethaddr;
 #endif
     struct ex_list *exec_list;
Index: trunk/src/VBox/Devices/Network/slirp/socket.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 19839)
@@ -593,15 +593,4 @@
              * make it look like that's where it came from, done by udp_output
              */
-#ifdef VBOX_WITH_NAT_SERVICE
-            {
-                struct ethhdr *eh0;
-                struct ethhdr *eh;
-                Assert(so->so_m);
-                eh0 = (struct ethhdr *)so->so_m->m_dat;
-                eh = (struct ethhdr *)m->m_dat;
-
-                memcpy(eh->h_source, eh0->h_source, ETH_ALEN);
-            }
-#endif
             udp_output(pData, so, m, &addr);
             SOCKET_UNLOCK(so);
Index: trunk/src/VBox/Devices/Network/slirp/tcp_input.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_input.c	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_input.c	(revision 19839)
@@ -294,13 +294,5 @@
         tp = sototcpcb(so);
         m = so->so_m;
-#ifdef VBOX_WITH_NAT_SERVICE
-        {
-            struct ethhdr *eh;
-
-            Assert(m);
-            eh = (struct ethhdr *)m->m_dat;
-            memcpy(so->so_ethaddr, eh->h_source, ETH_ALEN);
-        }
-#endif
+
         so->so_m = 0;
         ti = so->so_ti;
@@ -483,12 +475,4 @@
             goto dropwithreset;
         }
-#ifdef VBOX_WITH_NAT_SERVICE
-        Assert(m);
-        so->so_m = m; /* save the initial packet */
-        {
-            struct ethhdr *eh0;
-            eh0 = (struct ethhdr *)m->m_dat;
-        }
-#endif        
         SOCKET_LOCK(so); 
         sbreserve(&so->so_snd, tcp_sndspace);
Index: trunk/src/VBox/Devices/Network/slirp/tcp_output.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_output.c	(revision 19838)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_output.c	(revision 19839)
@@ -378,19 +378,4 @@
             goto out;
         }
-#ifdef VBOX_WITH_NAT_SERVICE
-        {
-            struct ethhdr *eh, *eh0;
-            eh = (struct ethhdr *)m->m_dat;
-            if (so->so_m)
-            {
-                eh0 = (struct ethhdr *)so->so_m->m_dat;
-                memcpy(eh->h_source, eh0->h_source, ETH_ALEN);
-            }
-            else 
-            {
-                memcpy(eh->h_source, so->so_ethaddr, ETH_ALEN);
-            }
-        }
-#endif
         m->m_data += if_maxlinkhdr;
         m->m_len = hdrlen;
@@ -442,11 +427,4 @@
             goto out;
         }
-#ifdef VBOX_WITH_NAT_SERVICE
-        {
-            struct ethhdr *eh;
-            eh = (struct ethhdr *)m->m_dat;
-            memcpy(eh->h_source, so->so_ethaddr, ETH_ALEN);
-        }
-#endif
         m->m_data += if_maxlinkhdr;
         m->m_len = hdrlen;
