Coverage Report

Created: 2026-10-17 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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_ */