Index: /trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
===================================================================
--- /trunk/src/VBox/Devices/Network/slirp/ip_icmp.c	(revision 15085)
+++ /trunk/src/VBox/Devices/Network/slirp/ip_icmp.c	(revision 15086)
@@ -80,4 +80,5 @@
 #else
         pData->icmp_socket.s = IcmpCreateFile();
+    	pData->phEvents[VBOX_ICMP_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL);
 #endif
         insque(pData, &pData->icmp_socket, &udb);
@@ -279,6 +280,5 @@
       memset(&ipopt, 0, sizeof(IP_OPTION_INFORMATION));
       ipopt.Ttl = ip->ip_ttl;
-      m->m_ext = malloc(1500);
-      status = IcmpSendEcho(pData->icmp_socket.s, VBOX_SOCKET_EVENT, &addr, icp, icmplen, m->m_ext, 1500, 0);
+      status = IcmpSendEcho2(pData->icmp_socket.s, pData->phEvents[VBOX_ICMP_EVENT_INDEX], NULL, NULL, &addr, icp, icmplen, &ipopt, pData->pvIcmpBuffer, pData->szIcmpBuffer, 0);
       if (status == 0) {
             LogRel(("error(%d) occured while sending ICMP\n", GetLastError()));
Index: /trunk/src/VBox/Devices/Network/slirp/libslirp.h
===================================================================
--- /trunk/src/VBox/Devices/Network/slirp/libslirp.h	(revision 15085)
+++ /trunk/src/VBox/Devices/Network/slirp/libslirp.h	(revision 15086)
@@ -69,8 +69,21 @@
 #define VBOX_SOCKET_EVENT_INDEX         1
 
+#ifdef VBOX_WITH_SLIRP_ICMP
+/*
+ * ICMP handle state change
+ */
+#define VBOX_ICMP_EVENT_INDEX         2
+
+/*
+ * The number of events for WSAWaitForMultipleEvents().
+ */
+#define VBOX_EVENT_COUNT                3
+#else
 /*
  * The number of events for WSAWaitForMultipleEvents().
  */
 #define VBOX_EVENT_COUNT                2
+
+#endif
 
 HANDLE *slirp_get_events(PNATState pData);
Index: /trunk/src/VBox/Devices/Network/slirp/slirp_state.h
===================================================================
--- /trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 15085)
+++ /trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 15086)
@@ -137,4 +137,8 @@
     struct socket icmp_socket;
     struct icmp_storage icmp_msg_head;
+#ifdef RT_OS_WINDOWS
+    void *pvIcmpBuffer;
+    size_t szIcmpBuffer;
+#endif
 #endif
 #if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && defined(RT_OS_WINDOWS)
Index: /trunk/src/VBox/Devices/Network/slirp/socket.c
===================================================================
--- /trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 15085)
+++ /trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 15086)
@@ -13,4 +13,13 @@
 #include <sys/filio.h>
 #endif
+#if defined(VBOX_WITH_SLIRP_ICMP) && defined (RT_OS_WINDOWS) 
+#include <icmpapi.h>
+#endif
+
+#ifdef VBOX_WITH_SLIRP_ICMP
+static void send_icmp_to_guest(PNATState, char *, struct socket *);
+static void sorecvfrom_icmp_win(PNATState, struct socket *);
+#endif
+static void sorecvfrom_icmp_unix(PNATState, struct socket *);
 
 void
@@ -423,97 +432,8 @@
     DEBUG_ARG("so = %lx", (long)so);
 
-        if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
-          char buff[1500];
-          int len;
-          len = recvfrom(so->s, buff, 1500, 0,
-                         (struct sockaddr *)&addr, &addrlen);
-          /* XXX Check if reply is "correct"? */
-
-        if(len == -1 || len == 0)
-        {
-            u_char code = ICMP_UNREACH_PORT;
-
-            if (errno == EHOSTUNREACH)
-                code=ICMP_UNREACH_HOST;
-            else if(errno == ENETUNREACH)
-                code=ICMP_UNREACH_NET;
-
-
-            DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
-                        errno,strerror(errno)));
-            icmp_error(pData, so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
-        }
-        else
-        {
-#ifdef VBOX_WITH_SLIRP_ICMP
-            struct ip *ip;
-            uint32_t dst,src;
-            char ip_copy[256];
-            struct icmp *icp;
-            int old_ip_len;
-            struct mbuf *m;
-            struct icmp_msg *icm;
-
-            ip = (struct ip *)buff;
-            icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2));
-
-            Assert(icp->icmp_type == ICMP_ECHOREPLY || icp->icmp_type == ICMP_TIMXCEED);
-
-            if (icp->icmp_type == ICMP_TIMXCEED ) {
-                ip = &icp->icmp_ip;
-            }
-
-            icm = icmp_find_original_mbuf(pData, ip);
-
-            if (icm == NULL) {
-                LogRel(("Can't find the corresponding packet for the received ICMP\n"));
-                return;
-            }
-
-            m = icm->im_m;
-            Assert(m != NULL);
-
-            src = addr.sin_addr.s_addr;
-
-            ip = mtod(m, struct ip *);
-            /* Now ip is pointing on header we've sent from guest */
-            if (icp->icmp_type == ICMP_TIMXCEED) {
-                old_ip_len = (ip->ip_hl << 2) + 64;
-                memcpy(ip_copy, ip, old_ip_len);
-            }
-
-            /* source address from original IP packet*/
-            dst = ip->ip_src.s_addr;
-
-            /* overide ther tail of old packet */
-            memcpy(m->m_data, buff, len);
-            m->m_len = len;
-            ip = mtod(m, struct ip *); /* ip is from mbuf we've overrided */
-
-            icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2));
-            if (icp->icmp_type == ICMP_TIMXCEED) {
-                /* according RFC 793 error messages required copy of initial IP header + 64 bit */
-                memcpy(&icp->icmp_ip, ip_copy, old_ip_len);
-                ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0);  /* high priority for errors */
-            }
-
-            /* the low level expects fields to be in host format so let's convert them*/
-            NTOHS(ip->ip_len);
-            NTOHS(ip->ip_off);
-            NTOHS(ip->ip_id);
-            ip->ip_src.s_addr = src;
-            ip->ip_dst.s_addr = dst;
-            icmp_reflect(pData, m);
-            LIST_REMOVE(icm, im_list);
-            /* Don't call m_free here*/
-            free(icm);
-#else
-            icmp_reflect(pData, so->so_m);
-            so->so_m = 0; /* Don't m_free() it again! */
-#endif
-          }
-          /* No need for this socket anymore, udp_detach it */
+    if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
+          sorecvfrom_icmp_unix(pData, so);
           udp_detach(pData, so);
