libcoap 4.3.2rc1
Loading...
Searching...
No Matches
coap_address.c
Go to the documentation of this file.
1/* coap_address.c -- representation of network addresses
2 *
3 * Copyright (C) 2015-2016,2019-2023 Olaf Bergmann <bergmann@tzi.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10
16#include "coap3/coap_internal.h"
17
18#if !defined(WITH_CONTIKI) && !defined(WITH_LWIP)
19#ifdef HAVE_ARPA_INET_H
20#include <arpa/inet.h>
21#endif
22#ifdef HAVE_NETINET_IN_H
23#include <netinet/in.h>
24#endif
25#ifdef HAVE_SYS_SOCKET_H
26#include <sys/socket.h>
27#endif
28#ifdef HAVE_WS2TCPIP_H
29#include <ws2tcpip.h>
30#endif
31
32#ifdef RIOT_VERSION
33/* FIXME */
34#define IN_MULTICAST(Address) (0)
35#endif /* RIOT_VERSION */
36
37uint16_t
39 assert(addr != NULL);
40 switch (addr->addr.sa.sa_family) {
41#if COAP_IPV4_SUPPORT
42 case AF_INET:
43 return ntohs(addr->addr.sin.sin_port);
44#endif /* COAP_IPV4_SUPPORT */
45#if COAP_IPV6_SUPPORT
46 case AF_INET6:
47 return ntohs(addr->addr.sin6.sin6_port);
48#endif /* COAP_IPV6_SUPPORT */
49 default: /* undefined */
50 ;
51 }
52 return 0;
53}
54
55void
57 assert(addr != NULL);
58 switch (addr->addr.sa.sa_family) {
59#if COAP_IPV4_SUPPORT
60 case AF_INET:
61 addr->addr.sin.sin_port = htons(port);
62 break;
63#endif /* COAP_IPV4_SUPPORT */
64#if COAP_IPV6_SUPPORT
65 case AF_INET6:
66 addr->addr.sin6.sin6_port = htons(port);
67 break;
68#endif /* COAP_IPV6_SUPPORT */
69 default: /* undefined */
70 ;
71 }
72}
73
74int
76 assert(a);
77 assert(b);
78
79 if (a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family)
80 return 0;
81
82 /* need to compare only relevant parts of sockaddr_in6 */
83 switch (a->addr.sa.sa_family) {
84#if COAP_IPV4_SUPPORT
85 case AF_INET:
86 return a->addr.sin.sin_port == b->addr.sin.sin_port &&
87 memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr,
88 sizeof(struct in_addr)) == 0;
89#endif /* COAP_IPV4_SUPPORT */
90#if COAP_IPV6_SUPPORT
91 case AF_INET6:
92 return a->addr.sin6.sin6_port == b->addr.sin6.sin6_port &&
93 memcmp(&a->addr.sin6.sin6_addr, &b->addr.sin6.sin6_addr,
94 sizeof(struct in6_addr)) == 0;
95#endif /* COAP_IPV6_SUPPORT */
96 default: /* fall through and signal error */
97 ;
98 }
99 return 0;
100}
101
102int
104#if COAP_AF_UNIX_SUPPORT
105 return a->addr.sa.sa_family == AF_UNIX;
106#else /* ! COAP_AF_UNIX_SUPPORT */
107 (void)a;
108 return 0;
109#endif /* ! COAP_AF_UNIX_SUPPORT */
110}
111
112int
114 if (!a)
115 return 0;
116
117 /* Treat broadcast in same way as multicast */
118 if (coap_is_bcast(a))
119 return 1;
120
121 switch (a->addr.sa.sa_family) {
122#if COAP_IPV4_SUPPORT
123 case AF_INET:
124 return IN_MULTICAST(ntohl(a->addr.sin.sin_addr.s_addr));
125#endif /* COAP_IPV4_SUPPORT */
126#if COAP_IPV6_SUPPORT
127 case AF_INET6:
128#if COAP_IPV4_SUPPORT
129 return IN6_IS_ADDR_MULTICAST(&a->addr.sin6.sin6_addr) ||
130 (IN6_IS_ADDR_V4MAPPED(&a->addr.sin6.sin6_addr) &&
131 IN_MULTICAST(ntohl(a->addr.sin6.sin6_addr.s6_addr[12])));
132#else /* ! COAP_IPV4_SUPPORT */
133 return a->addr.sin6.sin6_addr.s6_addr[0] == 0xff;
134#endif /* ! COAP_IPV4_SUPPORT */
135#endif /* COAP_IPV6_SUPPORT */
136 default: /* fall through and signal not multicast */
137 ;
138 }
139 return 0;
140}
141
142#if !defined(WIN32) && !defined(ESPIDF_VERSION)
143
144#ifndef COAP_BCST_CNT
145#define COAP_BCST_CNT 6
146#endif /* COAP_BCST_CNT */
147
148/* How frequently to refresh the list of valid IPv4 broadcast addresses */
149#ifndef COAP_BCST_REFRESH_SECS
150#define COAP_BCST_REFRESH_SECS 30
151#endif /* COAP_BCST_REFRESH_SECS */
152
153#if COAP_IPV4_SUPPORT
154static int bcst_cnt = -1;
155static coap_tick_t last_refresh;
156static struct in_addr b_ipv4[COAP_BCST_CNT];
157#endif /* COAP_IPV4_SUPPORT */
158
159#include <net/if.h>
160#include <ifaddrs.h>
161
162int
164#if COAP_IPV4_SUPPORT
165 struct in_addr ipv4;
166 int i;
167 coap_tick_t now;
168#endif /* COAP_IPV4_SUPPORT */
169
170 if (!a)
171 return 0;
172
173 switch (a->addr.sa.sa_family) {
174#if COAP_IPV4_SUPPORT
175 case AF_INET:
176 ipv4.s_addr = a->addr.sin.sin_addr.s_addr;
177 break;
178#endif /* COAP_IPV4_SUPPORT */
179#if COAP_IPV6_SUPPORT
180 case AF_INET6:
181#if COAP_IPV4_SUPPORT
182 if (IN6_IS_ADDR_V4MAPPED(&a->addr.sin6.sin6_addr)) {
183 memcpy(&ipv4, &a->addr.sin6.sin6_addr.s6_addr[12], sizeof(ipv4));
184 break;
185 }
186#endif /* COAP_IPV4_SUPPORT */
187 /* IPv6 does not support broadcast */
188 return 0;
189#endif /* COAP_IPV6_SUPPORT */
190 default:
191 return 0;
192 }
193#if COAP_IPV4_SUPPORT
194 if (ipv4.s_addr == INADDR_BROADCAST)
195 return 1;
196
197 coap_ticks(&now);
198 if (bcst_cnt == -1 ||
199 (now - last_refresh) > (COAP_BCST_REFRESH_SECS * COAP_TICKS_PER_SECOND)) {
200 /* Determine the list of broadcast interfaces */
201 struct ifaddrs *ifa = NULL;
202 struct ifaddrs *ife;
203
204 if (getifaddrs(&ifa) != 0) {
205 coap_log_warn("coap_is_bcst: Cannot determine any broadcast addresses\n");
206 return 0;
207 }
208 bcst_cnt = 0;
209 last_refresh = now;
210 ife = ifa;
211 while (ife && bcst_cnt < COAP_BCST_CNT) {
212 if (ife->ifa_addr->sa_family == AF_INET &&
213 ife->ifa_flags & IFF_BROADCAST) {
214 b_ipv4[bcst_cnt].s_addr = ((struct sockaddr_in *)ife->ifa_broadaddr)->sin_addr.s_addr;
215 bcst_cnt++;
216 }
217 ife = ife->ifa_next;
218 }
219 if (ife) {
220 coap_log_warn("coap_is_bcst: Insufficient space for broadcast addresses\n");
221 }
222 freeifaddrs(ifa);
223 }
224 for (i = 0; i < bcst_cnt; i++) {
225 if (ipv4.s_addr == b_ipv4[i].s_addr)
226 return 1;
227 }
228 return 0;
229#endif /* COAP_IPV4_SUPPORT */
230}
231#else /* WIN32 || ESPIDF_VERSION */
232int
234 (void)a;
235 return 0;
236}
237#endif /* WIN32 || ESPIDF_VERSION */
238
239#endif /* !defined(WITH_CONTIKI) && !defined(WITH_LWIP) */
240
241void
243 assert(addr);
244 memset(addr, 0, sizeof(coap_address_t));
245#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
246 /* lwip and Contiki have constant address sizes and don't need the .size part */
247 addr->size = sizeof(addr->addr);
248#endif
249}
250
251int
253 const uint8_t *host, size_t host_len) {
254#if COAP_AF_UNIX_SUPPORT
255 size_t i;
256 size_t ofs = 0;
257
258 coap_address_init(addr);
259 addr->addr.cun.sun_family = AF_UNIX;
260 for (i = 0; i < host_len; i++) {
261 if ((host_len - i) >= 3 && host[i] == '%' && host[i+1] == '2' &&
262 (host[i+2] == 'F' || host[i+2] == 'f')) {
263 addr->addr.cun.sun_path[ofs++] = '/';
264 i += 2;
265 } else {
266 addr->addr.cun.sun_path[ofs++] = host[i];
267 }
268 if (ofs == COAP_UNIX_PATH_MAX)
269 break;
270 }
271 if (ofs < COAP_UNIX_PATH_MAX)
272 addr->addr.cun.sun_path[ofs] = '\000';
273 else
274 addr->addr.cun.sun_path[ofs-1] = '\000';
275 return 1;
276#else /* ! COAP_AF_UNIX_SUPPORT */
277 (void)addr;
278 (void)host;
279 (void)host_len;
280 return 0;
281#endif /* ! COAP_AF_UNIX_SUPPORT */
282}
283
284#if !defined(WITH_CONTIKI)
285static void
286update_port(coap_address_t *addr, uint16_t port, uint16_t default_port,
287 int update_port0) {
288 /* Client target port must be set if default of 0 */
289 if (port == 0 && update_port0)
290 port = default_port;
291
292 coap_address_set_port(addr, port);
293 return;
294}
295
296#ifdef HAVE_NETDB_H
297#include <netdb.h>
298#endif
299
300uint32_t
301coap_get_available_scheme_hint_bits(int have_pki_psk, int ws_check,
302 coap_proto_t use_unix_proto) {
303 uint32_t scheme_hint_bits = 0;
304 coap_uri_scheme_t scheme;
305
306 for (scheme = 0; scheme < COAP_URI_SCHEME_LAST; scheme++) {
307 switch (scheme) {
309 scheme_hint_bits |= 1 << scheme;
310 break;
312 if (!(coap_dtls_is_supported() && have_pki_psk))
313 continue;
314 scheme_hint_bits |= 1 << scheme;
315 break;
318 continue;
319 scheme_hint_bits |= 1 << scheme;
320 break;
322 if (!(coap_tls_is_supported() && have_pki_psk))
323 continue;
324 scheme_hint_bits |= 1 << scheme;
325 break;
327 if (!ws_check || !coap_ws_is_supported())
328 continue;
329 scheme_hint_bits |= 1 << scheme;
330 break;
332 if (!ws_check || !(coap_wss_is_supported() && have_pki_psk))
333 continue;
334 scheme_hint_bits |= 1 << scheme;
335 break;
339 default:
340 continue;
341 }
342 }
343
344 switch (use_unix_proto) {
345 /* For AF_UNIX, can only listen on a single endpoint */
346 case COAP_PROTO_UDP:
347 scheme_hint_bits = 1 << COAP_URI_SCHEME_COAP;
348 break;
349 case COAP_PROTO_TCP:
350 scheme_hint_bits = 1 << COAP_URI_SCHEME_COAP_TCP;
351 break;
352 case COAP_PROTO_DTLS:
353 scheme_hint_bits = 1 << COAP_URI_SCHEME_COAPS;
354 break;
355 case COAP_PROTO_TLS:
356 scheme_hint_bits = 1 << COAP_URI_SCHEME_COAPS_TCP;
357 break;
358 case COAP_PROTO_WS:
359 scheme_hint_bits = 1 << COAP_URI_SCHEME_COAP_WS;
360 break;
361 case COAP_PROTO_WSS:
362 scheme_hint_bits = 1 << COAP_URI_SCHEME_COAPS_WS;
363 break;
364 case COAP_PROTO_NONE: /* If use_unix_proto was not defined */
365 case COAP_PROTO_LAST:
366 default:
367 break;
368 }
369 return scheme_hint_bits;
370}
371
374 uint16_t port,
375 uint16_t secure_port,
376 int ai_hints_flags,
377 int scheme_hint_bits,
378 coap_resolve_type_t type) {
379#if !defined(RIOT_VERSION)
380
381 struct addrinfo *res, *ainfo;
382 struct addrinfo hints;
383 static char addrstr[256];
384 int error;
385 coap_addr_info_t *info = NULL;
386 coap_addr_info_t *info_prev = NULL;
387 coap_addr_info_t *info_list = NULL;
388 coap_uri_scheme_t scheme;
389 coap_proto_t proto = 0;
390
391#if COAP_AF_UNIX_SUPPORT
392 if (address && coap_host_is_unix_domain(address)) {
393 /* There can only be one unique filename entry for AF_UNIX */
394 if (address->length >= COAP_UNIX_PATH_MAX) {
395 coap_log_err("Unix Domain host too long\n");
396 return NULL;
397 }
398 /* Need to chose the first defined one in scheme_hint_bits */
399 for (scheme = 0; scheme < COAP_URI_SCHEME_LAST; scheme++) {
400 if (scheme_hint_bits & (1 << scheme)) {
401 break;
402 }
403 }
404 if (scheme == COAP_URI_SCHEME_LAST) {
405 return NULL;
406 }
407 switch (scheme) {
409 proto = COAP_PROTO_UDP;
410 break;
413 return NULL;
414 proto = COAP_PROTO_DTLS;
415 break;
418 return NULL;
419 proto = COAP_PROTO_TCP;
420 break;
423 return NULL;
424 proto = COAP_PROTO_TLS;
425 break;
428 return NULL;
429 proto = COAP_PROTO_NONE;
430 break;
433 return NULL;
434 proto = COAP_PROTO_NONE;
435 break;
438 return NULL;
439 proto = COAP_PROTO_WS;
440 break;
443 return NULL;
444 proto = COAP_PROTO_WSS;
445 break;
447 default:
448 return NULL;
449 }
451 if (info == NULL)
452 return NULL;
453 info->next = NULL;
454 info->proto = proto;
455 info->scheme = scheme;
456
457 coap_address_init(&info->addr);
458 if (!coap_address_set_unix_domain(&info->addr, address->s,
459 address->length)) {
461 return NULL;
462 }
463 return info;
464 }
465#endif /* COAP_AF_UNIX_SUPPORT */
466
467 memset(addrstr, 0, sizeof(addrstr));
468 if (address && address->length)
469 memcpy(addrstr, address->s, address->length);
470 else
471 memcpy(addrstr, "localhost", 9);
472
473 memset((char *)&hints, 0, sizeof(hints));
474 hints.ai_socktype = 0;
475 hints.ai_family = AF_UNSPEC;
476 hints.ai_flags = ai_hints_flags;
477
478 error = getaddrinfo(addrstr, NULL, &hints, &res);
479
480 if (error != 0) {
481 coap_log_warn("getaddrinfo: %s\n", gai_strerror(error));
482 return NULL;
483 }
484
485 for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {
486#if !defined(WITH_LWIP)
487 if (ainfo->ai_addrlen > (socklen_t)sizeof(info->addr.addr))
488 continue;
489#endif /* ! WITH_LWIP */
490
491 switch (ainfo->ai_family) {
492#if COAP_IPV4_SUPPORT
493 case AF_INET:
494#endif /* COAP_IPV4_SUPPORT */
495#if COAP_IPV6_SUPPORT
496 case AF_INET6:
497#endif /* COAP_IPV6_SUPPORT */
498 for (scheme = 0; scheme < COAP_URI_SCHEME_LAST; scheme++) {
499 if (scheme_hint_bits & (1 << scheme)) {
500 switch (scheme) {
502 proto = COAP_PROTO_UDP;
503#if !defined(__MINGW32__) && !defined(_WIN32)
504 if (ainfo->ai_socktype != SOCK_DGRAM)
505 continue;
506#endif /* ! __MINGW32__ && ! _WIN32 */
507 break;
510 continue;
511 proto = COAP_PROTO_DTLS;
512#if !defined(__MINGW32__) && !defined(_WIN32)
513 if (ainfo->ai_socktype != SOCK_DGRAM)
514 continue;
515#endif /* ! __MINGW32__ && ! _WIN32 */
516 break;
519 continue;
520 proto = COAP_PROTO_TCP;
521#if !defined(__MINGW32__) && !defined(_WIN32)
522 if (ainfo->ai_socktype != SOCK_STREAM)
523 continue;
524#endif /* ! __MINGW32__ && ! _WIN32 */
525 break;
528 continue;
529 proto = COAP_PROTO_TLS;
530#if !defined(__MINGW32__) && !defined(_WIN32)
531 if (ainfo->ai_socktype != SOCK_STREAM)
532 continue;
533#endif /* ! __MINGW32__ && ! _WIN32 */
534 break;
537 continue;
538 proto = COAP_PROTO_NONE;
539#if !defined(__MINGW32__) && !defined(_WIN32)
540 if (ainfo->ai_socktype != SOCK_STREAM)
541 continue;
542#endif /* ! __MINGW32__ && ! _WIN32 */
543 break;
546 continue;
547 proto = COAP_PROTO_NONE;
548#if !defined(__MINGW32__) && !defined(_WIN32)
549 if (ainfo->ai_socktype != SOCK_STREAM)
550 continue;
551#endif /* ! __MINGW32__ && ! _WIN32 */
552 break;
555 continue;
556 proto = COAP_PROTO_WS;
557#if !defined(__MINGW32__) && !defined(_WIN32)
558 if (ainfo->ai_socktype != SOCK_STREAM)
559 continue;
560#endif /* ! __MINGW32__ && ! _WIN32 */
561 break;
564 continue;
565 proto = COAP_PROTO_WSS;
566#if !defined(__MINGW32__) && !defined(_WIN32)
567 if (ainfo->ai_socktype != SOCK_STREAM)
568 continue;
569#endif /* ! __MINGW32__ && ! _WIN32 */
570 break;
572 default:
573 continue;
574 }
575
577 if (info == NULL) {
578 /* malloc failure - return what we have so far */
579 return info_list;
580 }
581 info->next = NULL;
582 /* Need to return in same order as getaddrinfo() */
583 if (!info_prev) {
584 info_list = info;
585 info_prev = info;
586 } else {
587 info_prev->next = info;
588 info_prev = info;
589 }
590
591 info->scheme = scheme;
592 info->proto = proto;
593 coap_address_init(&info->addr);
594#if !defined(WITH_LWIP)
595 info->addr.size = (socklen_t)ainfo->ai_addrlen;
596 memcpy(&info->addr.addr, ainfo->ai_addr, ainfo->ai_addrlen);
597#else /* WITH_LWIP */
598 memset(&info->addr, 0, sizeof(info->addr));
599 switch (ainfo->ai_family) {
600#if COAP_IPV6_SUPPORT
601 struct sockaddr_in6 *sock6;
602#endif /* COAP_IPV6_SUPPORT */
603#if COAP_IPV4_SUPPORT
604 struct sockaddr_in *sock4;
605 case AF_INET:
606 sock4 = (struct sockaddr_in *)ainfo->ai_addr;
607 info->addr.port = ntohs(sock4->sin_port);
608 memcpy(&info->addr.addr, &sock4->sin_addr, 4);
609#if LWIP_IPV6
610 info->addr.addr.type = IPADDR_TYPE_V4;
611#endif /* LWIP_IPV6 */
612 break;
613#endif /* COAP_IPV4_SUPPORT */
614#if COAP_IPV6_SUPPORT
615 case AF_INET6:
616 sock6 = (struct sockaddr_in6 *)ainfo->ai_addr;
617 info->addr.port = ntohs(sock6->sin6_port);
618 memcpy(&info->addr.addr, &sock6->sin6_addr, 16);
619#if LWIP_IPV6 && LWIP_IPV4
620 info->addr.addr.type = IPADDR_TYPE_V6;
621#endif /* LWIP_IPV6 && LWIP_IPV4 */
622 break;
623#endif /* COAP_IPV6_SUPPORT */
624 default:
625 ;
626 }
627#endif /* WITH_LWIP */
628 switch (scheme) {
630 update_port(&info->addr, port, COAP_DEFAULT_PORT,
632 break;
634 update_port(&info->addr, secure_port, COAPS_DEFAULT_PORT,
636 break;
638 update_port(&info->addr, port, COAP_DEFAULT_PORT,
640 break;
642 update_port(&info->addr, secure_port, COAPS_DEFAULT_PORT,
644 break;
646 update_port(&info->addr, port, 80,
648 break;
650 update_port(&info->addr, secure_port, 443,
652 break;
654 update_port(&info->addr, port, 80,
656 break;
658 update_port(&info->addr, secure_port, 443,
660 break;
662 default:
663 break;
664 }
665 }
666 }
667 break;
668 default:
669 break;
670 }
671 }
672
673 freeaddrinfo(res);
674 return info_list;
675#else /* RIOT_VERSION */
676#if COAP_IPV6_SUPPORT
677#include "net/utils.h"
678 ipv6_addr_t addr_ipv6;
679 netif_t *netif = NULL;
680 coap_addr_info_t *info = NULL;
681 coap_addr_info_t *info_prev = NULL;
682 coap_addr_info_t *info_list = NULL;
683 coap_uri_scheme_t scheme;
684 coap_proto_t proto = 0;
685 (void)ai_hints_flags;
686
687 if (netutils_get_ipv6(&addr_ipv6, &netif, (const char *)address->s) >= 0) {
688 for (scheme = 0; scheme < COAP_URI_SCHEME_LAST; scheme++) {
689 if (scheme_hint_bits & (1 << scheme)) {
690 switch (scheme) {
692 proto = COAP_PROTO_UDP;
693 break;
696 continue;
697 proto = COAP_PROTO_DTLS;
698 break;
701 continue;
702 proto = COAP_PROTO_TCP;
703 break;
706 continue;
707 proto = COAP_PROTO_TLS;
708 break;
711 continue;
712 proto = COAP_PROTO_NONE;
713 break;
716 continue;
717 proto = COAP_PROTO_NONE;
718 break;
721 continue;
722 proto = COAP_PROTO_WS;
723 break;
726 continue;
727 proto = COAP_PROTO_WSS;
728 break;
730 default:
731 continue;
732 }
733
735 if (info == NULL) {
736 /* malloc failure - return what we have so far */
737 return info_list;
738 }
739 info->next = NULL;
740 /* Need to return in same order as getaddrinfo() */
741 if (!info_prev) {
742 info_list = info;
743 info_prev = info;
744 } else {
745 info_prev->next = info;
746 info_prev = info;
747 }
748
749 info->scheme = scheme;
750 info->proto = proto;
751 coap_address_init(&info->addr);
752 info->addr.size = sizeof(struct sockaddr_in6);
753 info->addr.addr.sin6.sin6_family = AF_INET6;
754 memcpy(&info->addr.addr.sin6.sin6_addr, &addr_ipv6,
755 sizeof(info->addr.addr.sin6.sin6_addr));
756 info->addr.addr.sin6.sin6_scope_id = (uint32_t)netif_get_id(netif);
757 switch (scheme) {
759 update_port(&info->addr, port, COAP_DEFAULT_PORT,
761 break;
763 update_port(&info->addr, secure_port, COAPS_DEFAULT_PORT,
765 break;
767 update_port(&info->addr, port, COAP_DEFAULT_PORT,
769 break;
771 update_port(&info->addr, secure_port, COAPS_DEFAULT_PORT,
773 break;
775 update_port(&info->addr, port, 80,
777 break;
779 update_port(&info->addr, secure_port, 443,
781 break;
783 default:
784 break;
785 }
786 }
787 }
788 return info_list;
789 }
790#endif /* COAP_IPV6_SUPPORT */
791 return NULL;
792#endif /* RIOT_VERSION */
793}
794#endif /* !WITH_CONTIKI */
795
796void
798 while (info) {
799 coap_addr_info_t *info_next = info->next;
800
802 info = info_next;
803 }
804}
805
806#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
807void
809#if defined(WITH_LWIP) || defined(WITH_CONTIKI)
810 memcpy(dst, src, sizeof(coap_address_t));
811#else
812 memset(dst, 0, sizeof(coap_address_t));
813 dst->size = src->size;
814#if COAP_IPV6_SUPPORT
815 if (src->addr.sa.sa_family == AF_INET6) {
816 dst->addr.sin6.sin6_family = src->addr.sin6.sin6_family;
817 dst->addr.sin6.sin6_addr = src->addr.sin6.sin6_addr;
818 dst->addr.sin6.sin6_port = src->addr.sin6.sin6_port;
819 dst->addr.sin6.sin6_scope_id = src->addr.sin6.sin6_scope_id;
820 }
821#endif /* COAP_IPV6_SUPPORT */
822#if COAP_IPV4_SUPPORT && COAP_IPV6_SUPPORT
823 else
824#endif /* COAP_IPV4_SUPPORT && COAP_IPV6_SUPPORT */
825#if COAP_IPV4_SUPPORT
826 if (src->addr.sa.sa_family == AF_INET) {
827 dst->addr.sin = src->addr.sin;
828 }
829#endif /* COAP_IPV4_SUPPORT */
830 else {
831 memcpy(&dst->addr, &src->addr, src->size);
832 }
833#endif
834}
835
836int
838 /* need to compare only relevant parts of sockaddr_in6 */
839 switch (a->addr.sa.sa_family) {
840#if COAP_IPV4_SUPPORT
841 case AF_INET:
842 return a->addr.sin.sin_addr.s_addr == INADDR_ANY;
843#endif /* COAP_IPV4_SUPPORT */
844#if COAP_IPV6_SUPPORT
845 case AF_INET6:
846 return memcmp(&in6addr_any,
847 &a->addr.sin6.sin6_addr,
848 sizeof(in6addr_any)) == 0;
849#endif /* COAP_IPV6_SUPPORT */
850 default:
851 ;
852 }
853
854 return 0;
855}
856#endif /* ! WITH_LWIP && ! WITH_CONTIKI */
void coap_address_set_port(coap_address_t *addr, uint16_t port)
Set the port field of addr to port (in host byte order).
int coap_address_set_unix_domain(coap_address_t *addr, const uint8_t *host, size_t host_len)
Copy the parsed unix domain host into coap_address_t structure translating %2F into / on the way.
#define COAP_BCST_REFRESH_SECS
void coap_free_address_info(coap_addr_info_t *info)
Free off the one or more linked sets of coap_addr_info_t returned from coap_resolve_address_info().
int coap_is_af_unix(const coap_address_t *a)
Checks if given address a denotes a AF_UNIX address.
int coap_is_bcast(const coap_address_t *a)
Checks if given address a denotes a broadcast address.
void coap_address_init(coap_address_t *addr)
Resets the given coap_address_t object addr to its default values.
int coap_is_mcast(const coap_address_t *a)
Checks if given address a denotes a multicast address.
int _coap_address_isany_impl(const coap_address_t *a)
uint16_t coap_address_get_port(const coap_address_t *addr)
Returns the port from addr in host byte order.
uint32_t coap_get_available_scheme_hint_bits(int have_pki_psk, int ws_check, coap_proto_t use_unix_proto)
Determine and set up scheme_hint_bits for a server that can be used in a call to coap_resolve_address...
coap_addr_info_t * coap_resolve_address_info(const coap_str_const_t *address, uint16_t port, uint16_t secure_port, int ai_hints_flags, int scheme_hint_bits, coap_resolve_type_t type)
Resolve the specified address into a set of coap_address_t that can be used to bind() (local) or conn...
#define COAP_BCST_CNT
void coap_address_copy(coap_address_t *dst, const coap_address_t *src)
int coap_address_equals(const coap_address_t *a, const coap_address_t *b)
Compares given address objects a and b.
static void update_port(coap_address_t *addr, uint16_t port, uint16_t default_port, int update_port0)
coap_resolve_type_t
coap_resolve_type_t values
@ COAP_RESOLVE_TYPE_LOCAL
local side of session
#define COAP_UNIX_PATH_MAX
Pulls together all the internal only header files.
@ COAP_STRING
Definition coap_mem.h:38
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
int coap_tcp_is_supported(void)
Check whether TCP is available.
Definition coap_tcp.c:37
int coap_host_is_unix_domain(const coap_str_const_t *host)
Determines from the host whether this is a Unix Domain socket request.
Definition coap_uri.c:381
coap_uri_scheme_t
The scheme specifiers.
Definition coap_uri.h:28
@ COAP_URI_SCHEME_COAPS_WS
Definition coap_uri.h:36
@ COAP_URI_SCHEME_COAPS_TCP
Definition coap_uri.h:32
@ COAP_URI_SCHEME_COAPS
Definition coap_uri.h:30
@ COAP_URI_SCHEME_COAP_TCP
Definition coap_uri.h:31
@ COAP_URI_SCHEME_COAP_WS
Definition coap_uri.h:35
@ COAP_URI_SCHEME_HTTPS
Definition coap_uri.h:34
@ COAP_URI_SCHEME_COAP
Definition coap_uri.h:29
@ COAP_URI_SCHEME_LAST
Definition coap_uri.h:37
@ COAP_URI_SCHEME_HTTP
Definition coap_uri.h:33
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition coap_time.h:144
#define COAP_TICKS_PER_SECOND
Use ms resolution on POSIX systems.
Definition coap_time.h:159
void coap_ticks(coap_tick_t *)
Returns the current value of an internal tick counter.
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition coap_notls.c:28
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition coap_notls.c:23
#define coap_log_warn(...)
Definition coap_debug.h:102
#define coap_log_err(...)
Definition coap_debug.h:96
#define COAP_DEFAULT_PORT
Definition coap_pdu.h:37
coap_proto_t
CoAP protocol types.
Definition coap_pdu.h:304
#define COAPS_DEFAULT_PORT
Definition coap_pdu.h:38
@ COAP_PROTO_WS
Definition coap_pdu.h:310
@ COAP_PROTO_DTLS
Definition coap_pdu.h:307
@ COAP_PROTO_UDP
Definition coap_pdu.h:306
@ COAP_PROTO_NONE
Definition coap_pdu.h:305
@ COAP_PROTO_TLS
Definition coap_pdu.h:309
@ COAP_PROTO_WSS
Definition coap_pdu.h:311
@ COAP_PROTO_TCP
Definition coap_pdu.h:308
@ COAP_PROTO_LAST
Definition coap_pdu.h:312
int coap_ws_is_supported(void)
Check whether WebSockets is available.
Definition coap_ws.c:929
int coap_wss_is_supported(void)
Check whether Secure WebSockets is available.
Definition coap_ws.c:934
Resolved addresses information.
coap_uri_scheme_t scheme
CoAP scheme to use.
coap_proto_t proto
CoAP protocol to use.
struct coap_addr_info_t * next
Next entry in the chain.
coap_address_t addr
The address to connect / bind to.
Multi-purpose address abstraction.
socklen_t size
size of addr
struct sockaddr_in sin
struct coap_sockaddr_un cun
struct sockaddr_in6 sin6
struct sockaddr sa
union coap_address_t::@0 addr
char sun_path[COAP_UNIX_PATH_MAX]
sa_family_t sun_family
CoAP string data definition with const data.
Definition coap_str.h:46
const uint8_t * s
read-only string data
Definition coap_str.h:48
size_t length
length of string
Definition coap_str.h:47