Line data Source code
1 1 : /*
2 : * Copyright (c) 2016 Intel Corporation.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Public API for network link address
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_NET_NET_LINKADDR_H_
13 : #define ZEPHYR_INCLUDE_NET_NET_LINKADDR_H_
14 :
15 : #include <zephyr/types.h>
16 : #include <stdbool.h>
17 : #include <errno.h>
18 :
19 : #ifdef __cplusplus
20 : extern "C" {
21 : #endif
22 :
23 : /**
24 : * @brief Network link address library
25 : * @defgroup net_linkaddr Network Link Address Library
26 : * @since 1.0
27 : * @version 1.0.0
28 : * @ingroup networking
29 : * @{
30 : */
31 :
32 : /** Maximum length of the link address */
33 : #if defined(CONFIG_NET_L2_PHY_IEEE802154) || defined(CONFIG_NET_L2_PPP)
34 : #define NET_LINK_ADDR_MAX_LENGTH 8
35 : #else
36 1 : #define NET_LINK_ADDR_MAX_LENGTH 6
37 : #endif
38 :
39 : /**
40 : * Type of the link address. This indicates the network technology that this
41 : * address is used in. Note that in order to save space we store the value
42 : * into a uint8_t variable, so please do not introduce any values > 255 in
43 : * this enum.
44 : */
45 1 : enum net_link_type {
46 : /** Unknown link address type. */
47 : NET_LINK_UNKNOWN = 0,
48 : /** IEEE 802.15.4 link address. */
49 : NET_LINK_IEEE802154,
50 : /** Bluetooth IPSP link address. */
51 : NET_LINK_BLUETOOTH,
52 : /** Ethernet link address. */
53 : NET_LINK_ETHERNET,
54 : /** Dummy link address. Used in testing apps and loopback support. */
55 : NET_LINK_DUMMY,
56 : /** CANBUS link address. */
57 : NET_LINK_CANBUS_RAW,
58 : } __packed;
59 :
60 : /**
61 : * @brief Hardware link address structure
62 : *
63 : * Used to hold the link address information. This variant is needed
64 : * when we have to store the link layer address.
65 : *
66 : * Note that you cannot cast this to net_linkaddr as uint8_t * is
67 : * handled differently than uint8_t addr[] and the fields are purposely
68 : * in different order.
69 : */
70 1 : struct net_linkaddr {
71 : /** What kind of address is this for */
72 1 : uint8_t type;
73 :
74 : /** The real length of the ll address. */
75 1 : uint8_t len;
76 :
77 : /** The array of bytes representing the address */
78 1 : uint8_t addr[NET_LINK_ADDR_MAX_LENGTH]; /* in big endian */
79 : };
80 :
81 : /**
82 : * @brief Compare two link layer addresses.
83 : *
84 : * @param lladdr1 Pointer to a link layer address
85 : * @param lladdr2 Pointer to a link layer address
86 : *
87 : * @return True if the addresses are the same, false otherwise.
88 : */
89 1 : static inline bool net_linkaddr_cmp(struct net_linkaddr *lladdr1,
90 : struct net_linkaddr *lladdr2)
91 : {
92 : if (!lladdr1 || !lladdr2) {
93 : return false;
94 : }
95 :
96 : if (lladdr1->len != lladdr2->len) {
97 : return false;
98 : }
99 :
100 : return !memcmp(lladdr1->addr, lladdr2->addr, lladdr1->len);
101 : }
102 :
103 : /**
104 : *
105 : * @brief Set the member data of a link layer address storage structure.
106 : *
107 : * @param lladdr The link address storage structure to change.
108 : * @param new_addr Array of bytes containing the link address.
109 : * @param new_len Length of the link address array.
110 : * This value should always be <= NET_LINK_ADDR_MAX_LENGTH.
111 : * @return 0 if ok, <0 if error
112 : */
113 1 : static inline int net_linkaddr_set(struct net_linkaddr *lladdr,
114 : const uint8_t *new_addr,
115 : uint8_t new_len)
116 : {
117 : if (lladdr == NULL || new_addr == NULL) {
118 : return -EINVAL;
119 : }
120 :
121 : if (new_len > NET_LINK_ADDR_MAX_LENGTH) {
122 : return -EMSGSIZE;
123 : }
124 :
125 : lladdr->len = new_len;
126 : memcpy(lladdr->addr, new_addr, new_len);
127 :
128 : return 0;
129 : }
130 :
131 : /**
132 : * @brief Copy link address from one variable to another.
133 : *
134 : * @param dst The link address structure destination.
135 : * @param src The link address structure to source.
136 : * @return 0 if ok, <0 if error
137 : */
138 1 : static inline int net_linkaddr_copy(struct net_linkaddr *dst,
139 : const struct net_linkaddr *src)
140 : {
141 : if (dst == NULL || src == NULL) {
142 : return -EINVAL;
143 : }
144 :
145 : if (src->len > NET_LINK_ADDR_MAX_LENGTH) {
146 : return -EMSGSIZE;
147 : }
148 :
149 : dst->type = src->type;
150 : dst->len = src->len;
151 : memcpy(dst->addr, src->addr, src->len);
152 :
153 : return 0;
154 : }
155 :
156 : /**
157 : * @brief Create a link address structure.
158 : *
159 : * @param lladdr The link address structure to change.
160 : * @param addr Array of bytes containing the link address. If set to NULL,
161 : * the address will be cleared.
162 : * @param len Length of the link address array.
163 : * @param type Type of the link address.
164 : * @return 0 if ok, <0 if error
165 : */
166 1 : static inline int net_linkaddr_create(struct net_linkaddr *lladdr,
167 : const uint8_t *addr, uint8_t len,
168 : enum net_link_type type)
169 : {
170 : if (lladdr == NULL) {
171 : return -EINVAL;
172 : }
173 :
174 : if (len > NET_LINK_ADDR_MAX_LENGTH) {
175 : return -EMSGSIZE;
176 : }
177 :
178 : if (addr == NULL) {
179 : memset(lladdr->addr, 0, NET_LINK_ADDR_MAX_LENGTH);
180 : } else {
181 : memcpy(lladdr->addr, addr, len);
182 : }
183 :
184 : lladdr->type = type;
185 : lladdr->len = len;
186 :
187 : return 0;
188 : }
189 :
190 : /**
191 : * @brief Clear link address.
192 : *
193 : * @param lladdr The link address structure.
194 : * @return 0 if ok, <0 if error
195 : */
196 1 : static inline int net_linkaddr_clear(struct net_linkaddr *lladdr)
197 : {
198 : return net_linkaddr_create(lladdr, NULL, 0, NET_LINK_UNKNOWN);
199 : }
200 :
201 : /**
202 : * @}
203 : */
204 :
205 : #ifdef __cplusplus
206 : }
207 : #endif
208 :
209 : #endif /* ZEPHYR_INCLUDE_NET_NET_LINKADDR_H_ */
|