1
0
Fork 0
forked from nuttx/nuttx-update

net/icmpv6/icmpv6_linkipaddr.c: Encapsulate the link scope address generation into icmpv6_linkipaddr()

This commit is contained in:
Xiang Xiao 2018-11-09 15:28:58 -06:00 committed by Gregory Nutt
parent 52021a5300
commit a3cda3867b
5 changed files with 208 additions and 20 deletions

View file

@ -1,7 +1,7 @@
############################################################################
# net/icmpv6/Make.defs
#
# Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
# Copyright (C) 2015, 2017-2018 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -39,6 +39,7 @@ ifneq ($(CONFIG_NET_ICMPv6_NO_STACK),y)
# ICMPv6 source files
NET_CSRCS += icmpv6_input.c icmpv6_solicit.c icmpv6_advertise.c
NET_CSRCS += icmpv6_linkipaddr.c
ifeq ($(CONFIG_NET_ICMPv6_SOCKET),y)
SOCK_CSRCS += icmpv6_sockif.c icmpv6_conn.c icmpv6_sendto.c
@ -72,4 +73,4 @@ DEPPATH += --dep-path icmpv6
VPATH += :icmpv6
endif # !CONFIG_NET_ICMPv6_NO_STACK
endif # CONFIG_NET_ICMPv6
endif # CONFIG_NET_ICMPv6

View file

@ -703,6 +703,29 @@ int icmpv6_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds);
int icmpv6_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds);
#endif
/****************************************************************************
* Name: icmpv6_linkipaddr
*
* Description:
* Generate the device link scope ipv6 address as below:
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
* fe80 0000 0000 0000 0000 00ff fe00 xx00 1-byte short address IEEE 48-bit MAC
* fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
* fe80 0000 0000 0000 xxxx xxff fexx xxxx 6-byte normal address IEEE 48-bit MAC
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
*
* Input Parameters:
* dev - The device driver structure containing the link layer address
* ipaddr - Receive the device link scope ipv6 address
*
* Returned Value:
* None
*
****************************************************************************/
void icmpv6_linkipaddr(FAR struct net_driver_s *dev, net_ipv6addr_t ipaddr);
#undef EXTERN
#ifdef __cplusplus
}

View file

