• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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