-        } else {                                /* A "normal" UDP packet */
+    } else {                                /* A "normal" UDP packet */
           struct mbuf *m;
           int len, n;
@@ -843,2 +763,111 @@
         sofcantsendmore(so);
 }
+
+#ifdef VBOX_WITH_SLIRP_ICMP
+static void 
+send_icmp_to_guest(PNATState pData, char *buff, struct socket *so)
+{
+        struct ip *ip;
+        uint32_t dst,src;
+        char ip_copy[256];
+        struct icmp *icp;
+        int old_ip_len;
+        struct mbuf *m;
+        struct icmp_msg *icm;
+        
+        ip = (struct ip *)buff;
+        icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2));
+        
+        Assert(icp->icmp_type == ICMP_ECHOREPLY || icp->icmp_type == ICMP_TIMXCEED);
+        
+        if (icp->icmp_type == ICMP_TIMXCEED ) {
+            ip = &icp->icmp_ip;
+        }
+        
+        icm = icmp_find_original_mbuf(pData, ip);
+        
+        if (icm == NULL) {
+            LogRel(("Can't find the corresponding packet for the received ICMP\n"));
+            return;
+        }
+        
+        m = icm->im_m;
+        Assert(m != NULL);
+        
+        src = addr.sin_addr.s_addr;
+        
+        ip = mtod(m, struct ip *);
+        /* Now ip is pointing on header we've sent from guest */
+        if (icp->icmp_type == ICMP_TIMXCEED) {
+            old_ip_len = (ip->ip_hl << 2) + 64;
+            memcpy(ip_copy, ip, old_ip_len);
+        }
+        
+        /* source address from original IP packet*/
+        dst = ip->ip_src.s_addr;
+        
+        /* overide ther tail of old packet */
+        memcpy(m->m_data, buff, len);
+        m->m_len = len;
+        ip = mtod(m, struct ip *); /* ip is from mbuf we've overrided */
+        
+        icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2));
+        if (icp->icmp_type == ICMP_TIMXCEED) {
+            /* according RFC 793 error messages required copy of initial IP header + 64 bit */
+            memcpy(&icp->icmp_ip, ip_copy, old_ip_len);
+            ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0);  /* high priority for errors */
+        }
+        
+        /* the low level expects fields to be in host format so let's convert them*/
+        NTOHS(ip->ip_len);
+        NTOHS(ip->ip_off);
+        NTOHS(ip->ip_id);
+        ip->ip_src.s_addr = src;
+        ip->ip_dst.s_addr = dst;
+        icmp_reflect(pData, m);
+        LIST_REMOVE(icm, im_list);
+        /* Don't call m_free here*/
+        free(icm);
+}
+#endif
+static void sorecvfrom_icmp_win(PNATState pData, struct socket *so){
+#if 0
+	int i;
+	len = IcmpParseReplies(pData->pvIcmpBuffer, pData->szIcmpBuffer);
+#endif
+}
+static void sorecvfrom_icmp_unix(PNATState pData, struct socket *so)
+{
+    struct sockaddr_in addr;
+    socklen_t addrlen = sizeof(struct sockaddr_in);
+    char buff[1500];
+    int len;
+    len = recvfrom(so->s, buff, 1500, 0,
+                   (struct sockaddr *)&addr, &addrlen);
+    /* XXX Check if reply is "correct"? */
+
+    if(len == -1 || len == 0)
+    {
+        u_char code = ICMP_UNREACH_PORT;
+
+        if (errno == EHOSTUNREACH)
+            code=ICMP_UNREACH_HOST;
+        else if(errno == ENETUNREACH)
+            code=ICMP_UNREACH_NET;
+
+
+        DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
+                    errno,strerror(errno)));
+        icmp_error(pData, so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
+    }
+    else
+    {
+#ifdef VBOX_WITH_SLIRP_ICMP
+        send_icmp_to_guest(pData, buff, so);
+#else
+        icmp_reflect(pData, so->so_m);
+        so->so_m = 0; /* Don't m_free() it again! */
+#endif
+    }
+}
+
