ICMPv6: Add 6LoWPAN and IP forwarding support.
This commit is contained in:
parent
9db4350097
commit
975473fed8
@ -310,7 +310,7 @@ void netdriver_loop(void)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nwarn("WARNING: Unsupported Ethernet type %u\n", eth->type)
|
||||
nwarn("WARNING: Unsupported Ethernet type %u\n", eth->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -481,6 +481,33 @@ cxxtest
|
||||
postpone running C++ static initializers until NuttX has been
|
||||
initialized.
|
||||
|
||||
ipforward
|
||||
|
||||
This is an NSH configuration that includes a simple test of the NuttX
|
||||
IP forwarding logic using apps/examples/ipforward. That example uses
|
||||
two TUN network devices to represent two networks. The test then sends
|
||||
packets from one network destined for the other network. The NuttX IP
|
||||
forwarding logic will recognize that the received packets are not destined
|
||||
for it and will forward the logic to the other TUN network. The
|
||||
application logic then both sends the packets on one network and receives
|
||||
and verifies the forwarded packet recieved on the other network. The
|
||||
received packets differ from the sent packets only in that the hop limit
|
||||
(TTL) has been decremented.
|
||||
|
||||
Be default, this test will forward TCP packets. The test can be modified
|
||||
to support forwarding of ICMPv6 multicast packets with these changes to
|
||||
the .config file:
|
||||
|
||||
-CONFIG_EXAMPLES_IPFORWARD_TCP=y
|
||||
+CONFIG_EXAMPLES_IPFORWARD_ICMPv6=y
|
||||
|
||||
+CONFIG_NET_ICMPv6=y
|
||||
+CONFIG_NET_ICMPv6_PING=y
|
||||
+CONFIG_NET_ETHERNET=y
|
||||
|
||||
Additional required settings will also be selected when you manually
|
||||
select the above via 'make menuconfig'.
|
||||
|
||||
minibasic
|
||||
|
||||
This configuration was used to test the Mini Basic port at
|
||||
|
@ -106,9 +106,7 @@ CONFIG_HOST_X86_64=y
|
||||
CONFIG_SIM_X8664_SYSTEMV=y
|
||||
# CONFIG_SIM_X8664_MICROSOFT is not set
|
||||
CONFIG_SIM_WALLTIME=y
|
||||
CONFIG_SIM_NETDEV=y
|
||||
CONFIG_SIM_NET_HOST_ROUTE=y
|
||||
# CONFIG_SIM_NET_BRIDGE is not set
|
||||
# CONFIG_SIM_NETDEV is not set
|
||||
# CONFIG_SIM_FRAMEBUFFER is not set
|
||||
# CONFIG_SIM_SPIFLASH is not set
|
||||
# CONFIG_SIM_QSPIFLASH is not set
|
||||
@ -808,6 +806,7 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024
|
||||
# CONFIG_EXAMPLES_HIDKBD is not set
|
||||
# CONFIG_EXAMPLES_IGMP is not set
|
||||
CONFIG_EXAMPLES_IPFORWARD=y
|
||||
CONFIG_EXAMPLES_IPFORWARD_TCP=y
|
||||
CONFIG_EXAMPLES_IPFORWARD_PRIORITY=100
|
||||
CONFIG_EXAMPLES_IPFORWARD_STACKSIZE=8192
|
||||
# CONFIG_EXAMPLES_JSON is not set
|
||||
|
@ -171,10 +171,8 @@ static void tun_poll_expiry(int argc, wdparm_t arg, ...);
|
||||
static int tun_ifup(FAR struct net_driver_s *dev);
|
||||
static int tun_ifdown(FAR struct net_driver_s *dev);
|
||||
static int tun_txavail(FAR struct net_driver_s *dev);
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int tun_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int tun_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
static int tun_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
@ -780,7 +778,7 @@ static int tun_txavail(struct net_driver_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int tun_addmac(struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
{
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
|
@ -107,6 +107,12 @@ systime_t g_polltime;
|
||||
* IEEE802.15.4 MAC network driver. Under those conditions, 6LoWPAN
|
||||
* logic will be called to create the IEEE80215.4 frames.
|
||||
*
|
||||
* All outgoing ICMPv6 messages come through one of two mechanisms:
|
||||
*
|
||||
* 1. The output from internal ICMPv6 message passing. These outgoing
|
||||
* messages will use device polling and will be handled here.
|
||||
* 2. ICMPv6 output resulting from TX or timer polling.
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
@ -124,17 +130,25 @@ static void devif_packet_conversion(FAR struct net_driver_s *dev,
|
||||
if (dev->d_len > 0)
|
||||
#endif
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)dev->d_buf;
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
if ((ipv6->vtc & IP_VERSION_MASK) != IPv6_VERSION)
|
||||
{
|
||||
nerr("ERROR: IPv6 version error: %02x... Packet dropped\n",
|
||||
ipv6->vtc);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_NET_TCP
|
||||
if (pkttype == DEVIF_TCP)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)dev->d_buf;
|
||||
|
||||
/* This packet came from a response to TCP polling and is directed
|
||||
* to an IEEE802.15.4 device using 6LoWPAN. Verify that the outgoing
|
||||
* packet is IPv6 with TCP protocol.
|
||||
*/
|
||||
|
||||
if (ipv6->vtc == IPv6_VERSION && ipv6->proto == IP_PROTO_TCP)
|
||||
if (ipv6->proto == IP_PROTO_TCP)
|
||||
{
|
||||
/* Let 6LoWPAN convert IPv6 TCP output into IEEE802.15.4 frames. */
|
||||
|
||||
@ -142,17 +156,40 @@ static void devif_packet_conversion(FAR struct net_driver_s *dev,
|
||||
}
|
||||
else
|
||||
{
|
||||
nerr("ERROR: IPv6 version or protocol error. Packet dropped\n");
|
||||
nerr(" IP version: %02x proocol: %u\n",
|
||||
ipv6->vtc, ipv6->proto);
|
||||
nerr("ERROR: TCP protocol error: %u... Packet dropped\n",
|
||||
ipv6->proto);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
if (pkttype == DEVIF_ICMP6)
|
||||
{
|
||||
/* This packet came from a response to TCP polling and is directed
|
||||
* to an IEEE802.15.4 device using 6LoWPAN. Verify that the outgoing
|
||||
* packet is IPv6 with TCP protocol.
|
||||
*/
|
||||
|
||||
if (ipv6->proto == IP_PROTO_ICMP6)
|
||||
{
|
||||
/* Let 6LoWPAN convert IPv6 ICMPv6 output into IEEE802.15.4 frames. */
|
||||
|
||||
sixlowpan_icmpv6_send(dev, dev, ipv6);
|
||||
}
|
||||
else
|
||||
{
|
||||
nerr("ERROR: ICMPv6 protocol error: %u... Packet dropped\n",
|
||||
ipv6->proto);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nerr("ERROR: Non-TCP packet dropped. Packet type: %u\n", pkttype);
|
||||
nerr("ERROR: Unhandled packet dropped. pkttype=%u protocol=%u\n",
|
||||
pkttype, ipv6->proto);
|
||||
}
|
||||
|
||||
UNUSED(ipv6);
|
||||
dev->d_len = 0;
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ int ipv6_input(FAR struct net_driver_s *dev)
|
||||
* during TCP packet processing by the TCP state meachine.
|
||||
* 3. TCP output resulting from TX or timer polling
|
||||
*
|
||||
* Cases 2 is handled here. Logic here detected if (1) an attempt
|
||||
* Case 3 is handled here. Logic here detects if (1) an attempt
|
||||
* to return with d_len > 0 and (2) that the device is an
|
||||
* IEEE802.15.4 MAC network driver. Under those conditions, 6LoWPAN
|
||||
* logic will be called to create the IEEE80215.4 frames.
|
||||
@ -457,8 +457,40 @@ int ipv6_input(FAR struct net_driver_s *dev)
|
||||
/* Forward the ICMPv6 packet */
|
||||
|
||||
icmpv6_input(dev);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET_6LOWPAN
|
||||
/* All outgoing ICMPv6 messages come through one of two mechanisms:
|
||||
*
|
||||
* 1. The output from internal ICMPv6 message passing. These
|
||||
* outgoing messages will use device polling and will be
|
||||
* handled elsewhere.
|
||||
* 2. ICMPv6 output resulting from TX or timer polling.
|
||||
*
|
||||
* Case 2 is handled here. Logic here detects if (1) an attempt
|
||||
* to return with d_len > 0 and (2) that the device is an
|
||||
* IEEE802.15.4 MAC network driver. Under those conditions, 6LoWPAN
|
||||
* logic will be called to create the IEEE80215.4 frames.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NET_MULTILINK
|
||||
/* Handle the case where multiple link layer protocols are supported */
|
||||
|
||||
if (dev->d_len > 0 && dev->d_lltype == CONFIG_NET_6LOWPAN)
|
||||
#else
|
||||
if (dev->d_len > 0)
|
||||
#endif
|
||||
{
|
||||
/* Let 6LoWPAN handle the ICMPv6 output */
|
||||
|
||||
sixlowpan_icmpv6_send(dev, dev, ipv6);
|
||||
|
||||
/* Drop the packet in the d_buf */
|
||||
|
||||
goto drop;
|
||||
}
|
||||
#endif /* CONFIG_NET_6LOWPAN */
|
||||
break;
|
||||
#endif /* CONFIG_NET_ICMPv6 */
|
||||
|
||||
default: /* Unrecognized/unsupported protocol */
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
|
@ -80,6 +80,12 @@
|
||||
# define DEV_LLTYPE(d) NET_LL_ETHERNET
|
||||
#elif defined(CONFIG_NET_6LOWPAN)
|
||||
# define DEV_LLTYPE(d) NET_LL_IEEE802154
|
||||
#elif defined(CONFIG_NET_SLIP)
|
||||
# define DEV_LLTYPE(d) NET_LL_SLIP
|
||||
#elif defined(CONFIG_NET_TUN)
|
||||
# define DEV_LLTYPE(d) NET_LL_TUN
|
||||
#else /* if defined(CONFIG_NET_LOOPBACK) */
|
||||
# define DEV_LLTYPE(d) NET_LL_LOOPBACK
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -140,7 +140,7 @@ static void ipfwd_packet_conversion(FAR struct net_driver_s *dev, int proto)
|
||||
{
|
||||
/* Let 6LoWPAN convert IPv6 UDP output into IEEE802.15.4 frames. */
|
||||
|
||||
nwerr("ERROR: Missing support for ICMPv6 packet forwarding\n");
|
||||
sixlowpan_icmpv6_send(dev, dev, ipv6);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -271,6 +271,36 @@ static int ipv6_packet_conversion(FAR struct net_driver_s *dev,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
if (ipv6->proto == IP_PROTO_ICMP6)
|
||||
{
|
||||
/* Decrement the TTL in the IPv6 header. If it decrements to
|
||||
* zero, then drop the packet.
|
||||
*/
|
||||
|
||||
ret = ipv6_decr_ttl(ipv6);
|
||||
if (ret < 1)
|
||||
{
|
||||
nwarn("WARNING: Hop limit exceeded... Dropping!\n");
|
||||
ret = -EMULTIHOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Let 6LoWPAN convert IPv6 ICMPv6 output into IEEE802.15.4
|
||||
* frames.
|
||||
*/
|
||||
|
||||
sixlowpan_icmpv6_send(dev, fwddev, ipv6);
|
||||
|
||||
/* The packet was forwarded */
|
||||
|
||||
dev->d_len = 0;
|
||||
return PACKET_FORWARDED;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Otherwise, we cannot forward the packet */
|
||||
|
||||
|
@ -47,7 +47,17 @@ NET_CSRCS += sixlowpan_tcpsend.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_UDP),y)
|
||||
NET_CSRCS += sixlowpan_udpsend.c sixlowpan_send.c
|
||||
NET_CSRCS += sixlowpan_udpsend.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_ICMPv6),y)
|
||||
NET_CSRCS += sixlowpan_icmpv6send.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_UDP),y)
|
||||
NET_CSRCS += sixlowpan_send.c
|
||||
else ifeq ($(CONFIG_NET_ICMPv6),y)
|
||||
NET_CSRCS += sixlowpan_send.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC1),y)
|
||||
|
@ -147,6 +147,41 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev,
|
||||
FAR struct net_driver_s *fwddev,
|
||||
FAR struct ipv6_hdr_s *ipv6);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_icmpv6_send
|
||||
*
|
||||
* Description:
|
||||
* All outgoing ICMPv6 messages come through one of two mechanisms:
|
||||
*
|
||||
* 1. The output from internal ICMPv6 message passing. These outgoing
|
||||
* messages will use device polling.
|
||||
* 2. ICMPv6 output resulting from TX or timer polling.
|
||||
*
|
||||
* Both cases are handled here.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - The network device containing the packet to be sent.
|
||||
* fwddev - The network device used to send the data. This will be the
|
||||
* same device except for the IP forwarding case where packets
|
||||
* are sent across devices.
|
||||
* ipv6 - A pointer to the IPv6 header in dev->d_buf which lies AFTER
|
||||
* the L1 header. NOTE: dev->d_len must have been decremented
|
||||
* by the size of any preceding MAC header.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
void sixlowpan_icmpv6_send(FAR struct net_driver_s *dev,
|
||||
FAR struct net_driver_s *fwddev,
|
||||
FAR struct ipv6_hdr_s *ipv6);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: psock_6lowpan_udp_send
|
||||
*
|
||||
|
@ -212,7 +212,7 @@ static uint16_t sixlowpan_protosize(FAR const struct ipv6_hdr_s *ipv6hdr,
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - The IEEE802.15.4 MAC driver instance
|
||||
* ipv6hdr - IPv6 header followed by TCP, UDP, or ICMPv6 header.
|
||||
* ipv6 - IPv6 header followed by TCP, UDP, or ICMPv6 header.
|
||||
* buf - Beginning of the packet packet to send (with IPv6 + protocol
|
||||
* headers)
|
||||
* buflen - Length of data to send (include IPv6 and protocol headers)
|
||||
@ -230,7 +230,7 @@ static uint16_t sixlowpan_protosize(FAR const struct ipv6_hdr_s *ipv6hdr,
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ipv6_hdr_s *destip,
|
||||
FAR const struct ipv6_hdr_s *ipv6,
|
||||
FAR const void *buf, size_t buflen,
|
||||
FAR const struct sixlowpan_tagaddr_s *destmac)
|
||||
{
|
||||
@ -266,10 +266,10 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
/* Set stream mode for all TCP packets, except FIN packets. */
|
||||
|
||||
#if 0 /* Currently the frame type is always data */
|
||||
if (destip->proto == IP_PROTO_TCP)
|
||||
if (ipv6->proto == IP_PROTO_TCP)
|
||||
{
|
||||
FAR const struct tcp_hdr_s *tcp =
|
||||
&((FAR const struct ipv6tcp_hdr_s *)destip)->tcp;
|
||||
&((FAR const struct ipv6tcp_hdr_s *)ipv6)->tcp;
|
||||
|
||||
if ((tcp->flags & TCP_FIN) == 0 &&
|
||||
(tcp->flags & TCP_CTL) != TCP_ACK)
|
||||
@ -379,9 +379,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
/* Try to compress the headers */
|
||||
|
||||
#if defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC1)
|
||||
ret = sixlowpan_compresshdr_hc1(ieee, destip, destmac, fptr);
|
||||
ret = sixlowpan_compresshdr_hc1(ieee, ipv6, destmac, fptr);
|
||||
#elif defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC06)
|
||||
ret = sixlowpan_compresshdr_hc06(ieee, destip, destmac, fptr);
|
||||
ret = sixlowpan_compresshdr_hc06(ieee, ipv6, destmac, fptr);
|
||||
#else
|
||||
# error No compression specified
|
||||
#endif
|
||||
@ -391,14 +391,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
{
|
||||
/* Small.. use IPv6 dispatch (no compression) */
|
||||
|
||||
ret = sixlowpan_compress_ipv6hdr(destip, fptr);
|
||||
ret = sixlowpan_compress_ipv6hdr(ipv6, fptr);
|
||||
}
|
||||
|
||||
/* Get the size of any uncompressed protocol headers */
|
||||
|
||||
if (ret == COMPRESS_HDR_INLINE)
|
||||
{
|
||||
protosize = sixlowpan_protosize(destip, fptr);
|
||||
protosize = sixlowpan_protosize(ipv6, fptr);
|
||||
}
|
||||
|
||||
ninfo("Header of length=%u protosize=%u\n", g_frame_hdrlen, protosize);
|
||||
@ -465,7 +465,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
if (protosize > 0)
|
||||
{
|
||||
FAR uint8_t *src = (FAR uint8_t *)destip + IPv6_HDRLEN;
|
||||
FAR uint8_t *src = (FAR uint8_t *)ipv6 + IPv6_HDRLEN;
|
||||
memcpy(fptr + g_frame_hdrlen, src, protosize);
|
||||
}
|
||||
|
||||
@ -625,7 +625,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
|
||||
if (protosize > 0)
|
||||
{
|
||||
FAR uint8_t *src = (FAR uint8_t *)destip + IPv6_HDRLEN;
|
||||
FAR uint8_t *src = (FAR uint8_t *)ipv6 + IPv6_HDRLEN;
|
||||
memcpy(fptr + g_frame_hdrlen, src, protosize);
|
||||
}
|
||||
|
||||
|
161
net/sixlowpan/sixlowpan_icmpv6send.c
Normal file
161
net/sixlowpan/sixlowpan_icmpv6send.c
Normal file
@ -0,0 +1,161 @@
|
||||
/****************************************************************************
|
||||
* net/sixlowpan/sixlowpan_icmpv6send.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
|
||||
#include "icmpv6/icmpv6.h"
|
||||
#include "sixlowpan/sixlowpan_internal.h"
|
||||
#include "sixlowpan/sixlowpan.h"
|
||||
|
||||
#if defined(CONFIG_NET_6LOWPAN) && defined(CONFIG_NET_ICMPv6)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_icmpv6_send
|
||||
*
|
||||
* Description:
|
||||
* Handles forwarding a ICMPv6 packet via 6LoWPAN. This is currently only
|
||||
* used by the IPv6 forwarding logic.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - An instance of nework device state structure
|
||||
* fwddev - The network device used to send the data. This will be the
|
||||
* same device except for the IP forwarding case where packets
|
||||
* are sent across devices.
|
||||
* ipv6 - A pointer to the IPv6 header in dev->d_buf which lies AFTER
|
||||
* the L1 header. NOTE: dev->d_len must have been decremented
|
||||
* by the size of any preceding MAC header.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPFORWARD
|
||||
void sixlowpan_icmpv6_send(FAR struct net_driver_s *dev,
|
||||
FAR struct net_driver_s *fwddev,
|
||||
FAR struct ipv6_hdr_s *ipv6)
|
||||
{
|
||||
FAR struct ipv6icmp_hdr_s *ipv6icmpv6 = (FAR struct ipv6icmp_hdr_s *)ipv6;
|
||||
|
||||
/* Double check */
|
||||
|
||||
DEBUGASSERT(dev != NULL && dev->d_len > 0);
|
||||
|
||||
ninfo("d_len %u\n", dev->d_len);
|
||||
|
||||
if (dev != NULL && dev->d_len > 0)
|
||||
{
|
||||
sixlowpan_dumpbuffer("Outgoing ICMPv6 packet",
|
||||
(FAR const uint8_t *)ipv6icmpv6, dev->d_len);
|
||||
|
||||
/* The ICMPv6 data payload should follow the IPv6 header plus the
|
||||
* protocol header.
|
||||
*/
|
||||
|
||||
if (ipv6icmpv6->ipv6.proto != IP_PROTO_ICMPv6)
|
||||
{
|
||||
nwarn("WARNING: Expected ICMPv6 protoype: %u vs %s\n",
|
||||
ipv6icmpv6->ipv6.proto, IP_PROTO_ICMPv6);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct sixlowpan_tagaddr_s destmac;
|
||||
FAR uint8_t *buf;
|
||||
uint16_t hdrlen;
|
||||
uint16_t buflen;
|
||||
int ret;
|
||||
|
||||
/* Get the IEEE 802.15.4 MAC address of the destination. This
|
||||
* assumes an encoding of the MAC address in the IPv6 address.
|
||||
*/
|
||||
|
||||
ret = sixlowpan_destaddrfromip((FAR struct ieee802154_driver_s *)dev,
|
||||
ipv6icmpv6->ipv6.destipaddr, &destmac);
|
||||
if (ret < 0)
|
||||
{
|
||||
nerr("ERROR: Failed to dest MAC address: %d\n", ret);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Get the IPv6 + ICMPv6 combined header length. NOTE: This header
|
||||
* size includes only the common 32-bit header at the beginning of
|
||||
* each ICMPv6 message.
|
||||
*/
|
||||
|
||||
hdrlen = IPv6_HDRLEN + ICMPv6_HDRLEN;
|
||||
|
||||
/* Drop the packet if the buffer length is less than this. */
|
||||
|
||||
if (hdrlen > dev->d_len)
|
||||
{
|
||||
nwarn("WARNING: Dropping small ICMPv6 packet: %u < %u\n",
|
||||
buflen, hdrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert the outgoing packet into a frame list. */
|
||||
|
||||
buf = (FAR uint8_t *)ipv6 + hdrlen;
|
||||
buflen = dev->d_len - hdrlen;
|
||||
|
||||
(void)sixlowpan_queue_frames(
|
||||
(FAR struct ieee802154_driver_s *)fwddev,
|
||||
&ipv6icmpv6->ipv6, buf, buflen, &destmac);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drop:
|
||||
dev->d_len = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_ICMPv6 */
|
@ -356,7 +356,7 @@ int sixlowpan_frame_submit(FAR struct ieee802154_driver_s *ieee,
|
||||
*
|
||||
* Input Parameters:
|
||||
* ieee - The IEEE802.15.4 MAC driver instance
|
||||
* ipv6hdr - IPv6 header followed by TCP or UDP header.
|
||||
* ipv6 - IPv6 header followed by TCP or UDP header.
|
||||
* buf - Beginning of the packet packet to send (with IPv6 + protocol
|
||||
* headers)
|
||||
* buflen - Length of data to send (include IPv6 and protocol headers)
|
||||
@ -374,7 +374,7 @@ int sixlowpan_frame_submit(FAR struct ieee802154_driver_s *ieee,
|
||||
****************************************************************************/
|
||||
|
||||
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||
FAR const struct ipv6_hdr_s *ipv6hdr,
|
||||
FAR const struct ipv6_hdr_s *ipv6,
|
||||
FAR const void *buf, size_t buflen,
|
||||
FAR const struct sixlowpan_tagaddr_s *destmac);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user