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 #ifdef CONFIG_NET_L2_IEEE802154
34 #define NET_LINK_ADDR_MAX_LENGTH 8
35 #else
36 #ifdef CONFIG_NET_L2_PPP
37 #define NET_LINK_ADDR_MAX_LENGTH 8
38 #else
39 #define NET_LINK_ADDR_MAX_LENGTH 6
40 #endif
41 #endif
42 
43 /**
44  * Type of the link address. This indicates the network technology that this
45  * address is used in. Note that in order to save space we store the value
46  * into a uint8_t variable, so please do not introduce any values > 255 in
47  * this enum.
48  */
49 enum net_link_type {
50 	/** Unknown link address type. */
51 	NET_LINK_UNKNOWN = 0,
52 	/** IEEE 802.15.4 link address. */
53 	NET_LINK_IEEE802154,
54 	/** Bluetooth IPSP link address. */
55 	NET_LINK_BLUETOOTH,
56 	/** Ethernet link address. */
57 	NET_LINK_ETHERNET,
58 	/** Dummy link address. Used in testing apps and loopback support. */
59 	NET_LINK_DUMMY,
60 	/** CANBUS link address. */
61 	NET_LINK_CANBUS_RAW,
62 } __packed;
63 
64 /**
65  *  @brief Hardware link address structure
66  *
67  *  Used to hold the link address information
68  */
69 struct net_linkaddr {
70 	/** The array of byte representing the address */
71 	uint8_t *addr; /* in big endian */
72 
73 	/** Length of that address array */
74 	uint8_t len;
75 
76 	/** What kind of address is this for */
77 	uint8_t type;
78 };
79 
80 /**
81  *  @brief Hardware link address structure
82  *
83  *  Used to hold the link address information. This variant is needed
84  *  when we have to store the link layer address.
85  *
86  *  Note that you cannot cast this to net_linkaddr as uint8_t * is
87  *  handled differently than uint8_t addr[] and the fields are purposely
88  *  in different order.
89  */
90 struct net_linkaddr_storage {
91 	/** What kind of address is this for */
92 	uint8_t type;
93 
94 	/** The real length of the ll address. */
95 	uint8_t len;
96 
97 	/** The array of bytes representing the address */
98 	uint8_t addr[NET_LINK_ADDR_MAX_LENGTH]; /* in big endian */
99 };
100 
101 /**
102  * @brief Compare two link layer addresses.
103  *
104  * @param lladdr1 Pointer to a link layer address
105  * @param lladdr2 Pointer to a link layer address
106  *
107  * @return True if the addresses are the same, false otherwise.
108  */
net_linkaddr_cmp(struct net_linkaddr * lladdr1,struct net_linkaddr * lladdr2)109 static inline bool net_linkaddr_cmp(struct net_linkaddr *lladdr1,
110 				    struct net_linkaddr *lladdr2)
111 {
112 	if (!lladdr1 || !lladdr2) {
113 		return false;
114 	}
115 
116 	if (lladdr1->len != lladdr2->len) {
117 		return false;
118 	}
119 
120 	return !memcmp(lladdr1->addr, lladdr2->addr, lladdr1->len);
121 }
122 
123 /**
124  *
125  * @brief Set the member data of a link layer address storage structure.
126  *
127  * @param lladdr_store The link address storage structure to change.
128  * @param new_addr Array of bytes containing the link address.
129  * @param new_len Length of the link address array.
130  * This value should always be <= NET_LINK_ADDR_MAX_LENGTH.
131  */
net_linkaddr_set(struct net_linkaddr_storage * lladdr_store,uint8_t * new_addr,uint8_t new_len)132 static inline int net_linkaddr_set(struct net_linkaddr_storage *lladdr_store,
133 				   uint8_t *new_addr, uint8_t new_len)
134 {
135 	if (!lladdr_store || !new_addr) {
136 		return -EINVAL;
137 	}
138 
139 	if (new_len > NET_LINK_ADDR_MAX_LENGTH) {
140 		return -EMSGSIZE;
141 	}
142 
143 	lladdr_store->len = new_len;
144 	memcpy(lladdr_store->addr, new_addr, new_len);
145 
146 	return 0;
147 }
148 
149 /**
150  * @}
151  */
152 
153 #ifdef __cplusplus
154 }
155 #endif
156 
157 #endif /* ZEPHYR_INCLUDE_NET_NET_LINKADDR_H_ */
158