Index: trunk/src/VBox/Devices/Network/slirp/ip_input.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/ip_input.c	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/ip_input.c	(revision 20164)
@@ -76,9 +76,11 @@
 {
     register struct ip *ip;
-    int hlen;
+    int hlen = 0;
 
     DEBUG_CALL("ip_input");
     DEBUG_ARG("m = %lx", (long)m);
-    DEBUG_ARG("m_len = %d", m->m_len);
+    ip = mtod(m, struct ip *);
+    DEBUG_ARG("ip_dst=%R[IP4](len:%d) m_len = %d", &ip->ip_dst, ntohs(ip->ip_len), m->m_len);
+    Log2(("ip_dst=%R[IP4](len:%d) m_len = %d\n", &ip->ip_dst, ntohs(ip->ip_len), m->m_len));
 
     ipstat.ips_total++;
@@ -86,5 +88,6 @@
     {
         int rc;
-        rc = LibAliasIn(LIST_FIRST(&instancehead), mtod(m, char *), m->m_len);
+        rc = LibAliasIn(m->m_la ? m->m_la : pData->proxy_alias, mtod(m, char *), 
+            m->m_len);
         Log2(("NAT: LibAlias return %d\n", rc));
     }
@@ -199,4 +202,6 @@
     return;
 bad:
+    Log2(("NAT: IP datagram to %R[IP4] with size(%d) claimed as bad\n", 
+        &ip->ip_dst, ip->ip_len));
     m_freem(pData, m);
     return;
Index: trunk/src/VBox/Devices/Network/slirp/ip_output.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/ip_output.c	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/ip_output.c	(revision 20164)
@@ -153,5 +153,6 @@
         {
             int rc;
-            rc = LibAliasOut(LIST_FIRST(&instancehead), mtod(m, char *), m->m_len);
+            rc = LibAliasOut((m->m_la ? m->m_la : pData->proxy_alias), 
+                mtod(m, char *), m->m_len);
             Log2(("NAT: LibAlias return %d\n", rc));
         }
@@ -254,5 +255,6 @@
         {
             int rc;
-            rc = LibAliasOut(LIST_FIRST(&instancehead), mtod(m, char *), m->m_len);
+            rc = LibAliasOut((m->m_la ? m->m_la : pData->proxy_alias), 
+                mtod(m, char *), m->m_len);
             Log2(("NAT: LibAlias return %d\n", rc));
         }
@@ -269,5 +271,6 @@
             {
                 int rc;
-                rc = LibAliasOut(LIST_FIRST(&instancehead), mtod(m, char *), m->m_len);
+                rc = LibAliasOut((m->m_la ? m->m_la : pData->proxy_alias), 
+                    mtod(m, char *), m->m_len);
                 Log2(("NAT: LibAlias return %d\n", rc));
             }
Index: trunk/src/VBox/Devices/Network/slirp/mbuf.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/mbuf.c	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/mbuf.c	(revision 20164)
@@ -82,4 +82,7 @@
     m->m_nextpkt = 0;
     m->m_prevpkt = 0;
+#ifdef VBOX_WITH_SLIRP_ALIAS
+    m->m_la = NULL;
+#endif
 
 end_error:
Index: trunk/src/VBox/Devices/Network/slirp/mbuf.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/mbuf.h	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/mbuf.h	(revision 20164)
@@ -74,4 +74,7 @@
     caddr_t mh_data;           /* Location of data */
     int     mh_len;            /* Amount of data in this mbuf */
+#ifndef VBOX_SLIRP_ALIAS
+    struct libalias *mh_la;     /*Real freebsd store hocksin similar way*/
+#endif
 };
 
@@ -111,4 +114,7 @@
 #define m_ext           M_dat.m_ext_
 #define m_so            m_hdr.mh_so
+#ifdef VBOX_WITH_SLIRP_ALIAS
+#define m_la            m_hdr.mh_la
+#endif
 
 #define ifq_prev m_prev
