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 #elif defined(WITH_CONTIKI)
60
61 #include "uip.h"
62
63 typedef struct coap_address_t {
64 uip_ipaddr_t addr;
65 uint16_t port;
66 } coap_address_t;
67
68 /**
69 * Returns the port from @p addr in host byte order.
70 */
71 COAP_STATIC_INLINE uint16_t
coap_address_get_port(const coap_address_t * addr)72 coap_address_get_port(const coap_address_t *addr) {
73 return uip_ntohs(addr->port);
74 }
75
76 /**
77 * Sets the port field of @p addr to @p port (in host byte order).
78 */
79 COAP_STATIC_INLINE void
coap_address_set_port(coap_address_t * addr,uint16_t port)80 coap_address_set_port(coap_address_t *addr, uint16_t port) {
81 addr->port = uip_htons(port);
82 }
83
84 #define _coap_address_equals_impl(A,B) \
85 ((A)->port == (B)->port \
86 && uip_ipaddr_cmp(&((A)->addr),&((B)->addr)))
87
88 /** @todo implementation of _coap_address_isany_impl() for Contiki */
89 #define _coap_address_isany_impl(A) 0
90
91 #define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr))
92
93 #else /* WITH_LWIP || WITH_CONTIKI */
94
95 /** multi-purpose address abstraction */
96 typedef struct coap_address_t {
97 socklen_t size; /**< size of addr */
98 union {
99 struct sockaddr sa;
100 struct sockaddr_in sin;
101 struct sockaddr_in6 sin6;
102 } addr;
103 } coap_address_t;
104
105 /**
106 * Returns the port from @p addr in host byte order.
107 */
108 uint16_t coap_address_get_port(const coap_address_t *addr);
109
110 /**
111 * Set the port field of @p addr to @p port (in host byte order).
112 */
113 void coap_address_set_port(coap_address_t *addr, uint16_t port);
114
115 /**
116 * Compares given address objects @p a and @p b. This function returns @c 1 if
117 * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
118 * @c NULL;
119 */
120 int coap_address_equals(const coap_address_t *a, const coap_address_t *b);
121
122 COAP_STATIC_INLINE int
_coap_address_isany_impl(const coap_address_t * a)123 _coap_address_isany_impl(const coap_address_t *a) {
124 /* need to compare only relevant parts of sockaddr_in6 */
125 switch (a->addr.sa.sa_family) {
126 case AF_INET:
127 return a->addr.sin.sin_addr.s_addr == INADDR_ANY;
128 case AF_INET6:
129 return memcmp(&in6addr_any,
130 &a->addr.sin6.sin6_addr,
131 sizeof(in6addr_any)) == 0;
132 default:
133 ;
134 }
135
136 return 0;
137 }
138 #endif /* WITH_LWIP || WITH_CONTIKI */
139
140 /**
141 * Resets the given coap_address_t object @p addr to its default values. In
142 * particular, the member size must be initialized to the available size for
143 * storing addresses.
144 *
145 * @param addr The coap_address_t object to initialize.
146 */
147 void coap_address_init(coap_address_t *addr);
148
149 /* Convenience function to copy IPv6 addresses without garbage. */
150
151 COAP_STATIC_INLINE void
coap_address_copy(coap_address_t * dst,const coap_address_t * src)152 coap_address_copy( coap_address_t *dst, const coap_address_t *src ) {
153 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
154 memcpy( dst, src, sizeof( coap_address_t ) );
155 #else
156 memset( dst, 0, sizeof( coap_address_t ) );
157 dst->size = src->size;
158 if ( src->addr.sa.sa_family == AF_INET6 ) {
159 dst->addr.sin6.sin6_family = src->addr.sin6.sin6_family;
160 dst->addr.sin6.sin6_addr = src->addr.sin6.sin6_addr;
161 dst->addr.sin6.sin6_port = src->addr.sin6.sin6_port;
162 dst->addr.sin6.sin6_scope_id = src->addr.sin6.sin6_scope_id;
163 } else if ( src->addr.sa.sa_family == AF_INET ) {
164 dst->addr.sin = src->addr.sin;
165 } else {
166 memcpy( &dst->addr, &src->addr, src->size );
167 }
168 #endif
169 }
170
171 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
172 /**
173 * Compares given address objects @p a and @p b. This function returns @c 1 if
174 * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
175 * @c NULL;
176 */
177 COAP_STATIC_INLINE int
coap_address_equals(const coap_address_t * a,const coap_address_t * b)178 coap_address_equals(const coap_address_t *a, const coap_address_t *b) {
179 assert(a); assert(b);
180 return _coap_address_equals_impl(a, b);
181 }
182 #endif
183
184 /**
185 * Checks if given address object @p a denotes the wildcard address. This
186 * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p
187 * a must not be @c NULL;
188 */
189 COAP_STATIC_INLINE int
coap_address_isany(const coap_address_t * a)190 coap_address_isany(const coap_address_t *a) {
191 assert(a);
192 return _coap_address_isany_impl(a);
193 }
194
195 #if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
196
197 /**
198 * Checks if given address @p a denotes a multicast address. This function
199 * returns @c 1 if @p a is multicast, @c 0 otherwise.
200 */
201 int coap_is_mcast(const coap_address_t *a);
202 #else /* !WITH_LWIP && !WITH_CONTIKI */
203 /**
204 * Checks if given address @p a denotes a multicast address. This function
205 * returns @c 1 if @p a is multicast, @c 0 otherwise.
206 */
207 COAP_STATIC_INLINE int
coap_is_mcast(const coap_address_t * a)208 coap_is_mcast(const coap_address_t *a) {
209 return a && _coap_is_mcast_impl(a);
210 }
211 #endif /* !WITH_LWIP && !WITH_CONTIKI */
212
213 #endif /* COAP_ADDRESS_H_ */
214