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