• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * coap_address.h -- representation of network addresses
3  *
4  * Copyright (C) 2010-2011,2015-2016,2022-2023 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 <assert.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include "libcoap.h"
25 
26 #include "coap3/coap_pdu.h"
27 
28 #if defined(WITH_LWIP)
29 
30 #include <lwip/ip_addr.h>
31 
32 struct coap_address_t {
33   uint16_t port;
34   ip_addr_t addr;
35 };
36 
37 /**
38  * Returns the port from @p addr in host byte order.
39  */
40 COAP_STATIC_INLINE uint16_t
coap_address_get_port(const coap_address_t * addr)41 coap_address_get_port(const coap_address_t *addr) {
42   return addr->port;
43 }
44 
45 /**
46  * Sets the port field of @p addr to @p port (in host byte order).
47  */
48 COAP_STATIC_INLINE void
coap_address_set_port(coap_address_t * addr,uint16_t port)49 coap_address_set_port(coap_address_t *addr, uint16_t port) {
50   addr->port = port;
51 }
52 
53 #define _coap_address_equals_impl(A, B) \
54   ((A)->port == (B)->port &&        \
55    (!!ip_addr_cmp(&(A)->addr,&(B)->addr)))
56 
57 #define _coap_address_isany_impl(A)  ip_addr_isany(&(A)->addr)
58 
59 #define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr)
60 
61 #ifdef COAP_SUPPORT_SOCKET_BROADCAST
62 #define _coap_is_bcast_impl(Address) ip_addr_isbroadcast(&(Address)->addr)
63 #endif
64 
65 #elif defined(WITH_CONTIKI)
66 
67 #include "uip.h"
68 
69 struct coap_address_t {
70   uip_ipaddr_t addr;
71   uint16_t port;
72 };
73 
74 /**
75  * Returns the port from @p addr in host byte order.
76  */
77 COAP_STATIC_INLINE uint16_t
coap_address_get_port(const coap_address_t * addr)78 coap_address_get_port(const coap_address_t *addr) {
79   return uip_ntohs(addr->port);
80 }
81 
82 /**
83  * Sets the port field of @p addr to @p port (in host byte order).
84  */
85 COAP_STATIC_INLINE void
coap_address_set_port(coap_address_t * addr,uint16_t port)86 coap_address_set_port(coap_address_t *addr, uint16_t port) {
87   addr->port = uip_htons(port);
88 }
89 
90 #define _coap_address_equals_impl(A,B) \
91   ((A)->port == (B)->port &&     \
92    uip_ipaddr_cmp(&((A)->addr),&((B)->addr)))
93 
94 /** @todo implementation of _coap_address_isany_impl() for Contiki */
95 #define _coap_address_isany_impl(A)  0
96 
97 #define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr))
98 
99 #ifdef COAP_SUPPORT_SOCKET_BROADCAST
100 #define _coap_is_bcast_impl(Address) (0)
101 #endif
102 
103 #else /* ! WITH_LWIP && ! WITH_CONTIKI */
104 
105 #ifdef _WIN32
106 #define sa_family_t short
107 #endif /* _WIN32 */
108 
109 #define COAP_UNIX_PATH_MAX   (sizeof(struct sockaddr_in6) - sizeof(sa_family_t))
110 
111 struct coap_sockaddr_un {
112   sa_family_t sun_family; /* AF_UNIX */
113   char sun_path[COAP_UNIX_PATH_MAX];   /* pathname max 26 with NUL byte */
114 };
115 
116 /** Multi-purpose address abstraction */
117 struct coap_address_t {
118   socklen_t size;           /**< size of addr */
119   union {
120     struct sockaddr         sa;
121     struct sockaddr_in      sin;
122     struct sockaddr_in6     sin6;
123     struct coap_sockaddr_un cun; /* CoAP shortened special */
124   } addr;
125 };
126 
127 /**
128  * Returns the port from @p addr in host byte order.
129  */
130 uint16_t coap_address_get_port(const coap_address_t *addr);
131 
132 /**
133  * Set the port field of @p addr to @p port (in host byte order).
134  */
135 void coap_address_set_port(coap_address_t *addr, uint16_t port);
136 
137 /**
138  * Compares given address objects @p a and @p b. This function returns @c 1 if
139  * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
140  * @c NULL;
141  */
142 int coap_address_equals(const coap_address_t *a, const coap_address_t *b);
143 
144 int _coap_address_isany_impl(const coap_address_t *a);
145 #endif /* ! WITH_LWIP && ! WITH_CONTIKI */
146 
147 /** Resolved addresses information */
148 typedef struct coap_addr_info_t {
149   struct coap_addr_info_t *next; /**< Next entry in the chain */
150   coap_uri_scheme_t scheme;      /**< CoAP scheme to use */
151   coap_proto_t proto;            /**< CoAP protocol to use */
152   coap_address_t addr;           /**< The address to connect / bind to */
153 } coap_addr_info_t;
154 
155 /**
156  * Determine and set up scheme_hint_bits for a server that can be used in
157  * a call to coap_resolve_address_info().
158  *
159  * @param have_pki_psk Set to @c 1 if PSK/PKI information is known else @c 0.
160  * @param ws_check Set to @c 1 is WebSockets is to be included in the list
161  *                  else @c 0.
162  * @param use_unix_proto Set to the appropriate protocol to use for Unix
163  *                       sockets, else set to COAP_PROTO_NONE for INET / INET6
164  *                       sockets.
165  * @return A bit mask of the available CoAP protocols (can be @c 0 if none)
166  *         suitable for passing to coap_resolve_address_info().
167  */
168 uint32_t coap_get_available_scheme_hint_bits(int have_pki_psk, int ws_check,
169                                              coap_proto_t use_unix_proto);
170 
171 /**
172  * coap_resolve_type_t values
173  */
174 typedef enum coap_resolve_type_t {
175   COAP_RESOLVE_TYPE_LOCAL,   /**< local side of session */
176   COAP_RESOLVE_TYPE_REMOTE,  /**< remote side of session */
177 } coap_resolve_type_t;
178 
179 /**
180  * Resolve the specified @p address into a set of coap_address_t that can
181  * be used to bind() (local) or connect() (remote) to.
182  *
183  * @param address The Address to resolve.
184  * @param port    The unsecured protocol port to use.
185  * @param secure_port The secured protocol port to use.
186  * @param ws_port The unsecured WebSockets port to use.
187  * @param ws_secure_port The secured WebSockets port to use.
188  * @param ai_hints_flags AI_* Hint flags to use for internal getaddrinfo().
189  * @param scheme_hint_bits Which schemes to return information for. One or
190  *                         more of COAP_URI_SCHEME_*_BIT or'd together.
191  * @param type COAP_ADDRESS_TYPE_LOCAL or COAP_ADDRESS_TYPE_REMOTE
192  *
193  * @return One or more linked sets of coap_addr_info_t or @c NULL if error.
194  */
195 coap_addr_info_t *coap_resolve_address_info(const coap_str_const_t *address,
196                                             uint16_t port,
197                                             uint16_t secure_port,
198                                             uint16_t ws_port,
199                                             uint16_t ws_secure_port,
200                                             int ai_hints_flags,
201                                             int scheme_hint_bits,
202                                             coap_resolve_type_t type);
203 
204 /**
205  * Free off the one or more linked sets of coap_addr_info_t returned from
206  * coap_resolve_address_info().
207  *
208  * @param info_list The set of coap_addr_info_t to free off.
209  */
210 void coap_free_address_info(coap_addr_info_t *info_list);
211 
212 /**
213  * Resets the given coap_address_t object @p addr to its default values. In
214  * particular, the member size must be initialized to the available size for
215  * storing addresses.
216  *
217  * @param addr The coap_address_t object to initialize.
218  */
219 void coap_address_init(coap_address_t *addr);
220 
221 /**
222  * Convert the given coap_address_t object @p addr from binary to text form.
223  * Write the result to the destination space @p dst of length @p len.
224  */
225 void coap_address_ntop(const coap_address_t *addr, char *dst, int len);
226 
227 /**
228  * Copy the parsed unix domain host into coap_address_t structure
229  * translating %2F into / on the way. All other fields set as appropriate.
230  *
231  * @param addr coap_address_t to update.
232  * @param host The parsed host from the CoAP URI with potential %2F encoding.
233  * @param host_len The length of the parsed host from the CoAP URI with
234  *                 potential %2F encoding.
235  *
236  * @return @c 1 success, @c 0 failure.
237  */
238 int coap_address_set_unix_domain(coap_address_t *addr,
239                                  const uint8_t *host, size_t host_len);
240 
241 /* Convenience function to copy IPv6 addresses without garbage. */
242 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
243 COAP_STATIC_INLINE void
coap_address_copy(coap_address_t * dst,const coap_address_t * src)244 coap_address_copy(coap_address_t *dst, const coap_address_t *src) {
245   memcpy(dst, src, sizeof(coap_address_t));
246 }
247 #else /* ! WITH_LWIP && ! WITH_CONTIKI */
248 void coap_address_copy(coap_address_t *dst, const coap_address_t *src);
249 #endif /* ! WITH_LWIP && ! WITH_CONTIKI */
250 
251 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
252 /**
253  * Compares given address objects @p a and @p b. This function returns @c 1 if
254  * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
255  * @c NULL;
256  */
257 COAP_STATIC_INLINE int
coap_address_equals(const coap_address_t * a,const coap_address_t * b)258 coap_address_equals(const coap_address_t *a, const coap_address_t *b) {
259   assert(a);
260   assert(b);
261   return _coap_address_equals_impl(a, b);
262 }
263 #endif
264 
265 /**
266  * Checks if given address object @p a denotes the wildcard address. This
267  * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p
268  * a must not be @c NULL;
269  */
270 COAP_STATIC_INLINE int
coap_address_isany(const coap_address_t * a)271 coap_address_isany(const coap_address_t *a) {
272   assert(a);
273   return _coap_address_isany_impl(a);
274 }
275 
276 #if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
277 
278 /**
279  * Checks if given address @p a denotes a multicast address. This function
280  * returns @c 1 if @p a is multicast, @c 0 otherwise.
281  */
282 int coap_is_mcast(const coap_address_t *a);
283 
284 /**
285  * Checks if given address @p a denotes a broadcast address. This function
286  * returns @c 1 if @p a is broadcast, @c 0 otherwise.
287  */
288 int coap_is_bcast(const coap_address_t *a);
289 
290 /**
291  * Checks if given address @p a denotes a AF_UNIX address. This function
292  * returns @c 1 if @p a is of type AF_UNIX, @c 0 otherwise.
293  */
294 int coap_is_af_unix(const coap_address_t *a);
295 
296 #else /* WITH_LWIP || WITH_CONTIKI */
297 
298 /**
299  * Checks if given address @p a denotes a multicast address. This function
300  * returns @c 1 if @p a is multicast, @c 0 otherwise.
301  */
302 COAP_STATIC_INLINE int
coap_is_mcast(const coap_address_t * a)303 coap_is_mcast(const coap_address_t *a) {
304   return a && _coap_is_mcast_impl(a);
305 }
306 
307 /**
308  * Checks if given address @p a denotes a AF_UNIX address. This function
309  * returns @c 1 if @p a is of type AF_UNIX, @c 0 otherwise.
310  */
311 COAP_STATIC_INLINE int
coap_is_af_unix(const coap_address_t * a)312 coap_is_af_unix(const coap_address_t *a) {
313   (void)a;
314   return 0;
315 }
316 
317 #ifdef COAP_SUPPORT_SOCKET_BROADCAST
318 COAP_STATIC_INLINE int
coap_is_bcast(const coap_address_t * a)319 coap_is_bcast(const coap_address_t *a) {
320   return a && _coap_is_bcast_impl(a);
321 }
322 #endif
323 
324 #endif /* WITH_LWIP || WITH_CONTIKI */
325 
326 #endif /* COAP_ADDRESS_H_ */
327