Index: trunk/src/VBox/Devices/Network/slirp/slirp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 20164)
@@ -686,16 +686,15 @@
 #ifdef VBOX_WITH_SLIRP_ALIAS
     {
-        struct libalias *lib = NULL; 
         int flags = 0;
-        lib = LibAliasInit(pData, NULL);
-        if (lib == NULL)
+        pData->proxy_alias = LibAliasInit(pData, NULL);
+        if (pData->proxy_alias == NULL)
         {
             LogRel(("NAT: LibAlias default rule wasn't initialized\n"));
             AssertMsgFailed(("NAT: LibAlias default rule wasn't initialized\n"));
         }
-        flags = LibAliasSetMode(lib, 0, 0);
+        flags = LibAliasSetMode(pData->proxy_alias, 0, 0);
         flags |= PKT_ALIAS_LOG; /* set logging */
-        flags = LibAliasSetMode(lib, flags, ~0);
-        LibAliasSetAddress(lib, special_addr);
+        flags = LibAliasSetMode(pData->proxy_alias, flags, ~0);
+        LibAliasSetAddress(pData->proxy_alias, special_addr);
         ftp_alias_load();
         
@@ -1541,4 +1540,5 @@
     struct ethhdr *eh = (struct ethhdr*)pkt;
 
+    Log2(("NAT: slirp_input %d\n", pkt_len));
     if (pkt_len < ETH_HLEN)
     {
@@ -1546,5 +1546,5 @@
         return;
     }
-    Log4(("NAT: in:%R[ether]->%R[ether]\n", eh->h_source, eh->h_dest));
+    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) 
@@ -1582,6 +1582,5 @@
              * the first outgoing connection gets an incorrect timestamp. */
             updtime(pData);
-            m->m_data += ETH_HLEN;
-            m->m_len -= ETH_HLEN;
+            m_adj(m, ETH_HLEN);
             ip_input(pData, m);
             break;
@@ -1629,5 +1628,9 @@
         memcpy(eh->h_source, special_ethaddr, ETH_ALEN);
         Assert(memcmp(eh->h_dest, special_ethaddr, ETH_ALEN) != 0);
-        Assert(memcmp(eh->h_dest, zerro_ethaddr, ETH_ALEN) != 0);
+        if (memcmp(eh->h_dest, zerro_ethaddr, ETH_ALEN) == 0)
+        {
+            /* don't do anything */
+            goto done;
+        }
     }
 #endif
@@ -1638,4 +1641,5 @@
     memcpy(buf, mtod(m, uint8_t *), m->m_len);
     slirp_output(pData->pvUser, NULL, buf, m->m_len);
+done:
     m_free(pData, m);
 #endif
@@ -1646,4 +1650,14 @@
 {
     struct socket *so;
+#ifdef VBOX_WITH_SLIRP_ALIAS
+    struct alias_link *link;
+    struct libalias *lib;
+    int flags;
+    struct sockaddr sa;
+    struct sockaddr_in *psin;
+    socklen_t socketlen;
+    struct in_addr alias;
+    int rc;
+#endif
     Log2(("NAT: set redirect %s hp:%d gp:%d\n", (is_udp?"UDP":"TCP"), host_port, guest_port));
     if (is_udp)
@@ -1657,6 +1671,48 @@
                       htons(guest_port), 0);
     }
+#ifndef VBOX_WITH_SLIRP_ALIAS
     Log2(("NAT: redirecting socket %R[natsock]\n", so));
     return (so != NULL ? 0 : -1);
+#else
+
+    psin = (struct sockaddr_in *)&sa;
+    psin->sin_family = AF_INET;
+    psin->sin_port = 0;
+    psin->sin_addr.s_addr = INADDR_ANY;
+    socketlen = sizeof(struct sockaddr);
+    
+    rc = getsockname(so->s, &sa, &socketlen); 
+    if (rc < 0 || sa.sa_family != AF_INET) 
+    {
+        Log(("NAT: can't get socket's name\n"));
+        return 1;
+    }
+
+    psin = (struct sockaddr_in *)&sa;
+    
+#if 1
+    lib = LibAliasInit(pData, NULL);
+    flags = LibAliasSetMode(lib, 0, 0);
+    flags |= PKT_ALIAS_LOG; /* set logging */
+    flags |= PKT_ALIAS_REVERSE; /* set logging */
+    flags = LibAliasSetMode(lib, flags, ~0);
+#else
+    lib = LIST_FIRST(&instancehead);
+#endif
+
+    alias.s_addr =  htonl(ntohl(guest_addr.s_addr) | CTL_ALIAS);
+    link = LibAliasRedirectPort(lib, psin->sin_addr, htons(host_port),
+        alias, htons(guest_port),
+        special_addr,  -1, /* not very clear for now*/
+        (is_udp ? IPPROTO_UDP : IPPROTO_TCP));
+    if (link == NULL) 
+    {
+        Log(("NAT: can't create redirect\n"));
+        return 1;
+    }
+    so->so_la = lib;
+    
+    return 0;
+#endif
 }
 
@@ -1733,5 +1789,5 @@
     Log2(("proto: %d, dport: %d sport: %d\n", proto, hdport, hsport));
     service = 0;
-#if 1
+#if 0
     /* Always return 0 here */
     switch (hdport)
Index: trunk/src/VBox/Devices/Network/slirp/slirp_state.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 20164)
@@ -228,4 +228,5 @@
 #ifdef VBOX_WITH_SLIRP_ALIAS
     LIST_HEAD(, libalias) instancehead;
+    struct libalias *proxy_alias;
 #endif
     STAMPROFILE StatFill;
Index: trunk/src/VBox/Devices/Network/slirp/socket.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 20164)
@@ -87,4 +87,8 @@
     unsigned char so_ethaddr[6]; 
 #endif
+#ifdef VBOX_WITH_SLIRP_ALIAS
+    /* required for port-forwarding */
+    struct libalias *so_la;
+#endif
 };
 
Index: trunk/src/VBox/Devices/Network/slirp/tcp_output.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_output.c	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_output.c	(revision 20164)
@@ -601,4 +601,8 @@
         }
 #endif
+#ifdef VBOX_WITH_SLIRP_ALIAS
+        if(so->so_la != NULL)
+            m->m_la = so->so_la;
+#endif
         error = ip_output(pData, so, m);
 
Index: trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 20164)
@@ -487,4 +487,7 @@
         so->so_laddr = inso->so_laddr;
         so->so_lport = inso->so_lport;
+#ifdef VBOX_WITH_SLIRP_ALIAS
+        so->so_la = inso->so_la;
+#endif
     }
 
Index: trunk/src/VBox/Devices/Network/slirp/udp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/udp.c	(revision 20119)
+++ trunk/src/VBox/Devices/Network/slirp/udp.c	(revision 20164)
@@ -78,5 +78,7 @@
     DEBUG_CALL("udp_input");
     DEBUG_ARG("m = %lx", (long)m);
+    ip = mtod(m, struct ip *);
     DEBUG_ARG("iphlen = %d", iphlen);
+    Log2(("%R[IP4] iphlen = %d\n", &ip->ip_dst, iphlen));
 
     udpstat.udps_ipackets++;
@@ -259,5 +261,6 @@
         m->m_data -= iphlen;
         *ip = save_ip;
-        DEBUG_MISC((dfd,"udp tx errno = %d-%s\n", errno, strerror(errno)));
+        DEBUG_MISC((dfd,"NAT: UDP tx errno = %d-%s (on sent to %R[IP4])\n", errno, 
+                strerror(errno), &ip->ip_dst));
         icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
         /* in case we receive ICMP on this socket we'll aware that ICMP has been already sent to host*/
@@ -276,4 +279,6 @@
 
 bad:
+    Log2(("NAT: UDP datagram to %R[IP4] with size(%d) claimed as bad\n", 
+        &ip->ip_dst, ip->ip_len));
     m_freem(pData, m);
     return;
