1 /*
2 * address.h -- representation of network addresses
3 *
4 * Copyright (C) 2010-2011,2015-2016 Olaf Bergmann <bergmann@tzi.org>
5 *
6 * This file is part of the CoAP library libcoap. Please see README for terms
7 * of use.
8 */
9
10 /**
11 * @file address.h
12 * @brief Representation of network addresses
13 */
14
15 #ifndef COAP_ADDRESS_H_
16 #define COAP_ADDRESS_H_
17
18 #ifdef HAVE_ASSERT_H
19 #include <assert.h>
20 #endif /* HAVE_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 #define _coap_address_equals_impl(A, B) \
36 ((A)->port == (B)->port \
37 && (IP_GET_TYPE(&(A)->addr) == IP_GET_TYPE(&(B)->addr)) \
38 && (ip_addr_isany(&(A)->addr) || ip_addr_isany(&(B)->addr) || !!ip_addr_cmp(&(A)->addr, &(B)->addr)))
39
40 #define _coap_address_isany_impl(A) ip_addr_isany(&(A)->addr)
41
42 #define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr)
43
44 #elif defined(WITH_CONTIKI)
45
46 #include "uip.h"
47
48 typedef struct coap_address_t {
49 uip_ipaddr_t addr;
50 uint16_t port;
51 } coap_address_t;
52
53 #define _coap_address_equals_impl(A,B) \
54 ((A)->port == (B)->port \
55 && uip_ipaddr_cmp(&((A)->addr),&((B)->addr)))
56
57 /** @todo implementation of _coap_address_isany_impl() for Contiki */
58 #define _coap_address_isany_impl(A) 0
59
60 #define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr))
61
62 #else /* WITH_LWIP || WITH_CONTIKI */
63
64 /** multi-purpose address abstraction */
65 typedef struct coap_address_t {
66 socklen_t size; /**< size of addr */
67 union {
68 struct sockaddr sa;
69 struct sockaddr_in sin;
70 struct sockaddr_in6 sin6;
71 } addr;
72 } coap_address_t;
73
74 /**
75 * Compares given address objects @p a and @p b. This function returns @c 1 if
76 * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
77 * @c NULL;
78 */
79 int coap_address_equals(const coap_address_t *a, const coap_address_t *b);
80
81 COAP_STATIC_INLINE int
_coap_address_isany_impl(const coap_address_t * a)82 _coap_address_isany_impl(const coap_address_t *a) {
83 /* need to compare only relevant parts of sockaddr_in6 */
84 switch (a->addr.sa.sa_family) {
85 case AF_INET:
86 return a->addr.sin.sin_addr.s_addr == INADDR_ANY;
87 case AF_INET6:
88 return memcmp(&in6addr_any,
89 &a->addr.sin6.sin6_addr,
90 sizeof(in6addr_any)) == 0;
91 default:
92 ;
93 }
94
95 return 0;
96 }
97 #endif /* WITH_LWIP || WITH_CONTIKI */
98
99 /**
100 * Resets the given coap_address_t object @p addr to its default values. In
101 * particular, the member size must be initialized to the available size for
102 * storing addresses.
103 *
104 * @param addr The coap_address_t object to initialize.
105 */
106 void coap_address_init(coap_address_t *addr);
107
108 /* Convenience function to copy IPv6 addresses without garbage. */
109
110 COAP_STATIC_INLINE void
coap_address_copy(coap_address_t * dst,const coap_address_t * src)111 coap_address_copy( coap_address_t *dst, const coap_address_t *src ) {
112 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
113 memcpy( dst, src, sizeof( coap_address_t ) );
114 #else
115 memset( dst, 0, sizeof( coap_address_t ) );
116 dst->size = src->size;
117 if ( src->addr.sa.sa_family == AF_INET6 ) {
118 dst->addr.sin6.sin6_family = src->addr.sin6.sin6_family;
119 dst->addr.sin6.sin6_addr = src->addr.sin6.sin6_addr;
120 dst->addr.sin6.sin6_port = src->addr.sin6.sin6_port;
121 dst->addr.sin6.sin6_scope_id = src->addr.sin6.sin6_scope_id;
122 } else if ( src->addr.sa.sa_family == AF_INET ) {
123 dst->addr.sin = src->addr.sin;
124 } else {
125 memcpy( &dst->addr, &src->addr, src->size );
126 }
127 #endif
128 }
129
130 #if defined(WITH_LWIP) || defined(WITH_CONTIKI)
131 /**
132 * Compares given address objects @p a and @p b. This function returns @c 1 if
133 * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
134 * @c NULL;
135 */
136 COAP_STATIC_INLINE int
coap_address_equals(const coap_address_t * a,const coap_address_t * b)137 coap_address_equals(const coap_address_t *a, const coap_address_t *b) {
138 #ifdef HAVE_ASSERT_H
139 assert(a); assert(b);
140 #endif /* HAVE_ASSERT_H */
141 return _coap_address_equals_impl(a, b);
142 }
143 #endif
144
145 /**
146 * Checks if given address object @p a denotes the wildcard address. This
147 * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p
148 * a must not be @c NULL;
149 */
150 COAP_STATIC_INLINE int
coap_address_isany(const coap_address_t * a)151 coap_address_isany(const coap_address_t *a) {
152 #ifdef HAVE_ASSERT_H
153 assert(a);
154 #endif /* HAVE_ASSERT_H */
155 return _coap_address_isany_impl(a);
156 }
157
158 #if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
159
160 /**
161 * Checks if given address @p a denotes a multicast address. This function
162 * returns @c 1 if @p a is multicast, @c 0 otherwise.
163 */
164 int coap_is_mcast(const coap_address_t *a);
165 #else /* !WITH_LWIP && !WITH_CONTIKI */
166 /**
167 * Checks if given address @p a denotes a multicast address. This function
168 * returns @c 1 if @p a is multicast, @c 0 otherwise.
169 */
170 COAP_STATIC_INLINE int
coap_is_mcast(const coap_address_t * a)171 coap_is_mcast(const coap_address_t *a) {
172 return a && _coap_is_mcast_impl(a);
173 }
174 #endif /* !WITH_LWIP && !WITH_CONTIKI */
175
176 #endif /* COAP_ADDRESS_H_ */
177