1 /*
2 * address.h -- representation of network addresses
3 *
4 * Copyright (C) 2010-2011,2015-2016 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 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 #if defined(WITH_LWIP)
27
28 #include <lwip/ip_addr.h>
29
30 typedef struct coap_address_t {
31 uint16_t port;
32 ip_addr_t addr;
33 } coap_address_t;
34
35 /**
36 * Returns the port from @p addr in host byte order.
37 */
38 COAP_STATIC_INLINE uint16_t
coap_address_get_port(const coap_address_t * addr)39 coap_address_get_port(const coap_address_t *addr) {
40 return ntohs(addr->port);
41 }
42
43 /**
44 * Sets the port field of @p addr to @p port (in host byte order).
45 */
46 COAP_STATIC_INLINE void
coap_address_set_port(coap_address_t * addr,uint16_t port)47 coap_address_set_port(coap_address_t *addr, uint16_t port) {
48 addr->port = htons(port);
49 }
50
51 #define _coap_address_equals_impl(A, B) \
52 ((A)->port == (B)->port \
53 && (!!ip_addr_cmp(&(A)->addr,&(B)->addr)))
54
55 #define _coap_address_isany_impl(A) ip_addr_isany(&(A)->addr)
56
57 #define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr)
58
59 #ifdef COAP_SUPPORT_SOCKET_BROADCAST
60 #define _coap_is_bcast_impl(Address) ip_addr_isbroadcast(&(Address)->addr)
61 #endif
62
63 #elif defined(WITH_CONTIKI)
64
65 #include "uip.h"
66
67 typedef struct coap_address_t {
68 uip_ipaddr_t addr;
69 uint16_t port;
70 } coap_address_t;
71
72 /**
73 * Returns the port from @p addr in host byte order.
74 */
75 COAP_STATIC_INLINE uint16_t
coap_address_get_port(const coap_address_t * addr)76 coap_address_get_port(const coap_address_t *addr) {
77 return uip_ntohs(addr->port);
78 }
79
80 /**
81 * Sets the port field of @p addr to @p port (in host byte order).
82 */
83 COAP_STATIC_INLINE void
coap_address_set_port(coap_address_t * addr,uint16_t port)84 coap_address_set_port(coap_address_t *addr, uint16_t port) {
85 addr->port = uip_htons(port);
86 }
87
88 #define _coap_address_equals_impl(A,B) \
89 ((A)->port == (B)->port \
90 && uip_ipaddr_cmp(&((A)->addr),&((B)->addr)))
91
92 /** @todo implementation of _coap_address_isany_impl() for Contiki */
93 #define _coap_address_isany_impl(A) 0
94
95 #define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr))
96
97 #ifdef COAP_SUPPORT_SOCKET_BROADCAST
98 #define _coap_is_bcast_impl(Address) (0)
99 #endif
100
101 #else /* WITH_LWIP || WITH_CONTIKI */
102
103 /** multi-purpose address abstraction */
104 typedef struct coap_address_t {
105 socklen_t size; /**< size of addr */
106 union {
107 struct sockaddr sa;
108 struct sockaddr_in sin;
109 struct sockaddr_in6 sin6;
110 } addr;
111 } coap_address_t;
112
113 /**
114 * Returns the port from @p addr in host byte order.
115 */
116 uint16_t coap_address_get_port(const coap_address_t *addr);
117
118 /**
119 * Set the port field of @p addr to @p port (in host byte order).
120 */
121 void coap_address_set_port(coap_address_t *addr, uint16_t port);
122
123 /**
124 * Compares given address objects @p a and @p b. This function returns @c 1 if
125 * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
126 * @c NULL;
127 */
128 int coap_address_equals(const coap_address_t *a, const coap_address_t *b);
129
130 COAP_STATIC_INLINE int
_coap_address_isany_impl(const coap_address_t * a)131 _coap_address_isany_impl(const coap_address_t *a) {
132 /* need to compare only relevant parts of sockaddr_in6 */
133 switch (a->addr.sa.sa_family) {
134 case AF_INET:
135 return a->addr.sin.sin_addr.s_addr == INADDR_ANY;
136 case AF_INET6:
137 return memcmp(&in6addr_any,
138 &a->addr.sin6.sin6_addr,
139 sizeof(in6addr_any)) == 0;
140 default:
141 ;
142 }
143
144 return 0;
145 }
146 #endif /* WITH_LWIP || WITH_CONTIKI */
147
148 /**
149 * Resets the given coap_address_t object @p addr to its default values. In
150 * particular, the member size must be initialized to the available size for
151 * storing addresses.
152 *
153 * @param addr The coap_address_t object to initialize.
154 */
155 void coap_address_init(coap_address_t *addr);
156
157 void coap_address_ntop(const coap_address_t *addr, char *dst, int len);
158
159 /* Convenience function to copy IPv6 addresses without garbage. */
160
161 COAP_STATIC_INLINE void
coap_address_copy(coap_address_t * dst,const coap_address_t * src)162 coap_address_copy( coap_address_t *dst, const coap_address_t *src ) {
163 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
164 memcpy( dst, src, sizeof( coap_address_t ) );
165 #else
166 memset( dst, 0, sizeof( coap_address_t ) );
167 dst->size = src->size;
168 if ( src->addr.sa.sa_family == AF_INET6 ) {
169 dst->addr.sin6.sin6_family = src->addr.sin6.sin6_family;
170 dst->addr.sin6.sin6_addr = src->addr.sin6.sin6_addr;
171 dst->addr.sin6.sin6_port = src->addr.sin6.sin6_port;
172 dst->addr.sin6.sin6_scope_id = src->addr.sin6.sin6_scope_id;
173 } else if ( src->addr.sa.sa_family == AF_INET ) {
174 dst->addr.sin = src->addr.sin;
175 } else {
176 memcpy( &dst->addr, &src->addr, src->size );
177 }
178 #endif
179 }
180
181 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
182 /**
183 * Compares given address objects @p a and @p b. This function returns @c 1 if
184 * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
185 * @c NULL;
186 */
187 COAP_STATIC_INLINE int
coap_address_equals(const coap_address_t * a,const coap_address_t * b)188 coap_address_equals(const coap_address_t *a, const coap_address_t *b) {
189 assert(a); assert(b);
190 return _coap_address_equals_impl(a, b);
191 }
192 #endif
193
194 /**
195 * Checks if given address object @p a denotes the wildcard address. This
196 * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p
197 * a must not be @c NULL;
198 */
199 COAP_STATIC_INLINE int
coap_address_isany(const coap_address_t * a)200 coap_address_isany(const coap_address_t *a) {
201 assert(a);
202 return _coap_address_isany_impl(a);
203 }
204
205 #if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
206
207 /**
208 * Checks if given address @p a denotes a multicast address. This function
209 * returns @c 1 if @p a is multicast, @c 0 otherwise.
210 */
211 int coap_is_mcast(const coap_address_t *a);
212
213 #ifdef COAP_SUPPORT_SOCKET_BROADCAST
214 int coap_is_bcast(const coap_address_t *a);
215 #endif
216
217 #else /* !WITH_LWIP && !WITH_CONTIKI */
218 /**
219 * Checks if given address @p a denotes a multicast address. This function
220 * returns @c 1 if @p a is multicast, @c 0 otherwise.
221 */
222 COAP_STATIC_INLINE int
coap_is_mcast(const coap_address_t * a)223 coap_is_mcast(const coap_address_t *a) {
224 return a && _coap_is_mcast_impl(a);
225 }
226
227 #ifdef COAP_SUPPORT_SOCKET_BROADCAST
228 COAP_STATIC_INLINE int
coap_is_bcast(const coap_address_t * a)229 coap_is_bcast(const coap_address_t *a) {
230 return a && _coap_is_bcast_impl(a);
231 }
232 #endif
233
234 #endif /* !WITH_LWIP && !WITH_CONTIKI */
235
236 #endif /* COAP_ADDRESS_H_ */
237