• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* address.c -- representation of network addresses
2  *
3  * Copyright (C) 2015-2016,2019 Olaf Bergmann <bergmann@tzi.org>
4  * Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved.
5  *
6  * This file is part of the CoAP library libcoap. Please see
7  * README for terms of use.
8  */
9 
10 #include "coap_internal.h"
11 
12 #if !defined(WITH_CONTIKI) && !defined(WITH_LWIP)
13 #ifdef HAVE_ARPA_INET_H
14 #include <arpa/inet.h>
15 #endif
16 #ifdef HAVE_NETINET_IN_H
17 #include <netinet/in.h>
18 #endif
19 #ifdef HAVE_SYS_SOCKET_H
20 #include <sys/socket.h>
21 #endif
22 #ifdef HAVE_WS2TCPIP_H
23 #include <ws2tcpip.h>
24 #endif
25 
26 #ifdef RIOT_VERSION
27 /* FIXME */
28 #define IN_MULTICAST(Address) (0)
29 #endif /* RIOT_VERSION */
30 
31 int
coap_address_equals(const coap_address_t * a,const coap_address_t * b)32 coap_address_equals(const coap_address_t *a, const coap_address_t *b) {
33   assert(a); assert(b);
34 
35   if (a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family)
36     return 0;
37 
38   /* need to compare only relevant parts of sockaddr_in6 */
39  switch (a->addr.sa.sa_family) {
40  case AF_INET:
41    return
42      a->addr.sin.sin_port == b->addr.sin.sin_port &&
43      memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr,
44             sizeof(struct in_addr)) == 0;
45  case AF_INET6:
46    return a->addr.sin6.sin6_port == b->addr.sin6.sin6_port &&
47      memcmp(&a->addr.sin6.sin6_addr, &b->addr.sin6.sin6_addr,
48             sizeof(struct in6_addr)) == 0;
49  default: /* fall through and signal error */
50    ;
51  }
52  return 0;
53 }
54 
55 #ifdef COAP_SUPPORT_SOCKET_BROADCAST
coap_is_bcast(const coap_address_t * a)56 int coap_is_bcast(const coap_address_t *a) {
57   if (a == NULL) {
58     return 0;
59   }
60 
61   switch (a->addr.sa.sa_family) {
62     case AF_INET:
63       if (a->addr.sin.sin_addr.s_addr == 0xFFFFFFFF) {
64         return 1;
65       } else {
66         return 0;
67       }
68     case AF_INET6:
69       /* not support ipv6 */
70       return 0;
71     default:
72       return 0;
73   }
74 }
75 #endif
76 
coap_is_mcast(const coap_address_t * a)77 int coap_is_mcast(const coap_address_t *a) {
78   if (!a)
79     return 0;
80 
81  switch (a->addr.sa.sa_family) {
82  case AF_INET:
83    return IN_MULTICAST(ntohl(a->addr.sin.sin_addr.s_addr));
84  case  AF_INET6:
85    return IN6_IS_ADDR_MULTICAST(&a->addr.sin6.sin6_addr);
86  default:  /* fall through and signal error */
87    ;
88   }
89  return 0;
90 }
91 
92 #endif /* !defined(WITH_CONTIKI) && !defined(WITH_LWIP) */
93 
coap_address_init(coap_address_t * addr)94 void coap_address_init(coap_address_t *addr) {
95   assert(addr);
96   memset(addr, 0, sizeof(coap_address_t));
97 #if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
98   /* lwip and Contiki have constant address sizes and don't need the .size part */
99   addr->size = sizeof(addr->addr);
100 #endif
101 }
102 
103 #if defined(WITH_LWIP)
104 #include <lwip/inet.h>
105 #endif
106 
coap_address_ntop(const coap_address_t * addr,char * dst,int len)107 void coap_address_ntop(const coap_address_t *addr, char *dst, int len) {
108   if ((addr == NULL) || (dst == NULL) || (len < INET6_ADDRSTRLEN)) {
109     return;
110   }
111 #if defined(WITH_LWIP)
112   (void)ipaddr_ntoa_r(&(addr->addr), dst, len);
113 #elif defined(WITH_CONTIKI)
114   /* not supported yet */
115 #else
116   if (addr->addr.sa.sa_family == AF_INET) {
117     const void *addrptr = &addr->addr.sin.sin_addr;
118     (void)inet_ntop(addr->addr.sa.sa_family, addrptr, dst, len);
119   } else {
120     const void *addrptr = &addr->addr.sin6.sin6_addr;
121     (void)inet_ntop(addr->addr.sa.sa_family, addrptr, dst, len);
122   }
123 #endif
124 }
125 
126