You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/11/26 14:47:59 UTC

[incubator-nuttx] branch master updated (dd647d2 -> 3b69d09)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from dd647d2  arch/samv7/sam_progmem: fix page size flash writing
     new 6cd850b  net/icmp/v6: add ICMP Destination Unreachable code definitions
     new 3b69d09  net/udp/icmp: correct the unreadchable handling

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 include/nuttx/net/icmp.h   |  32 ++++++++-
 include/nuttx/net/icmpv6.h |  12 ++++
 net/icmp/Make.defs         |   2 +-
 net/icmp/icmp.h            |  24 +++++++
 net/icmp/icmp_reply.c      | 171 +++++++++++++++++++++++++++++++++++++++++++++
 net/icmpv6/Make.defs       |   2 +-
 net/icmpv6/icmpv6.h        |  26 +++++++
 net/icmpv6/icmpv6_reply.c  | 153 ++++++++++++++++++++++++++++++++++++++++
 net/udp/udp_input.c        |  28 ++++++++
 net/utils/net_icmpchksum.c |   4 +-
 net/utils/utils.h          |   2 +-
 11 files changed, 449 insertions(+), 7 deletions(-)
 create mode 100644 net/icmp/icmp_reply.c
 create mode 100644 net/icmpv6/icmpv6_reply.c

[incubator-nuttx] 02/02: net/udp/icmp: correct the unreadchable handling

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 3b69d09c80b4d21681475c43d9f165838bbf1a5c
Author: chao.an <an...@xiaomi.com>
AuthorDate: Thu Nov 25 22:03:33 2021 +0800

    net/udp/icmp: correct the unreadchable handling
    
    Reference RFC1122:
    https://datatracker.ietf.org/doc/html/rfc1122
    ----------------------------------------------
    
    4.1.3  SPECIFIC ISSUES
    
      4.1.3.1  Ports
    
        If a datagram arrives addressed to a UDP port for which
        there is no pending LISTEN call, UDP SHOULD send an ICMP
        Port Unreachable message.
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 net/icmp/Make.defs         |   2 +-
 net/icmp/icmp.h            |  24 +++++++
 net/icmp/icmp_reply.c      | 171 +++++++++++++++++++++++++++++++++++++++++++++
 net/icmpv6/Make.defs       |   2 +-
 net/icmpv6/icmpv6.h        |  26 +++++++
 net/icmpv6/icmpv6_reply.c  | 153 ++++++++++++++++++++++++++++++++++++++++
 net/udp/udp_input.c        |  28 ++++++++
 net/utils/net_icmpchksum.c |   4 +-
 net/utils/utils.h          |   2 +-
 9 files changed, 407 insertions(+), 5 deletions(-)

diff --git a/net/icmp/Make.defs b/net/icmp/Make.defs
index d85f696..0a0c230 100644
--- a/net/icmp/Make.defs
+++ b/net/icmp/Make.defs
@@ -23,7 +23,7 @@ ifneq ($(CONFIG_NET_ICMP_NO_STACK),y)
 
 # ICMP source files
 
-NET_CSRCS += icmp_input.c
+NET_CSRCS += icmp_input.c icmp_reply.c
 
 ifeq ($(CONFIG_NET_ICMP_SOCKET),y)
 SOCK_CSRCS += icmp_sockif.c icmp_poll.c icmp_conn.c icmp_sendmsg.c
diff --git a/net/icmp/icmp.h b/net/icmp/icmp.h
index 031ac45..b1379f8 100644
--- a/net/icmp/icmp.h
+++ b/net/icmp/icmp.h
@@ -362,6 +362,30 @@ int icmp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds);
 int icmp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
 #endif
 
