diff -Naur lwip-master/src/core/ipv4/ip4.c lwip-raw-deliver/src/core/ipv4/ip4.c
--- lwip-master/src/core/ipv4/ip4.c	Sat Jan 20 04:08:52 2018
+++ lwip-raw-deliver/src/core/ipv4/ip4.c	Mon Jan 22 11:30:10 2018
@@ -423,6 +423,9 @@
 #if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP
   int check_ip_src = 1;
 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */
+#if LWIP_RAW
+  u8_t raw_deliver;
+#endif /* LWIP_RAW */
 
   LWIP_ASSERT_CORE_LOCKED();
 
@@ -675,7 +678,7 @@
 
 #if LWIP_RAW
   /* raw input did not eat the packet? */
-  if (raw_input(p, inp) == 0)
+  if (raw_input(p, inp, &raw_deliver) == 0)
 #endif /* LWIP_RAW */
   {
     pbuf_remove_header(p, iphdr_hlen); /* Move to payload, no check necessary. */
@@ -709,11 +712,16 @@
 #endif /* LWIP_IGMP */
       default:
 #if LWIP_ICMP
-        /* send ICMP destination protocol unreachable unless is was a broadcast */
-        if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
-            !ip4_addr_ismulticast(ip4_current_dest_addr())) {
-          pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */
-          icmp_dest_unreach(p, ICMP_DUR_PROTO);
+#if LWIP_RAW
+        if (!raw_deliver) 
+#endif /* LWIP_RAW */
+        {
+          /* send ICMP destination protocol unreachable unless is was a broadcast */
+          if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
+              !ip4_addr_ismulticast(ip4_current_dest_addr())) {
+            pbuf_header_force(p, (s16_t)iphdr_hlen); /* Move to ip header, no check necessary. */
+            icmp_dest_unreach(p, ICMP_DUR_PROTO);
+          }
         }
 #endif /* LWIP_ICMP */
         pbuf_free(p);
diff -Naur lwip-master/src/core/ipv6/ip6.c lwip-raw-deliver/src/core/ipv6/ip6.c
--- lwip-master/src/core/ipv6/ip6.c	Sat Jan 20 04:08:52 2018
+++ lwip-raw-deliver/src/core/ipv6/ip6.c	Mon Jan 22 11:31:31 2018
@@ -516,6 +516,9 @@
   @todo
   int check_ip_src=1;
 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
+#if LWIP_RAW
+  u8_t raw_deliver;
+#endif /* LWIP_RAW */
 
   LWIP_ASSERT_CORE_LOCKED();
 
@@ -1055,7 +1058,7 @@
   /* p points to IPv6 header again for raw_input. */
   pbuf_header_force(p, (s16_t)hlen_tot);
   /* raw input did not eat the packet? */
-  if (raw_input(p, inp) == 0)
+  if (raw_input(p, inp, &raw_deliver) == 0)
   {
     /* Point to payload. */
     pbuf_remove_header(p, hlen_tot);
@@ -1086,12 +1089,17 @@
 #endif /* LWIP_ICMP */
     default:
 #if LWIP_ICMP6
-      /* p points to IPv6 header again for raw_input. */
-      pbuf_header_force(p, (s16_t)hlen_tot);
-      /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
-      if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
-          (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
-        icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
+#if LWIP_RAW
+      if (!raw_deliver) 
+#endif /* LWIP_RAW */
+      {
+        /* p points to IPv6 header again for raw_input. */
+        pbuf_header_force(p, (s16_t)hlen_tot);
+        /* send ICMP parameter problem unless it was a multicast or ICMPv6 */
+        if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) &&
+            (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) {
+          icmp6_param_problem(p, ICMP6_PP_HEADER, nexth);
+        }
       }
 #endif /* LWIP_ICMP */
       LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr)));
diff -Naur lwip-master/src/core/raw.c lwip-raw-deliver/src/core/raw.c
--- lwip-master/src/core/raw.c	Sat Jan 20 04:08:52 2018
+++ lwip-raw-deliver/src/core/raw.c	Mon Jan 22 11:28:53 2018
@@ -123,6 +123,7 @@
  *
  * @param p pbuf to be demultiplexed to a RAW PCB.
  * @param inp network interface on which the datagram was received.
+ * @param deliver whether this packet is delivered.
  * @return - 1 if the packet has been eaten by a RAW PCB receive
  *           callback function. The caller MAY NOT not reference the
  *           packet any longer, and MAY NOT call pbuf_free().
@@ -131,7 +132,7 @@
  *
  */
 u8_t
-raw_input(struct pbuf *p, struct netif *inp)
+raw_input(struct pbuf *p, struct netif *inp, u8_t *deliver)
 {
   struct raw_pcb *pcb, *prev;
   s16_t proto;
@@ -158,6 +159,7 @@
   }
 #endif /* LWIP_IPV4 */
 
+  *deliver = 0;
   prev = NULL;
   pcb = raw_pcbs;
   /* loop through all raw pcbs until the packet is eaten by one */
@@ -171,6 +173,7 @@
 #ifndef LWIP_NOASSERT
         void *old_payload = p->payload;
 #endif
+        *deliver = 1;
         /* the receive callback function did not eat the packet? */
         eaten = pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr());
         if (eaten != 0) {
diff -Naur lwip-master/src/include/lwip/raw.h lwip-raw-deliver/src/include/lwip/raw.h
--- lwip-master/src/include/lwip/raw.h	Sat Jan 20 04:08:52 2018
+++ lwip-raw-deliver/src/include/lwip/raw.h	Mon Jan 22 11:27:02 2018
@@ -123,7 +123,7 @@
 #define          raw_is_flag_set(pcb, flag)        (((pcb)->flags & (flag)) != 0)
 
 /* The following functions are the lower layer interface to RAW. */
-u8_t             raw_input      (struct pbuf *p, struct netif *inp);
+u8_t             raw_input      (struct pbuf *p, struct netif *inp, u8_t *deliver);
 #define raw_init() /* Compatibility define, no init needed. */
 
 void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr);
