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
|
else
|
||||||
#endif
|
#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
|
postpone running C++ static initializers until NuttX has been
|
||||||
initialized.
|
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
|
minibasic
|
||||||
|
|
||||||
This configuration was used to test the Mini Basic port at
|
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_SYSTEMV=y
|
||||||
# CONFIG_SIM_X8664_MICROSOFT is not set
|
# CONFIG_SIM_X8664_MICROSOFT is not set
|
||||||
CONFIG_SIM_WALLTIME=y
|
CONFIG_SIM_WALLTIME=y
|
||||||
CONFIG_SIM_NETDEV=y
|
# CONFIG_SIM_NETDEV is not set
|
||||||
CONFIG_SIM_NET_HOST_ROUTE=y
|
|
||||||
# CONFIG_SIM_NET_BRIDGE is not set
|
|
||||||
# CONFIG_SIM_FRAMEBUFFER is not set
|
# CONFIG_SIM_FRAMEBUFFER is not set
|
||||||
# CONFIG_SIM_SPIFLASH is not set
|
# CONFIG_SIM_SPIFLASH is not set
|
||||||
# CONFIG_SIM_QSPIFLASH 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_HIDKBD is not set
|
||||||
# CONFIG_EXAMPLES_IGMP is not set
|
# CONFIG_EXAMPLES_IGMP is not set
|
||||||
CONFIG_EXAMPLES_IPFORWARD=y
|
CONFIG_EXAMPLES_IPFORWARD=y
|
||||||
|
CONFIG_EXAMPLES_IPFORWARD_TCP=y
|
||||||
CONFIG_EXAMPLES_IPFORWARD_PRIORITY=100
|
CONFIG_EXAMPLES_IPFORWARD_PRIORITY=100
|
||||||
CONFIG_EXAMPLES_IPFORWARD_STACKSIZE=8192
|
CONFIG_EXAMPLES_IPFORWARD_STACKSIZE=8192
|
||||||
# CONFIG_EXAMPLES_JSON is not set
|
# 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_ifup(FAR struct net_driver_s *dev);
|
||||||
static int tun_ifdown(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);
|
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
|
#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);
|
static int tun_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NET_ICMPv6
|
#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)
|
static int tun_addmac(struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||||
{
|
{
|
||||||
/* Add the MAC address to the hardware multicast routing table */
|
/* 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
|
* IEEE802.15.4 MAC network driver. Under those conditions, 6LoWPAN
|
||||||
* logic will be called to create the IEEE80215.4 frames.
|
* 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:
|
* Assumptions:
|
||||||
* The network is locked.
|
* The network is locked.
|
||||||
*
|
*
|
||||||
@ -124,17 +130,25 @@ static void devif_packet_conversion(FAR struct net_driver_s *dev,
|
|||||||
if (dev->d_len > 0)
|
if (dev->d_len > 0)
|
||||||
#endif
|
#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
|
#ifdef CONFIG_NET_TCP
|
||||||
if (pkttype == DEVIF_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
|
/* This packet came from a response to TCP polling and is directed
|
||||||
* to an IEEE802.15.4 device using 6LoWPAN. Verify that the outgoing
|
* to an IEEE802.15.4 device using 6LoWPAN. Verify that the outgoing
|
||||||
* packet is IPv6 with TCP protocol.
|
* 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. */
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
nerr("ERROR: IPv6 version or protocol error. Packet dropped\n");
|
nerr("ERROR: TCP protocol error: %u... Packet dropped\n",
|
||||||
nerr(" IP version: %02x proocol: %u\n",
|
ipv6->proto);
|
||||||
ipv6->vtc, 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
|
else
|
||||||
#endif
|
#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;
|
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.
|
* during TCP packet processing by the TCP state meachine.
|
||||||
* 3. TCP output resulting from TX or timer polling
|
* 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
|
* to return with d_len > 0 and (2) that the device is an
|
||||||
* IEEE802.15.4 MAC network driver. Under those conditions, 6LoWPAN
|
* IEEE802.15.4 MAC network driver. Under those conditions, 6LoWPAN
|
||||||
* logic will be called to create the IEEE80215.4 frames.
|
* 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 */
|
/* Forward the ICMPv6 packet */
|
||||||
|
|
||||||
icmpv6_input(dev);
|
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
|
#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 */
|
default: /* Unrecognized/unsupported protocol */
|
||||||
#ifdef CONFIG_NET_STATISTICS
|
#ifdef CONFIG_NET_STATISTICS
|
||||||
|
@ -80,6 +80,12 @@
|
|||||||
# define DEV_LLTYPE(d) NET_LL_ETHERNET
|
# define DEV_LLTYPE(d) NET_LL_ETHERNET
|
||||||
#elif defined(CONFIG_NET_6LOWPAN)
|
#elif defined(CONFIG_NET_6LOWPAN)
|
||||||
# define DEV_LLTYPE(d) NET_LL_IEEE802154
|
# 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
|
#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. */
|
/* 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
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -271,6 +271,36 @@ static int ipv6_packet_conversion(FAR struct net_driver_s *dev,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#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 */
|
/* Otherwise, we cannot forward the packet */
|
||||||
|
|
||||||
|
@ -47,7 +47,17 @@ NET_CSRCS += sixlowpan_tcpsend.c
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_NET_UDP),y)
|
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
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC1),y)
|
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 net_driver_s *fwddev,
|
||||||
FAR struct ipv6_hdr_s *ipv6);
|
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
|
* Name: psock_6lowpan_udp_send
|
||||||
*
|
*
|
||||||
|
@ -212,7 +212,7 @@ static uint16_t sixlowpan_protosize(FAR const struct ipv6_hdr_s *ipv6hdr,
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* ieee - The IEEE802.15.4 MAC driver instance
|
* 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
|
* buf - Beginning of the packet packet to send (with IPv6 + protocol
|
||||||
* headers)
|
* headers)
|
||||||
* buflen - Length of data to send (include IPv6 and 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,
|
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 void *buf, size_t buflen,
|
||||||
FAR const struct sixlowpan_tagaddr_s *destmac)
|
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. */
|
/* Set stream mode for all TCP packets, except FIN packets. */
|
||||||
|
|
||||||
#if 0 /* Currently the frame type is always data */
|
#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 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 &&
|
if ((tcp->flags & TCP_FIN) == 0 &&
|
||||||
(tcp->flags & TCP_CTL) != TCP_ACK)
|
(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 */
|
/* Try to compress the headers */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC1)
|
#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)
|
#elif defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC06)
|
||||||
ret = sixlowpan_compresshdr_hc06(ieee, destip, destmac, fptr);
|
ret = sixlowpan_compresshdr_hc06(ieee, ipv6, destmac, fptr);
|
||||||
#else
|
#else
|
||||||
# error No compression specified
|
# error No compression specified
|
||||||
#endif
|
#endif
|
||||||
@ -391,14 +391,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
|||||||
{
|
{
|
||||||
/* Small.. use IPv6 dispatch (no compression) */
|
/* 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 */
|
/* Get the size of any uncompressed protocol headers */
|
||||||
|
|
||||||
if (ret == COMPRESS_HDR_INLINE)
|
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);
|
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)
|
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);
|
memcpy(fptr + g_frame_hdrlen, src, protosize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -625,7 +625,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
|||||||
|
|
||||||
if (protosize > 0)
|
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);
|
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:
|
* Input Parameters:
|
||||||
* ieee - The IEEE802.15.4 MAC driver instance
|
* 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
|
* buf - Beginning of the packet packet to send (with IPv6 + protocol
|
||||||
* headers)
|
* headers)
|
||||||
* buflen - Length of data to send (include IPv6 and 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,
|
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 void *buf, size_t buflen,
|
||||||
FAR const struct sixlowpan_tagaddr_s *destmac);
|
FAR const struct sixlowpan_tagaddr_s *destmac);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user