forked from RIOT-OS/RIOT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheui48.h
164 lines (145 loc) · 3.96 KB
/
eui48.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
* 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_eui48 IEEE EUI-48 identifier
* @ingroup net
* @brief Definition and IPv6 IID conversion for IEEE EUI-48 identifiers
* @{
*
* @file
* @brief Definition and IPv6 IID conversion for IEEE EUI-48 identifiers
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef NET_EUI48_H
#define NET_EUI48_H
#include <stdint.h>
#include "net/eui64.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Data type to represent an EUI-48
*/
typedef struct {
uint8_t uint8[6]; /**< split into 6 8-bit words. */
} eui48_t;
/**
* @name EUI-48 bit flags contained in the first octet
*
* @see IEEE 802-2001 section 9.2
* @{
*/
/**
* @brief Locally administered address.
*/
#define EUI48_LOCAL_FLAG 0x02
/**
* @brief Group type address.
*/
#define EUI48_GROUP_FLAG 0x01
/** @} */
/**
* @brief Set the locally administrated bit in the EUI-48 address.
*
* @see IEEE 802-2001 section 9.2
*
* @param addr ethernet address
*/
static inline void eui48_set_local(eui48_t *addr)
{
addr->uint8[0] |= EUI48_LOCAL_FLAG;
}
/**
* @brief Clear the group address bit to signal the address as individual
* address
*
* @see IEEE 802-2001 section 9.2
*
* @param addr ethernet address
*/
static inline void eui48_clear_group(eui48_t *addr)
{
addr->uint8[0] &= ~EUI48_GROUP_FLAG;
}
/**
* @brief Generates an EUI-64 from a 48-bit device address
*
* @see [RFC 2464, section 4](https://tools.ietf.org/html/rfc2464#section-4)
*
* @param[out] eui64 the resulting EUI-64.
* @param[in] addr a 48-bit device address
*/
static inline void eui48_to_eui64(eui64_t *eui64, const eui48_t *addr)
{
eui64->uint8[0] = addr->uint8[0];
eui64->uint8[1] = addr->uint8[1];
eui64->uint8[2] = addr->uint8[2];
eui64->uint8[3] = 0xff;
eui64->uint8[4] = 0xfe;
eui64->uint8[5] = addr->uint8[3];
eui64->uint8[6] = addr->uint8[4];
eui64->uint8[7] = addr->uint8[5];
}
/**
* @brief Generates an EUI-48 from a 64-bit device address
*
* @warning The resulting EUI-48 is not guaranteed to be unique
* and, hence, marked as only locally unique.
*
* @param[out] eui48 the resulting EUI-48.
* @param[in] addr a 64-bit device address
*/
static inline void eui64_to_eui48(eui48_t *eui48, const eui64_t *addr)
{
/* Preserve vendor id */
eui48->uint8[0] = addr->uint8[0];
eui48->uint8[1] = addr->uint8[1];
eui48->uint8[2] = addr->uint8[2];
/* Use most volatile bits */
eui48->uint8[3] = addr->uint8[5];
eui48->uint8[4] = addr->uint8[6];
eui48->uint8[5] = addr->uint8[7];
/* EUI is only locally unique */
eui48_set_local(eui48);
}
/**
* @brief Generates an IPv6 interface identifier from a 48-bit device address
*
* @note The IPv6 IID is derived from the EUI-64 by flipping the U/L bit.
* @see [RFC 2464, section 4](https://tools.ietf.org/html/rfc2464#section-4)
* @see [RFC 4291, section 2.5.1](https://tools.ietf.org/html/rfc4291#section-2.5.1)
*
* @param[out] iid the resulting EUI-64.
* @param[in] addr a 48-bit device address
*/
static inline void eui48_to_ipv6_iid(eui64_t *iid, const eui48_t *addr)
{
eui48_to_eui64(iid, addr);
iid->uint8[0] ^= 0x02;
}
/**
* @brief Convert a 64-bit IPv6 IID into a EUI-48 device address
*
* @param[out] addr the resulting EUI-48
* @param[in] iid a 64-bit IPv6 interface identifier
*/
static inline void eui48_from_ipv6_iid(eui48_t *addr, const eui64_t *iid)
{
addr->uint8[0] = iid->uint8[0] ^ 0x02;
addr->uint8[1] = iid->uint8[1];
addr->uint8[2] = iid->uint8[2];
addr->uint8[3] = iid->uint8[5];
addr->uint8[4] = iid->uint8[6];
addr->uint8[5] = iid->uint8[7];
}
#ifdef __cplusplus
}
#endif
#endif /* NET_EUI48_H */
/** @} */