ICMPv6: Fix so that ICMPv6 can be used with 6LoWPAN.
This commit is contained in:
parent
76587b2c6f
commit
a5f361e984
@ -2,7 +2,7 @@
|
|||||||
* include/nuttx/net/icmpv6.h
|
* include/nuttx/net/icmpv6.h
|
||||||
* Header file for the NuttX ICMPv6 stack.
|
* Header file for the NuttX ICMPv6 stack.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2012, 2014 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2012, 2014, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* This logic was leveraged from uIP which also has a BSD-style license:
|
* This logic was leveraged from uIP which also has a BSD-style license:
|
||||||
@ -123,6 +123,13 @@
|
|||||||
#define ICMPv6_PRFX_FLAG_L (1 << 7) /* On-link flag */
|
#define ICMPv6_PRFX_FLAG_L (1 << 7) /* On-link flag */
|
||||||
#define ICMPv6_PRFX_FLAG_A (1 << 6) /* Autonomous address-configuration flag
|
#define ICMPv6_PRFX_FLAG_A (1 << 6) /* Autonomous address-configuration flag
|
||||||
|
|
||||||
|
/* Return with size of an option (in full octects) using the size of a link
|
||||||
|
* layer address taking into account a header of the two-bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ICMPv6_OPT_SIZE(a) (((a) + 2 + 7) & ~7)
|
||||||
|
#define ICMPv6_OPT_OCTECTS(a) (((a) + 2 + 7) >> 3)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -178,11 +185,12 @@ struct icmpv6_neighbor_solicit_s
|
|||||||
|
|
||||||
uint8_t opttype; /* Option Type: ICMPv6_OPT_SRCLLADDR */
|
uint8_t opttype; /* Option Type: ICMPv6_OPT_SRCLLADDR */
|
||||||
uint8_t optlen; /* Option length: 1 octet */
|
uint8_t optlen; /* Option length: 1 octet */
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
|
||||||
uint8_t srclladdr[6]; /* Options: Source link layer address */
|
uint8_t srclladdr[6]; /* Options: Source link layer address */
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SIZEOF_ICMPV6_NEIGHBOR_SOLICIT_S(n) \
|
||||||
|
(sizeof(struct icmpv6_neighbor_solicit_s) + ICMPv6_OPT_SIZE(n) - 8)
|
||||||
|
|
||||||
/* This the message format for the ICMPv6 Neighbor Advertisement message */
|
/* This the message format for the ICMPv6 Neighbor Advertisement message */
|
||||||
|
|
||||||
struct icmpv6_neighbor_advertise_s
|
struct icmpv6_neighbor_advertise_s
|
||||||
@ -194,12 +202,14 @@ struct icmpv6_neighbor_advertise_s
|
|||||||
net_ipv6addr_t tgtaddr; /* Target IPv6 address */
|
net_ipv6addr_t tgtaddr; /* Target IPv6 address */
|
||||||
|
|
||||||
uint8_t opttype; /* Option Type: ICMPv6_OPT_TGTLLADDR */
|
uint8_t opttype; /* Option Type: ICMPv6_OPT_TGTLLADDR */
|
||||||
uint8_t optlen; /* Option length: 1 octet */
|
uint8_t optlen; /* Option length in octets */
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
|
||||||
uint8_t tgtlladdr[6]; /* Options: Target link layer address */
|
uint8_t tgtlladdr[6]; /* Options: Target link layer address */
|
||||||
#endif
|
/* Actual size detemined by optlen */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SIZEOF_ICMPV6_NEIGHBOR_ADVERTISE_S(n) \
|
||||||
|
(sizeof(struct icmpv6_neighbor_advertise_s) + ICMPv6_OPT_SIZE(n) - 8)
|
||||||
|
|
||||||
/* This the message format for the ICMPv6 Router Solicitation message */
|
/* This the message format for the ICMPv6 Router Solicitation message */
|
||||||
|
|
||||||
struct icmpv6_router_solicit_s
|
struct icmpv6_router_solicit_s
|
||||||
@ -210,12 +220,13 @@ struct icmpv6_router_solicit_s
|
|||||||
uint8_t flags[4]; /* See ICMPv6_RADV_FLAG_ definitions (must be zero) */
|
uint8_t flags[4]; /* See ICMPv6_RADV_FLAG_ definitions (must be zero) */
|
||||||
|
|
||||||
uint8_t opttype; /* Option Type: ICMPv6_OPT_SRCLLADDR */
|
uint8_t opttype; /* Option Type: ICMPv6_OPT_SRCLLADDR */
|
||||||
uint8_t optlen; /* Option length: 1 octet */
|
uint8_t optlen; /* Option length in octets */
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
|
||||||
uint8_t srclladdr[6]; /* Options: Source link layer address */
|
uint8_t srclladdr[6]; /* Options: Source link layer address */
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SIZEOF_ICMPV6_ROUTER_SOLICIT_S(n) \
|
||||||
|
(sizeof(struct icmpv6_router_solicit_s) + ICMPv6_OPT_SIZE(n) - 8)
|
||||||
|
|
||||||
/* This the message format for the ICMPv6 Router Advertisement message:
|
/* This the message format for the ICMPv6 Router Advertisement message:
|
||||||
* Options may include: ICMPv6_OPT_SRCLLADDR, ICMPv6_OPT_MTU, and/or
|
* Options may include: ICMPv6_OPT_SRCLLADDR, ICMPv6_OPT_MTU, and/or
|
||||||
* ICMPv6_OPT_PREFIX
|
* ICMPv6_OPT_PREFIX
|
||||||
@ -231,7 +242,7 @@ struct icmpv6_router_advertise_s
|
|||||||
uint16_t lifetime; /* Router lifetime */
|
uint16_t lifetime; /* Router lifetime */
|
||||||
uint16_t reachable[2]; /* Reachable time */
|
uint16_t reachable[2]; /* Reachable time */
|
||||||
uint16_t retrans[2]; /* Retransmission timer */
|
uint16_t retrans[2]; /* Retransmission timer */
|
||||||
uint8_t options[1]; /* Options begin here */
|
/* Options begin here */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ICMPv6_RADV_MINLEN (16)
|
#define ICMPv6_RADV_MINLEN (16)
|
||||||
@ -280,20 +291,20 @@ struct icmpv6_srclladdr_s
|
|||||||
{
|
{
|
||||||
uint8_t opttype; /* Octet 1: Option Type: ICMPv6_OPT_SRCLLADDR */
|
uint8_t opttype; /* Octet 1: Option Type: ICMPv6_OPT_SRCLLADDR */
|
||||||
uint8_t optlen; /* " " ": Option length: 1 octet */
|
uint8_t optlen; /* " " ": Option length: 1 octet */
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
|
||||||
uint8_t srclladdr[6]; /* " " ": Options: Source link layer address */
|
uint8_t srclladdr[6]; /* " " ": Options: Source link layer address */
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SIZEOF_ICMPV6_SRCLLADDR_S(n) ICMPv6_OPT_SIZE(n)
|
||||||
|
|
||||||
struct icmpv6_tgrlladdr_s
|
struct icmpv6_tgrlladdr_s
|
||||||
{
|
{
|
||||||
uint8_t opttype; /* Octet 1: Option Type: ICMPv6_OPT_TGTLLADDR */
|
uint8_t opttype; /* Octet 1: Option Type: ICMPv6_OPT_TGTLLADDR */
|
||||||
uint8_t optlen; /* " " ": Option length: 1 octet */
|
uint8_t optlen; /* " " ": Option length in octets */
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
|
||||||
uint8_t tgtlladdr[6]; /* " " ": Options: Target link layer address */
|
uint8_t tgtlladdr[6]; /* " " ": Options: Target link layer address */
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SIZEOF_ICMPV6_TGRLLADDR_S(n) ICMPv6_OPT_SIZE(n)
|
||||||
|
|
||||||
struct icmpv6_prefixinfo_s
|
struct icmpv6_prefixinfo_s
|
||||||
{
|
{
|
||||||
uint8_t opttype; /* Octet 1: Option Type: ICMPv6_OPT_PREFIX */
|
uint8_t opttype; /* Octet 1: Option Type: ICMPv6_OPT_PREFIX */
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* net/icmpv6/icmpv6_advertise.c
|
* net/icmpv6/icmpv6_advertise.c
|
||||||
* Send an ICMPv6 Neighbor Advertisement
|
* Send an ICMPv6 Neighbor Advertisement
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||||
@ -96,6 +96,8 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
|
|||||||
{
|
{
|
||||||
FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF;
|
FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF;
|
||||||
FAR struct icmpv6_neighbor_advertise_s *adv;
|
FAR struct icmpv6_neighbor_advertise_s *adv;
|
||||||
|
uint16_t l1size;
|
||||||
|
uint16_t l3size;
|
||||||
|
|
||||||
/* Set up the IPv6 header */
|
/* Set up the IPv6 header */
|
||||||
|
|
||||||
@ -105,8 +107,10 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Length excludes the IPv6 header */
|
/* Length excludes the IPv6 header */
|
||||||
|
|
||||||
icmp->len[0] = (sizeof(struct icmpv6_neighbor_advertise_s) >> 8);
|
l1size = NET_LL_HDRLEN(dev);
|
||||||
icmp->len[1] = (sizeof(struct icmpv6_neighbor_advertise_s) & 0xff);
|
l3size = SIZEOF_ICMPV6_NEIGHBOR_ADVERTISE_S(l1size);
|
||||||
|
icmp->len[0] = (l3size >> 8);
|
||||||
|
icmp->len[1] = (l3size & 0xff);
|
||||||
|
|
||||||
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
||||||
icmp->ttl = 255; /* Hop limit */
|
icmp->ttl = 255; /* Hop limit */
|
||||||
@ -133,13 +137,13 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
|
|||||||
/* Set up the options */
|
/* Set up the options */
|
||||||
|
|
||||||
adv->opttype = ICMPv6_OPT_TGTLLADDR; /* Option type */
|
adv->opttype = ICMPv6_OPT_TGTLLADDR; /* Option type */
|
||||||
adv->optlen = 1; /* Option length = 1 octet */
|
adv->optlen = ICMPv6_OPT_OCTECTS(l1size); /* Option length in octets */
|
||||||
|
|
||||||
/* Copy our link layer address into the message
|
/* Copy our link layer address into the message
|
||||||
* REVISIT: What if the link layer is not Ethernet?
|
* REVISIT: What if the link layer is not Ethernet?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memcpy(adv->tgtlladdr, &dev->d_mac.ether, IFHWADDRLEN);
|
memcpy(adv->tgtlladdr, &dev->d_mac, l1size);
|
||||||
|
|
||||||
/* Calculate the checksum over both the ICMP header and payload */
|
/* Calculate the checksum over both the ICMP header and payload */
|
||||||
|
|
||||||
@ -148,7 +152,7 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Set the size to the size of the IPv6 header and the payload size */
|
/* Set the size to the size of the IPv6 header and the payload size */
|
||||||
|
|
||||||
dev->d_len = IPv6_HDRLEN + sizeof(struct icmpv6_neighbor_advertise_s);
|
dev->d_len = IPv6_HDRLEN + l3size;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
#ifdef CONFIG_NET_ETHERNET
|
||||||
/* Add the size of the Ethernet header */
|
/* Add the size of the Ethernet header */
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* net/icmpv6/icmpv6_input.c
|
* net/icmpv6/icmpv6_input.c
|
||||||
* Handling incoming ICMPv6 input
|
* Handling incoming ICMPv6 input
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||||
|
@ -58,31 +58,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_ICMPv6_ROUTER
|
#ifdef CONFIG_NET_ICMPv6_ROUTER
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Types
|
|
||||||
****************************************************************************/
|
|
||||||
/* This is the same as struct icmpv6_router_advertise_s, but with the
|
|
||||||
* source address and prefix options included for simplicity.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct icmpv6_radvertise_s
|
|
||||||
{
|
|
||||||
uint8_t type; /* Message Type: ICMPV6_ROUTER_ADVERTISE */
|
|
||||||
uint8_t code; /* Further qualifies the ICMP messages */
|
|
||||||
uint16_t chksum; /* Checksum of ICMP header and data */
|
|
||||||
uint8_t hoplimit; /* Current hop limit */
|
|
||||||
uint8_t flags; /* See ICMPv6_RADV_FLAG_* definitions */
|
|
||||||
uint16_t lifetime; /* Router lifetime */
|
|
||||||
uint16_t reachable[2]; /* Reachable time */
|
|
||||||
uint16_t retrans[2]; /* Retransmission timer */
|
|
||||||
|
|
||||||
/* Options */
|
|
||||||
|
|
||||||
struct icmpv6_srclladdr_s srcaddr;
|
|
||||||
struct icmpv6_mtu_s mtu;
|
|
||||||
struct icmpv6_prefixinfo_s prefix;
|
|
||||||
};
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -91,7 +66,7 @@ struct icmpv6_radvertise_s
|
|||||||
#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
||||||
|
|
||||||
#define ICMPv6ADVERTISE \
|
#define ICMPv6ADVERTISE \
|
||||||
((struct icmpv6_radvertise_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
|
((struct icmpv6_router_advertise_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
@ -134,10 +109,12 @@ static const net_ipv6addr_t g_ipv6_prefix =
|
|||||||
void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
||||||
{
|
{
|
||||||
FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF;
|
FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF;
|
||||||
FAR struct icmpv6_radvertise_s *adv;
|
FAR struct icmpv6_router_advertise_s *adv;
|
||||||
FAR struct icmpv6_srclladdr_s *srcaddr;
|
FAR struct icmpv6_srclladdr_s *srcaddr;
|
||||||
FAR struct icmpv6_mtu_s *mtu;
|
FAR struct icmpv6_mtu_s *mtu;
|
||||||
FAR struct icmpv6_prefixinfo_s *prefix;
|
FAR struct icmpv6_prefixinfo_s *prefix;
|
||||||
|
uint16_t l1size;
|
||||||
|
uint16_t l3size;
|
||||||
|
|
||||||
/* Set up the IPv6 header */
|
/* Set up the IPv6 header */
|
||||||
|
|
||||||
@ -147,8 +124,14 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Length excludes the IPv6 header */
|
/* Length excludes the IPv6 header */
|
||||||
|
|
||||||
icmp->len[0] = (sizeof(struct icmpv6_radvertise_s) >> 8);
|
l1size = NET_LL_HDRLEN(dev);
|
||||||
icmp->len[1] = (sizeof(struct icmpv6_radvertise_s) & 0xff);
|
l3size = sizeof(icmpv6_router_advertise_s) +
|
||||||
|
SIZEOF_ICMPV6_SRCLLADDR_S(l1size) +
|
||||||
|
sizeof(struct icmpv6_mtu_s) +
|
||||||
|
sizeof(icmpv6_prefixinfo_s);
|
||||||
|
|
||||||
|
icmp->len[0] = (l3size >> 8);
|
||||||
|
icmp->len[1] = (l3size & 0xff);
|
||||||
|
|
||||||
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
||||||
icmp->ttl = 255; /* Hop limit */
|
icmp->ttl = 255; /* Hop limit */
|
||||||
@ -173,13 +156,16 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set up the source address option */
|
/* Set up the source address option */
|
||||||
|
|
||||||
srcaddr = &adv->srcaddr;
|
srcaddr = (FAR struct icmpv6_srclladdr_s *)
|
||||||
|
((FAR uint8_t *)adv + sizeof(icmpv6_router_advertise_s));
|
||||||
srcaddr->opttype = ICMPv6_OPT_SRCLLADDR;
|
srcaddr->opttype = ICMPv6_OPT_SRCLLADDR;
|
||||||
srcaddr->optlen = 1;
|
srcaddr->optlen = ICMPv6_OPT_OCTECTS(l1size);
|
||||||
memcpy(srcaddr->srclladdr, &dev->d_mac.ether.ether_addr_octet, ETHER_ADDR_LEN);
|
memcpy(srcaddr->srclladdr, &dev->d_mac, l1size);
|
||||||
|
|
||||||
/* Set up the MTU option */
|
/* Set up the MTU option */
|
||||||
|
|
||||||
|
mtu = (FAR struct icmpv6_mtu_s *)
|
||||||
|
((FAR uint8_t *)srcaddr + SIZEOF_ICMPV6_SRCLLADDR_S(l1size));
|
||||||
mtu = &adv->mtu;
|
mtu = &adv->mtu;
|
||||||
mtu->opttype = ICMPv6_OPT_MTU;
|
mtu->opttype = ICMPv6_OPT_MTU;
|
||||||
mtu->optlen = 1;
|
mtu->optlen = 1;
|
||||||
@ -189,6 +175,8 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set up the prefix option */
|
/* Set up the prefix option */
|
||||||
|
|
||||||
|
prefix = (FAR struct icmpv6_prefixinfo_s *)
|
||||||
|
((FAR uint8_t *)mtu + sizeof(icmpv6_mtu_s));
|
||||||
prefix = &adv->prefix;
|
prefix = &adv->prefix;
|
||||||
prefix->opttype = ICMPv6_OPT_MTU;
|
prefix->opttype = ICMPv6_OPT_MTU;
|
||||||
prefix->optlen = 4;
|
prefix->optlen = 4;
|
||||||
@ -210,7 +198,7 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set the size to the size of the IPv6 header and the payload size */
|
/* Set the size to the size of the IPv6 header and the payload size */
|
||||||
|
|
||||||
dev->d_len = IPv6_HDRLEN + sizeof(struct icmpv6_radvertise_s);
|
dev->d_len = IPv6_HDRLEN + sizeof(struct icmpv6_router_advertise_s);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
#ifdef CONFIG_NET_ETHERNET
|
||||||
/* Add the size of the Ethernet header */
|
/* Add the size of the Ethernet header */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmpv6/icmpv6_rsolicit.c
|
* net/icmpv6/icmpv6_rsolicit.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -92,6 +92,8 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
|||||||
FAR struct icmpv6_iphdr_s *icmp;
|
FAR struct icmpv6_iphdr_s *icmp;
|
||||||
FAR struct icmpv6_router_solicit_s *sol;
|
FAR struct icmpv6_router_solicit_s *sol;
|
||||||
FAR struct eth_hdr_s *eth;
|
FAR struct eth_hdr_s *eth;
|
||||||
|
uint16_t l1size;
|
||||||
|
uint16_t l3size;
|
||||||
|
|
||||||
/* Set up the IPv6 header (most is probably already in place) */
|
/* Set up the IPv6 header (most is probably already in place) */
|
||||||
|
|
||||||
@ -102,8 +104,10 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Length excludes the IPv6 header */
|
/* Length excludes the IPv6 header */
|
||||||
|
|
||||||
icmp->len[0] = (sizeof(struct icmpv6_router_solicit_s) >> 8);
|
l1size = NET_LL_HDRLEN(dev);
|
||||||
icmp->len[1] = (sizeof(struct icmpv6_router_solicit_s) & 0xff);
|
l3size = SIZEOF_ICMPV6_ROUTER_SOLICIT_S(l1size);
|
||||||
|
icmp->len[0] = (l3size >> 8);
|
||||||
|
icmp->len[1] = (l3size & 0xff);
|
||||||
|
|
||||||
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
||||||
icmp->ttl = 255; /* Hop limit */
|
icmp->ttl = 255; /* Hop limit */
|
||||||
@ -130,14 +134,14 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set up the options */
|
/* Set up the options */
|
||||||
|
|
||||||
sol->opttype = ICMPv6_OPT_SRCLLADDR; /* Option type */
|
sol->opttype = ICMPv6_OPT_SRCLLADDR; /* Option type */
|
||||||
sol->optlen = 1; /* Option length = 1 octet */
|
sol->optlen = ICMPv6_OPT_OCTECTS(l1size); /* Option length in octets */
|
||||||
|
|
||||||
/* Copy our link layer address into the message
|
/* Copy our link layer address into the message
|
||||||
* REVISIT: What if the link layer is not Ethernet?
|
* REVISIT: What if the link layer is not Ethernet?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memcpy(sol->srclladdr, dev->d_mac.ether.ether_addr_octet, sizeof(net_ipv6addr_t));
|
memcpy(sol->srclladdr, &dev->d_mac, l1size);
|
||||||
|
|
||||||
/* Calculate the checksum over both the ICMP header and payload */
|
/* Calculate the checksum over both the ICMP header and payload */
|
||||||
|
|
||||||
@ -146,7 +150,7 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
/* Set the size to the size of the IPv6 header and the payload size */
|
/* Set the size to the size of the IPv6 header and the payload size */
|
||||||
|
|
||||||
dev->d_len = IPv6_HDRLEN + sizeof(struct icmpv6_router_solicit_s);
|
dev->d_len = IPv6_HDRLEN + l3size;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
#ifdef CONFIG_NET_ETHERNET
|
||||||
#ifdef CONFIG_NET_MULTILINK
|
#ifdef CONFIG_NET_MULTILINK
|
||||||
@ -182,6 +186,7 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
|||||||
/* Add the size of the layer layer header to the total size of the
|
/* Add the size of the layer layer header to the total size of the
|
||||||
* outgoing packet.
|
* outgoing packet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dev->d_len += netdev_ipv6_hdrlen(dev);
|
dev->d_len += netdev_ipv6_hdrlen(dev);
|
||||||
ninfo("Outgoing ICMPv6 Router Solicitation length: %d (%d)\n",
|
ninfo("Outgoing ICMPv6 Router Solicitation length: %d (%d)\n",
|
||||||
dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);
|
dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/icmpv6/icmpv6_solicit.c
|
* net/icmpv6/icmpv6_solicit.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -102,7 +102,8 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
|||||||
{
|
{
|
||||||
FAR struct icmpv6_iphdr_s *icmp;
|
FAR struct icmpv6_iphdr_s *icmp;
|
||||||
FAR struct icmpv6_neighbor_solicit_s *sol;
|
FAR struct icmpv6_neighbor_solicit_s *sol;
|
||||||
FAR struct eth_hdr_s *eth;
|
uint16_t l1size;
|
||||||
|
uint16_t l3size;
|
||||||
|
|
||||||
/* Set up the IPv6 header (most is probably already in place) */
|
/* Set up the IPv6 header (most is probably already in place) */
|
||||||
|
|
||||||
@ -113,8 +114,10 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Length excludes the IPv6 header */
|
/* Length excludes the IPv6 header */
|
||||||
|
|
||||||
icmp->len[0] = (sizeof(struct icmpv6_neighbor_solicit_s) >> 8);
|
l1size = NET_LL_HDRLEN(dev);
|
||||||
icmp->len[1] = (sizeof(struct icmpv6_neighbor_solicit_s) & 0xff);
|
l3size = SIZEOF_ICMPV6_NEIGHBOR_SOLICIT_S(l1size);
|
||||||
|
icmp->len[0] = (l3size >> 8);
|
||||||
|
icmp->len[1] = (l3size & 0xff);
|
||||||
|
|
||||||
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
icmp->proto = IP_PROTO_ICMP6; /* Next header */
|
||||||
icmp->ttl = 255; /* Hop limit */
|
icmp->ttl = 255; /* Hop limit */
|
||||||
@ -145,14 +148,14 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Set up the options */
|
/* Set up the options */
|
||||||
|
|
||||||
sol->opttype = ICMPv6_OPT_SRCLLADDR; /* Option type */
|
sol->opttype = ICMPv6_OPT_SRCLLADDR; /* Option type */
|
||||||
sol->optlen = 1; /* Option length = 1 octet */
|
sol->optlen = ICMPv6_OPT_OCTECTS(l1size); /* Option length in octets */
|
||||||
|
|
||||||
/* Copy our link layer address into the message
|
/* Copy our link layer address into the message
|
||||||
* REVISIT: What if the link layer is not Ethernet?
|
* REVISIT: What if the link layer is not Ethernet?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memcpy(sol->srclladdr, &dev->d_mac.ether, IFHWADDRLEN);
|
memcpy(sol->srclladdr, &dev->d_mac, l1size);
|
||||||
|
|
||||||
/* Calculate the checksum over both the ICMP header and payload */
|
/* Calculate the checksum over both the ICMP header and payload */
|
||||||
|
|
||||||
@ -161,13 +164,15 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
/* Set the size to the size of the IPv6 header and the payload size */
|
/* Set the size to the size of the IPv6 header and the payload size */
|
||||||
|
|
||||||
dev->d_len = IPv6_HDRLEN + sizeof(struct icmpv6_neighbor_solicit_s);
|
dev->d_len = IPv6_HDRLEN + l3size;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
#ifdef CONFIG_NET_ETHERNET
|
||||||
#ifdef CONFIG_NET_MULTILINK
|
#ifdef CONFIG_NET_MULTILINK
|
||||||
if (dev->d_lltype == NET_LL_ETHERNET)
|
if (dev->d_lltype == NET_LL_ETHERNET)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
FAR struct eth_hdr_s *eth;
|
||||||
|
|
||||||
/* Set the destination IPv6 multicast Ethernet address:
|
/* Set the destination IPv6 multicast Ethernet address:
|
||||||
*
|
*
|
||||||
* For IPv6 multicast addresses, the Ethernet MAC is derived by
|
* For IPv6 multicast addresses, the Ethernet MAC is derived by
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* Describes the link layer address */
|
/* Describes the link layer address */
|
||||||
|
|
||||||
struct neighbor_addr_s
|
struct neighbor_addr_s
|
||||||
|
Loading…
Reference in New Issue
Block a user