• 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  * 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