diff --git a/include/nuttx/net/icmpv6.h b/include/nuttx/net/icmpv6.h index 787ce3a8cc..4f3c1dcfe4 100644 --- a/include/nuttx/net/icmpv6.h +++ b/include/nuttx/net/icmpv6.h @@ -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 diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index df82948dcd..6393f7cabd 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -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 */ diff --git a/include/nuttx/wireless/pktradio.h b/include/nuttx/wireless/pktradio.h index 48316f263d..299b29d570 100644 --- a/include/nuttx/wireless/pktradio.h +++ b/include/nuttx/wireless/pktradio.h @@ -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 diff --git a/net/icmpv6/icmpv6.h b/net/icmpv6/icmpv6.h index 2aae09cc7f..7743521bb5 100644 --- a/net/icmpv6/icmpv6.h +++ b/net/icmpv6/icmpv6.h @@ -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 diff --git a/net/icmpv6/icmpv6_advertise.c b/net/icmpv6/icmpv6_advertise.c index d6bfe7ec83..796a859482 100644 --- a/net/icmpv6/icmpv6_advertise.c +++ b/net/icmpv6/icmpv6_advertise.c @@ -53,7 +53,6 @@ #include #include #include -#include #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]); diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index e8fcb5cb47..254a4da5b9 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -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 * * Redistribution and use in source and binary forms, with or without @@ -45,8 +45,6 @@ #include #include -#include - #include #include #include @@ -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 */ diff --git a/net/icmpv6/icmpv6_input.c b/net/icmpv6/icmpv6_input.c index 5bae9597e1..7258c79dff 100644 --- a/net/icmpv6/icmpv6_input.c +++ b/net/icmpv6/icmpv6_input.c @@ -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; diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c index d5a7e22fd8..bf24de82e0 100644 --- a/net/icmpv6/icmpv6_neighbor.c +++ b/net/icmpv6/icmpv6_neighbor.c @@ -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)) diff --git a/net/icmpv6/icmpv6_radvertise.c b/net/icmpv6/icmpv6_radvertise.c index f2ec88277d..e650298f2c 100644 --- a/net/icmpv6/icmpv6_radvertise.c +++ b/net/icmpv6/icmpv6_radvertise.c @@ -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]); diff --git a/net/icmpv6/icmpv6_rsolicit.c b/net/icmpv6/icmpv6_rsolicit.c index cf4aa0e8cf..1b63548ed2 100644 --- a/net/icmpv6/icmpv6_rsolicit.c +++ b/net/icmpv6/icmpv6_rsolicit.c @@ -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]); diff --git a/net/icmpv6/icmpv6_solicit.c b/net/icmpv6/icmpv6_solicit.c index 05e099264e..754d5bbce0 100644 --- a/net/icmpv6/icmpv6_solicit.c +++ b/net/icmpv6/icmpv6_solicit.c @@ -46,7 +46,6 @@ #include #include #include -#include #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]); diff --git a/net/neighbor/neighbor_ethernet_out.c b/net/neighbor/neighbor_ethernet_out.c index c61c71dade..26f0298df6 100644 --- a/net/neighbor/neighbor_ethernet_out.c +++ b/net/neighbor/neighbor_ethernet_out.c @@ -42,7 +42,7 @@ #include #include -#include +#include #include #include @@ -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); }