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