1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 14:33:52 +01:00

Merge pull request #10567 from haukepetersen/add_eui48

net: add eui48 type including IPv6 IID conversion funcs
This commit is contained in:
Hauke Petersen 2018-12-06 22:38:02 +01:00 committed by GitHub
commit e8535f23a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 36 deletions

View File

@ -22,6 +22,7 @@
#include <errno.h>
#include "net/netdev.h"
#include "net/eui48.h"
#include "net/eui64.h"
#include "net/ethernet.h"
@ -34,9 +35,9 @@ static int _get_iid(netdev_t *netdev, eui64_t *value, size_t max_len)
return -EOVERFLOW;
}
uint8_t addr[ETHERNET_ADDR_LEN];
netdev->driver->get(netdev, NETOPT_ADDRESS, addr, ETHERNET_ADDR_LEN);
ethernet_get_iid(value, addr);
eui48_t mac;
netdev->driver->get(netdev, NETOPT_ADDRESS, mac.uint8, sizeof(eui48_t));
eui48_to_ipv6_iid(value, &mac);
return sizeof(eui64_t);
}

View File

@ -47,29 +47,6 @@ extern "C" {
*/
#define ETHERNET_MAX_LEN (ETHERNET_FRAME_LEN + ETHERNET_FCS_LEN)
/**
* @brief Generates an IPv6 interface identifier from a 48-bit MAC address.
*
* @see <a href="https://tools.ietf.org/html/rfc2464#section-4">
* RFC 2464, section 4
* </a>
*
* @param[out] eui64 The resulting EUI-64.
* @param[in] mac A 48-bit MAC address. Is expected to be at least
* @ref ETHERNET_ADDR_LEN long.
*/
static inline void ethernet_get_iid(eui64_t *eui64, const uint8_t *mac)
{
eui64->uint8[0] = mac[0] ^ 0x02;
eui64->uint8[1] = mac[1];
eui64->uint8[2] = mac[2];
eui64->uint8[3] = 0xff;
eui64->uint8[4] = 0xfe;
eui64->uint8[5] = mac[3];
eui64->uint8[6] = mac[4];
eui64->uint8[7] = mac[5];
}
#ifdef __cplusplus
}
#endif

82
sys/include/net/eui48.h Normal file
View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_eui48 IEEE EUI-48 identifier
* @ingroup net
* @brief Definition and IPv6 IID conversion for IEEE EUI-48 identifiers
* @{
*
* @file
* @brief Definition and IPv6 IID conversion for IEEE EUI-48 identifiers
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef NET_EUI48_H
#define NET_EUI48_H
#include <stdint.h>
#include "net/eui64.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Data type to represent an EUI-48
*/
typedef union {
uint8_t uint8[6]; /**< split into 6 8-bit words. */
network_uint16_t uint16[3]; /**< split into 3 16-bit words. */
} eui48_t;
/**
* @brief Generates an IPv6 interface identifier from a 48-bit device address
*
* @see [RFC 2464, section 4](https://tools.ietf.org/html/rfc2464#section-4)
* @see [RFC 4291, section 2.5.1](https://tools.ietf.org/html/rfc4291#section-2.5.1)
*
* @param[out] iid the resulting EUI-64.
* @param[in] addr a 48-bit device address
*/
static inline void eui48_to_ipv6_iid(eui64_t *iid, const eui48_t *addr)
{
iid->uint8[0] = addr->uint8[0] ^ 0x02;
iid->uint8[1] = addr->uint8[1];
iid->uint8[2] = addr->uint8[2];
iid->uint8[3] = 0xff;
iid->uint8[4] = 0xfe;
iid->uint8[5] = addr->uint8[3];
iid->uint8[6] = addr->uint8[4];
iid->uint8[7] = addr->uint8[5];
}
/**
* @brief Convert a 64-bit IPv6 IID into a EUI-48 device address
*
* @param[out] addr the resulting EUI-48
* @param[in] iid a 64-bit IPv6 interface identifier
*/
static inline void eui48_from_ipv6_iid(eui48_t *addr, const eui64_t *iid)
{
addr->uint8[0] = iid->uint8[0] ^ 0x02;
addr->uint8[1] = iid->uint8[1];
addr->uint8[2] = iid->uint8[2];
addr->uint8[3] = iid->uint8[5];
addr->uint8[4] = iid->uint8[6];
addr->uint8[5] = iid->uint8[7];
}
#ifdef __cplusplus
}
#endif
#endif /* NET_EUI48_H */
/** @} */

View File

@ -18,7 +18,7 @@
#include "log.h"
#include "net/gnrc/netif.h"
#include "net/ethernet.h"
#include "net/eui48.h"
#include "net/ieee802154.h"
#ifdef MODULE_GNRC_IPV6
@ -45,8 +45,8 @@ int gnrc_netif_ipv6_iid_from_addr(const gnrc_netif_t *netif,
#if defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW)
case NETDEV_TYPE_ETHERNET:
case NETDEV_TYPE_ESP_NOW:
if (addr_len == ETHERNET_ADDR_LEN) {
ethernet_get_iid(iid, (uint8_t *)addr);
if (addr_len == sizeof(eui48_t)) {
eui48_to_ipv6_iid(iid, (const eui48_t *)addr);
return sizeof(eui64_t);
}
else {
@ -108,13 +108,8 @@ int gnrc_netif_ipv6_iid_to_addr(const gnrc_netif_t *netif, const eui64_t *iid,
#if defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW)
case NETDEV_TYPE_ETHERNET:
case NETDEV_TYPE_ESP_NOW:
addr[0] = iid->uint8[0] ^ 0x02;
addr[1] = iid->uint8[1];
addr[2] = iid->uint8[2];
addr[3] = iid->uint8[5];
addr[4] = iid->uint8[6];
addr[5] = iid->uint8[7];
return ETHERNET_ADDR_LEN;
eui48_from_ipv6_iid((eui48_t *)addr, iid);
return sizeof(eui48_t);
#endif /* defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW) */
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
case NETDEV_TYPE_IEEE802154: