forked from nuttx/nuttx-update
net/icmpv6/icmpv6_linkipaddr.c: Encapsulate the link scope address generation into icmpv6_linkipaddr()
This commit is contained in:
parent
52021a5300
commit
a3cda3867b
5 changed files with 208 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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],
|
||||
|
|
180
net/icmpv6/icmpv6_linkipaddr.c
Normal file
180
net/icmpv6/icmpv6_linkipaddr.c
Normal 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 */
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue