Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ng_net: add IID option and simplify upper layers accordingly #3159

Merged
merged 9 commits into from
Jul 1, 2015
15 changes: 15 additions & 0 deletions drivers/ng_at86rf2xx/ng_at86rf2xx_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* @}
*/

#include "net/eui64.h"
#include "net/ng_ieee802154.h"
#include "net/ng_netbase.h"
#include "ng_at86rf2xx.h"
Expand Down Expand Up @@ -400,6 +401,20 @@ static int _get(ng_netdev_t *device, ng_netconf_opt_t opt,
*((uint16_t *)val) = dev->pan;
return sizeof(uint16_t);

case NETCONF_OPT_IPV6_IID:
if (max_len < sizeof(eui64_t)) {
return -EOVERFLOW;
}
if (dev->options & NG_AT86RF2XX_OPT_SRC_ADDR_LONG) {
uint64_t addr = ng_at86rf2xx_get_addr_long(dev);
ng_ieee802154_get_iid(val, (uint8_t *)&addr, 8);
}
else {
uint16_t addr = ng_at86rf2xx_get_addr_short(dev);
ng_ieee802154_get_iid(val, (uint8_t *)&addr, 2);
}
return sizeof(eui64_t);

case NETCONF_OPT_PROTO:
if (max_len < sizeof(ng_nettype_t)) {
return -EOVERFLOW;
Expand Down
14 changes: 14 additions & 0 deletions drivers/xbee/xbee.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "xbee.h"
#include "hwtimer.h"
#include "msg.h"
#include "net/eui64.h"
#include "net/ng_ieee802154.h"
#include "periph/cpuid.h"

#define ENABLE_DEBUG (0)
Expand Down Expand Up @@ -620,6 +622,18 @@ static int _get(ng_netdev_t *netdev, ng_netconf_opt_t opt,
*((uint16_t *)value) = 2;
}
return sizeof(uint16_t);
case NETCONF_OPT_IPV6_IID:
if (max_len < sizeof(eui64_t)) {
return -EOVERFLOW;
}
if (dev->addr_flags & XBEE_ADDR_FLAGS_LONG) {
ng_ieee802154_get_iid(value, (uint8_t *)&dev->addr_long, 8);
}
else {
ng_ieee802154_get_iid(value, (uint8_t *)&dev->addr_short, 2);
}

return sizeof(eui64_t);
case NETCONF_OPT_CHANNEL:
return _get_channel(dev, (uint8_t *)value, max_len);
case NETCONF_OPT_MAX_PACKET_SIZE:
Expand Down
48 changes: 48 additions & 0 deletions sys/include/net/eui64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2015 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_eui64 IEEE EUI-64 identifier
* @ingroup net
* @brief Type definiton of the IEEE EUI-64 identifier
* @see <a href="http://standards.ieee.org/regauth/oui/tutorials/EUI64.html">
* IEEE, "Guidelines for 64-bit Global Identifier (EUI-64)"
* </a>
* @{
*
* @file
* @brief EUI-64 data type definition
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
*/
#ifndef EUI64_H_
#define EUI64_H_

#include <stdint.h>
#include "byteorder.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Data type to represent an EUI-64.
*/
typedef union {
network_uint64_t uint64; /**< represented as 64 bit value */
uint8_t uint8[8]; /**< split into 8 8-bit words. */
network_uint16_t uint16[4]; /**< split into 4 16-bit words. */
} eui64_t;

#ifdef __cplusplus
}
#endif

#endif /* EUI64_H_ */
/** @} */
26 changes: 26 additions & 0 deletions sys/include/net/ng_ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
#ifndef NG_ETHERNET_H_
#define NG_ETHERNET_H_

#include <stdint.h>

#include "net/ng_ethernet/hdr.h"
#include "net/eui64.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -46,6 +49,29 @@ extern "C" {
#define NG_ETHERNET_MAX_LEN (NG_ETHERNET_FRAME_LEN + \
NG_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 NG_ETHERNET_ADDR_LEN long.
*/
static inline void ng_ethernet_get_iid(eui64_t *eui64, 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
Expand Down
66 changes: 58 additions & 8 deletions sys/include/net/ng_ieee802154.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
#ifndef NG_IEEE802154_H_
#define NG_IEEE802154_H_

#include <stdint.h>
#include "byteorder.h"
#include <stdlib.h>

#include "net/eui64.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -62,13 +63,62 @@ extern "C" {
/** @} */

/**
* @brief Data type to represent an EUI-64.
* @brief Generates an IPv6 interface identifier from an IEEE 802.15.4 address.
*
* @see <a href="https://tools.ietf.org/html/rfc4944#section-6">
* RFC 4944, section 6
* </a>
* @see <a href="https://tools.ietf.org/html/rfc6282#section-3.2.2">
* RFC 6282, section 3.2.2
* </a>
*
* @param[out] eui64 The resulting EUI-64.
* @param[in] addr An IEEE 802.15.4 address.
* @param[in] addr_len The length of @p addr. Must be 2 (short address),
* 4 (PAN ID + short address), or 8 (long address).
*
* @return Copy of @p eui64 on success.
* @return NULL, if @p addr_len was of illegal length.
*/
typedef union {
le_uint64_t uint64; /**< represented as 64 bit value */
uint8_t uint8[8]; /**< split into 8 8-bit words. */
le_uint16_t uint16[4]; /**< split into 4 16-bit words. */
} eui64_t ;
static inline eui64_t *ng_ieee802154_get_iid(eui64_t *eui64, uint8_t *addr,
size_t addr_len)
{
int i = 0;

eui64->uint8[0] = eui64->uint8[1] = 0;

switch (addr_len) {
case 8:
eui64->uint8[0] = addr[i++] ^ 0x02;
eui64->uint8[1] = addr[i++];
eui64->uint8[2] = addr[i++];
eui64->uint8[3] = addr[i++];
eui64->uint8[4] = addr[i++];
eui64->uint8[5] = addr[i++];
eui64->uint8[6] = addr[i++];
eui64->uint8[7] = addr[i++];
break;

case 4:
eui64->uint8[0] = addr[i++] ^ 0x02;
eui64->uint8[1] = addr[i++];

case 2:
eui64->uint8[2] = 0;
eui64->uint8[3] = 0xff;
eui64->uint8[4] = 0xfe;
eui64->uint8[5] = 0;
eui64->uint8[6] = addr[i++];
eui64->uint8[7] = addr[i++];
break;

default:
return NULL;
}

return eui64;
}


#ifdef __cplusplus
}
Expand Down
16 changes: 16 additions & 0 deletions sys/include/net/ng_netconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@ typedef enum {
* Examples for this include the PAN ID in IEEE 802.15.4
*/
NETCONF_OPT_NID,

/**
* @brief get the IPv6 interface identifier of a network interface as
* eui64_t.
*
* @see <a href="https://tools.ietf.org/html/rfc4291#section-2.5.1">
* RFC 4291, section 2.5.1
* </a>
*
* The generation of the interface identifier is dependent on the link-layer.
* Please refer to the appropriate IPv6 over `<link>` specification for
* further implementation details (such as
* <a href="https://tools.ietf.org/html/rfc2464">RFC 2464</a> or
* <a href="https://tools.ietf.org/html/rfc4944">RFC 4944</a>).
*/
NETCONF_OPT_IPV6_IID,
NETCONF_OPT_TX_POWER, /**< get/set the output power for radio
* devices in dBm as int16_t in host byte
* order */
Expand Down
20 changes: 20 additions & 0 deletions sys/net/link_layer/ng_netdev_eth/ng_netdev_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <string.h>

#include "byteorder.h"
#include "net/eui64.h"
#include "net/ng_ethernet.h"
#include "net/ng_ethertype.h"
#include "net/ng_netdev.h"
Expand Down Expand Up @@ -198,6 +199,21 @@ static inline int _get_addr_len(uint16_t *value, size_t max_len)
return sizeof(uint16_t);
}

static inline int _get_iid(ng_netdev_eth_t *netdev, eui64_t *value, size_t max_len)
{
if (max_len < sizeof(eui64_t)) {
/* value buffer not big enough */
return -EOVERFLOW;
}

dev_eth_t *dev = netdev->ethdev;
uint8_t addr[NG_ETHERNET_ADDR_LEN];
dev->driver->get_mac_addr(dev, addr);
ng_ethernet_get_iid(value, addr);

return sizeof(eui64_t);
}

static inline int _get_max_pkt_sz(uint16_t *value, size_t max_len)
{
if (max_len != sizeof(uint16_t)) {
Expand Down Expand Up @@ -244,6 +260,10 @@ static int _get(ng_netdev_t *dev, ng_netconf_opt_t opt, void *value,
DEBUG("address length\n");
return _get_addr_len(value, max_len);

case NETCONF_OPT_IPV6_IID:
DEBUG("IPv6 IID\n");
return _get_iid((ng_netdev_eth_t *)dev, value, max_len);

case NETCONF_OPT_MAX_PACKET_SIZE:
DEBUG("maximum packet size\n");
return _get_max_pkt_sz(value, max_len);
Expand Down
Loading