+/****************************************************************************
+ * Name: icmp_reply
+ *
+ * Description:
+ *   Send an ICMP message in response to a situation
+ *   RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header.
+ *       MAY send more (we do).
+ *       MUST NOT change this header information.
+ *       MUST NOT reply to a multicast/broadcast IP address.
+ *       MUST NOT reply to a multicast/broadcast MAC address.
+ *       MUST reply to only the first fragment.
+ *
+ * Input Parameters:
+ *   dev   - The device driver structure containing the received packet
+ *   type  - ICMP Message Type, eg. ICMP_DEST_UNREACHABLE
+ *   code  - ICMP Message Code, eg. ICMP_PORT_UNREACH
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void icmp_reply(FAR struct net_driver_s *dev, int type, int code);
+
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/net/icmp/icmp_reply.c b/net/icmp/icmp_reply.c
new file mode 100644
index 0000000..c98a5f7
--- /dev/null
+++ b/net/icmp/icmp_reply.c
@@ -0,0 +1,171 @@
+/****************************************************************************
+ * net/icmp/icmp_reply.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdint.h>
+#include <string.h>
+#include <debug.h>
+
+#include <netinet/in.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+
+#include <nuttx/net/net.h>
+#include <nuttx/net/netdev.h>
+#include <nuttx/net/ip.h>
+#include <nuttx/net/icmp.h>
+
+#include "utils/utils.h"
+#include "netdev/netdev.h"
+#include "devif/devif.h"
+#include "inet/inet.h"
+#include "icmp/icmp.h"
+
+#ifdef CONFIG_NET_ICMP
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define IPv4BUF ((struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+
+/* RFC 1812:
+ * 4.3.2.3, Original Message Header
+ * ...
+ * The ICMP datagram SHOULD contain as much of the original datagram as
+ * possible without the length of the ICMP datagram exceeding 576 bytes.
+ * ...
+ */
+
+#define ICMP_MAXMSGLEN  576
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: icmp_reply
+ *
+ * Description:
+ *   Send an ICMP message in response to a situation
+ *   RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header.
+ *       MAY send more (we do).
+ *       MUST NOT change this header information.
+ *       MUST NOT reply to a multicast/broadcast IP address.
+ *       MUST NOT reply to a multicast/broadcast MAC address.
+ *       MUST reply to only the first fragment.
+ *
+ * Input Parameters:
+ *   dev   - The device driver structure containing the received packet
+ *   type  - ICMP Message Type, eg. ICMP_DEST_UNREACHABLE
+ *   code  - ICMP Message Code, eg. ICMP_PORT_UNREACH
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
+{
+  int ipicmplen = IPv4_HDRLEN + sizeof(struct icmp_hdr_s);
+  FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
+  FAR struct icmp_hdr_s *icmp = (FAR void *)(ipv4 + 1);
+  uint16_t datalen;
+#ifdef CONFIG_NET_BROADCAST
+  const in_addr_t bcast = INADDR_BROADCAST;
+#endif /* CONFIG_NET_BROADCAST */
+  const in_addr_t any = INADDR_ANY;
+
+  if (net_ipv4addr_hdrcmp(ipv4->destipaddr, &any)
+#  ifdef CONFIG_NET_BROADCAST
+      || net_ipv4addr_hdrcmp(ipv4->destipaddr, &bcast)
+#  endif /* CONFIG_NET_BROADCAST */
+     )
+    {
+      dev->d_len = 0;
+      return;
+    }
+
+  /* Get the data size of the packet. */
+
+  datalen = (ipv4->len[0] << 8) + ipv4->len[1];
+
+  /* RFC says return as much as we can without exceeding 576 bytes. */
+
+  if (datalen > ICMP_MAXMSGLEN - ipicmplen)
+    {
+      datalen = ICMP_MAXMSGLEN - ipicmplen;
+    }
+
+  dev->d_len = ipicmplen + datalen;
+
+  /* Copy fields from original packet */
+
+  memmove(icmp + 1, ipv4, datalen);
+
+  /* Initialize the IP header. */
+
+  ipv4->vhl         = 0x45;
+  ipv4->tos         = 0;
+  ipv4->len[0]      = (dev->d_len >> 8);
+  ipv4->len[1]      = (dev->d_len & 0xff);
+  ++g_ipid;
+  ipv4->ipid[0]     = g_ipid >> 8;
+  ipv4->ipid[1]     = g_ipid & 0xff;
+  ipv4->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
+  ipv4->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
+  ipv4->ttl         = IP_TTL_DEFAULT;
+  ipv4->proto       = IP_PROTO_ICMP;
+
+  /* Calculate IP checksum. */
+
+  ipv4->ipchksum    = 0;
+  ipv4->ipchksum    = ~ipv4_chksum(dev);
+
+  net_ipv4addr_hdrcopy(ipv4->destipaddr, ipv4->srcipaddr);
+  net_ipv4addr_hdrcopy(ipv4->srcipaddr, &dev->d_ipaddr);
+
+  /* Initialize the ICMP header */
+
+  icmp->type        = type;
+  icmp->icode       = code;
+  icmp->data        = 0;
+
+  /* Calculate the ICMP checksum. */
+
+  icmp->icmpchksum  = 0;
+  icmp->icmpchksum  = ~icmp_chksum(dev, datalen + sizeof(*icmp));
+  if (icmp->icmpchksum == 0)
+    {
+      icmp->icmpchksum = 0xffff;
+    }
+
+  ninfo("Outgoing ICMP packet length: %d (%d)\n",
+         dev->d_len, (ipv4->len[0] << 8) | ipv4->len[1]);
+}
+
+#endif /* CONFIG_NET_ICMP */
diff --git a/net/icmpv6/Make.defs b/net/icmpv6/Make.defs
index 516c3e3..4f71904 100644
--- a/net/icmpv6/Make.defs
+++ b/net/icmpv6/Make.defs
@@ -24,7 +24,7 @@ ifneq ($(CONFIG_NET_ICMPv6_NO_STACK),y)
 # ICMPv6 source files
 
 NET_CSRCS += icmpv6_input.c icmpv6_solicit.c icmpv6_advertise.c
-NET_CSRCS += icmpv6_linkipaddr.c
+NET_CSRCS += icmpv6_linkipaddr.c icmpv6_reply.c
 
 ifeq ($(CONFIG_NET_ICMPv6_SOCKET),y)
 SOCK_CSRCS += icmpv6_sockif.c icmpv6_conn.c icmpv6_sendmsg.c
diff --git a/net/icmpv6/icmpv6.h b/net/icmpv6/icmpv6.h
index 42bc405..f08517b 100644
--- a/net/icmpv6/icmpv6.h
+++ b/net/icmpv6/icmpv6.h
@@ -726,6 +726,32 @@ int icmpv6_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
 
 void icmpv6_linkipaddr(FAR struct net_driver_s *dev, net_ipv6addr_t ipaddr);
 
+/****************************************************************************
+ * Name: icmpv6_reply
+ *
+ * Description:
+ *   Send an ICMPv6 message in response to a situation
+ *   RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header.
+ *       MAY send more (we do).
+ *       MUST NOT change this header information.
+ *       MUST NOT reply to a multicast/broadcast IP address.
+ *       MUST NOT reply to a multicast/broadcast MAC address.
+ *       MUST reply to only the first fragment.
+ *
+ * Input Parameters:
+ *   dev   - The device driver structure containing the received packet
+ *   type  - ICMPv6 Message Type, eg. ICMPv6_DEST_UNREACHABLE
+ *   code  - ICMPv6 Message Code, eg. ICMPv6_PORT_UNREACH
+ *   data  - Additional 32-bit parameter in the ICMPv6 header
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void icmpv6_reply(FAR struct net_driver_s *dev,
+                  int type, int code, int data);
+
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/net/icmpv6/icmpv6_reply.c b/net/icmpv6/icmpv6_reply.c
new file mode 100644
index 0000000..179c31b
--- /dev/null
+++ b/net/icmpv6/icmpv6_reply.c
@@ -0,0 +1,153 @@
+/****************************************************************************
+ * net/icmpv6/icmpv6_reply.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdint.h>
+#include <string.h>
+#include <debug.h>
+
+#include <netinet/in.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+
+#include <nuttx/net/net.h>
+#include <nuttx/net/netdev.h>
+#include <nuttx/net/ip.h>
+#include <nuttx/net/icmpv6.h>
+
+#include "utils/utils.h"
+#include "netdev/netdev.h"
+#include "devif/devif.h"
+#include "inet/inet.h"
+#include "icmpv6/icmpv6.h"
+
+#ifdef CONFIG_NET_ICMPv6
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define IPv6BUF ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
+
+/* The latest drafts declared increase in minimal mtu up to 1280. */
+
+#define ICMPv6_MINMTULEN  1280
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: icmp_reply
+ *
+ * Description:
+ *   Send an ICMPv6 message in response to a situation
+ *   RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header.
+ *       MAY send more (we do).
+ *       MUST NOT change this header information.
+ *       MUST NOT reply to a multicast/broadcast IP address.
+ *       MUST NOT reply to a multicast/broadcast MAC address.
+ *       MUST reply to only the first fragment.
+ *
+ * Input Parameters:
+ *   dev   - The device driver structure containing the received packet
+ *   type  - ICMPv6 Message Type, eg. ICMPv6_DEST_UNREACHABLE
+ *   code  - ICMPv6 Message Code, eg. ICMPv6_PORT_UNREACH
+ *   data  - Additional 32-bit parameter in the ICMPv6 header
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data)
+{
+  int ipicmplen = IPv6_HDRLEN + sizeof(struct icmpv6_hdr_s);
+  FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
+  FAR struct icmpv6_hdr_s *icmpv6 = (FAR void *)(ipv6 + 1);
+  uint16_t datalen;
+
+  if (net_ipv6addr_cmp(ipv6->destipaddr, g_ipv6_unspecaddr)
+#  ifdef CONFIG_NET_BROADCAST
+      || net_is_addr_mcast(ipv6->destipaddr)
+#  endif /* CONFIG_NET_BROADCAST */
+     )
+    {
+      dev->d_len = 0;
+      return;
+    }
+
+  /* Get the data size of the packet. */
+
+  datalen = (ipv6->len[0] << 8) + ipv6->len[1];
+
+  /* RFC says return as much as we can without exceeding 1280 bytes. */
+
+  if (datalen > ICMPv6_MINMTULEN - ipicmplen)
+    {
+      datalen = ICMPv6_MINMTULEN - ipicmplen;
+    }
+
+  dev->d_len = ipicmplen + datalen;
+
+  /* Copy fields from original packet */
+
+  memmove(icmpv6 + 1, ipv6, datalen);
+
+  /* Set up the IPv6 header (most is probably already in place) */
+
+  ipv6->vtc      = 0x60;               /* Version/traffic class (MS) */
+  ipv6->tcf      = 0;                  /* Traffic class(LS)/Flow label(MS) */
+  ipv6->flow     = 0;                  /* Flow label (LS) */
+  ipv6->len[0]   = (dev->d_len >> 8);  /* Length excludes the IPv6 header */
+  ipv6->len[1]   = (dev->d_len & 0xff);
+  ipv6->proto    = IP_PROTO_ICMP6;     /* Next header */
+  ipv6->ttl      = 255;                /* Hop limit */
+
+  net_ipv6addr_hdrcopy(ipv6->destipaddr, ipv6->srcipaddr);
+  net_ipv6addr_hdrcopy(ipv6->srcipaddr, dev->d_ipv6addr);
+
+  /* Initialize the ICMPv6 header */
+
+  icmpv6->type   = type;
+  icmpv6->code   = code;
+  icmpv6->data   = htonl(data);
+
+  /* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */
+
+  icmpv6->chksum = 0;
+  icmpv6->chksum = ~icmpv6_chksum(dev, datalen + sizeof(*icmpv6));
+  if (icmpv6->chksum == 0)
+    {
+      icmpv6->chksum = 0xffff;
+    }
+
+  ninfo("Outgoing ICMPv6 packet length: %d (%d)\n",
+         dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
+}
+
+#endif /* CONFIG_NET_ICMPv6 */
diff --git a/net/udp/udp_input.c b/net/udp/udp_input.c
index c1e5ced..095a314 100644
--- a/net/udp/udp_input.c
+++ b/net/udp/udp_input.c
@@ -56,6 +56,8 @@
 #include "devif/devif.h"
 #include "utils/utils.h"
 #include "udp/udp.h"
+#include "icmp/icmp.h"
+#include "icmpv6/icmpv6.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -230,7 +232,33 @@ static int udp_input(FAR struct net_driver_s *dev, unsigned int iplen)
       else
         {
           nwarn("WARNING: No listener on UDP port\n");
+
+          /* No match was found, send ICMP destination port unreachable
+           * unless destination address was broadcast/multicast.
+           */
+
+#if defined(CONFIG_NET_ICMP) || defined(CONFIG_NET_ICMPv6)
+#  ifdef CONFIG_NET_ICMPv6
+#    ifdef CONFIG_NET_ICMP
+          if (IFF_IS_IPv6(dev->d_flags))
+#    endif
+            {
+              icmpv6_reply(dev, ICMPv6_DEST_UNREACHABLE,
+                           ICMPv6_PORT_UNREACH, 0);
+            }
+#  endif /* CONFIG_NET_ICMPv6 */
+
+#  ifdef CONFIG_NET_ICMP
+#    ifdef CONFIG_NET_ICMPv6
+          else
+#    endif
+            {
+              icmp_reply(dev, ICMP_DEST_UNREACHABLE, ICMP_PORT_UNREACH);
+            }
+#  endif /* CONFIG_NET_ICMP */
+#else
           dev->d_len = 0;
+#endif /* CONFIG_NET_ICMP || CONFIG_NET_ICMPv6 */
         }
     }
 