@ -379,23 +379,9 @@ int icmpv6_autoconfig(FAR struct net_driver_s *dev)
* ten bits. The generated address uses those ten bits followed by 54
* zeroes and then the 64 bit interface identifier. Typically this
* will be derived from the link layer (MAC) address.
*
* IEEE 802 MAC addresses, used by Ethernet and other IEEE 802 Project
* networking technologies, have 48 bits. The IEEE has also defined a
* format called the 64-bit extended unique identifier, abbreviated
* EUI-64. To get the modified EUI-64 interface ID for a device, you
* simply take the EUI-64 address and change the 7th bit from the left
* (the"universal/local" or "U/L" bit) from a zero to a one.
*
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
* fe80 0000 0000 0000 0000 xxxx xxxx xxxx
*/
lladdr[0] = HTONS(0xfe80); /* 10-bit address + 6 zeroes */
memset(&lladdr[1], 0, 4 * sizeof(uint16_t)); /* 64 more zeroes */
memcpy(&lladdr[5], dev->d_mac.ether.ether_addr_octet,
sizeof(struct ether_addr)); /* 48-bit Ethernet address */
icmpv6_linkipaddr(dev, lladdr);
ninfo("lladdr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
lladdr[0], lladdr[1], lladdr[2], lladdr[3],

View file

@ -0,0 +1,180 @@
/****************************************************************************
* net/icmpv6/icmpv6_linkipaddr.c
* Generate the link local ipv6 address
*
* Copyright (C) 2018 Pinecone Inc. All rights reserved.
* Author: Xiang Xiao <xiaoxiang@pinecone.net>
*
* 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. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 "netdev/netdev.h"
#include "icmpv6/icmpv6.h"
#ifdef CONFIG_NET_ICMPv6
/****************************************************************************
* Private Functions
****************************************************************************/
static inline void
icmpv6_linkipaddr_0(FAR struct net_driver_s *dev, net_ipv6addr_t ipaddr)
{
ipaddr[0] = HTONS(0xfe80);
ipaddr[1] = 0;
ipaddr[2] = 0;
ipaddr[3] = 0;
ipaddr[4] = 0;
ipaddr[5] = 0;
ipaddr[6] = 0;
#ifdef CONFIG_NETDEV_IFINDEX
ipaddr[7] = HTONS(dev->d_ifindex);
#else
ipaddr[7] = 0;
#endif
}
static inline void
icmpv6_linkipaddr_1(FAR const void *mac_, net_ipv6addr_t ipaddr)
{
FAR const uint8_t *mac = mac_;
ipaddr[0] = HTONS(0xfe80);
ipaddr[1] = 0;
ipaddr[2] = 0;
ipaddr[3] = 0;
ipaddr[4] = 0;
ipaddr[5] = HTONS(0x00ff);
ipaddr[6] = HTONS(0xfe00);
ipaddr[7] = HTONS(mac[0] << 8);
}
static inline void
icmpv6_linkipaddr_2(FAR const void *mac_, net_ipv6addr_t ipaddr)
{
FAR const uint8_t *mac = mac_;
ipaddr[0] = HTONS(0xfe80);
ipaddr[1] = 0;
ipaddr[2] = 0;
ipaddr[3] = 0;
ipaddr[4] = 0;
ipaddr[5] = HTONS(0x00ff);
ipaddr[6] = HTONS(0xfe00);
ipaddr[7] = HTONS(mac[0] << 8 | mac[1]);
}
static inline void
icmpv6_linkipaddr_6(FAR const void *mac_, net_ipv6addr_t ipaddr)
{
FAR const uint8_t *mac = mac_;
ipaddr[0] = HTONS(0xfe80);
ipaddr[1] = 0;
ipaddr[2] = 0;
ipaddr[3] = 0;
ipaddr[4] = HTONS(mac[0] << 8 | mac[1]);
ipaddr[5] = HTONS(mac[2] << 8 | 0x00ff);
ipaddr[6] = HTONS(0x00fe << 8 | mac[3]);
ipaddr[7] = HTONS(mac[4] << 8 | mac[5]);
ipaddr[4] ^= HTONS(0x0200);
}
static inline void
icmpv6_linkipaddr_8(FAR const void *mac_, net_ipv6addr_t ipaddr)
{
FAR const uint8_t *mac = mac_;
ipaddr[0] = HTONS(0xfe80);
ipaddr[1] = 0;
ipaddr[2] = 0;
ipaddr[3] = 0;
ipaddr[4] = HTONS(mac[0] << 8 | mac[1]);
ipaddr[5] = HTONS(mac[2] << 8 | mac[3]);
ipaddr[6] = HTONS(mac[4] << 8 | mac[5]);
ipaddr[7] = HTONS(mac[6] << 8 | mac[7]);
ipaddr[4] ^= HTONS(0x0200);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: icmpv6_linkipaddr
*
* Description:
* Generate the device link scope ipv6 address as below:
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
* fe80 0000 0000 0000 0000 00ff fe00 xx00 1-byte short address IEEE 48-bit MAC
* fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
* fe80 0000 0000 0000 xxxx xxff fexx xxxx 6-byte normal address IEEE 48-bit MAC
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
*
* Input Parameters:
* dev - The device driver structure containing the link layer address
* ipaddr - Receive the device link scope ipv6 address
*
* Returned Value:
* None
*
****************************************************************************/
void icmpv6_linkipaddr(FAR struct net_driver_s *dev, net_ipv6addr_t ipaddr)
{
switch (netdev_dev_lladdrsize(dev))
{
case 1:
icmpv6_linkipaddr_1(&dev->d_mac, ipaddr);
break;
case 2:
icmpv6_linkipaddr_2(&dev->d_mac, ipaddr);
break;
case 6:
icmpv6_linkipaddr_6(&dev->d_mac, ipaddr);
break;
case 8:
icmpv6_linkipaddr_8(&dev->d_mac, ipaddr);
break;
default:
icmpv6_linkipaddr_0(dev, ipaddr);
break;
}
}
#endif /* CONFIG_NET_ICMPv6 */

View file

@ -179,9 +179,7 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
/* Source IP address must be set to link-local IP */
ipv6->srcipaddr[0] = HTONS(0xfe80);
memset(&ipv6->srcipaddr[1], 0, 4 * sizeof(uint16_t));
memcpy(&ipv6->srcipaddr[5], &dev->d_mac.ether.ether_addr_octet, sizeof(struct ether_addr));
icmpv6_linkipaddr(dev, ipv6->srcipaddr);
/* Set up the ICMPv6 Router Advertise response */