diff --git a/drivers/netdev_eth/netdev_eth.c b/drivers/netdev_eth/netdev_eth.c index ec54dc0cc8ae15eecda8def83240813a78557736..1b94991b5c5e68ed3504212517ee0733f309baa2 100644 --- a/drivers/netdev_eth/netdev_eth.c +++ b/drivers/netdev_eth/netdev_eth.c @@ -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); } diff --git a/sys/include/net/ethernet.h b/sys/include/net/ethernet.h index e8185d64924f8471f2ab9d0dfda60eec47c76682..ac79d314f3d7def8b92d47f74e83ce8d67ee98d5 100644 --- a/sys/include/net/ethernet.h +++ b/sys/include/net/ethernet.h @@ -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 diff --git a/sys/include/net/eui48.h b/sys/include/net/eui48.h new file mode 100644 index 0000000000000000000000000000000000000000..56f2ee5db6613120ae328fae1ea80615840d7fd2 --- /dev/null +++ b/sys/include/net/eui48.h @@ -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 */ +/** @} */ diff --git a/sys/net/gnrc/netif/gnrc_netif_device_type.c b/sys/net/gnrc/netif/gnrc_netif_device_type.c index 622ed6b9678ab2431872b74d25dd9ed8167e706b..a44fdc3a3b1c54baf7a2adff9f2793e3b50b0396 100644 --- a/sys/net/gnrc/netif/gnrc_netif_device_type.c +++ b/sys/net/gnrc/netif/gnrc_netif_device_type.c @@ -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: