Merge pull request #3159 from authmillenon/ng_net/feat/iid
ng_net: add IID option and simplify upper layers accordingly
This commit is contained in:
commit
3238ccd47e
@ -19,6 +19,7 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "net/eui64.h"
|
||||
#include "net/ng_ieee802154.h"
|
||||
#include "net/ng_netbase.h"
|
||||
#include "ng_at86rf2xx.h"
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
@ -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:
|
||||
|
||||
48
sys/include/net/eui64.h
Normal file
48
sys/include/net/eui64.h
Normal file
@ -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_ */
|
||||
/** @} */
|
||||
@ -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" {
|
||||
@ -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
|
||||
|
||||
@ -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" {
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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"
|
||||
@ -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)) {
|
||||
@ -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);
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "mutex.h"
|
||||
#include "net/eui64.h"
|
||||
#include "net/ng_ipv6/addr.h"
|
||||
#include "net/ng_ndp.h"
|
||||
#include "net/ng_netapi.h"
|
||||
@ -445,62 +446,6 @@ ng_ipv6_addr_t *ng_ipv6_netif_find_best_src_addr(kernel_pid_t pid, const ng_ipv6
|
||||
return _match_prefix(pid, dest, true);
|
||||
}
|
||||
|
||||
/* TODO: put this somewhere more central and L2 protocol dependent */
|
||||
#define IID_LEN (8)
|
||||
|
||||
static bool _hwaddr_to_iid(uint8_t *iid, const uint8_t *hwaddr, size_t hwaddr_len)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
memset(iid, 0, IID_LEN);
|
||||
|
||||
switch (hwaddr_len) {
|
||||
case 8:
|
||||
iid[0] = hwaddr[i++];
|
||||
iid[0] ^= 0x02;
|
||||
iid[1] = hwaddr[i++];
|
||||
iid[2] = hwaddr[i++];
|
||||
iid[3] = hwaddr[i++];
|
||||
iid[4] = hwaddr[i++];
|
||||
iid[5] = hwaddr[i++];
|
||||
iid[6] = hwaddr[i++];
|
||||
iid[7] = hwaddr[i++];
|
||||
break;
|
||||
|
||||
case 6:
|
||||
iid[0] = hwaddr[i++];
|
||||
iid[0] ^= 0x02;
|
||||
iid[1] = hwaddr[i++];
|
||||
iid[2] = hwaddr[i++];
|
||||
iid[3] = 0xff;
|
||||
iid[4] = 0xfe;
|
||||
iid[5] = hwaddr[i++];
|
||||
iid[6] = hwaddr[i++];
|
||||
iid[7] = hwaddr[i++];
|
||||
break;
|
||||
|
||||
case 4:
|
||||
iid[0] = hwaddr[i++];
|
||||
iid[0] ^= 0x02;
|
||||
iid[1] = hwaddr[i++];
|
||||
|
||||
case 2:
|
||||
iid[6] = hwaddr[i++];
|
||||
|
||||
case 1:
|
||||
iid[3] = 0xff;
|
||||
iid[4] = 0xfe;
|
||||
iid[7] = hwaddr[i++];
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG("Unknown hardware address length\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ng_ipv6_netif_init_by_dev(void)
|
||||
{
|
||||
kernel_pid_t ifs[NG_NETIF_NUMOF];
|
||||
@ -508,11 +453,8 @@ void ng_ipv6_netif_init_by_dev(void)
|
||||
|
||||
for (size_t i = 0; i < ifnum; i++) {
|
||||
ng_ipv6_addr_t addr;
|
||||
uint16_t hwaddr_len = 0;
|
||||
uint8_t hwaddr[NG_NETIF_HDR_L2ADDR_MAX_LEN];
|
||||
bool try_long = false;
|
||||
eui64_t iid;
|
||||
ng_ipv6_netif_t *ipv6_if = ng_ipv6_netif_get(ifs[i]);
|
||||
int res = 0;
|
||||
|
||||
if (ipv6_if == NULL) {
|
||||
continue;
|
||||
@ -532,25 +474,14 @@ void ng_ipv6_netif_init_by_dev(void)
|
||||
|
||||
#endif
|
||||
|
||||
if ((ng_netapi_get(ifs[i], NETCONF_OPT_SRC_LEN, 0, &hwaddr_len,
|
||||
sizeof(hwaddr_len)) != -ENOTSUP) &&
|
||||
(hwaddr_len == 8)) {
|
||||
try_long = true;
|
||||
if ((ng_netapi_get(ifs[i], NETCONF_OPT_IPV6_IID, 0, &iid,
|
||||
sizeof(eui64_t)) < 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((try_long && ((res = ng_netapi_get(ifs[i], NETCONF_OPT_ADDRESS_LONG, 0,
|
||||
&hwaddr, sizeof(hwaddr))) > 0)) ||
|
||||
((res = ng_netapi_get(ifs[i], NETCONF_OPT_ADDRESS, 0, &hwaddr,
|
||||
sizeof(hwaddr))) > 0)) {
|
||||
uint8_t iid[IID_LEN];
|
||||
hwaddr_len = (uint16_t)res;
|
||||
|
||||
if (_hwaddr_to_iid(iid, hwaddr, hwaddr_len)) {
|
||||
ng_ipv6_addr_set_aiid(&addr, iid);
|
||||
ng_ipv6_addr_set_link_local_prefix(&addr);
|
||||
_add_addr_to_entry(ipv6_if, &addr, 64, 0);
|
||||
}
|
||||
}
|
||||
ng_ipv6_addr_set_aiid(&addr, iid.uint8);
|
||||
ng_ipv6_addr_set_link_local_prefix(&addr);
|
||||
_add_addr_to_entry(ipv6_if, &addr, 64, 0);
|
||||
|
||||
mutex_unlock(&ipv6_if->mutex);
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "net/ng_ieee802154.h"
|
||||
#include "net/ng_ipv6/hdr.h"
|
||||
#include "net/ng_netbase.h"
|
||||
#include "net/ng_sixlowpan/ctx.h"
|
||||
@ -67,39 +68,9 @@
|
||||
#define IPHC_M_DAC_DAM_M_8 (0x0b)
|
||||
#define IPHC_M_DAC_DAM_M_UC_PREFIX (0x0c)
|
||||
|
||||
static network_uint64_t _init_iid(uint8_t *l2addr, size_t l2addr_len)
|
||||
{
|
||||
network_uint64_t res = { 0 };
|
||||
|
||||
if (l2addr_len <= 4) {
|
||||
res = byteorder_htonll(0x000000fffe000000);
|
||||
|
||||
if (l2addr_len == 1) {
|
||||
res.u8[7] = l2addr[0];
|
||||
}
|
||||
else if (l2addr_len == 2) {
|
||||
res.u8[6] = l2addr[0];
|
||||
res.u8[7] = l2addr[1];
|
||||
}
|
||||
else if (l2addr_len == 4) {
|
||||
res.u8[0] = l2addr[0];
|
||||
res.u8[1] = l2addr[1];
|
||||
res.u8[6] = l2addr[2];
|
||||
res.u8[7] = l2addr[3];
|
||||
}
|
||||
}
|
||||
else if (l2addr_len == 8) {
|
||||
network_uint64_t *l2addr_u64 = (network_uint64_t *)l2addr;
|
||||
res = *l2addr_u64;
|
||||
res.u8[0] ^= 0x02; /* swap local/universal bit */
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline bool _context_overlaps_iid(ng_sixlowpan_ctx_t *ctx,
|
||||
ng_ipv6_addr_t *addr,
|
||||
network_uint64_t *iid)
|
||||
eui64_t *iid)
|
||||
{
|
||||
uint8_t byte_mask[] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
|
||||
|
||||
@ -111,11 +82,11 @@ static inline bool _context_overlaps_iid(ng_sixlowpan_ctx_t *ctx,
|
||||
((ctx->prefix_len > 64) && /* otherwise, if bigger than 64-bit */
|
||||
/* compare bytes until prefix length with IID */
|
||||
(memcmp(&(addr->u8[(ctx->prefix_len / 8) + 1]),
|
||||
&(iid->u8[(ctx->prefix_len / 8) - 7]),
|
||||
&(iid->uint8[(ctx->prefix_len / 8) - 7]),
|
||||
sizeof(network_uint64_t) - ((ctx->prefix_len / 8) - 7)) == 0) &&
|
||||
/* compare bits at prefix length with IID */
|
||||
(addr->u8[(ctx->prefix_len / 8)] & byte_mask[ctx->prefix_len % 8]) ==
|
||||
(iid->u8[(ctx->prefix_len / 8) - 8] & byte_mask[ctx->prefix_len % 8])));
|
||||
(iid->uint8[(ctx->prefix_len / 8) - 8] & byte_mask[ctx->prefix_len % 8])));
|
||||
}
|
||||
|
||||
bool ng_sixlowpan_iphc_decode(ng_pktsnip_t *pkt)
|
||||
@ -230,9 +201,10 @@ bool ng_sixlowpan_iphc_decode(ng_pktsnip_t *pkt)
|
||||
break;
|
||||
|
||||
case IPHC_SAC_SAM_L2:
|
||||
ng_ieee802154_get_iid((eui64_t *)(&ipv6_hdr->src.u64[1]),
|
||||
ng_netif_hdr_get_src_addr(netif_hdr),
|
||||
netif_hdr->src_l2addr_len);
|
||||
ng_ipv6_addr_set_link_local_prefix(&ipv6_hdr->src);
|
||||
ipv6_hdr->src.u64[1] = _init_iid(ng_netif_hdr_get_src_addr(netif_hdr),
|
||||
netif_hdr->src_l2addr_len);
|
||||
break;
|
||||
|
||||
case IPHC_SAC_SAM_UNSPEC:
|
||||
@ -256,8 +228,9 @@ bool ng_sixlowpan_iphc_decode(ng_pktsnip_t *pkt)
|
||||
break;
|
||||
|
||||
case IPHC_SAC_SAM_CTX_L2:
|
||||
ipv6_hdr->src.u64[1] = _init_iid(ng_netif_hdr_get_src_addr(netif_hdr),
|
||||
netif_hdr->src_l2addr_len);
|
||||
ng_ieee802154_get_iid((eui64_t *)(&ipv6_hdr->src.u64[1]),
|
||||
ng_netif_hdr_get_src_addr(netif_hdr),
|
||||
netif_hdr->src_l2addr_len);
|
||||
ng_ipv6_addr_init_prefix(&ipv6_hdr->src, &ctx->prefix,
|
||||
ctx->prefix_len);
|
||||
break;
|
||||
@ -303,9 +276,10 @@ bool ng_sixlowpan_iphc_decode(ng_pktsnip_t *pkt)
|
||||
break;
|
||||
|
||||
case IPHC_M_DAC_DAM_U_L2:
|
||||
ng_ieee802154_get_iid((eui64_t *)(&ipv6_hdr->dst.u64[1]),
|
||||
ng_netif_hdr_get_dst_addr(netif_hdr),
|
||||
netif_hdr->dst_l2addr_len);
|
||||
ng_ipv6_addr_set_link_local_prefix(&ipv6_hdr->dst);
|
||||
ipv6_hdr->dst.u64[1] = _init_iid(ng_netif_hdr_get_src_addr(netif_hdr),
|
||||
netif_hdr->src_l2addr_len);
|
||||
break;
|
||||
|
||||
case IPHC_M_DAC_DAM_U_CTX_64:
|
||||
@ -325,8 +299,9 @@ bool ng_sixlowpan_iphc_decode(ng_pktsnip_t *pkt)
|
||||
break;
|
||||
|
||||
case IPHC_M_DAC_DAM_U_CTX_L2:
|
||||
ipv6_hdr->dst.u64[1] = _init_iid(ng_netif_hdr_get_src_addr(netif_hdr),
|
||||
netif_hdr->src_l2addr_len);
|
||||
ng_ieee802154_get_iid((eui64_t *)(&ipv6_hdr->dst.u64[1]),
|
||||
ng_netif_hdr_get_dst_addr(netif_hdr),
|
||||
netif_hdr->dst_l2addr_len);
|
||||
ng_ipv6_addr_init_prefix(&ipv6_hdr->dst, &ctx->prefix,
|
||||
ctx->prefix_len);
|
||||
break;
|
||||
@ -520,38 +495,24 @@ bool ng_sixlowpan_iphc_encode(ng_pktsnip_t *pkt)
|
||||
}
|
||||
|
||||
if ((src_ctx != NULL) || ng_ipv6_addr_is_link_local(&(ipv6_hdr->src))) {
|
||||
uint16_t l2src_len = 0;
|
||||
uint8_t l2src[8];
|
||||
eui64_t iid;
|
||||
|
||||
if (netif_hdr->src_l2addr_len > 0) {
|
||||
l2src_len = netif_hdr->src_l2addr_len;
|
||||
memcpy(l2src, ng_netif_hdr_get_src_addr(netif_hdr), l2src_len);
|
||||
if ((netif_hdr->src_l2addr_len == 2) ||
|
||||
(netif_hdr->src_l2addr_len == 4) ||
|
||||
(netif_hdr->src_l2addr_len == 8)) {
|
||||
ng_ieee802154_get_iid(&iid, ng_netif_hdr_get_src_addr(netif_hdr),
|
||||
netif_hdr->src_l2addr_len);
|
||||
addr_comp = true;
|
||||
}
|
||||
else {
|
||||
bool try_long = false;
|
||||
|
||||
if ((ng_netapi_get(netif_hdr->if_pid, NETCONF_OPT_ADDR_LEN, 0,
|
||||
&l2src_len, sizeof(l2src_len)) >= 0) &&
|
||||
(l2src_len >= 8)) {
|
||||
try_long = true;
|
||||
if (ng_netapi_get(netif_hdr->if_pid, NETCONF_OPT_IPV6_IID, 0,
|
||||
&iid, sizeof(eui64_t)) >= 0) {
|
||||
addr_comp = true;
|
||||
}
|
||||
|
||||
if ((!try_long) || (ng_netapi_get(netif_hdr->if_pid,
|
||||
NETCONF_OPT_ADDRESS_LONG, 0,
|
||||
&l2src, sizeof(l2src)) < 0)) {
|
||||
if (ng_netapi_get(netif_hdr->if_pid, NETCONF_OPT_ADDRESS,
|
||||
0, &l2src, sizeof(l2src)) < 0) {
|
||||
l2src_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (l2src_len > 0) {
|
||||
network_uint64_t iid = _init_iid(l2src, l2src_len);
|
||||
|
||||
if ((memcmp(ipv6_hdr->src.u64 + 1, &iid,
|
||||
sizeof(network_uint64_t)) == 0) ||
|
||||
if (addr_comp) {
|
||||
if ((ipv6_hdr->src.u64[1].u64 == iid.uint64.u64) ||
|
||||
_context_overlaps_iid(src_ctx, &ipv6_hdr->src, &iid)) {
|
||||
/* 0 bits. The address is derived from link-layer address */
|
||||
iphc_hdr[IPHC2_IDX] |= IPHC_SAC_SAM_L2;
|
||||
@ -569,8 +530,6 @@ bool ng_sixlowpan_iphc_encode(ng_pktsnip_t *pkt)
|
||||
memcpy(iphc_hdr + inline_pos, ipv6_hdr->src.u64 + 1, 8);
|
||||
inline_pos += 8;
|
||||
}
|
||||
|
||||
addr_comp = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -647,10 +606,12 @@ bool ng_sixlowpan_iphc_encode(ng_pktsnip_t *pkt)
|
||||
}
|
||||
else if (((dst_ctx != NULL) || ng_ipv6_addr_is_link_local(&ipv6_hdr->dst)) &&
|
||||
(netif_hdr->dst_l2addr_len > 0)) {
|
||||
network_uint64_t iid = _init_iid(ng_netif_hdr_get_dst_addr(netif_hdr),
|
||||
netif_hdr->dst_l2addr_len);
|
||||
eui64_t iid;
|
||||
|
||||
if ((memcmp(&(ipv6_hdr->dst.u8[8]), &iid, sizeof(uint64_t)) == 0) ||
|
||||
ng_ieee802154_get_iid(&iid, ng_netif_hdr_get_dst_addr(netif_hdr),
|
||||
netif_hdr->dst_l2addr_len);
|
||||
|
||||
if ((ipv6_hdr->dst.u64[1].u64 == iid.uint64.u64) ||
|
||||
_context_overlaps_iid(dst_ctx, &(ipv6_hdr->dst), &iid)) {
|
||||
/* 0 bits. The address is derived using the link-layer address */
|
||||
iphc_hdr[IPHC2_IDX] |= IPHC_M_DAC_DAM_U_L2;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user