et/icmpv6: Remove the coupling between ICMPv6 and Ethernet by moving all Ethernet stuff to neighbor_ethernet_out.c and make the mac address as first field.
This commit is contained in:
parent
a3cda3867b
commit
4f25b83f8f
|
@ -128,8 +128,8 @@
|
|||
* 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)
|
||||
#define ICMPv6_OPT_SIZE(a) ((a) > 0 ? ((a) + 2 + 7) & ~7 : 0)
|
||||
#define ICMPv6_OPT_OCTECTS(a) ((a) > 0 ? ((a) + 2 + 7) >> 3 : 0)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
|
|
|
@ -212,8 +212,8 @@ struct netdev_maxaddr_s
|
|||
|
||||
struct netdev_varaddr_s
|
||||
{
|
||||
uint8_t nv_addrlen;
|
||||
uint8_t nv_addr[RADIO_MAX_ADDRLEN];
|
||||
uint8_t nv_addrlen;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -255,9 +255,6 @@ struct net_driver_s
|
|||
|
||||
uint16_t d_pktsize; /* Maximum packet size */
|
||||
|
||||
#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_NET_6LOWPAN) || \
|
||||
defined(CONFIG_NET_BLUETOOTH) || defined(CONFIG_NET_IEEE802154)
|
||||
|
||||
/* Link layer address */
|
||||
|
||||
union
|
||||
|
@ -275,7 +272,6 @@ struct net_driver_s
|
|||
struct netdev_varaddr_s radio;
|
||||
#endif
|
||||
} d_mac;
|
||||
#endif /* CONFIG_NET_ETHERNET || CONFIG_NET_6LOWPAN ... || CONFIG_NET_IEEE802154 */
|
||||
|
||||
/* Network identity */
|
||||
|
||||
|
|
|
@ -103,8 +103,8 @@
|
|||
|
||||
struct pktradio_addr_s
|
||||
{
|
||||
uint8_t pa_addrlen; /* Length of the following address */
|
||||
uint8_t pa_addr[RADIO_MAX_ADDRLEN];
|
||||
uint8_t pa_addrlen; /* Length of the following address */
|
||||
};
|
||||
|
||||
/* Different packet radios may have different properties. If there are
|
||||
|
|
|
@ -238,7 +238,7 @@ void icmpv6_poll(FAR struct net_driver_s *dev);
|
|||
* Set up to send an ICMPv6 Neighbor Solicitation message
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Reference to an Ethernet device driver structure
|
||||
* dev - Reference to a device driver structure
|
||||
* ipaddr - IP address of Neighbor to be solicited
|
||||
*
|
||||
* Returned Value:
|
||||
|
@ -256,7 +256,6 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
|||
* Set up to send an ICMPv6 Router Solicitation message. This version
|
||||
* is for a standalone solicitation. If formats:
|
||||
*
|
||||
* - The Ethernet header
|
||||
* - The IPv6 header
|
||||
* - The ICMPv6 Neighbor Router Message
|
||||
*
|
||||
|
@ -264,7 +263,7 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
|||
* prior to calling this function.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Reference to an Ethernet device driver structure
|
||||
* dev - Reference to a device driver structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/icmpv6.h>
|
||||
#include <nuttx/net/ethernet.h>
|
||||
|
||||
#include "netdev/netdev.h"
|
||||
#include "utils/utils.h"
|
||||
|
@ -65,7 +64,6 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#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 \
|
||||
|
@ -141,9 +139,7 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
|
|||
adv->opttype = ICMPv6_OPT_TGTLLADDR; /* Option type */
|
||||
adv->optlen = ICMPv6_OPT_OCTECTS(lladdrsize); /* Option length in octets */
|
||||
|
||||
/* Copy our link layer address into the message
|
||||
* REVISIT: What if the link layer is not Ethernet?
|
||||
*/
|
||||
/* Copy our link layer address into the message */
|
||||
|
||||
memcpy(adv->tgtlladdr, &dev->d_mac, lladdrsize);
|
||||
|
||||
|
@ -156,34 +152,6 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
|
|||
|
||||
dev->d_len = IPv6_HDRLEN + l3size;
|
||||
|
||||
#ifdef CONFIG_NET_ETHERNET
|
||||
/* Add the size of the Ethernet header */
|
||||
|
||||
dev->d_len += ETH_HDRLEN;
|
||||
|
||||
/* Move the source and to the destination addresses in the Ethernet header
|
||||
* and use our MAC as the new source address
|
||||
*/
|
||||
|
||||
if (dev->d_lltype == NET_LL_ETHERNET)
|
||||
{
|
||||
FAR struct eth_hdr_s *eth = ETHBUF;
|
||||
|
||||
memcpy(eth->dest, eth->src, ETHER_ADDR_LEN);
|
||||
memcpy(eth->src, dev->d_mac.ether.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
|
||||
/* Set the IPv6 Ethernet type */
|
||||
|
||||
eth->type = HTONS(ETHTYPE_IP6);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* No additional neighbor lookup is required on this packet (We are using
|
||||
* a multicast address).
|
||||
*/
|
||||
|
||||
IFF_SET_NOARP(dev->d_flags);
|
||||
|
||||
ninfo("Outgoing ICMPv6 Neighbor Advertise length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* net/icmpv6/icmpv6_autoconfig.c
|
||||
*
|
||||
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2015-2016, 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -45,8 +45,6 @@
|
|||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
@ -150,8 +148,10 @@ static uint16_t icmpv6_router_eventhandler(FAR struct net_driver_s *dev,
|
|||
return flags;
|
||||
}
|
||||
|
||||
/* It looks like we are good to send the data */
|
||||
/* Copy the packet data into the device packet buffer and send it */
|
||||
/* It looks like we are good to send the data.
|
||||
*
|
||||
* Copy the packet data into the device packet buffer and send it.
|
||||
*/
|
||||
|
||||
if (state->snd_advertise)
|
||||
{
|
||||
|
@ -166,11 +166,7 @@ static uint16_t icmpv6_router_eventhandler(FAR struct net_driver_s *dev,
|
|||
icmpv6_rsolicit(dev);
|
||||
}
|
||||
|
||||
/* Make sure no additional Router Solicitation overwrites this one.
|
||||
* This flag will be cleared in icmpv6_out().
|
||||
*/
|
||||
|
||||
IFF_SET_NOARP(dev->d_flags);
|
||||
IFF_SET_IPv6(dev->d_flags);
|
||||
|
||||
/* Don't allow any further call backs. */
|
||||
|
||||
|
@ -336,13 +332,6 @@ static int icmpv6_wait_radvertise(FAR struct net_driver_s *dev,
|
|||
|
||||
int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
||||
{
|
||||
#ifndef CONFIG_NET_ETHERNET
|
||||
/* Only Ethernet supported for now */
|
||||
|
||||
nerr("ERROR: Only Ethernet is supported\n");
|
||||
return -ENOSYS;
|
||||
|
||||
#else /* CONFIG_NET_ETHERNET */
|
||||
struct icmpv6_rnotify_s notify;
|
||||
net_ipv6addr_t lladdr;
|
||||
int retries;
|
||||
|
@ -353,14 +342,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
|||
DEBUGASSERT(dev);
|
||||
ninfo("Auto-configuring %s\n", dev->d_ifname);
|
||||
|
||||
/* Only Ethernet devices are supported for now */
|
||||
|
||||
if (dev->d_lltype != NET_LL_ETHERNET)
|
||||
{
|
||||
nerr("ERROR: Only Ethernet is supported\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* The interface should be in the down state */
|
||||
|
||||
net_lock();
|
||||
|
@ -534,7 +515,6 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
|
|||
netdev_ifup(dev);
|
||||
net_unlock();
|
||||
return OK;
|
||||
#endif /* CONFIG_NET_ETHERNET */
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_ICMPv6_AUTOCONF */
|
||||
|
|
|
@ -265,6 +265,13 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||
sol = ICMPv6SOLICIT;
|
||||
if (net_ipv6addr_cmp(sol->tgtaddr, dev->d_ipv6addr))
|
||||
{
|
||||
if (sol->opttype == ICMPv6_OPT_SRCLLADDR)
|
||||
{
|
||||
/* Save the sender's address mapping in our Neighbor Table. */
|
||||
|
||||
neighbor_add(dev, ipicmp->srcipaddr, sol->srclladdr);
|
||||
}
|
||||
|
||||
/* Yes.. Send a neighbor advertisement back to where the neighbor
|
||||
* solicitation came from.
|
||||
*/
|
||||
|
@ -308,19 +315,19 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||
/* Save the sender's address mapping in our Neighbor Table. */
|
||||
|
||||
neighbor_add(dev, ipv6->srcipaddr, adv->tgtlladdr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
||||
/* Then notify any logic waiting for the Neighbor Advertisement */
|
||||
/* Then notify any logic waiting for the Neighbor Advertisement */
|
||||
|
||||
icmpv6_notify(ipv6->srcipaddr);
|
||||
icmpv6_notify(ipv6->srcipaddr);
|
||||
#endif
|
||||
|
||||
/* We consumed the packet but we don't send anything in
|
||||
* response.
|
||||
*/
|
||||
/* We consumed the packet but we don't send anything in
|
||||
* response.
|
||||
*/
|
||||
|
||||
goto icmpv6_send_nothing;
|
||||
}
|
||||
goto icmpv6_send_nothing;
|
||||
}
|
||||
|
||||
goto icmpv6_drop_packet;
|
||||
|
@ -351,6 +358,7 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||
{
|
||||
FAR struct icmpv6_router_advertise_s *adv;
|
||||
FAR uint8_t *options;
|
||||
bool prefix = false;
|
||||
uint16_t pktlen;
|
||||
uint16_t optlen;
|
||||
int ndx;
|
||||
|
@ -380,7 +388,7 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||
FAR struct icmpv6_srclladdr_s *sllopt =
|
||||
(FAR struct icmpv6_srclladdr_s *)&options[ndx];
|
||||
|
||||
if (sllopt->opttype == 1 && sllopt->optlen == 1)
|
||||
if (sllopt->opttype == ICMPv6_OPT_SRCLLADDR)
|
||||
{
|
||||
neighbor_add(dev, ipv6->srcipaddr, sllopt->srclladdr);
|
||||
}
|
||||
|
@ -392,14 +400,13 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||
* the "A" flag set?
|
||||
*/
|
||||
|
||||
if (opt->opttype &&
|
||||
opt->optlen == 4 &&
|
||||
if (opt->opttype == ICMPv6_OPT_PREFIX &&
|
||||
(opt->flags & ICMPv6_PRFX_FLAG_A) != 0)
|
||||
{
|
||||
/* Yes.. Notify any waiting threads */
|
||||
|
||||
icmpv6_rnotify(dev, ipv6->srcipaddr, opt->prefix, opt->preflen);
|
||||
goto icmpv6_send_nothing;
|
||||
prefix = true;
|
||||
}
|
||||
|
||||
/* Skip to the next option (units of octets) */
|
||||
|
@ -407,6 +414,11 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||
ndx += (opt->optlen << 3);
|
||||
}
|
||||
|
||||
if (prefix)
|
||||
{
|
||||
goto icmpv6_send_nothing;
|
||||
}
|
||||
|
||||
goto icmpv6_drop_packet;
|
||||
}
|
||||
break;
|
||||
|
@ -515,7 +527,6 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||
}
|
||||
break;
|
||||
|
||||
|
||||
case ICMPV6_MCAST_LISTEN_REPORT_V2: /* Version 2 Multicast Listener Report, RFC 3810 */
|
||||
{
|
||||
FAR struct mld_mcast_listen_report_v2_s *report = MLDREPORT_V2;
|
||||
|
|
|
@ -136,16 +136,14 @@ static uint16_t icmpv6_neighbor_eventhandler(FAR struct net_driver_s *dev,
|
|||
return flags;
|
||||
}
|
||||
|
||||
/* It looks like we are good to send the data */
|
||||
/* Copy the packet data into the device packet buffer and send it */
|
||||
/* It looks like we are good to send the data.
|
||||
*
|
||||
* Copy the packet data into the device packet buffer and send it.
|
||||
*/
|
||||
|
||||
icmpv6_solicit(dev, state->snd_ipaddr);
|
||||
|
||||
/* Make sure no additional Neighbor Solicitation overwrites this one.
|
||||
* This flag will be cleared in icmpv6_out().
|
||||
*/
|
||||
|
||||
IFF_SET_NOARP(dev->d_flags);
|
||||
IFF_SET_IPv6(dev->d_flags);
|
||||
|
||||
/* Don't allow any further call backs. */
|
||||
|
||||
|
@ -232,18 +230,6 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr)
|
|||
goto errout;
|
||||
}
|
||||
|
||||
/* Send the Neighbor Solicitation request only if this device uses the
|
||||
* Ethernet link layer protocol.
|
||||
*
|
||||
* REVISIT: Other link layer protocols may require Neighbor Discovery
|
||||
* as well.
|
||||
*/
|
||||
|
||||
if (dev->d_lltype != NET_LL_ETHERNET)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Check if the destination address is on the local network. */
|
||||
|
||||
if (net_ipv6addr_maskcmp(ipaddr, dev->d_ipv6addr, dev->d_ipv6netmask))
|
||||
|
|
|
@ -64,7 +64,6 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#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 \
|
||||
|
@ -207,7 +206,7 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
|||
mtu->opttype = ICMPv6_OPT_MTU;
|
||||
mtu->optlen = 1;
|
||||
mtu->reserved = 0;
|
||||
mtu->mtu = HTONL(CONFIG_NET_ETH_PKTSIZE - ETH_HDRLEN);
|
||||
mtu->mtu = HTONL(dev->d_pktsize - dev->d_llhdrlen);
|
||||
|
||||
/* Set up the prefix option */
|
||||
|
||||
|
@ -242,34 +241,6 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
|||
|
||||
dev->d_len = IPv6_HDRLEN + l3size;
|
||||
|
||||
#ifdef CONFIG_NET_ETHERNET
|
||||
/* Add the size of the Ethernet header */
|
||||
|
||||
dev->d_len += ETH_HDRLEN;
|
||||
|
||||
/* Move the source and to the destination addresses in the Ethernet header
|
||||
* and use our MAC as the new source address
|
||||
*/
|
||||
|
||||
if (dev->d_lltype == NET_LL_ETHERNET)
|
||||
{
|
||||
FAR struct eth_hdr_s *eth = ETHBUF;
|
||||
|
||||
memcpy(eth->dest, g_ipv6_ethallnodes.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
memcpy(eth->src, dev->d_mac.ether.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
|
||||
/* Set the IPv6 Ethernet type */
|
||||
|
||||
eth->type = HTONS(ETHTYPE_IP6);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* No additional neighbor lookup is required on this packet (We are using
|
||||
* a multicast address).
|
||||
*/
|
||||
|
||||
IFF_SET_NOARP(dev->d_flags);
|
||||
|
||||
ninfo("Outgoing ICMPv6 Router Advertise length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#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])
|
||||
|
@ -74,7 +73,6 @@
|
|||
* Set up to send an ICMPv6 Router Solicitation message. This version
|
||||
* is for a standalone solicitation. If formats:
|
||||
*
|
||||
* - The Ethernet header
|
||||
* - The IPv6 header
|
||||
* - The ICMPv6 Router Solicitation Message
|
||||
*
|
||||
|
@ -82,7 +80,7 @@
|
|||
* prior to calling this function.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Reference to an Ethernet device driver structure
|
||||
* dev - Reference to a device driver structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
|
@ -93,7 +91,6 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
|||
{
|
||||
FAR struct ipv6_hdr_s *ipv6;
|
||||
FAR struct icmpv6_router_solicit_s *sol;
|
||||
FAR struct eth_hdr_s *eth;
|
||||
uint16_t lladdrsize;
|
||||
uint16_t l3size;
|
||||
|
||||
|
@ -139,9 +136,7 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
|||
sol->opttype = ICMPv6_OPT_SRCLLADDR; /* Option type */
|
||||
sol->optlen = ICMPv6_OPT_OCTECTS(lladdrsize); /* Option length in octets */
|
||||
|
||||
/* Copy our link layer address into the message
|
||||
* REVISIT: What if the link layer is not Ethernet?
|
||||
*/
|
||||
/* Copy our link layer address into the message */
|
||||
|
||||
memcpy(sol->srclladdr, &dev->d_mac, lladdrsize);
|
||||
|
||||
|
@ -154,40 +149,6 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
|||
|
||||
dev->d_len = IPv6_HDRLEN + l3size;
|
||||
|
||||
#ifdef CONFIG_NET_ETHERNET
|
||||
if (dev->d_lltype == NET_LL_ETHERNET)
|
||||
{
|
||||
/* Set the destination IPv6 all-routers multicast Ethernet
|
||||
* address
|
||||
*/
|
||||
|
||||
eth = ETHBUF;
|
||||
memcpy(eth->dest, g_ipv6_ethallrouters.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
|
||||
/* Move our source Ethernet addresses into the Ethernet header */
|
||||
|
||||
memcpy(eth->src, dev->d_mac.ether.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
|
||||
/* Set the IPv6 Ethernet type */
|
||||
|
||||
eth->type = HTONS(ETHTYPE_IP6);
|
||||
#if 0
|
||||
/* No additional neighbor lookup is required on this packet.
|
||||
* REVISIT: It is inappropriate to set this bit if we get here
|
||||
* via neighbor_out(); It is no necessary to set this bit if we
|
||||
* get here via icmpv6_input(). Is it ever necessary?
|
||||
*/
|
||||
|
||||
IFF_SET_NOARP(dev->d_flags);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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 Router Solicitation length: %d (%d)\n",
|
||||
dev->d_len, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/netstats.h>
|
||||
#include <nuttx/net/ethernet.h>
|
||||
|
||||
#include "devif/devif.h"
|
||||
#include "netdev/netdev.h"
|
||||
|
@ -59,7 +58,6 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#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])
|
||||
|
@ -87,12 +85,11 @@ static const uint16_t g_icmpv_mcastaddr[6] =
|
|||
* Set up to send an ICMPv6 Neighbor Solicitation message. This version
|
||||
* is for a standalone solicitation. If formats:
|
||||
*
|
||||
* - The Ethernet header
|
||||
* - The IPv6 header
|
||||
* - The ICMPv6 Neighbor Solicitation Message
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Reference to an Ethernet device driver structure
|
||||
* dev - Reference to a device driver structure
|
||||
* ipaddr - IP address of Neighbor to be solicited
|
||||
*
|
||||
* Returned Value:
|
||||
|
@ -154,9 +151,7 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
|||
sol->opttype = ICMPv6_OPT_SRCLLADDR; /* Option type */
|
||||
sol->optlen = ICMPv6_OPT_OCTECTS(lladdrsize); /* Option length in octets */
|
||||
|
||||
/* Copy our link layer address into the message
|
||||
* REVISIT: What if the link layer is not Ethernet?
|
||||
*/
|
||||
/* Copy our link layer address into the message */
|
||||
|
||||
memcpy(sol->srclladdr, &dev->d_mac, lladdrsize);
|
||||
|
||||
|
@ -169,56 +164,6 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
|||
|
||||
dev->d_len = IPv6_HDRLEN + l3size;
|
||||
|
||||
#ifdef CONFIG_NET_ETHERNET
|
||||
if (dev->d_lltype == NET_LL_ETHERNET)
|
||||
{
|
||||
FAR struct eth_hdr_s *eth;
|
||||
|
||||
/* Set the destination IPv6 multicast Ethernet address:
|
||||
*
|
||||
* For IPv6 multicast addresses, the Ethernet MAC is derived by
|
||||
* the four low-order octets OR'ed with the MAC 33:33:00:00:00:00,
|
||||
* so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map
|
||||
* to the Ethernet MAC address 33:33:00:01:00:03.
|
||||
*
|
||||
* NOTES: This appears correct for the ICMPv6 Router Solicitation
|
||||
* Message, but the ICMPv6 Neighbor Solicitation message seems to
|
||||
* use 33:33:ff:01:00:03.
|
||||
*/
|
||||
|
||||
eth = ETHBUF;
|
||||
eth->dest[0] = 0x33;
|
||||
eth->dest[1] = 0x33;
|
||||
eth->dest[2] = 0xff;
|
||||
eth->dest[3] = ipaddr[6] >> 8;
|
||||
eth->dest[4] = ipaddr[7] & 0xff;
|
||||
eth->dest[5] = ipaddr[7] >> 8;
|
||||
|
||||
/* Move our source Ethernet addresses into the Ethernet header */
|
||||
|
||||
memcpy(eth->src, dev->d_mac.ether.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
|
||||
/* Set the IPv6 Ethernet type */
|
||||
|
||||
eth->type = HTONS(ETHTYPE_IP6);
|
||||
#if 0
|
||||
/* No additional neighbor lookup is required on this packet.
|
||||
* REVISIT: It is inappropriate to set this bit if we get here
|
||||
* via neighbor_out(); It is no necessary to set this bit if we
|
||||
* get here via icmpv6_input(). Is it ever necessary?
|
||||
*/
|
||||
|
||||
IFF_SET_NOARP(dev->d_flags);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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, (ipv6->len[0] << 8) | ipv6->len[1]);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include <string.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/ethernet.h>
|
||||
#include <nuttx/net/ip.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
|
@ -61,15 +61,6 @@
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Support for broadcast address */
|
||||
|
||||
static const struct ether_addr g_broadcast_ethaddr =
|
||||
{
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
}
|
||||
};
|
||||
|
||||
/* Support for MLD multicast addresses.
|
||||
*
|
||||
* Well-known ethernet multicast address:
|
||||
|
@ -83,17 +74,8 @@ static const struct ether_addr g_broadcast_ethaddr =
|
|||
* 01-00-5e-xx-xx-xx 0x0800 IPv4 IGMP Multicast Address
|
||||
* 33-33-00-00-00-00 0x86DD IPv6 Neighbor Discovery
|
||||
* 33-33-xx-xx-xx-xx 0x86DD IPv6 Multicast Address (RFC3307)
|
||||
*
|
||||
* The following is the first three octects of the IGMP address:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NET_MLD
|
||||
static const uint8_t g_multicast_ethaddr[3] =
|
||||
{
|
||||
0x01, 0x00, 0x5e
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -134,11 +116,9 @@ void neighbor_ethernet_out(FAR struct net_driver_s *dev)
|
|||
FAR struct eth_hdr_s *eth = ETHBUF;
|
||||
FAR struct ipv6_hdr_s *ip = IPv6BUF;
|
||||
struct neighbor_addr_s laddr;
|
||||
net_ipv6addr_t ipaddr;
|
||||
|
||||
/* Skip sending Neighbor Solicitations when the frame to be transmitted was
|
||||
* written into a packet socket or if we are sending certain Neighbor
|
||||
* messages (solicitation, advertisement, echo request).
|
||||
* written into a packet socket.
|
||||
*/
|
||||
|
||||
if (IFF_IS_NOARP(dev->d_flags))
|
||||
|
@ -157,31 +137,12 @@ void neighbor_ethernet_out(FAR struct net_driver_s *dev)
|
|||
* packet with an Neighbor Solicitation Request for the IPv6 address.
|
||||
*/
|
||||
|
||||
/* First check if destination is a IPv6 multicast address.
|
||||
*
|
||||
* REVISIT: Need to revisit IPv6 broadcast support. Broadcast
|
||||
* IP addresses are not used with IPv6; multicast is used instead.
|
||||
* Does this mean that all multicast address should go to the
|
||||
* broadcast Ethernet address?
|
||||
*/
|
||||
/* First check if destination isn't IPv6 multicast address. */
|
||||
|
||||
if (net_is_addr_mcast(ip->destipaddr))
|
||||
if (!net_is_addr_mcast(ip->destipaddr))
|
||||
{
|
||||
memcpy(eth->dest, g_broadcast_ethaddr.ether_addr_octet,
|
||||
ETHER_ADDR_LEN);
|
||||
}
|
||||
net_ipv6addr_t ipaddr;
|
||||
|
||||
#ifdef CONFIG_NET_MLD
|
||||
/* Check if the destination address is a multicast address
|
||||
*
|
||||
* IPv6 multicast addresses are have the high-order octet of the
|
||||
* addresses=0xff (ff00::/8.)
|
||||
*/
|
||||
#warning Missing logic
|
||||
#endif
|
||||
|
||||
else
|
||||
{
|
||||
/* Check if the destination address is on the local network. */
|
||||
|
||||
if (!net_ipv6addr_maskcmp(ip->destipaddr, dev->d_ipv6addr,
|
||||
|
@ -224,11 +185,18 @@ void neighbor_ethernet_out(FAR struct net_driver_s *dev)
|
|||
*/
|
||||
|
||||
icmpv6_solicit(dev, ipaddr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Build an Ethernet header. */
|
||||
/* Build an Ethernet header. */
|
||||
|
||||
if (net_is_addr_mcast(ip->destipaddr))
|
||||
{
|
||||
eth->dest[0] = eth->dest[1] = 0x33;
|
||||
memcpy(ð->dest[2], &ip->destipaddr[6], 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(eth->dest, laddr.u.na_ethernet.ether_addr_octet, ETHER_ADDR_LEN);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue