/src/libcoap/include/coap3/coap_address.h
Line | Count | Source |
1 | | /* |
2 | | * coap_address.h -- representation of network addresses |
3 | | * |
4 | | * Copyright (C) 2010-2011,2015-2016,2022-2026 Olaf Bergmann <bergmann@tzi.org> |
5 | | * |
6 | | * SPDX-License-Identifier: BSD-2-Clause |
7 | | * |
8 | | * This file is part of the CoAP library libcoap. Please see README for terms |
9 | | * of use. |
10 | | */ |
11 | | |
12 | | /** |
13 | | * @file coap_address.h |
14 | | * @brief Representation of network addresses |
15 | | */ |
16 | | |
17 | | #ifndef COAP_ADDRESS_H_ |
18 | | #define COAP_ADDRESS_H_ |
19 | | |
20 | | #include "coap3/coap_pdu.h" |
21 | | |
22 | | #ifdef __cplusplus |
23 | | extern "C" { |
24 | | #endif |
25 | | |
26 | | #if defined(WITH_LWIP) |
27 | | |
28 | | #include <lwip/ip_addr.h> |
29 | | #include <string.h> |
30 | | |
31 | | struct coap_address_t { |
32 | | uint16_t port; |
33 | | ip_addr_t addr; |
34 | | }; |
35 | | |
36 | | /** |
37 | | * Returns the port from @p addr in host byte order. |
38 | | */ |
39 | | COAP_STATIC_INLINE uint16_t |
40 | | coap_address_get_port(const coap_address_t *addr) { |
41 | | return addr->port; |
42 | | } |
43 | | |
44 | | /** |
45 | | * Sets the port field of @p addr to @p port (in host byte order). |
46 | | */ |
47 | | COAP_STATIC_INLINE void |
48 | | coap_address_set_port(coap_address_t *addr, uint16_t port) { |
49 | | addr->port = port; |
50 | | } |
51 | | |
52 | | /** |
53 | | * Sets the addr field of @p addr to 0. |
54 | | */ |
55 | | COAP_STATIC_INLINE void |
56 | | coap_address_clr_addr(coap_address_t *addr) { |
57 | | memset(&addr->addr, 0, sizeof(addr->addr)); |
58 | | } |
59 | | |
60 | | #define _coap_address_equals_impl(A, B) \ |
61 | | ((A)->port == (B)->port && \ |
62 | | (!!ip_addr_cmp(&(A)->addr,&(B)->addr))) |
63 | | |
64 | | #define _coap_address_isany_impl(A) ip_addr_isany(&(A)->addr) |
65 | | |
66 | | #elif defined(WITH_CONTIKI) |
67 | | |
68 | | #include "uip.h" |
69 | | |
70 | | struct coap_address_t { |
71 | | uip_ipaddr_t addr; |
72 | | uint16_t port; |
73 | | }; |
74 | | |
75 | | /** |
76 | | * Returns the port from @p addr in host byte order. |
77 | | */ |
78 | | COAP_STATIC_INLINE uint16_t |
79 | | coap_address_get_port(const coap_address_t *addr) { |
80 | | return uip_ntohs(addr->port); |
81 | | } |
82 | | |
83 | | /** |
84 | | * Sets the port field of @p addr to @p port (in host byte order). |
85 | | */ |
86 | | COAP_STATIC_INLINE void |
87 | | coap_address_set_port(coap_address_t *addr, uint16_t port) { |
88 | | addr->port = uip_htons(port); |
89 | | } |
90 | | |
91 | | /** |
92 | | * Sets the addr field of @p addr to 0. |
93 | | */ |
94 | | COAP_STATIC_INLINE void |
95 | | coap_address_clr_addr(coap_address_t *addr) { |
96 | | memset(&addr->addr, 0, sizeof(addr->addr)); |
97 | | } |
98 | | |
99 | | #define _coap_address_equals_impl(A,B) \ |
100 | | ((A)->port == (B)->port && \ |
101 | | uip_ipaddr_cmp(&((A)->addr),&((B)->addr))) |
102 | | |
103 | | /** @todo implementation of _coap_address_isany_impl() for Contiki */ |
104 | | #define _coap_address_isany_impl(A) 0 |
105 | | |
106 | | #define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr)) |
107 | | |
108 | | #elif defined(RIOT_VERSION) |
109 | | |
110 | | #include "net/sock.h" |
111 | | #include "net/af.h" |
112 | | #include <string.h> |
113 | | |
114 | | #ifndef INET6_ADDRSTRLEN |
115 | | #define INET6_ADDRSTRLEN IPV6_ADDR_MAX_STR_LEN |
116 | | #endif /* !INET6_ADDRSTRLEN */ |
117 | | |
118 | | struct coap_address_t { |
119 | | struct _sock_tl_ep riot; |
120 | | }; |
121 | | |
122 | | #define _coap_address_isany_impl(A) (0) |
123 | | |
124 | | #ifdef SOCK_HAS_IPV6 |
125 | | #define _coap_address_equals_impl(A, B) \ |
126 | | ((A)->riot.family == (B)->riot.family && \ |
127 | | (A)->riot.port == (B)->riot.port && \ |
128 | | memcmp(&(A)->riot, &(B)->riot, (A)->riot.family == AF_INET6 ? \ |
129 | | sizeof((A)->riot.addr.ipv6) : sizeof((A)->riot.addr.ipv4)) == 0) |
130 | | |
131 | | #define _coap_is_mcast_impl(Address) ((Address)->riot.addr.ipv6[0] == 0xff) |
132 | | #else /* !SOCK_HAS_IPV6 */ |
133 | | #define _coap_address_equals_impl(A, B) \ |
134 | | ((A)->riot.family == (B)->riot.family && \ |
135 | | (A)->riot.port == (B)->riot.port && \ |
136 | | memcmp(&(A)->riot, &(B)->riot, sizeof((A)->riot.addr.ipv4)) == 0) |
137 | | |
138 | | #define _coap_is_mcast_impl(Address) (0) |
139 | | #endif /* !SOCK_HAS_IPV6 */ |
140 | | |
141 | | /** |
142 | | * Returns the port from @p addr in host byte order. |
143 | | */ |
144 | | COAP_STATIC_INLINE uint16_t |
145 | | coap_address_get_port(const coap_address_t *addr) { |
146 | | return addr->riot.port; |
147 | | } |
148 | | |
149 | | /** |
150 | | * Sets the port field of @p addr to @p port (in host byte order). |
151 | | */ |
152 | | COAP_STATIC_INLINE void |
153 | | coap_address_set_port(coap_address_t *addr, uint16_t port) { |
154 | | addr->riot.port = port; |
155 | | } |
156 | | |
157 | | /** |
158 | | * Sets the addr field of @p addr to 0. |
159 | | */ |
160 | | COAP_STATIC_INLINE void |
161 | | coap_address_clr_addr(coap_address_t *addr) { |
162 | | memset(&addr->riot.addr, 0, sizeof(addr->riot.addr)); |
163 | | } |
164 | | |
165 | | #else /* ! WITH_LWIP && ! WITH_CONTIKI && ! RIOT_VERSION */ |
166 | | |
167 | | #if COAP_AF_LLC_SUPPORT |
168 | | |
169 | | /* Including net/if.h after linux/llc.h results in redefinitions of numerous |
170 | | * symbols. |
171 | | */ |
172 | | #include <net/if.h> |
173 | | #include <linux/llc.h> |
174 | | |
175 | | /* 00:11:22:33:44:55 */ |
176 | 0 | #define HW_ADDRSTRLEN 17 |
177 | | /* llc[00:11:22:33:44:55]:DC */ |
178 | 0 | #define LLC_HOST_LEN (4 + HW_ADDRSTRLEN + 4) |
179 | | |
180 | | #endif /* COAP_AF_LLC_SUPPORT */ |
181 | | |
182 | | #ifdef _WIN32 |
183 | | #define sa_family_t short |
184 | | #endif /* _WIN32 */ |
185 | | |
186 | 0 | #define COAP_UNIX_PATH_MAX (sizeof(struct sockaddr_in6) - sizeof(sa_family_t)) |
187 | | |
188 | | struct coap_sockaddr_un { |
189 | | sa_family_t sun_family; /* AF_UNIX */ |
190 | | char sun_path[COAP_UNIX_PATH_MAX]; /* pathname max 26 with NUL byte */ |
191 | | }; |
192 | | |
193 | | /** Multi-purpose address abstraction */ |
194 | | struct coap_address_t { |
195 | | socklen_t size; /**< size of addr */ |
196 | | union { |
197 | | struct sockaddr sa; |
198 | | struct sockaddr_in sin; |
199 | | struct sockaddr_in6 sin6; |
200 | | struct coap_sockaddr_un cun; /* CoAP shortened special */ |
201 | | #if COAP_AF_LLC_SUPPORT |
202 | | struct sockaddr_llc llc; |
203 | | #endif /* COAP_AF_LLC_SUPPORT */ |
204 | | } addr; |
205 | | }; |
206 | | |
207 | | /** |
208 | | * Returns the port from @p addr in host byte order. |
209 | | */ |
210 | | uint16_t coap_address_get_port(const coap_address_t *addr); |
211 | | |
212 | | /** |
213 | | * Set the port field of @p addr to @p port (in host byte order). |
214 | | */ |
215 | | void coap_address_set_port(coap_address_t *addr, uint16_t port); |
216 | | |
217 | | /** |
218 | | * Sets the addr field of @p addr to 0. |
219 | | */ |
220 | | void coap_address_clr_addr(coap_address_t *addr); |
221 | | |
222 | | /** |
223 | | * Compares given address objects @p a and @p b. This function returns @c 1 if |
224 | | * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be |
225 | | * @c NULL; |
226 | | */ |
227 | | int coap_address_equals(const coap_address_t *a, const coap_address_t *b); |
228 | | |
229 | | int _coap_address_isany_impl(const coap_address_t *a); |
230 | | #endif /* ! WITH_LWIP && ! WITH_CONTIKI */ |
231 | | |
232 | | /** Resolved addresses information */ |
233 | | typedef struct coap_addr_info_t { |
234 | | struct coap_addr_info_t *next; /**< Next entry in the chain */ |
235 | | coap_uri_scheme_t scheme; /**< CoAP scheme to use */ |
236 | | coap_proto_t proto; /**< CoAP protocol to use */ |
237 | | coap_address_t addr; /**< The address to connect / bind to */ |
238 | | } coap_addr_info_t; |
239 | | |
240 | | /** |
241 | | * Determine and set up scheme_hint_bits for a server that can be used in |
242 | | * a call to coap_resolve_address_info(). |
243 | | * |
244 | | * @param have_pki_psk Set to @c 1 if PSK/PKI information is known else @c 0. |
245 | | * @param ws_check Set to @c 1 is WebSockets is to be included in the list |
246 | | * else @c 0. |
247 | | * @param use_proto Set to the appropriate protocol to use for Unix/LLC |
248 | | * sockets, else set to COAP_PROTO_NONE for INET / INET6 |
249 | | * sockets. |
250 | | * @return A bit mask of the available CoAP protocols (can be @c 0 if none) |
251 | | * suitable for passing to coap_resolve_address_info(). |
252 | | */ |
253 | | uint32_t coap_get_available_scheme_hint_bits(int have_pki_psk, int ws_check, |
254 | | coap_proto_t use_proto); |
255 | | |
256 | | /** |
257 | | * coap_resolve_type_t values |
258 | | */ |
259 | | typedef enum coap_resolve_type_t { |
260 | | COAP_RESOLVE_TYPE_LOCAL, /**< local side of session */ |
261 | | COAP_RESOLVE_TYPE_REMOTE, /**< remote side of session */ |
262 | | } coap_resolve_type_t; |
263 | | |
264 | | /** |
265 | | * Resolve the specified @p address into a set of coap_address_t that can |
266 | | * be used to bind() (local) or connect() (remote) to. |
267 | | * |
268 | | * Note: coap_startup() must have been called first, otherwise @c NULL |
269 | | * is returned. |
270 | | * |
271 | | * @param address The Address to resolve. |
272 | | * @param port The unsecured protocol port to use. |
273 | | * @param secure_port The secured protocol port to use. |
274 | | * @param ws_port The unsecured WebSockets port to use. |
275 | | * @param ws_secure_port The secured WebSockets port to use. |
276 | | * @param ai_hints_flags AI_* Hint flags to use for internal getaddrinfo(). |
277 | | * @param scheme_hint_bits Which schemes to return information for. One or |
278 | | * more of COAP_URI_SCHEME_*_BIT or'd together. |
279 | | * @param type COAP_ADDRESS_TYPE_LOCAL or COAP_ADDRESS_TYPE_REMOTE |
280 | | * |
281 | | * @return One or more linked sets of coap_addr_info_t or @c NULL if error. |
282 | | */ |
283 | | COAP_API coap_addr_info_t *coap_resolve_address_info(const coap_str_const_t *address, |
284 | | uint16_t port, |
285 | | uint16_t secure_port, |
286 | | uint16_t ws_port, |
287 | | uint16_t ws_secure_port, |
288 | | int ai_hints_flags, |
289 | | int scheme_hint_bits, |
290 | | coap_resolve_type_t type); |
291 | | |
292 | | /** |
293 | | * Free off the one or more linked sets of coap_addr_info_t returned from |
294 | | * coap_resolve_address_info(). |
295 | | * |
296 | | * @param info_list The set of coap_addr_info_t to free off. |
297 | | */ |
298 | | void coap_free_address_info(coap_addr_info_t *info_list); |
299 | | |
300 | | /** |
301 | | * Resets the given coap_address_t object @p addr to its default values. In |
302 | | * particular, the member size must be initialized to the available size for |
303 | | * storing addresses. |
304 | | * |
305 | | * @param addr The coap_address_t object to initialize. |
306 | | */ |
307 | | void coap_address_init(coap_address_t *addr); |
308 | | |
309 | | /** |
310 | | * Copy the parsed unix domain host into coap_address_t structure |
311 | | * translating %2F into / on the way. All other fields set as appropriate. |
312 | | * |
313 | | * @param addr coap_address_t to update. |
314 | | * @param host The parsed host from the CoAP URI with potential %2F encoding. |
315 | | * @param host_len The length of the parsed host from the CoAP URI with |
316 | | * potential %2F encoding. |
317 | | * |
318 | | * @return @c 1 success, @c 0 failure. |
319 | | */ |
320 | | int coap_address_set_unix_domain(coap_address_t *addr, |
321 | | const uint8_t *host, size_t host_len); |
322 | | |
323 | | /** |
324 | | * Copy the parsed LLC host into @p addr, setting other fields as appropriate. |
325 | | * |
326 | | * @param addr coap_address_t to update. |
327 | | * @param host The parsed host from the CoAP URI. |
328 | | * @param host_len The length of the parsed host from the CoAP URI. |
329 | | * |
330 | | * @return @c 1 success, @c 0 failure. |
331 | | */ |
332 | | int coap_address_set_llc(coap_address_t *addr, |
333 | | const uint8_t *host, size_t host_len); |
334 | | |
335 | | /* Convenience function to copy IPv6 addresses without garbage. */ |
336 | | #if defined(WITH_LWIP) || defined(WITH_CONTIKI) || defined(RIOT_VERSION) |
337 | | COAP_STATIC_INLINE void |
338 | | coap_address_copy(coap_address_t *dst, const coap_address_t *src) { |
339 | | memcpy(dst, src, sizeof(coap_address_t)); |
340 | | } |
341 | | #else /* ! WITH_LWIP && ! WITH_CONTIKI */ |
342 | | void coap_address_copy(coap_address_t *dst, const coap_address_t *src); |
343 | | #endif /* ! WITH_LWIP && ! WITH_CONTIKI */ |
344 | | |
345 | | #if defined(WITH_LWIP) || defined(WITH_CONTIKI) || defined(RIOT_VERSION) |
346 | | /** |
347 | | * Compares given address objects @p a and @p b. This function returns @c 1 if |
348 | | * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be |
349 | | * @c NULL; |
350 | | */ |
351 | | COAP_STATIC_INLINE int |
352 | | coap_address_equals(const coap_address_t *a, const coap_address_t *b) { |
353 | | if (a && b) |
354 | | return _coap_address_equals_impl(a, b); |
355 | | return 0; |
356 | | } |
357 | | #endif |
358 | | |
359 | | /** |
360 | | * Checks if given address object @p a denotes the wildcard address. This |
361 | | * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p |
362 | | * a must not be @c NULL; |
363 | | */ |
364 | | COAP_STATIC_INLINE int |
365 | 0 | coap_address_isany(const coap_address_t *a) { |
366 | 0 | if (a) |
367 | 0 | return _coap_address_isany_impl(a); |
368 | 0 | return 0; |
369 | 0 | } Unexecuted instantiation: async_target.c:coap_address_isany Unexecuted instantiation: coap_fuzz_helper.c:coap_address_isany Unexecuted instantiation: coap_address.c:coap_address_isany Unexecuted instantiation: coap_async.c:coap_address_isany Unexecuted instantiation: coap_debug.c:coap_address_isany Unexecuted instantiation: coap_encode.c:coap_address_isany Unexecuted instantiation: coap_event.c:coap_address_isany Unexecuted instantiation: coap_io.c:coap_address_isany Unexecuted instantiation: coap_io_posix.c:coap_address_isany Unexecuted instantiation: coap_mem.c:coap_address_isany Unexecuted instantiation: coap_net.c:coap_address_isany Unexecuted instantiation: coap_netif.c:coap_address_isany Unexecuted instantiation: coap_openssl.c:coap_address_isany Unexecuted instantiation: coap_option.c:coap_address_isany Unexecuted instantiation: coap_oscore.c:coap_address_isany Unexecuted instantiation: coap_pdu.c:coap_address_isany Unexecuted instantiation: coap_proxy.c:coap_address_isany Unexecuted instantiation: coap_prng.c:coap_address_isany Unexecuted instantiation: coap_resource.c:coap_address_isany Unexecuted instantiation: coap_session.c:coap_address_isany Unexecuted instantiation: coap_str.c:coap_address_isany Unexecuted instantiation: coap_strm_posix.c:coap_address_isany Unexecuted instantiation: coap_subscribe.c:coap_address_isany Unexecuted instantiation: coap_time.c:coap_address_isany Unexecuted instantiation: coap_uri.c:coap_address_isany Unexecuted instantiation: coap_ws.c:coap_address_isany Unexecuted instantiation: oscore.c:coap_address_isany Unexecuted instantiation: oscore_cbor.c:coap_address_isany Unexecuted instantiation: oscore_context.c:coap_address_isany Unexecuted instantiation: oscore_cose.c:coap_address_isany Unexecuted instantiation: oscore_crypto.c:coap_address_isany Unexecuted instantiation: coap_block.c:coap_address_isany Unexecuted instantiation: coap_cache.c:coap_address_isany Unexecuted instantiation: coap_dgrm_posix.c:coap_address_isany Unexecuted instantiation: coap_dtls.c:coap_address_isany Unexecuted instantiation: coap_layers.c:coap_address_isany |
370 | | |
371 | | #if !defined(WITH_CONTIKI) && !defined(RIOT_VERSION) |
372 | | |
373 | | /** |
374 | | * Checks if given address @p a denotes a multicast address. This function |
375 | | * returns @c 1 if @p a is multicast, @c 0 otherwise. |
376 | | */ |
377 | | int coap_is_mcast(const coap_address_t *a); |
378 | | |
379 | | /** |
380 | | * Checks if given address @p a denotes a broadcast address. This function |
381 | | * returns @c 1 if @p a is broadcast, @c 0 otherwise. |
382 | | */ |
383 | | int coap_is_bcast(const coap_address_t *a); |
384 | | |
385 | | /** |
386 | | * Checks if given address @p a denotes a AF_UNIX address. This function |
387 | | * returns @c 1 if @p a is of type AF_UNIX, @c 0 otherwise. |
388 | | */ |
389 | | int coap_is_af_unix(const coap_address_t *a); |
390 | | |
391 | | /** |
392 | | * Checks if given address @p a denotes an AF_LLC address. This function |
393 | | * returns @c 1 if @p a is of type AF_LLC, @c 0 otherwise. |
394 | | */ |
395 | | int coap_is_af_llc(const coap_address_t *a); |
396 | | |
397 | | #else /* WITH_CONTIKI || RIOT_VERSION */ |
398 | | |
399 | | /** |
400 | | * Checks if given address @p a denotes a multicast address. This function |
401 | | * returns @c 1 if @p a is multicast, @c 0 otherwise. |
402 | | */ |
403 | | COAP_STATIC_INLINE int |
404 | | coap_is_mcast(const coap_address_t *a) { |
405 | | return a && _coap_is_mcast_impl(a); |
406 | | } |
407 | | |
408 | | /** |
409 | | * Checks if given address @p a denotes a AF_UNIX address. This function |
410 | | * returns @c 1 if @p a is of type AF_UNIX, @c 0 otherwise. |
411 | | */ |
412 | | COAP_STATIC_INLINE int |
413 | | coap_is_af_unix(const coap_address_t *a) { |
414 | | (void)a; |
415 | | return 0; |
416 | | } |
417 | | |
418 | | #endif /* WITH_CONTIKI || RIOT_VERSION */ |
419 | | |
420 | | #ifdef __cplusplus |
421 | | } |
422 | | #endif |
423 | | |
424 | | #endif /* COAP_ADDRESS_H_ */ |