mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
219 lines
8.1 KiB
C
219 lines
8.1 KiB
C
/*
|
|
* 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);
|
|
|
|
/**
|
|
* @brief Converts an IPv6 multicast address to a multicast address
|
|
* of the respective link layer.
|
|
*
|
|
* @pre There is enough allocated space in @p l2_group for an address for a
|
|
* device of type @p dev_type (e.g. 6 bytes for an ethernet address).
|
|
*
|
|
* @param[in] dev_type The network device type of the device @p l2_addr
|
|
* should be generated for.
|
|
* @param[in] ipv6_group An IPv6 multicast address.
|
|
* @param[out] l2_group A link layer multicast address
|
|
*
|
|
* @return Length of @p l2_group in bytes
|
|
* @return `-ENOTSUP` if link layer does not support multicast.
|
|
*/
|
|
int l2util_ipv6_group_to_l2_group(int dev_type,
|
|
const ipv6_addr_t *ipv6_group,
|
|
uint8_t *l2_group);
|
|
|
|
/**
|
|
* @brief Converts a hardware address to a human readable string.
|
|
*
|
|
* @details The format will be like `xx:xx:xx:xx` where `xx` are the bytes
|
|
* of @p addr in hexadecimal representation.
|
|
*
|
|
* @pre `(out != NULL) && ((addr != NULL) || (addr_len == 0))`
|
|
* @pre @p out **MUST** have allocated at least 3 * @p addr_len bytes.
|
|
*
|
|
* @param[in] addr A hardware address.
|
|
* @param[in] addr_len Length of @p addr.
|
|
* @param[out] out A string to store the output in. Must at least have
|
|
* 3 * @p addr_len bytes allocated.
|
|
*
|
|
* @return @p out.
|
|
*/
|
|
char *l2util_addr_to_str(const uint8_t *addr, size_t addr_len, char *out);
|
|
|
|
/**
|
|
* @brief Parses a string of colon-separated hexadecimals to a hardware
|
|
* address.
|
|
*
|
|
* @details The input format must be like `xx:xx:xx:xx` where `xx` will be the
|
|
* bytes of @p addr in hexadecimal representation.
|
|
*
|
|
* @pre `(out != NULL)`
|
|
* @pre @p out **MUST** have allocated at least
|
|
* @ref GNRC_NETIF_L2ADDR_MAXLEN bytes.
|
|
*
|
|
* @param[in] str A string of colon-separated hexadecimals.
|
|
* @param[out] out The resulting hardware address. Must at least have
|
|
* @ref GNRC_NETIF_L2ADDR_MAXLEN bytes allocated.
|
|
*
|
|
* @return Actual length of @p out on success.
|
|
* @return 0, on failure.
|
|
*/
|
|
size_t l2util_addr_from_str(const char *str, uint8_t *out);
|
|
|
|
/**
|
|
* @brief Checks if two l2 addresses are equal.
|
|
*
|
|
* @param[in] addr_a First hardware address.
|
|
* @param[in] addr_a_len Length of first hardware address.
|
|
* @param[in] addr_b Second hardware address.
|
|
* @param[in] addr_b_len Length of second hardware address.
|
|
*
|
|
* @return true if the addresses match, false if not.
|
|
*/
|
|
static inline bool l2util_addr_equal(const uint8_t *addr_a, uint8_t addr_a_len,
|
|
const uint8_t *addr_b, uint8_t addr_b_len)
|
|
{
|
|
if (addr_a_len != addr_b_len) {
|
|
return false;
|
|
}
|
|
|
|
return memcmp(addr_a, addr_b, addr_a_len) == 0;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* NET_L2UTIL_H */
|
|
/** @} */
|