Index: trunk/src/VBox/Devices/Network/slirp/socket.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 71945)
+++ trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 71982)
@@ -36,4 +36,5 @@
 #include <icmpapi.h>
 #endif
+#include <alias.h>
 
 #if defined(DECLARE_IOVEC) && defined(RT_OS_WINDOWS)
@@ -170,4 +171,88 @@
     LogFlowFuncLeave();
 }
+
+
+int
+sobind(PNATState pData, struct socket *so)
+{
+    bool fSamePorts = !!(pData->i32AliasMode & PKT_ALIAS_SAME_PORTS);
+    struct sockaddr_in self;
+    int opt;
+    int binderr;
+    int ret;
+    
+    /* do we need to bind the socket to specific host address/port? */
+    if (pData->bindIP.s_addr == INADDR_ANY && !fSamePorts)
+        return 0;
+
+    opt = 1;
+    setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
+
+    RT_ZERO(self);
+#ifdef RT_OS_DARWIN
+    self.sin_len = sizeof(self);
+#endif
+    self.sin_family = AF_INET;
+    self.sin_addr = pData->bindIP;
+    self.sin_port = fSamePorts ? so->so_lport : 0;
+    
+    Log2(("NAT: binding guest %RTnaipv4:%d to host %RTnaipv4:%d\n",
+          so->so_laddr.s_addr, ntohs(so->so_lport),
+          self.sin_addr.s_addr, ntohs(self.sin_port)));
+
+    ret = bind(so->s, (struct sockaddr *)&self, sizeof(self));
+    if (ret == 0)
+    {
+        Log2(("NAT: ... bind ok\n"));
+        return 0;
+    }
+
+    if (self.sin_port != 0)
+    {
+        if (pData->bindIP.s_addr != INADDR_ANY)
+        {
+            Log2(("NAT: failed to bind to %RTnaipv4:%d (bindip,sameports),"
+                  " retrying with random port\n",
+                  self.sin_addr.s_addr, self.sin_port));
+
+            /*
+             * don't try to guess why bind() failed, retry without
+             * requesting the same port port
+             */
+            self.sin_port = 0;
+
+            ret = bind(so->s, (struct sockaddr *)&self, sizeof(self));
+            if (ret == 0)   /* bindIP ok (but port is not the same) */
+            {
+                Log2(("NAT: ... bind ok (without sameports)\n"));
+                return 0;
+            }
+        }
+        else
+        {
+            Log2(("NAT: failed to bind to 0.0.0.0:%d (sameports),"
+                  " ignoring sameports\n",
+                  self.sin_port));
+
+            /* it's ok if we failed to get the same port */
+            return 0;
+        }
+    }
+
+    binderr = errno;
+
+    Log2(("NAT: failed to bind to %RTnaipv4 (bindip)\n",
+          self.sin_addr.s_addr));
+
+    closesocket(so->s);
+    so->s = -1;
+#ifdef RT_OS_WINDOWS
+    WSASetLastError(binderr);
+#else
+    errno = binderr;
+#endif
+    return -1;
+}
+
 
 /*
Index: trunk/src/VBox/Devices/Network/slirp/socket.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 71945)
+++ trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 71982)
@@ -167,4 +167,5 @@
 struct socket * socreate (void);
 void sofree (PNATState, struct socket *);
+int sobind(PNATState, struct socket *);
 int soread (PNATState, struct socket *);
 void sorecvoob (PNATState, struct socket *);
Index: trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 71945)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 71982)
@@ -413,23 +413,11 @@
 
         fd_nonblock(s);
-        opt = 1;
-        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
+
         opt = 1;
         setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(opt));
 
-        if (pData->bindIP.s_addr != INADDR_ANY)
-        {
-            struct sockaddr_in self;
-            self.sin_family = AF_INET;
-            self.sin_addr = pData->bindIP;
-            self.sin_port = 0;
-
-            ret = bind(s, (struct sockaddr *)&self, sizeof(self));
-            if (ret != 0)
-            {
-                Log2(("NAT: bind(%RTnaipv4): %s\n", pData->bindIP.s_addr, strerror(errno)));
-                return ret;
-            }
-        }
+        ret = sobind(pData, so);
+        if (ret != 0)
+            return ret;
 
         addr.sin_family = AF_INET;
Index: trunk/src/VBox/Devices/Network/slirp/udp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/udp.c	(revision 71945)
+++ trunk/src/VBox/Devices/Network/slirp/udp.c	(revision 71982)
@@ -271,4 +271,12 @@
             goto bad_free_mbuf;
         }
+
+        /*
+         * Setup fields
+         */
+        so->so_laddr = ip->ip_src;
+        so->so_lport = uh->uh_sport;
+        so->so_iptos = ip->ip_tos;
+
         if (udp_attach(pData, so) <= 0)
         {
@@ -279,13 +287,5 @@
         }
 
-        /*
-         * Setup fields
-         */
         /* udp_last_so = so; */
-        so->so_laddr = ip->ip_src;
-        so->so_lport = uh->uh_sport;
-
-        so->so_iptos = ip->ip_tos;
-
         /*
          * XXXXX Here, check if it's in udpexec_list,
@@ -526,5 +526,4 @@
 udp_attach(PNATState pData, struct socket *so)
 {
-    struct sockaddr_in *addr;
     struct sockaddr sa_addr;
     socklen_t socklen = sizeof(struct sockaddr);
@@ -539,29 +538,11 @@
     so->so_sotos = 0;
     so->so_sodf = -1;
-    /*
-     * Here, we bind() the socket.  Although not really needed
-     * (sendto() on an unbound socket will bind it), it's done
-     * here so that emulation of ytalk etc. don't have to do it
-     */
-    memset(&sa_addr, 0, sizeof(struct sockaddr));
-    addr = (struct sockaddr_in *)&sa_addr;
-#ifdef RT_OS_DARWIN
-    addr->sin_len = sizeof(struct sockaddr_in);
-#endif
-    addr->sin_family = AF_INET;
-    addr->sin_addr.s_addr = pData->bindIP.s_addr;
+
     fd_nonblock(so->s);
-    if (bind(so->s, &sa_addr, sizeof(struct sockaddr_in)) < 0)
-    {
-        int lasterrno = errno;
-        closesocket(so->s);
-        so->s = -1;
-#ifdef RT_OS_WINDOWS
-        WSASetLastError(lasterrno);
-#else
-        errno = lasterrno;
-#endif
-        goto error;
-    }
+
+    status = sobind(pData, so);
+    if (status != 0)
+        return status;
+
     /* success, insert in queue */
     so->so_expire = curtime + SO_EXPIRE;
