Index: /trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/icmp6.c
===================================================================
--- /trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/icmp6.c	(revision 49591)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/icmp6.c	(revision 49592)
@@ -66,4 +66,9 @@
 /* Forward declarations */
 static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type);
+
+#if LWIP_CONNECTION_PROXY
+static ping6_proxy_fn ping6_proxy_accept_callback;
+static void *ping6_proxy_accept_arg;
+#endif
 
 
@@ -199,4 +204,66 @@
 }
 
+
+#if LWIP_CONNECTION_PROXY
+
+void
+ping6_proxy_accept(ping6_proxy_fn callback, void *arg)
+{
+  ping6_proxy_accept_callback = callback;
+  ping6_proxy_accept_arg = arg;
+}
+
+
+void
+icmp6_proxy_input(struct pbuf *p, struct netif *inp)
+{
+  struct icmp6_hdr *icmp6hdr;
+  struct pbuf * r;
+  ip6_addr_t * reply_src;
+
+  ICMP6_STATS_INC(icmp6.recv);
+
+  /* Check that ICMPv6 header fits in payload */
+  if (p->len < sizeof(struct icmp6_hdr)) {
+    /* drop short packets */
+    pbuf_free(p);
+    ICMP6_STATS_INC(icmp6.lenerr);
+    ICMP6_STATS_INC(icmp6.drop);
+    return;
+  }
+
+  icmp6hdr = (struct icmp6_hdr *)p->payload;
+  if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(),
+                        ip6_current_dest_addr()) != 0) {
+    /* Checksum failed */
+    pbuf_free(p);
+    ICMP6_STATS_INC(icmp6.chkerr);
+    ICMP6_STATS_INC(icmp6.drop);
+    return;
+  }
+
+  switch (icmp6hdr->type) {
+
+  case ICMP6_TYPE_EREQ:
+    if (ping6_proxy_accept_callback != NULL) {
+      (*ping6_proxy_accept_callback)(ping6_proxy_accept_arg, p);
+      return;
+    }
+    ICMP6_STATS_INC(icmp6.drop);
+    break;
+
+  case ICMP6_TYPE_EREP:
+    /* ignore silently */
+    ICMP6_STATS_INC(icmp6.drop);
+    break;
+
+  default:
+    ICMP6_STATS_INC(icmp6.drop);
+    break;
+  }
+
+  pbuf_free(p);
+}
+#endif /* LWIP_CONNECTION_PROXY */
 
 /**
Index: /trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c
===================================================================
--- /trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c	(revision 49591)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/core/ipv6/ip6.c	(revision 49592)
@@ -779,4 +779,12 @@
       break;
 #endif /* LWIP_TCP */
+
+#if LWIP_ICMP6
+    case IP6_NEXTH_ICMP6:
+      /* Point to payload. */
+      pbuf_header(p, -ip_data.current_ip_header_tot_len);
+      icmp6_proxy_input(p, inp);
+      break;
+#endif /* LWIP_ICMP */
 
     default:
Index: /trunk/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/icmp6.h
===================================================================
--- /trunk/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/icmp6.h	(revision 49591)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/include/ipv6/lwip/icmp6.h	(revision 49592)
@@ -137,8 +137,16 @@
 
 void icmp6_input(struct pbuf *p, struct netif *inp);
+#if LWIP_CONNECTION_PROXY
+void icmp6_proxy_input(struct pbuf *p, struct netif *inp);
+#endif
 void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c);
 void icmp6_packet_too_big(struct pbuf *p, u32_t mtu);
 void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c);
 void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer);
+
+#if LWIP_CONNECTION_PROXY
+typedef void (*ping6_proxy_fn)(void *arg, struct pbuf *p);
+void ping6_proxy_accept(ping6_proxy_fn callback, void *arg);
+#endif
 
 #endif /* LWIP_ICMP6 && LWIP_IPV6 */