diff --git a/net/utils/net_icmpchksum.c b/net/utils/net_icmpchksum.c
index 8a93ee7..6816b94 100644
--- a/net/utils/net_icmpchksum.c
+++ b/net/utils/net_icmpchksum.c
@@ -49,7 +49,7 @@
  *
  ****************************************************************************/
 
-#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_SOCKET)
+#ifdef CONFIG_NET_ICMP
 uint16_t icmp_chksum(FAR struct net_driver_s *dev, int len)
 {
   FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
@@ -65,7 +65,7 @@ uint16_t icmp_chksum(FAR struct net_driver_s *dev, int len)
   icmp = ICMPBUF(iphdrlen);
   return net_chksum((FAR uint16_t *)&icmp->type, len);
 }
-#endif /* CONFIG_NET_ICMP && CONFIG_NET_ICMP_SOCKET */
+#endif /* CONFIG_NET_ICMP */
 
 /****************************************************************************
  * Name: icmpv6_chksum
diff --git a/net/utils/utils.h b/net/utils/utils.h
index e341ca2..5004b5e 100644
--- a/net/utils/utils.h
+++ b/net/utils/utils.h
@@ -361,7 +361,7 @@ uint16_t udp_ipv6_chksum(FAR struct net_driver_s *dev);
  *
  ****************************************************************************/
 
