Index: /trunk/src/VBox/Devices/Network/slirp/socket.c
===================================================================
--- /trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 27465)
+++ /trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 27466)
@@ -1057,5 +1057,11 @@
     ip = (struct ip *)buff;
     hlen = (ip->ip_hl << 2);
-    if (RT_N2H_U16(ip->ip_len) < hlen + ICMP_MINLEN)
+    /* Note: ip->ip_len in host byte order */
+    ip->ip_len = RT_N2H_U16(ip->ip_len);
+#ifdef RT_OS_SOLARIS
+    /* Solaris doesn't pass raw IP datagram, ip_len is size of payload only */
+    ip->ip_len += hlen;
+#endif
+    if (ip->ip_len < hlen + ICMP_MINLEN)
     {
        Log(("send_icmp_to_guest: ICMP header is too small to understand which type/subtype of the datagram\n"));
@@ -1077,5 +1083,5 @@
      * icmp_{type(8), code(8), cksum(16),identifier(16),seqnum(16)}
      */
-    if (RT_N2H_U16(ip->ip_len) < hlen + 8)
+    if (ip->ip_len < hlen + 8)
     {
         Log(("send_icmp_to_guest: NAT accept ICMP_{ECHOREPLY, TIMXCEED, UNREACH} the minimum size is 64 (see rfc792)\n"));
@@ -1091,5 +1097,5 @@
          * icmp_{type(8), code(8), cksum(16),unused(32)} + IP header + 64 bit of original datagram
          */
-        if (RT_N2H_U16(ip->ip_len) < hlen + 2*8 + sizeof(struct ip))
+        if (ip->ip_len < hlen + 2*8 + sizeof(struct ip))
         {
             Log(("send_icmp_to_guest: NAT accept ICMP_{TIMXCEED, UNREACH} the minimum size of ipheader + 64 bit of data (see rfc792)\n"));
@@ -1111,6 +1117,4 @@
 
     src = addr->sin_addr.s_addr;
-#if 0
-    /* @todo: check why it's too strict. */
     if (type == ICMP_ECHOREPLY)
     {
@@ -1122,13 +1126,20 @@
             return;
         }
-        if (   (RT_N2H_U16(ip->ip_len) - hlen )
-            != (ip0->ip_len - (ip0->ip_hl << 2))) /* the IP header in the list is in host format */
-        {
-            Log(("NAT: ECHO lenght doesn't match ECHOREPLY\n"));
+#if 0
+        /* 
+         * @todo ip0 seems have different byte order on different OSes, e.g. on Solaris it's required
+         * to N2H, but on Linux no convertaion required.
+         */
+        if (   (ip->ip_len - hlen )
+            != (ip0->ip_len - (ip0->ip_hl << 2))) 
+        {
+            Log(("NAT: ECHO(%d) lenght doesn't match ECHOREPLY(%d)\n",
+                (ip->ip_len - hlen ), (ip0->ip_len - (ip0->ip_hl << 2))));
             return;
         }
-    }
-#endif
-
+#endif
+    }
+
+    /* ip points on origianal ip header */
     ip = mtod(m, struct ip *);
     proto = ip->ip_p;
@@ -1373,4 +1384,7 @@
 
     len = RT_N2H_U16(ip.ip_len);
+#ifdef RT_OS_SOLARIS
+    len += (ip.ip_hl << 2); /* Solaris: reports only payload length */
+#endif
     buff = RTMemAlloc(len);
     if (buff == NULL)
@@ -1396,5 +1410,9 @@
     }
     if (   len < 0
+#ifndef RT_OS_SOLARIS
         || len < (RT_N2H_U16(ip.ip_len))
+#else
+        || len < ((RT_N2H_U16(ip.ip_len)) + (ip.ip_hl << 2))
+#endif
         || len == 0)
     {
