ICMPv6: Fix an address size calculation that was bungled in a recent commit.

This commit is contained in:
Gregory Nutt 2017-07-06 19:37:01 -06:00
parent db69e4b09c
commit 70c6b52132
9 changed files with 223 additions and 95 deletions

View file

@ -40,8 +40,9 @@
#include <nuttx/config.h>
#include <string.h>
#include <debug.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include "devif/ip_forward.h"
@ -79,6 +80,12 @@ void ip_forward_initialize(void)
FAR struct forward_s *fwd;
int i;
/* The IOB size must be such that the maximum L2 and L3 headers fit into
* the contiguous memory of the first IOB in the IOB chain.
*/
DEBUGASSERT(sizeof(union fwd_iphdr_u) <= CONFIG_IOB_BUFSIZE);
/* Add all pre-allocated forwarding structures to the free list */
g_fwdfree = NULL;

View file

@ -54,6 +54,7 @@
#include <nuttx/net/net.h>
#include <nuttx/net/icmpv6.h>
#include "netdev/netdev.h"
#include "utils/utils.h"
#include "icmpv6/icmpv6.h"
@ -63,8 +64,8 @@
* Pre-processor Definitions
****************************************************************************/
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
#define IPv6BUF ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
#define ICMPv6ADVERTISE \
((struct icmpv6_neighbor_advertise_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
@ -94,31 +95,31 @@
void icmpv6_advertise(FAR struct net_driver_s *dev,
const net_ipv6addr_t destipaddr)
{
FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF;
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
FAR struct icmpv6_neighbor_advertise_s *adv;
uint16_t l1size;
uint16_t l3size;
/* Set up the IPv6 header */
icmp->vtc = 0x60; /* Version/traffic class (MS) */
icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
icmp->flow = 0; /* Flow label (LS) */
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
ipv6->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */
l1size = NET_LL_HDRLEN(dev);
l1size = netdev_dev_l1size(dev);
l3size = SIZEOF_ICMPV6_NEIGHBOR_ADVERTISE_S(l1size);
icmp->len[0] = (l3size >> 8);
icmp->len[1] = (l3size & 0xff);
ipv6->len[0] = (l3size >> 8);
ipv6->len[1] = (l3size & 0xff);
icmp->proto = IP_PROTO_ICMP6; /* Next header */
icmp->ttl = 255; /* Hop limit */
ipv6->proto = IP_PROTO_ICMP6; /* Next header */
ipv6->ttl = 255; /* Hop limit */
/* Swap source for destination IP address, add our source IP address */
net_ipv6addr_copy(icmp->destipaddr, destipaddr);
net_ipv6addr_copy(icmp->srcipaddr, dev->d_ipv6addr);
net_ipv6addr_copy(ipv6->destipaddr, destipaddr);
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Set up the ICMPv6 Neighbor Advertise response */
@ -147,8 +148,8 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
/* Calculate the checksum over both the ICMP header and payload */
icmp->chksum = 0;
icmp->chksum = ~icmpv6_chksum(dev);
adv->chksum = 0;
adv->chksum = ~icmpv6_chksum(dev);
/* Set the size to the size of the IPv6 header and the payload size */
@ -185,7 +186,7 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
IFF_SET_NOARP(dev->d_flags);
ninfo("Outgoing ICMPv6 Neighbor Advertise length: %d (%d)\n",
dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++;

View file

@ -53,6 +53,7 @@
#include <nuttx/net/netdev.h>
#include <nuttx/net/icmpv6.h>
#include "netdev/netdev.h"
#include "utils/utils.h"
#include "icmpv6/icmpv6.h"
@ -62,8 +63,8 @@
* Pre-processor Definitions
****************************************************************************/
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
#define IPv6BUF ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
#define ICMPv6ADVERTISE \
((struct icmpv6_router_advertise_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
@ -108,7 +109,7 @@ static const net_ipv6addr_t g_ipv6_prefix =
void icmpv6_radvertise(FAR struct net_driver_s *dev)
{
FAR struct icmpv6_iphdr_s *icmp = ICMPv6BUF;
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
FAR struct icmpv6_router_advertise_s *adv;
FAR struct icmpv6_srclladdr_s *srcaddr;
FAR struct icmpv6_mtu_s *mtu;
@ -118,28 +119,28 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
/* Set up the IPv6 header */
icmp->vtc = 0x60; /* Version/traffic class (MS) */
icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
icmp->flow = 0; /* Flow label (LS) */
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
ipv6->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */
l1size = NET_LL_HDRLEN(dev);
l1size = netdev_dev_l1size(dev);
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);
ipv6->len[0] = (l3size >> 8);
ipv6->len[1] = (l3size & 0xff);
icmp->proto = IP_PROTO_ICMP6; /* Next header */
icmp->ttl = 255; /* Hop limit */
ipv6->proto = IP_PROTO_ICMP6; /* Next header */
ipv6->ttl = 255; /* Hop limit */
/* Swap source for destination IP address, add our source IP address */
net_ipv6addr_copy(icmp->destipaddr, g_ipv6_allnodes);
net_ipv6addr_copy(icmp->srcipaddr, dev->d_ipv6addr);
net_ipv6addr_copy(ipv6->destipaddr, g_ipv6_allnodes);
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Set up the ICMPv6 Router Advertise response */
@ -193,8 +194,8 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
/* Calculate the checksum over both the ICMP header and payload */
icmp->chksum = 0;
icmp->chksum = ~icmpv6_chksum(dev);
adv->chksum = 0;
adv->chksum = ~icmpv6_chksum(dev);
/* Set the size to the size of the IPv6 header and the payload size */
@ -231,7 +232,7 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
IFF_SET_NOARP(dev->d_flags);
ninfo("Outgoing ICMPv6 Router Advertise length: %d (%d)\n",
dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++;

View file

@ -47,6 +47,7 @@
#include <nuttx/net/netstats.h>
#include "devif/devif.h"
#include "netdev/netdev.h"
#include "utils/utils.h"
#include "icmpv6/icmpv6.h"
@ -56,8 +57,8 @@
* Pre-processor Definitions
****************************************************************************/
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
#define IPv6BUF ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
#define ICMPv6RSOLICIT \
((struct icmpv6_router_solicit_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
@ -89,7 +90,7 @@
void icmpv6_rsolicit(FAR struct net_driver_s *dev)
{
FAR struct icmpv6_iphdr_s *icmp;
FAR struct ipv6_hdr_s *ipv6;
FAR struct icmpv6_router_solicit_s *sol;
FAR struct eth_hdr_s *eth;
uint16_t l1size;
@ -97,30 +98,30 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
/* Set up the IPv6 header (most is probably already in place) */
icmp = ICMPv6BUF;
icmp->vtc = 0x60; /* Version/traffic class (MS) */
icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
icmp->flow = 0; /* Flow label (LS) */
ipv6 = IPv6BUF;
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
ipv6->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */
l1size = NET_LL_HDRLEN(dev);
l3size = SIZEOF_ICMPV6_ROUTER_SOLICIT_S(l1size);
icmp->len[0] = (l3size >> 8);
icmp->len[1] = (l3size & 0xff);
l1size = netdev_dev_l1size(dev);
l3size = SIZEOF_ICMPV6_ROUTER_SOLICIT_S(l1size);
ipv6->len[0] = (l3size >> 8);
ipv6->len[1] = (l3size & 0xff);
icmp->proto = IP_PROTO_ICMP6; /* Next header */
icmp->ttl = 255; /* Hop limit */
ipv6->proto = IP_PROTO_ICMP6; /* Next header */
ipv6->ttl = 255; /* Hop limit */
/* Set the multicast destination IP address to the IPv6 all link-
* loocal routers address: ff02::2
*/
net_ipv6addr_copy(icmp->destipaddr, g_ipv6_allrouters);
net_ipv6addr_copy(ipv6->destipaddr, g_ipv6_allrouters);
/* Add our link local IPv6 address as the source address */
net_ipv6addr_copy(icmp->srcipaddr, dev->d_ipv6addr);
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Set up the ICMPv6 Router Solicitation message */
@ -145,8 +146,8 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
/* Calculate the checksum over both the ICMP header and payload */
icmp->chksum = 0;
icmp->chksum = ~icmpv6_chksum(dev);
sol->chksum = 0;
sol->chksum = ~icmpv6_chksum(dev);
/* Set the size to the size of the IPv6 header and the payload size */
@ -189,7 +190,7 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
dev->d_len += netdev_ipv6_hdrlen(dev);
ninfo("Outgoing ICMPv6 Router Solicitation length: %d (%d)\n",
dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++;

View file

@ -48,6 +48,7 @@
#include <nuttx/net/netstats.h>
#include "devif/devif.h"
#include "netdev/netdev.h"
#include "utils/utils.h"
#include "icmpv6/icmpv6.h"
@ -57,8 +58,8 @@
* Pre-processor Definitions
****************************************************************************/
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
#define ICMPv6BUF ((struct icmpv6_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
#define ETHBUF ((struct eth_hdr_s *)&dev->d_buf[0])
#define IPv6BUF ((struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
#define ICMPv6SOLICIT \
((struct icmpv6_neighbor_solicit_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
@ -100,37 +101,37 @@ static const uint16_t g_icmpv_mcastaddr[6] =
void icmpv6_solicit(FAR struct net_driver_s *dev,
FAR const net_ipv6addr_t ipaddr)
{
FAR struct icmpv6_iphdr_s *icmp;
FAR struct ipv6_hdr_s *ipv6;
FAR struct icmpv6_neighbor_solicit_s *sol;
uint16_t l1size;
uint16_t l3size;
/* Set up the IPv6 header (most is probably already in place) */
icmp = ICMPv6BUF;
icmp->vtc = 0x60; /* Version/traffic class (MS) */
icmp->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
icmp->flow = 0; /* Flow label (LS) */
ipv6 = IPv6BUF;
ipv6->vtc = 0x60; /* Version/traffic class (MS) */
ipv6->tcf = 0; /* Traffic class (LS)/Flow label (MS) */
ipv6->flow = 0; /* Flow label (LS) */
/* Length excludes the IPv6 header */
l1size = NET_LL_HDRLEN(dev);
l1size = netdev_dev_l1size(dev);
l3size = SIZEOF_ICMPV6_NEIGHBOR_SOLICIT_S(l1size);
icmp->len[0] = (l3size >> 8);
icmp->len[1] = (l3size & 0xff);
ipv6->len[0] = (l3size >> 8);
ipv6->len[1] = (l3size & 0xff);
icmp->proto = IP_PROTO_ICMP6; /* Next header */
icmp->ttl = 255; /* Hop limit */
ipv6->proto = IP_PROTO_ICMP6; /* Next header */
ipv6->ttl = 255; /* Hop limit */
/* Set the multicast destination IP address */
memcpy(icmp->destipaddr, g_icmpv_mcastaddr, 6*sizeof(uint16_t));
icmp->destipaddr[6] = ipaddr[6] | HTONS(0xff00);
icmp->destipaddr[7] = ipaddr[7];
memcpy(ipv6->destipaddr, g_icmpv_mcastaddr, 6*sizeof(uint16_t));
ipv6->destipaddr[6] = ipaddr[6] | HTONS(0xff00);
ipv6->destipaddr[7] = ipaddr[7];
/* Add out IPv6 address as the source address */
net_ipv6addr_copy(icmp->srcipaddr, dev->d_ipv6addr);
net_ipv6addr_copy(ipv6->srcipaddr, dev->d_ipv6addr);
/* Set up the ICMPv6 Neighbor Solicitation message */
@ -159,8 +160,8 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
/* Calculate the checksum over both the ICMP header and payload */
icmp->chksum = 0;
icmp->chksum = ~icmpv6_chksum(dev);
sol->chksum = 0;
sol->chksum = ~icmpv6_chksum(dev);
/* Set the size to the size of the IPv6 header and the payload size */
@ -215,9 +216,11 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
/* Add the size of the layer layer header to the total size of the
* outgoing packet.
*/
dev->d_len += netdev_ipv6_hdrlen(dev);
ninfo("Outgoing ICMPv6 Neighbor Solicitation length: %d (%d)\n",
dev->d_len, (icmp->len[0] << 8) | icmp->len[1]);
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS
g_netstats.icmpv6.sent++;

View file

@ -52,6 +52,7 @@
#include <nuttx/net/net.h>
#include <nuttx/net/ip.h>
#include "netdev/netdev.h"
#include "neighbor/neighbor.h"
/****************************************************************************
@ -78,34 +79,10 @@
void neighbor_add(FAR net_ipv6addr_t ipaddr, uint8_t lltype,
FAR uint8_t *addr)
{
uint8_t addrlen;
uint8_t oldest_time;
int oldest_ndx;
int i;
/* Get the length of the address for this link layer type */
#ifdef CONFIG_NET_ETHERNET
#ifdef CONFIG_NET_6LOWPAN
if (lltype == NET_LL_ETHERNET)
#endif
{
addrlen = IFHWADDRLEN;
}
#endif
#ifdef CONFIG_NET_6LOWPAN
#ifdef CONFIG_NET_ETHERNET
else
#endif
{
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
addrlen = NET_6LOWPAN_EADDRSIZE;
#else
addrlen = NET_6LOWPAN_SADDRSIZE;
#endif
}
#endif
/* Find the first unused entry or the oldest used entry. */
oldest_time = 0;
@ -147,7 +124,7 @@ void neighbor_add(FAR net_ipv6addr_t ipaddr, uint8_t lltype,
#ifdef CONFIG_NET_MULTILINK
g_neighbors[oldest_ndx].ne_addr.u.na_lltype = lltype;
#endif
memcpy(&g_neighbors[oldest_ndx].ne_addr.u, addr, addrlen);
memcpy(&g_neighbors[oldest_ndx].ne_addr.u, addr, netdev_type_l1size(lltype));
/* Dump the contents of the new entry */

View file

@ -39,6 +39,7 @@ NETDEV_CSRCS += netdev_register.c netdev_ioctl.c netdev_txnotify.c
NETDEV_CSRCS += netdev_findbyname.c netdev_findbyaddr.c netdev_findbyindex.c
NETDEV_CSRCS += netdev_count.c netdev_foreach.c netdev_unregister.c
NETDEV_CSRCS += netdev_carrier.c netdev_default.c netdev_verify.c
NETDEV_CSRCS += netdev_l1size.c
ifeq ($(CONFIG_NET_RXAVAIL),y)
NETDEV_CSRCS += netdev_rxnotify.c

View file

@ -437,6 +437,26 @@ void netdev_ipv6_rxnotify(FAR const net_ipv6addr_t ripaddr);
int netdev_count(void);
#endif
/****************************************************************************
* Name: netdev_dev_l1size and netdev_type_llsize
*
* Description:
* Size of the MAC address associated with a device or with a link layer
* type.
*
* Parameters:
* dev - A reference to the device of interest
* OR
* lltype - link layer type code
*
* Returned Value:
* The size of the MAC address associated with this device
*
****************************************************************************/
int netdev_type_l1size(uint8_t lltype);
int netdev_dev_l1size(FAR struct net_driver_s *dev);
#undef EXTERN
#ifdef __cplusplus
}

117
net/netdev/netdev_l1size.c Normal file
View file

@ -0,0 +1,117 @@
/****************************************************************************
* net/netdev/netdev_l1size.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 <string.h>
#include <errno.h>
#include <net/if.h>
#include <nuttx/net/net.h>
#include <nuttx/net/netdev.h>
#include "netdev/netdev.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: netdev_dev_l1size and netdev_type_llsize
*
* Description:
* Size of the MAC address associated with a device or with a link layer
* type.
*
* Parameters:
* dev - A reference to the device of interest
* OR
* lltype - link layer type code
*
* Returned Value:
* The size of the MAC address associated with this device
*
****************************************************************************/
int netdev_type_l1size(uint8_t lltype)
{
/* Get the length of the address for this link layer type */
#ifdef CONFIG_NET_ETHERNET
if (lltype == NET_LL_ETHERNET)
{
return IFHWADDRLEN;
}
else
#endif
#ifdef CONFIG_NET_6LOWPAN
if (lltype == NET_LL_IEEE802154)
{
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
return NET_6LOWPAN_EADDRSIZE;
#else
return NET_6LOWPAN_SADDRSIZE;
#endif
}
else
#endif
{
return 0;
}
}
int netdev_dev_l1size(FAR struct net_driver_s *dev)
{
/* Get the length of the address for this device */
#if defined(CONFIG_NET_MULTILINK)
return netdev_type_l1size(dev->d_lltype);
#elif defined(CONFIG_NET_ETHERNET)
return IFHWADDRLEN;
#elif defined(CONFIG_NET_6LOWPAN)
#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
return NET_6LOWPAN_EADDRSIZE;
#else
return NET_6LOWPAN_SADDRSIZE;
#endif
#else
return 0;
#endif
}