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 32struct 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 */ 40COAP_STATIC_INLINE uint16_t 41coap_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 */ 48COAP_STATIC_INLINE void 49coap_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 69struct 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 */ 77COAP_STATIC_INLINE uint16_t 78coap_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 */ 85COAP_STATIC_INLINE void 86coap_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 111struct 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 */ 117struct 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 */ 130uint16_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 */ 135void 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 */ 142int coap_address_equals(const coap_address_t *a, const coap_address_t *b); 143 144int _coap_address_isany_impl(const coap_address_t *a); 145#endif /* ! WITH_LWIP && ! WITH_CONTIKI */ 146 147/** Resolved addresses information */ 148typedef 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 */ 168uint32_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 */ 174typedef 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 */ 195coap_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 */ 210void 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 */ 219void 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 */ 225void 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 */ 238int 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) 243COAP_STATIC_INLINE void 244coap_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 */ 248void 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 */ 257COAP_STATIC_INLINE int 258coap_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 */ 270COAP_STATIC_INLINE int 271coap_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 */ 282int 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 */ 288int 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 */ 294int 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 */ 302COAP_STATIC_INLINE int 303coap_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 */ 311COAP_STATIC_INLINE int 312coap_is_af_unix(const coap_address_t *a) { 313 (void)a; 314 return 0; 315} 316 317#ifdef COAP_SUPPORT_SOCKET_BROADCAST 318COAP_STATIC_INLINE int 319coap_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