gnrc_netif: introduce L2 address to EUI-64 conversion
This commit is contained in:
parent
a2b2f96fe3
commit
16e7fc8336
@ -426,6 +426,59 @@ static inline bool gnrc_netif_is_6lbr(const gnrc_netif_t *netif)
|
|||||||
*/
|
*/
|
||||||
netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif);
|
netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts a given hardware address to an EUI-64.
|
||||||
|
*
|
||||||
|
* @attention When the link-layer of the interface has link-layer addresses, and
|
||||||
|
* `NDEBUG` is not defined, the node fails with an assertion instead
|
||||||
|
* returning `-ENOTSUP`.
|
||||||
|
*
|
||||||
|
* @param[in] netif The network interface @p addr came from (either as
|
||||||
|
* gnrc_netif_t::l2addr or from a packet that came over
|
||||||
|
* it).
|
||||||
|
* @param[in] addr A hardware address.
|
||||||
|
* @param[in] addr_len Number of bytes in @p addr.
|
||||||
|
* @param[out] eui64 The EUI-64 based on gnrc_netif_t::device_type
|
||||||
|
*
|
||||||
|
* @return `sizeof(eui64_t)` on success.
|
||||||
|
* @return `-ENOTSUP`, when gnrc_netif_t::device_type of @p netif does not
|
||||||
|
* support IID conversion.
|
||||||
|
* @return `-EINVAL`, when @p addr_len is invalid for the
|
||||||
|
* gnrc_netif_t::device_type of @p netif.
|
||||||
|
*/
|
||||||
|
int gnrc_netif_eui64_from_addr(const gnrc_netif_t *netif,
|
||||||
|
const uint8_t *addr, size_t addr_len,
|
||||||
|
eui64_t *eui64);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts an interface EUI-64 from an interface's hardware address
|
||||||
|
*
|
||||||
|
* @param[in] netif The network interface @p eui64 came from
|
||||||
|
* @param[out] eui64 The EUI-64 based on gnrc_netif_t::device_type
|
||||||
|
*
|
||||||
|
* @note This wraps around @ref gnrc_netif_eui64_from_addr by using by using
|
||||||
|
* gnrc_netif_t::l2addr and gnrc_netif_t::l2addr_len of @p netif.
|
||||||
|
*
|
||||||
|
* @return `sizeof(eui64_t)` on success.
|
||||||
|
* @return `-ENOTSUP`, if interface has no link-layer address or if
|
||||||
|
* gnrc_netif_t::device_type is not supported.
|
||||||
|
* @return `-EINVAL`, when gnrc_netif_t::l2addr_len of @p netif is invalid for
|
||||||
|
* the gnrc_netif_t::device_type of @p netif.
|
||||||
|
*/
|
||||||
|
static inline int gnrc_netif_get_eui64(gnrc_netif_t *netif, eui64_t *eui64)
|
||||||
|
{
|
||||||
|
#if GNRC_NETIF_L2ADDR_MAXLEN > 0
|
||||||
|
if (netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR) {
|
||||||
|
return gnrc_netif_eui64_from_addr(netif,
|
||||||
|
netif->l2addr, netif->l2addr_len,
|
||||||
|
eui64);
|
||||||
|
}
|
||||||
|
#endif /* GNRC_NETIF_L2ADDR_MAXLEN > 0 */
|
||||||
|
(void)netif;
|
||||||
|
(void)eui64;
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(MODULE_GNRC_IPV6) || defined(DOXYGEN)
|
#if defined(MODULE_GNRC_IPV6) || defined(DOXYGEN)
|
||||||
/**
|
/**
|
||||||
* @brief Initialize IPv6 MTU and other packet length related members of
|
* @brief Initialize IPv6 MTU and other packet length related members of
|
||||||
@ -438,6 +491,9 @@ void gnrc_netif_ipv6_init_mtu(gnrc_netif_t *netif);
|
|||||||
/**
|
/**
|
||||||
* @brief Converts a given hardware address to an IPv6 IID.
|
* @brief Converts a given hardware address to an IPv6 IID.
|
||||||
*
|
*
|
||||||
|
* @note The IPv6 IID is derived from the EUI-64 for most link-layers by
|
||||||
|
* flipping the U/L bit.
|
||||||
|
* @see [RFC 2464, section 4](https://tools.ietf.org/html/rfc2464#section-4)
|
||||||
* @attention When the link-layer of the interface has link-layer addresses, and
|
* @attention When the link-layer of the interface has link-layer addresses, and
|
||||||
* `NDEBUG` is not defined, the node fails with an assertion instead
|
* `NDEBUG` is not defined, the node fails with an assertion instead
|
||||||
* returning `-ENOTSUP`.
|
* returning `-ENOTSUP`.
|
||||||
@ -492,6 +548,9 @@ int gnrc_netif_ipv6_iid_to_addr(const gnrc_netif_t *netif, const eui64_t *iid,
|
|||||||
* @param[in] netif The network interface @p iid came from
|
* @param[in] netif The network interface @p iid came from
|
||||||
* @param[out] iid The IID based on gnrc_netif_t::device_type
|
* @param[out] iid The IID based on gnrc_netif_t::device_type
|
||||||
*
|
*
|
||||||
|
* @note The IPv6 IID is derived from the EUI-64 for most link-layers by
|
||||||
|
* flipping the U/L bit.
|
||||||
|
* @see [RFC 2464, section 4](https://tools.ietf.org/html/rfc2464#section-4)
|
||||||
* @note This wraps around @ref gnrc_netif_ipv6_iid_from_addr by using
|
* @note This wraps around @ref gnrc_netif_ipv6_iid_from_addr by using
|
||||||
* by using gnrc_netif_t::l2addr and gnrc_netif_t::l2addr_len of
|
* by using gnrc_netif_t::l2addr and gnrc_netif_t::l2addr_len of
|
||||||
* @p netif.
|
* @p netif.
|
||||||
|
|||||||
@ -54,6 +54,81 @@ netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MODULE_CC110X) || defined(MODULE_NRFMIN)
|
||||||
|
static void _create_eui64_from_short(const uint8_t *addr, size_t addr_len,
|
||||||
|
eui64_t *eui64)
|
||||||
|
{
|
||||||
|
const unsigned offset = sizeof(eui64_t) - addr_len;
|
||||||
|
|
||||||
|
memset(eui64->uint8, 0, sizeof(eui64->uint8));
|
||||||
|
eui64->uint8[3] = 0xff;
|
||||||
|
eui64->uint8[4] = 0xfe;
|
||||||
|
memcpy(&eui64->uint8[offset], addr, addr_len);
|
||||||
|
}
|
||||||
|
#endif /* defined(MODULE_CC110X) || defined(MODULE_NRFMIN) */
|
||||||
|
|
||||||
|
int gnrc_netif_eui64_from_addr(const gnrc_netif_t *netif,
|
||||||
|
const uint8_t *addr, size_t addr_len,
|
||||||
|
eui64_t *eui64)
|
||||||
|
{
|
||||||
|
#if GNRC_NETIF_L2ADDR_MAXLEN > 0
|
||||||
|
if (netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR) {
|
||||||
|
switch (netif->device_type) {
|
||||||
|
#if defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW) || \
|
||||||
|
defined(MODULE_NORDIC_SOFTDEVICE_BLE)
|
||||||
|
case NETDEV_TYPE_ETHERNET:
|
||||||
|
case NETDEV_TYPE_ESP_NOW:
|
||||||
|
case NETDEV_TYPE_BLE:
|
||||||
|
if (addr_len == sizeof(eui48_t)) {
|
||||||
|
eui48_to_eui64(eui64, (const eui48_t *)addr);
|
||||||
|
return sizeof(eui64_t);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif /* defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW) */
|
||||||
|
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
|
||||||
|
case NETDEV_TYPE_IEEE802154:
|
||||||
|
switch (addr_len) {
|
||||||
|
case IEEE802154_SHORT_ADDRESS_LEN: {
|
||||||
|
netdev_t *dev = netif->dev;
|
||||||
|
return dev->driver->get(dev, NETOPT_ADDRESS_LONG, eui64,
|
||||||
|
sizeof(eui64_t));
|
||||||
|
}
|
||||||
|
case IEEE802154_LONG_ADDRESS_LEN:
|
||||||
|
memcpy(eui64, addr, addr_len);
|
||||||
|
return sizeof(eui64_t);
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) */
|
||||||
|
#if defined(MODULE_CC110X) || defined(MODULE_NRFMIN)
|
||||||
|
case NETDEV_TYPE_CC110X:
|
||||||
|
case NETDEV_TYPE_NRFMIN:
|
||||||
|
if (addr_len <= 3) {
|
||||||
|
_create_eui64_from_short(addr, addr_len, eui64);
|
||||||
|
return sizeof(eui64_t);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif /* defined(MODULE_CC110X) || defined(MODULE_NRFMIN) */
|
||||||
|
default:
|
||||||
|
(void)addr;
|
||||||
|
(void)addr_len;
|
||||||
|
(void)eui64;
|
||||||
|
#ifdef DEVELHELP
|
||||||
|
LOG_ERROR("gnrc_netif: can't convert hardware address to EUI-64"
|
||||||
|
" on interface %u\n", netif->pid);
|
||||||
|
#endif /* DEVELHELP */
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* GNRC_NETIF_L2ADDR_MAXLEN > 0 */
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef MODULE_GNRC_IPV6
|
#ifdef MODULE_GNRC_IPV6
|
||||||
void gnrc_netif_ipv6_init_mtu(gnrc_netif_t *netif)
|
void gnrc_netif_ipv6_init_mtu(gnrc_netif_t *netif)
|
||||||
{
|
{
|
||||||
@ -122,19 +197,6 @@ void gnrc_netif_ipv6_init_mtu(gnrc_netif_t *netif)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MODULE_CC110X) || defined(MODULE_NRFMIN)
|
|
||||||
static void _create_eui64_from_short(const uint8_t *addr, size_t addr_len,
|
|
||||||
eui64_t *eui64)
|
|
||||||
{
|
|
||||||
const unsigned offset = sizeof(eui64_t) - addr_len;
|
|
||||||
|
|
||||||
memset(eui64->uint8, 0, sizeof(eui64->uint8));
|
|
||||||
eui64->uint8[3] = 0xff;
|
|
||||||
eui64->uint8[4] = 0xfe;
|
|
||||||
memcpy(&eui64->uint8[offset], addr, addr_len);
|
|
||||||
}
|
|
||||||
#endif /* defined(MODULE_CC110X) || defined(MODULE_NRFMIN) */
|
|
||||||
|
|
||||||
int gnrc_netif_ipv6_iid_from_addr(const gnrc_netif_t *netif,
|
int gnrc_netif_ipv6_iid_from_addr(const gnrc_netif_t *netif,
|
||||||
const uint8_t *addr, size_t addr_len,
|
const uint8_t *addr, size_t addr_len,
|
||||||
eui64_t *iid)
|
eui64_t *iid)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user