-#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_SOCKET)
+#ifdef CONFIG_NET_ICMP
 uint16_t icmp_chksum(FAR struct net_driver_s *dev, int len);
 #endif
 

[incubator-nuttx] 01/02: net/icmp/v6: add ICMP Destination Unreachable code definitions

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 6cd850b0e68f87fa99946ad2e006e4397e1b26ba
Author: chao.an <an...@xiaomi.com>
AuthorDate: Thu Nov 25 22:02:07 2021 +0800

    net/icmp/v6: add ICMP Destination Unreachable code definitions
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 include/nuttx/net/icmp.h   | 32 ++++++++++++++++++++++++++++++--
 include/nuttx/net/icmpv6.h | 12 ++++++++++++
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/include/nuttx/net/icmp.h b/include/nuttx/net/icmp.h
index d949c25..eeb52a3 100644
--- a/include/nuttx/net/icmp.h
+++ b/include/nuttx/net/icmp.h
@@ -94,6 +94,26 @@
 #define ICMP_HDRLEN    8                           /* Size of ICMP header */
 #define IPICMP_HDRLEN  (ICMP_HDRLEN + IPv4_HDRLEN) /* Size of IPv4 + ICMP header */
 
+/* Codes for UNREACH. */
+
+#define ICMP_NET_UNREACH             0    /* Network Unreachable    */
+#define ICMP_HOST_UNREACH            1    /* Host Unreachable   */
+#define ICMP_PROT_UNREACH            2    /* Protocol Unreachable   */
+#define ICMP_PORT_UNREACH            3    /* Port Unreachable   */
+#define ICMP_FRAG_NEEDED             4    /* Fragmentation Needed/DF set  */
+#define ICMP_SR_FAILED               5    /* Source Route failed    */
+#define ICMP_NET_UNKNOWN             6
+#define ICMP_HOST_UNKNOWN            7
+#define ICMP_HOST_ISOLATED           8
+#define ICMP_NET_ANO                 9
+#define ICMP_HOST_ANO                10
+#define ICMP_NET_UNR_TOS             11
+#define ICMP_HOST_UNR_TOS            12
+#define ICMP_PKT_FILTERED            13   /* Packet filtered */
+#define ICMP_PREC_VIOLATION          14   /* Precedence violation */
+#define ICMP_PREC_CUTOFF             15   /* Precedence cut off */
+#define NR_ICMP_UNREACH              15   /* instead of hardcoding immediate value */
+
 /****************************************************************************
  * Public Type Definitions
  ****************************************************************************/
@@ -113,8 +133,16 @@ struct icmp_hdr_s
 
   /* ICMP_ECHO_REQUEST and ICMP_ECHO_REPLY data */
 
-  uint16_t id;               /* Used to match requests with replies */
-  uint16_t seqno;            /* "  " "" "   " "      " "  " "     " */
+  union
+    {
+      struct
+        {
+          uint16_t id;      /* Used to match requests with replies */
+          uint16_t seqno;   /* "  " "" "   " "      " "  " "     " */
+        };
+
+      uint32_t data;
+    };
 };
 
 /* The structure holding the ICMP statistics that are gathered if
diff --git a/include/nuttx/net/icmpv6.h b/include/nuttx/net/icmpv6.h
index e520fc1..457619d 100644
--- a/include/nuttx/net/icmpv6.h
+++ b/include/nuttx/net/icmpv6.h
@@ -131,6 +131,16 @@
 #define ICMPv6_OPT_SIZE(a)    ((a) > 0 ? ((a) + 2 + 7) & ~7 : 0)
 #define ICMPv6_OPT_OCTECTS(a) ((a) > 0 ? ((a) + 2 + 7) >> 3 : 0)
 
+/* Codes for Destination Unreachable */
+
+#define ICMPv6_NOROUTE        0
+#define ICMPv6_ADM_PROHIBITED 1
+#define ICMPv6_NOT_NEIGHBOUR  2
+#define ICMPv6_ADDR_UNREACH   3
+#define ICMPv6_PORT_UNREACH   4
+#define ICMPv6_POLICY_FAIL    5
+#define ICMPv6_REJECT_ROUTE   6
+
 /****************************************************************************
  * Public Type Definitions
  ****************************************************************************/
@@ -146,6 +156,8 @@ struct icmpv6_hdr_s
   /* Data following the ICMP header contains the data specific to the
    * message type indicated by the Type and Code fields.
    */
+
+  uint32_t data;
 };
 
 /* The ICMPv6 and IPv6 headers */