Merge pull request #10589 from miri64/l2util/feat/initial
l2util: initial import of a general IPv6 over X helper module
This commit is contained in:
commit
f2df22ed99
@ -146,6 +146,7 @@ endif
|
|||||||
|
|
||||||
ifneq (,$(filter gnrc_netif,$(USEMODULE)))
|
ifneq (,$(filter gnrc_netif,$(USEMODULE)))
|
||||||
USEMODULE += netif
|
USEMODULE += netif
|
||||||
|
USEMODULE += l2util
|
||||||
USEMODULE += fmt
|
USEMODULE += fmt
|
||||||
ifneq (,$(filter netdev_ieee802154,$(USEMODULE)))
|
ifneq (,$(filter netdev_ieee802154,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_netif_ieee802154
|
USEMODULE += gnrc_netif_ieee802154
|
||||||
|
|||||||
@ -204,6 +204,13 @@ extern "C" {
|
|||||||
#include "net/l2filter.h"
|
#include "net/l2filter.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Network device types
|
||||||
|
* @anchor net_netdev_type
|
||||||
|
* @attention When implementing a new type that is able to carry IPv6, have
|
||||||
|
* a look if you need to update @ref net_l2util as well.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
enum {
|
enum {
|
||||||
NETDEV_TYPE_UNKNOWN,
|
NETDEV_TYPE_UNKNOWN,
|
||||||
NETDEV_TYPE_TEST,
|
NETDEV_TYPE_TEST,
|
||||||
@ -217,6 +224,7 @@ enum {
|
|||||||
NETDEV_TYPE_SLIP,
|
NETDEV_TYPE_SLIP,
|
||||||
NETDEV_TYPE_ESP_NOW,
|
NETDEV_TYPE_ESP_NOW,
|
||||||
};
|
};
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Possible event types that are send from the device driver to the
|
* @brief Possible event types that are send from the device driver to the
|
||||||
|
|||||||
@ -8,9 +8,9 @@ BOARD ?= native
|
|||||||
RIOTBASE ?= $(CURDIR)/../..
|
RIOTBASE ?= $(CURDIR)/../..
|
||||||
|
|
||||||
BOARD_INSUFFICIENT_MEMORY := arduino-duemilanove arduino-mega2560 arduino-nano \
|
BOARD_INSUFFICIENT_MEMORY := arduino-duemilanove arduino-mega2560 arduino-nano \
|
||||||
arduino-uno calliope-mini chronos hifive1 \
|
arduino-uno blackpill bluepill calliope-mini \
|
||||||
mega-xplained microbit msb-430 msb-430h \
|
chronos hifive1 mega-xplained microbit msb-430 \
|
||||||
nucleo-f031k6 nucleo-f042k6 nucleo-f303k8 \
|
msb-430h nucleo-f031k6 nucleo-f042k6 nucleo-f303k8 \
|
||||||
nucleo-l031k6 nucleo-f030r8 nucleo-f070rb \
|
nucleo-l031k6 nucleo-f030r8 nucleo-f070rb \
|
||||||
nucleo-f072rb nucleo-f103rb nucleo-f302r8 \
|
nucleo-f072rb nucleo-f103rb nucleo-f302r8 \
|
||||||
nucleo-f334r8 nucleo-l053r8 saml10-xpro \
|
nucleo-f334r8 nucleo-l053r8 saml10-xpro \
|
||||||
|
|||||||
@ -124,6 +124,9 @@ endif
|
|||||||
ifneq (,$(filter l2filter,$(USEMODULE)))
|
ifneq (,$(filter l2filter,$(USEMODULE)))
|
||||||
DIRS += net/link_layer/l2filter
|
DIRS += net/link_layer/l2filter
|
||||||
endif
|
endif
|
||||||
|
ifneq (,$(filter l2util,$(USEMODULE)))
|
||||||
|
DIRS += net/link_layer/l2util
|
||||||
|
endif
|
||||||
ifneq (,$(filter nanocoap,$(USEMODULE)))
|
ifneq (,$(filter nanocoap,$(USEMODULE)))
|
||||||
DIRS += net/application_layer/nanocoap
|
DIRS += net/application_layer/nanocoap
|
||||||
endif
|
endif
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#define NET_GNRC_NETIF_INTERNAL_H
|
#define NET_GNRC_NETIF_INTERNAL_H
|
||||||
|
|
||||||
#include "net/gnrc/netif.h"
|
#include "net/gnrc/netif.h"
|
||||||
|
#include "net/l2util.h"
|
||||||
#include "net/netopt.h"
|
#include "net/netopt.h"
|
||||||
|
|
||||||
#ifdef MODULE_GNRC_IPV6_NIB
|
#ifdef MODULE_GNRC_IPV6_NIB
|
||||||
@ -539,8 +540,12 @@ int gnrc_netif_ipv6_iid_from_addr(const gnrc_netif_t *netif,
|
|||||||
* @return `-ENOTSUP`, when gnrc_netif_t::device_type of @p netif does not
|
* @return `-ENOTSUP`, when gnrc_netif_t::device_type of @p netif does not
|
||||||
* support reverse IID conversion.
|
* support reverse IID conversion.
|
||||||
*/
|
*/
|
||||||
int gnrc_netif_ipv6_iid_to_addr(const gnrc_netif_t *netif, const eui64_t *iid,
|
static inline int gnrc_netif_ipv6_iid_to_addr(const gnrc_netif_t *netif,
|
||||||
uint8_t *addr);
|
const eui64_t *iid, uint8_t *addr)
|
||||||
|
{
|
||||||
|
assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR);
|
||||||
|
return l2util_ipv6_iid_to_addr(netif->device_type, iid, addr);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Converts an interface IID of an interface's hardware address
|
* @brief Converts an interface IID of an interface's hardware address
|
||||||
@ -602,8 +607,12 @@ static inline int gnrc_netif_ipv6_get_iid(gnrc_netif_t *netif, eui64_t *iid)
|
|||||||
* @return `-EINVAL` if `opt->len` was an invalid value for the given
|
* @return `-EINVAL` if `opt->len` was an invalid value for the given
|
||||||
* gnrc_netif_t::device_type of @p netif.
|
* gnrc_netif_t::device_type of @p netif.
|
||||||
*/
|
*/
|
||||||
int gnrc_netif_ndp_addr_len_from_l2ao(gnrc_netif_t *netif,
|
static inline int gnrc_netif_ndp_addr_len_from_l2ao(gnrc_netif_t *netif,
|
||||||
const ndp_opt_t *opt);
|
const ndp_opt_t *opt)
|
||||||
|
{
|
||||||
|
assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR);
|
||||||
|
return l2util_ndp_addr_len_from_l2ao(netif->device_type, opt);
|
||||||
|
}
|
||||||
#else /* defined(MODULE_GNRC_IPV6) || defined(DOXYGEN) */
|
#else /* defined(MODULE_GNRC_IPV6) || defined(DOXYGEN) */
|
||||||
#define gnrc_netif_ipv6_init_mtu(netif) (void)netif
|
#define gnrc_netif_ipv6_init_mtu(netif) (void)netif
|
||||||
#define gnrc_netif_ipv6_iid_from_addr(netif, addr, addr_len, iid) (-ENOTSUP)
|
#define gnrc_netif_ipv6_iid_from_addr(netif, addr, addr_len, iid) (-ENOTSUP)
|
||||||
|
|||||||
142
sys/include/net/l2util.h
Normal file
142
sys/include/net/l2util.h
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* 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_l2util Stack-independent helpers for IPv6 over X
|
||||||
|
* @ingroup net
|
||||||
|
* @brief This implements some common helper functions for IPv6 over X
|
||||||
|
* implementations based on [network device types]
|
||||||
|
* (@ref net_netdev_type).
|
||||||
|
*
|
||||||
|
* @attention If you add a new [network device type](@ref net_netdev_type)
|
||||||
|
* have at least a look at the implementation of these functions.
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Link-layer helper function definitions
|
||||||
|
*
|
||||||
|
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||||
|
*/
|
||||||
|
#ifndef NET_L2UTIL_H
|
||||||
|
#define NET_L2UTIL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "net/eui64.h"
|
||||||
|
#include "net/ndp.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define L2UTIL_ADDR_MAX_LEN (8U) /**< maximum expected length for addresses */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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] dev_type The network device type of the device @p addr came from
|
||||||
|
* (either because it is the configured address of the
|
||||||
|
* device 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 @p dev_type does not support EUI-64 conversion.
|
||||||
|
* @return `-EINVAL`, when @p addr_len is invalid for the @p dev_type.
|
||||||
|
*/
|
||||||
|
int l2util_eui64_from_addr(int dev_type, const uint8_t *addr, size_t addr_len,
|
||||||
|
eui64_t *eui64);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts a given hardware address to an IPv6 IID.
|
||||||
|
*
|
||||||
|
* @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] dev_type The network device type of the device @p addr came from
|
||||||
|
* (either because it is the configured address of the
|
||||||
|
* device 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] iid The IID based on gnrc_netif_t::device_type
|
||||||
|
*
|
||||||
|
* @return `sizeof(eui64_t)` on success.
|
||||||
|
* @return `-ENOTSUP`, when @p dev_type does not support IID conversion.
|
||||||
|
* @return `-EINVAL`, when @p addr_len is invalid for the @p dev_type.
|
||||||
|
*/
|
||||||
|
int l2util_ipv6_iid_from_addr(int dev_type,
|
||||||
|
const uint8_t *addr, size_t addr_len,
|
||||||
|
eui64_t *iid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts an IPv6 IID to a hardware address
|
||||||
|
*
|
||||||
|
* @pre @p iid was based on a hardware address
|
||||||
|
* @pre The number of bytes available at @p addr is less or equal to
|
||||||
|
* @ref L2UTIL_ADDR_MAX_LEN.
|
||||||
|
*
|
||||||
|
* @attention When `NDEBUG` is not defined, the node fails with an assertion
|
||||||
|
* instead of returning `-ENOTSUP`
|
||||||
|
*
|
||||||
|
* @param[in] dev_type The network device type of the device the @p iid came
|
||||||
|
* from (either because it is based on the configured
|
||||||
|
* address of the device or from a packet that came over
|
||||||
|
* it).
|
||||||
|
* @param[in] iid An IID based on @p dev_type.
|
||||||
|
* @param[out] addr The hardware address. It is assumed that @p iid was
|
||||||
|
* based on a hardware address and that the available
|
||||||
|
* number of bytes in @p addr are greater or equal to
|
||||||
|
* @ref L2UTIL_ADDR_MAX_LEN.
|
||||||
|
*
|
||||||
|
* @return Length of resulting @p addr on success.
|
||||||
|
* @return `-ENOTSUP`, when @p dev_type does not support reverse IID
|
||||||
|
* conversion.
|
||||||
|
*/
|
||||||
|
int l2util_ipv6_iid_to_addr(int dev_type, const eui64_t *iid, uint8_t *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Derives the length of the link-layer address in an NDP link-layer
|
||||||
|
* address option from that option's length field and the given device
|
||||||
|
* type.
|
||||||
|
*
|
||||||
|
* @note If an RFC exists that specifies how IPv6 operates over a link-layer,
|
||||||
|
* this function usually implements the section "Unicast Address
|
||||||
|
* Mapping".
|
||||||
|
*
|
||||||
|
* @see [RFC 4861, section 4.6.1](https://tools.ietf.org/html/rfc4861#section-4.6.1)
|
||||||
|
*
|
||||||
|
* @attention When `NDEBUG` is not defined, the node fails with an assertion
|
||||||
|
* instead of returning `-ENOTSUP`
|
||||||
|
*
|
||||||
|
* @param[in] dev_type The network device type of the device the @p opt came
|
||||||
|
* over in an NDP message.
|
||||||
|
* @param[in] opt An NDP source/target link-layer address option.
|
||||||
|
*
|
||||||
|
* @return Length of the link-layer address in @p opt on success
|
||||||
|
* @return `-ENOTSUP`, when implementation does not know how to derive the
|
||||||
|
* length of the link-layer address from @p opt's length field based
|
||||||
|
* on @p dev_type.
|
||||||
|
* @return `-EINVAL` if `opt->len` was an invalid value for the given
|
||||||
|
* @p dev_type.
|
||||||
|
*/
|
||||||
|
int l2util_ndp_addr_len_from_l2ao(int dev_type,
|
||||||
|
const ndp_opt_t *opt);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NET_L2UTIL_H */
|
||||||
|
/** @} */
|
||||||
@ -24,6 +24,7 @@
|
|||||||
#include "net/eui48.h"
|
#include "net/eui48.h"
|
||||||
#include "net/ethernet.h"
|
#include "net/ethernet.h"
|
||||||
#include "net/ieee802154.h"
|
#include "net/ieee802154.h"
|
||||||
|
#include "net/l2util.h"
|
||||||
|
|
||||||
netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif)
|
netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif)
|
||||||
{
|
{
|
||||||
@ -54,19 +55,6 @@ 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,
|
int gnrc_netif_eui64_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 *eui64)
|
eui64_t *eui64)
|
||||||
@ -74,55 +62,24 @@ int gnrc_netif_eui64_from_addr(const gnrc_netif_t *netif,
|
|||||||
#if GNRC_NETIF_L2ADDR_MAXLEN > 0
|
#if GNRC_NETIF_L2ADDR_MAXLEN > 0
|
||||||
if (netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR) {
|
if (netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR) {
|
||||||
switch (netif->device_type) {
|
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)
|
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
|
||||||
case NETDEV_TYPE_IEEE802154:
|
case NETDEV_TYPE_IEEE802154:
|
||||||
|
/* try getting EUI-64 from device if short address is
|
||||||
|
* provided */
|
||||||
switch (addr_len) {
|
switch (addr_len) {
|
||||||
case IEEE802154_SHORT_ADDRESS_LEN: {
|
case IEEE802154_SHORT_ADDRESS_LEN: {
|
||||||
netdev_t *dev = netif->dev;
|
netdev_t *dev = netif->dev;
|
||||||
return dev->driver->get(dev, NETOPT_ADDRESS_LONG, eui64,
|
return dev->driver->get(dev, NETOPT_ADDRESS_LONG, eui64,
|
||||||
sizeof(eui64_t));
|
sizeof(eui64_t));
|
||||||
}
|
}
|
||||||
case IEEE802154_LONG_ADDRESS_LEN:
|
|
||||||
memcpy(eui64, addr, addr_len);
|
|
||||||
return sizeof(eui64_t);
|
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
break;
|
||||||
}
|
}
|
||||||
|
/* Intentionally falls through */
|
||||||
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) */
|
#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:
|
default:
|
||||||
(void)addr;
|
return l2util_eui64_from_addr(netif->device_type, addr,
|
||||||
(void)addr_len;
|
addr_len, eui64);
|
||||||
(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 */
|
#endif /* GNRC_NETIF_L2ADDR_MAXLEN > 0 */
|
||||||
@ -204,141 +161,13 @@ int gnrc_netif_ipv6_iid_from_addr(const gnrc_netif_t *netif,
|
|||||||
{
|
{
|
||||||
#if GNRC_NETIF_L2ADDR_MAXLEN > 0
|
#if GNRC_NETIF_L2ADDR_MAXLEN > 0
|
||||||
if (netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR) {
|
if (netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR) {
|
||||||
switch (netif->device_type) {
|
return l2util_ipv6_iid_from_addr(netif->device_type,
|
||||||
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
|
addr, addr_len, iid);
|
||||||
case NETDEV_TYPE_IEEE802154:
|
|
||||||
if (ieee802154_get_iid(iid, addr, addr_len) != NULL) {
|
|
||||||
return sizeof(eui64_t);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
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, iid);
|
|
||||||
/* since this address conversion is based on the IEEE
|
|
||||||
* 802.15.4 address conversion for short addresses, the
|
|
||||||
* U/L bit doesn't need to be flipped.
|
|
||||||
* see https://tools.ietf.org/html/rfc6282#section-3.2.2 */
|
|
||||||
return sizeof(eui64_t);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
#endif /* defined(MODULE_CC110X) || defined(MODULE_NRFMIN) */
|
|
||||||
default: {
|
|
||||||
int res = gnrc_netif_eui64_from_addr(netif, addr, addr_len,
|
|
||||||
iid);
|
|
||||||
if (res == sizeof(eui64_t)) {
|
|
||||||
iid->uint8[0] ^= 0x02;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* GNRC_NETIF_L2ADDR_MAXLEN > 0 */
|
#endif /* GNRC_NETIF_L2ADDR_MAXLEN > 0 */
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gnrc_netif_ipv6_iid_to_addr(const gnrc_netif_t *netif, const eui64_t *iid,
|
|
||||||
uint8_t *addr)
|
|
||||||
{
|
|
||||||
assert(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:
|
|
||||||
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:
|
|
||||||
/* assume address was based on EUI-64
|
|
||||||
* (see https://tools.ietf.org/html/rfc6775#section-5.2) */
|
|
||||||
memcpy(addr, iid, sizeof(eui64_t));
|
|
||||||
addr[0] ^= 0x02;
|
|
||||||
return sizeof(eui64_t);
|
|
||||||
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) */
|
|
||||||
#ifdef MODULE_NRFMIN
|
|
||||||
case NETDEV_TYPE_NRFMIN:
|
|
||||||
addr[0] = iid->uint8[6];
|
|
||||||
addr[1] = iid->uint8[7];
|
|
||||||
return sizeof(uint16_t);
|
|
||||||
#endif /* MODULE_NETDEV_IEEE802154 */
|
|
||||||
#ifdef MODULE_CC110X
|
|
||||||
case NETDEV_TYPE_CC110X:
|
|
||||||
addr[0] = iid->uint8[7];
|
|
||||||
return sizeof(uint8_t);
|
|
||||||
#endif /* MODULE_CC110X */
|
|
||||||
default:
|
|
||||||
(void)iid;
|
|
||||||
(void)addr;
|
|
||||||
#ifdef DEVELHELP
|
|
||||||
LOG_ERROR("gnrc_netif: can't convert IID to hardware address "
|
|
||||||
"on interface %u\n", netif->pid);
|
|
||||||
#endif /* DEVELHELP */
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gnrc_netif_ndp_addr_len_from_l2ao(gnrc_netif_t *netif,
|
|
||||||
const ndp_opt_t *opt)
|
|
||||||
{
|
|
||||||
assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR);
|
|
||||||
switch (netif->device_type) {
|
|
||||||
#ifdef MODULE_CC110X
|
|
||||||
case NETDEV_TYPE_CC110X:
|
|
||||||
(void)opt;
|
|
||||||
return sizeof(uint8_t);
|
|
||||||
#endif /* MODULE_CC110X */
|
|
||||||
#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:
|
|
||||||
/* see https://tools.ietf.org/html/rfc2464#section-6*/
|
|
||||||
if (opt->len == 1U) {
|
|
||||||
return ETHERNET_ADDR_LEN;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
#endif /* defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW) */
|
|
||||||
#ifdef MODULE_NRFMIN
|
|
||||||
case NETDEV_TYPE_NRFMIN:
|
|
||||||
(void)opt;
|
|
||||||
return sizeof(uint16_t);
|
|
||||||
#endif /* MODULE_NRFMIN */
|
|
||||||
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
|
|
||||||
case NETDEV_TYPE_IEEE802154:
|
|
||||||
/* see https://tools.ietf.org/html/rfc4944#section-8 */
|
|
||||||
switch (opt->len) {
|
|
||||||
case 1U:
|
|
||||||
return IEEE802154_SHORT_ADDRESS_LEN;
|
|
||||||
case 2U:
|
|
||||||
return IEEE802154_LONG_ADDRESS_LEN;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) */
|
|
||||||
default:
|
|
||||||
(void)opt;
|
|
||||||
#ifdef DEVELHELP
|
|
||||||
LOG_ERROR("gnrc_netif: can't get address length from NDP link-layer "
|
|
||||||
"address option on interface %u\n", netif->pid);
|
|
||||||
#endif
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
#endif /* MODULE_GNRC_IPV6 */
|
#endif /* MODULE_GNRC_IPV6 */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
1
sys/net/link_layer/l2util/Makefile
Normal file
1
sys/net/link_layer/l2util/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
228
sys/net/link_layer/l2util/l2util.c
Normal file
228
sys/net/link_layer/l2util/l2util.c
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include "net/eui48.h"
|
||||||
|
#include "net/ieee802154.h"
|
||||||
|
#include "net/ipv6.h"
|
||||||
|
#include "net/netdev.h"
|
||||||
|
|
||||||
|
#include "net/l2util.h"
|
||||||
|
|
||||||
|
#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 l2util_eui64_from_addr(int dev_type, const uint8_t *addr, size_t addr_len,
|
||||||
|
eui64_t *eui64)
|
||||||
|
{
|
||||||
|
switch (dev_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) {
|
||||||
|
/* EUI-64 can *not* be generated from the short address */
|
||||||
|
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("l2util: can't convert hardware address to EUI-64 "
|
||||||
|
"for device type %d\n", dev_type);
|
||||||
|
#endif /* DEVELHELP */
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l2util_ipv6_iid_from_addr(int dev_type,
|
||||||
|
const uint8_t *addr, size_t addr_len,
|
||||||
|
eui64_t *iid)
|
||||||
|
{
|
||||||
|
switch (dev_type) {
|
||||||
|
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
|
||||||
|
case NETDEV_TYPE_IEEE802154:
|
||||||
|
if (ieee802154_get_iid(iid, addr, addr_len) != NULL) {
|
||||||
|
return sizeof(eui64_t);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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, iid);
|
||||||
|
/* since this address conversion is based on the IEEE
|
||||||
|
* 802.15.4 address conversion for short addresses, the
|
||||||
|
* U/L bit doesn't need to be flipped.
|
||||||
|
* see https://tools.ietf.org/html/rfc6282#section-3.2.2 */
|
||||||
|
return sizeof(eui64_t);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif /* defined(MODULE_CC110X) || defined(MODULE_NRFMIN) */
|
||||||
|
default: {
|
||||||
|
int res = l2util_eui64_from_addr(dev_type, addr, addr_len, iid);
|
||||||
|
if (res == sizeof(eui64_t)) {
|
||||||
|
iid->uint8[0] ^= 0x02;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l2util_ipv6_iid_to_addr(int dev_type, const eui64_t *iid, uint8_t *addr)
|
||||||
|
{
|
||||||
|
switch (dev_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:
|
||||||
|
eui48_from_ipv6_iid((eui48_t *)addr, iid);
|
||||||
|
return sizeof(eui48_t);
|
||||||
|
#endif /* defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW) || \
|
||||||
|
* defined(MODULE_NORDIC_SOFTDEVICE_BLE) */
|
||||||
|
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
|
||||||
|
case NETDEV_TYPE_IEEE802154:
|
||||||
|
/* assume address was based on EUI-64
|
||||||
|
* (see https://tools.ietf.org/html/rfc6775#section-5.2) */
|
||||||
|
memcpy(addr, iid, sizeof(eui64_t));
|
||||||
|
addr[0] ^= 0x02;
|
||||||
|
return sizeof(eui64_t);
|
||||||
|
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) */
|
||||||
|
#ifdef MODULE_NRFMIN
|
||||||
|
case NETDEV_TYPE_NRFMIN:
|
||||||
|
addr[0] = iid->uint8[6];
|
||||||
|
addr[1] = iid->uint8[7];
|
||||||
|
return sizeof(uint16_t);
|
||||||
|
#endif /* MODULE_NETDEV_IEEE802154 */
|
||||||
|
#ifdef MODULE_CC110X
|
||||||
|
case NETDEV_TYPE_CC110X:
|
||||||
|
addr[0] = iid->uint8[7];
|
||||||
|
return sizeof(uint8_t);
|
||||||
|
#endif /* MODULE_CC110X */
|
||||||
|
default:
|
||||||
|
(void)iid;
|
||||||
|
(void)addr;
|
||||||
|
#ifdef DEVELHELP
|
||||||
|
LOG_ERROR("l2util: can't convert IID to hardware address for "
|
||||||
|
"device type %d\n", dev_type);
|
||||||
|
#endif /* DEVELHELP */
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l2util_ndp_addr_len_from_l2ao(int dev_type,
|
||||||
|
const ndp_opt_t *opt)
|
||||||
|
{
|
||||||
|
switch (dev_type) {
|
||||||
|
#ifdef MODULE_CC110X
|
||||||
|
case NETDEV_TYPE_CC110X:
|
||||||
|
(void)opt;
|
||||||
|
return sizeof(uint8_t);
|
||||||
|
#endif /* MODULE_CC110X */
|
||||||
|
#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:
|
||||||
|
/* see https://tools.ietf.org/html/rfc2464#section-6*/
|
||||||
|
if (opt->len == 1U) {
|
||||||
|
return sizeof(eui48_t);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif /* defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW) */
|
||||||
|
#ifdef MODULE_NRFMIN
|
||||||
|
case NETDEV_TYPE_NRFMIN:
|
||||||
|
(void)opt;
|
||||||
|
return sizeof(uint16_t);
|
||||||
|
#endif /* MODULE_NRFMIN */
|
||||||
|
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
|
||||||
|
case NETDEV_TYPE_IEEE802154:
|
||||||
|
/* see https://tools.ietf.org/html/rfc4944#section-8 */
|
||||||
|
switch (opt->len) {
|
||||||
|
case 1U:
|
||||||
|
return IEEE802154_SHORT_ADDRESS_LEN;
|
||||||
|
case 2U:
|
||||||
|
return IEEE802154_LONG_ADDRESS_LEN;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) */
|
||||||
|
default:
|
||||||
|
(void)opt;
|
||||||
|
#ifdef DEVELHELP
|
||||||
|
LOG_ERROR("l2util: can't get address length from NDP link-layer "
|
||||||
|
"address option for device type %d\n", dev_type);
|
||||||
|
#endif
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @} */
|
||||||
25
tests/l2util/Makefile
Normal file
25
tests/l2util/Makefile
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
DEVELHELP = 0
|
||||||
|
|
||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
BOARD_INSUFFICIENT_MEMORY := blackpill bluepill
|
||||||
|
|
||||||
|
USEMODULE += embunit
|
||||||
|
USEMODULE += l2util
|
||||||
|
|
||||||
|
# defining the "module" path defines this way in the hopes to make it more
|
||||||
|
#clearer.
|
||||||
|
CHECKED_IFDEF_PATHS = cc110x \
|
||||||
|
esp_now \
|
||||||
|
netdev_eth \
|
||||||
|
netdev_ieee802154 \
|
||||||
|
xbee \
|
||||||
|
nordic_softdevice_ble \
|
||||||
|
nrfmin
|
||||||
|
|
||||||
|
CFLAGS += $(foreach path,$(CHECKED_IFDEF_PATHS),\
|
||||||
|
-DMODULE_$(shell echo $(path) | tr a-z A-Z))
|
||||||
|
|
||||||
|
TEST_ON_CI_WHITELIST += all
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
407
tests/l2util/main.c
Normal file
407
tests/l2util/main.c
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup tests
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Unit tests for l2util
|
||||||
|
*
|
||||||
|
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "embUnit.h"
|
||||||
|
#include "net/eui48.h"
|
||||||
|
#include "net/eui64.h"
|
||||||
|
#include "net/ieee802154.h"
|
||||||
|
#include "net/netdev.h"
|
||||||
|
|
||||||
|
#include "net/l2util.h"
|
||||||
|
|
||||||
|
#define TEST_ADDR { 0x21, 0x55, 0x31, 0x02, 0x41, 0xfd, 0xfb, 0xfd }
|
||||||
|
#define TEST_802154_S_IID { 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x21, 0x55 }
|
||||||
|
#define TEST_CC110X_IID { 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x21 }
|
||||||
|
#define TEST_EUI48_EUI64 { 0x21, 0x55, 0x31, 0xff, 0xfe, 0x02, 0x41, 0xfd }
|
||||||
|
#define TEST_EUI48_IID { 0x23, 0x55, 0x31, 0xff, 0xfe, 0x02, 0x41, 0xfd }
|
||||||
|
#define TEST_EUI64_IID { 0x23, 0x55, 0x31, 0x02, 0x41, 0xfd, 0xfb, 0xfd }
|
||||||
|
|
||||||
|
static void test_eui64_from_addr__success(void)
|
||||||
|
{
|
||||||
|
static const uint8_t test_addr[L2UTIL_ADDR_MAX_LEN] = TEST_ADDR;
|
||||||
|
static const eui64_t test_802154_s = { .uint8 = TEST_802154_S_IID };
|
||||||
|
static const eui64_t test_cc110x = { .uint8 = TEST_CC110X_IID };
|
||||||
|
static const eui64_t test_eui48 = { .uint8 = TEST_EUI48_EUI64 };
|
||||||
|
static const eui64_t test_eui64 = { .uint8 = TEST_ADDR };
|
||||||
|
eui64_t res;
|
||||||
|
|
||||||
|
/* test Ethernet */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_ETHERNET,
|
||||||
|
test_addr, sizeof(eui48_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_eui48, &res, sizeof(eui64_t)));
|
||||||
|
/* test IEEE 802.15.4 */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_IEEE802154,
|
||||||
|
test_addr, sizeof(eui64_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_eui64, &res, sizeof(eui64_t)));
|
||||||
|
/* test (nordic softdevice) BLE */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_BLE,
|
||||||
|
test_addr, sizeof(eui48_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_eui48, &res, sizeof(eui64_t)));
|
||||||
|
/* test cc110x */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_CC110X,
|
||||||
|
test_addr, sizeof(uint8_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_cc110x, &res, sizeof(eui64_t)));
|
||||||
|
/* test NRFMIN */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_NRFMIN,
|
||||||
|
test_addr, sizeof(uint16_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_802154_s, &res, sizeof(eui64_t)));
|
||||||
|
/* test ESP-Now */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_ESP_NOW,
|
||||||
|
test_addr, sizeof(eui48_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_eui48, &res, sizeof(eui64_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_eui64_from_addr__EINVAL(void)
|
||||||
|
{
|
||||||
|
static const uint8_t test_addr[L2UTIL_ADDR_MAX_LEN] = TEST_ADDR;
|
||||||
|
eui64_t res = { .uint8 = { 0 } };
|
||||||
|
|
||||||
|
/* test Ethernet */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_ETHERNET,
|
||||||
|
test_addr, sizeof(eui64_t),
|
||||||
|
&res));
|
||||||
|
/* test IEEE 802.15.4 */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_IEEE802154,
|
||||||
|
test_addr, sizeof(uint16_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_IEEE802154,
|
||||||
|
test_addr, sizeof(eui48_t),
|
||||||
|
&res));
|
||||||
|
/* test (nordic softdevice) BLE */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_BLE,
|
||||||
|
test_addr, sizeof(uint16_t),
|
||||||
|
&res));
|
||||||
|
/* test cc110x */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_CC110X,
|
||||||
|
test_addr, sizeof(uint64_t),
|
||||||
|
&res));
|
||||||
|
/* test NRFMIN */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_NRFMIN,
|
||||||
|
test_addr, sizeof(uint64_t),
|
||||||
|
&res));
|
||||||
|
/* test ESP-Now */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_ESP_NOW,
|
||||||
|
test_addr, 0,
|
||||||
|
&res));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_eui64_from_addr__ENOTSUP(void)
|
||||||
|
{
|
||||||
|
static const uint8_t test_addr[L2UTIL_ADDR_MAX_LEN] = TEST_ADDR;
|
||||||
|
eui64_t res = { .uint8 = { 0 } };
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(-ENOTSUP,
|
||||||
|
l2util_eui64_from_addr(NETDEV_TYPE_UNKNOWN,
|
||||||
|
test_addr, 0,
|
||||||
|
&res));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_iid_from_addr__success(void)
|
||||||
|
{
|
||||||
|
static const uint8_t test_addr[L2UTIL_ADDR_MAX_LEN] = TEST_ADDR;
|
||||||
|
static const eui64_t test_802154_s = { .uint8 = TEST_802154_S_IID };
|
||||||
|
static const eui64_t test_cc110x = { .uint8 = TEST_CC110X_IID };
|
||||||
|
static const eui64_t test_eui48 = { .uint8 = TEST_EUI48_IID };
|
||||||
|
static const eui64_t test_eui64 = { .uint8 = TEST_EUI64_IID };
|
||||||
|
eui64_t res;
|
||||||
|
|
||||||
|
/* test Ethernet */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_ETHERNET,
|
||||||
|
test_addr, sizeof(eui48_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_eui48, &res, sizeof(eui64_t)));
|
||||||
|
/* test IEEE 802.15.4 */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_IEEE802154,
|
||||||
|
test_addr, sizeof(eui64_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_eui64, &res, sizeof(eui64_t)));
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_IEEE802154,
|
||||||
|
test_addr,
|
||||||
|
IEEE802154_SHORT_ADDRESS_LEN,
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_802154_s, &res, sizeof(eui64_t)));
|
||||||
|
/* test (nordic softdevice) BLE */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_BLE,
|
||||||
|
test_addr, sizeof(eui48_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_eui48, &res, sizeof(eui64_t)));
|
||||||
|
/* test cc110x */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_CC110X,
|
||||||
|
test_addr, sizeof(uint8_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_cc110x, &res, sizeof(eui64_t)));
|
||||||
|
/* test NRFMIN */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_NRFMIN,
|
||||||
|
test_addr, sizeof(uint16_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_802154_s, &res, sizeof(eui64_t)));
|
||||||
|
/* test ESP-Now */
|
||||||
|
res.uint64.u64 = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_ESP_NOW,
|
||||||
|
test_addr, sizeof(eui48_t),
|
||||||
|
&res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(&test_eui48, &res, sizeof(eui64_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_iid_from_addr__EINVAL(void)
|
||||||
|
{
|
||||||
|
static const uint8_t test_addr[L2UTIL_ADDR_MAX_LEN] = TEST_ADDR;
|
||||||
|
eui64_t res = { .uint8 = { 0 } };
|
||||||
|
|
||||||
|
/* test Ethernet */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_ETHERNET,
|
||||||
|
test_addr, sizeof(eui64_t),
|
||||||
|
&res));
|
||||||
|
/* test IEEE 802.15.4 */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_IEEE802154,
|
||||||
|
test_addr, sizeof(eui48_t),
|
||||||
|
&res));
|
||||||
|
/* test (nordic softdevice) BLE */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_BLE,
|
||||||
|
test_addr, sizeof(uint16_t),
|
||||||
|
&res));
|
||||||
|
/* test cc110x */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_CC110X,
|
||||||
|
test_addr, sizeof(uint64_t),
|
||||||
|
&res));
|
||||||
|
/* test NRFMIN */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_NRFMIN,
|
||||||
|
test_addr, sizeof(uint64_t),
|
||||||
|
&res));
|
||||||
|
/* test ESP-Now */
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_ESP_NOW,
|
||||||
|
test_addr, 0,
|
||||||
|
&res));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_iid_from_addr__ENOTSUP(void)
|
||||||
|
{
|
||||||
|
static const uint8_t test_addr[L2UTIL_ADDR_MAX_LEN] = TEST_ADDR;
|
||||||
|
eui64_t res = { .uint8 = { 0 } };
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(-ENOTSUP,
|
||||||
|
l2util_ipv6_iid_from_addr(NETDEV_TYPE_UNKNOWN,
|
||||||
|
test_addr, 0,
|
||||||
|
&res));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_iid_to_addr__success(void)
|
||||||
|
{
|
||||||
|
static const uint8_t test_addr[L2UTIL_ADDR_MAX_LEN] = TEST_ADDR;
|
||||||
|
static const eui64_t test_802154_s = { .uint8 = TEST_802154_S_IID };
|
||||||
|
static const eui64_t test_cc110x = { .uint8 = TEST_CC110X_IID };
|
||||||
|
static const eui64_t test_eui48 = { .uint8 = TEST_EUI48_IID };
|
||||||
|
static const eui64_t test_eui64 = { .uint8 = TEST_EUI64_IID };
|
||||||
|
uint8_t res[L2UTIL_ADDR_MAX_LEN];
|
||||||
|
|
||||||
|
/* test Ethernet */
|
||||||
|
memset(res, 0, sizeof(res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui48_t),
|
||||||
|
l2util_ipv6_iid_to_addr(NETDEV_TYPE_ETHERNET,
|
||||||
|
&test_eui48, res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(test_addr, res, sizeof(eui48_t)));
|
||||||
|
/* test IEEE 802.15.4 */
|
||||||
|
memset(res, 0, sizeof(res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ipv6_iid_to_addr(NETDEV_TYPE_IEEE802154,
|
||||||
|
&test_eui64, res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(test_addr, res, sizeof(eui64_t)));
|
||||||
|
/* test (nordic softdevice) BLE */
|
||||||
|
memset(res, 0, sizeof(res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui48_t),
|
||||||
|
l2util_ipv6_iid_to_addr(NETDEV_TYPE_BLE,
|
||||||
|
&test_eui48, res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(test_addr, res, sizeof(eui48_t)));
|
||||||
|
/* test cc110x */
|
||||||
|
memset(res, 0, sizeof(res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(uint8_t),
|
||||||
|
l2util_ipv6_iid_to_addr(NETDEV_TYPE_CC110X,
|
||||||
|
&test_cc110x, res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(test_addr, res, sizeof(uint8_t)));
|
||||||
|
/* test NRFMIN */
|
||||||
|
memset(res, 0, sizeof(res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(uint16_t),
|
||||||
|
l2util_ipv6_iid_to_addr(NETDEV_TYPE_NRFMIN,
|
||||||
|
&test_802154_s, res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(test_addr, res, sizeof(uint16_t)));
|
||||||
|
/* test ESP-Now */
|
||||||
|
memset(res, 0, sizeof(res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui48_t),
|
||||||
|
l2util_ipv6_iid_to_addr(NETDEV_TYPE_ESP_NOW,
|
||||||
|
&test_eui48, res));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, memcmp(test_addr, res, sizeof(eui48_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_iid_to_addr__ENOTSUP(void)
|
||||||
|
{
|
||||||
|
static const eui64_t test_eui48 = { .uint8 = TEST_EUI48_IID };
|
||||||
|
uint8_t res[L2UTIL_ADDR_MAX_LEN];
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(-ENOTSUP,
|
||||||
|
l2util_ipv6_iid_to_addr(NETDEV_TYPE_UNKNOWN,
|
||||||
|
&test_eui48, res));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_addr_len_from_l2ao__success(void)
|
||||||
|
{
|
||||||
|
ndp_opt_t opt = { .type = NDP_OPT_SL2A };
|
||||||
|
|
||||||
|
/* test Ethernet */
|
||||||
|
opt.len = 1;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui48_t),
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_ETHERNET,
|
||||||
|
&opt));
|
||||||
|
/* test IEEE 802.15.4 */
|
||||||
|
opt.len = 1;
|
||||||
|
TEST_ASSERT_EQUAL_INT(IEEE802154_SHORT_ADDRESS_LEN,
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_IEEE802154,
|
||||||
|
&opt));
|
||||||
|
opt.len = 2;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui64_t),
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_IEEE802154,
|
||||||
|
&opt));
|
||||||
|
/* test BLE */
|
||||||
|
opt.len = 1;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui48_t),
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_BLE,
|
||||||
|
&opt));
|
||||||
|
/* test cc110x */
|
||||||
|
opt.len = 1;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(uint8_t),
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_CC110X,
|
||||||
|
&opt));
|
||||||
|
/* test NRFMIN */
|
||||||
|
opt.len = 1;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(uint16_t),
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_NRFMIN,
|
||||||
|
&opt));
|
||||||
|
/* test ESP-Now */
|
||||||
|
opt.len = 1;
|
||||||
|
TEST_ASSERT_EQUAL_INT(sizeof(eui48_t),
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_ESP_NOW,
|
||||||
|
&opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_addr_len_from_l2ao__EINVAL(void)
|
||||||
|
{
|
||||||
|
ndp_opt_t opt = { .type = NDP_OPT_SL2A };
|
||||||
|
|
||||||
|
/* test Ethernet */
|
||||||
|
opt.len = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_ETHERNET,
|
||||||
|
&opt));
|
||||||
|
/* test IEEE 802.15.4 */
|
||||||
|
opt.len = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_IEEE802154,
|
||||||
|
&opt));
|
||||||
|
/* test BLE */
|
||||||
|
opt.len = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_BLE,
|
||||||
|
&opt));
|
||||||
|
/* test ESP-Now */
|
||||||
|
opt.len = 0;
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL,
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_ESP_NOW,
|
||||||
|
&opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_addr_len_from_l2ao__ENOTSUP(void)
|
||||||
|
{
|
||||||
|
ndp_opt_t opt = { .type = NDP_OPT_SL2A };
|
||||||
|
|
||||||
|
opt.len = 1;
|
||||||
|
TEST_ASSERT_EQUAL_INT(-ENOTSUP,
|
||||||
|
l2util_ndp_addr_len_from_l2ao(NETDEV_TYPE_UNKNOWN,
|
||||||
|
&opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
TestRef test_l2util(void)
|
||||||
|
{
|
||||||
|
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||||
|
new_TestFixture(test_eui64_from_addr__success),
|
||||||
|
new_TestFixture(test_eui64_from_addr__EINVAL),
|
||||||
|
new_TestFixture(test_eui64_from_addr__ENOTSUP),
|
||||||
|
new_TestFixture(test_iid_from_addr__success),
|
||||||
|
new_TestFixture(test_iid_from_addr__EINVAL),
|
||||||
|
new_TestFixture(test_iid_from_addr__ENOTSUP),
|
||||||
|
new_TestFixture(test_iid_to_addr__success),
|
||||||
|
new_TestFixture(test_iid_to_addr__ENOTSUP),
|
||||||
|
new_TestFixture(test_addr_len_from_l2ao__success),
|
||||||
|
new_TestFixture(test_addr_len_from_l2ao__EINVAL),
|
||||||
|
new_TestFixture(test_addr_len_from_l2ao__ENOTSUP),
|
||||||
|
};
|
||||||
|
|
||||||
|
EMB_UNIT_TESTCALLER(tests_l2util, NULL, NULL, fixtures);
|
||||||
|
return (TestRef) & tests_l2util;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
TESTS_START();
|
||||||
|
TESTS_RUN(test_l2util());
|
||||||
|
TESTS_END();
|
||||||
|
}
|
||||||
18
tests/l2util/tests/01-run.py
Executable file
18
tests/l2util/tests/01-run.py
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (C) 2017 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.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from testrunner import run
|
||||||
|
|
||||||
|
|
||||||
|
def testfunc(child):
|
||||||
|
child.expect(r'OK \(\d+ tests\)')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(run(testfunc))
|
||||||
Loading…
x
Reference in New Issue
Block a user