1 /*
2  * address.h -- representation of network addresses
3  *
4  * Copyright (C) 2010-2011,2015 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 #include <assert.h>
19 #include <stdint.h>
20 #include <string.h>
21 
22 #ifdef WITH_LWIP
23 #include <lwip/ip_addr.h>
24 
25 typedef struct coap_address_t {
26   uint16_t port;
27   ip_addr_t addr;
28 } coap_address_t;
29 
30 #define _coap_address_equals_impl(A, B)   (!!ip_addr_cmp(&(A)->addr,&(B)->addr))
31 
32 #define _coap_address_isany_impl(A)  ip_addr_isany(&(A)->addr)
33 
34 #define _coap_is_mcast_impl(Address) ip_addr_ismulticast(&(Address)->addr)
35 #endif /* WITH_LWIP */
36 
37 #ifdef WITH_CONTIKI
38 #include "uip.h"
39 
40 typedef struct coap_address_t {
41   uip_ipaddr_t addr;
42   unsigned short port;
43 } coap_address_t;
44 
45 #define _coap_address_equals_impl(A,B) \
46         ((A)->port == (B)->port        \
47         && uip_ipaddr_cmp(&((A)->addr),&((B)->addr)))
48 
49 /** @todo implementation of _coap_address_isany_impl() for Contiki */
50 #define _coap_address_isany_impl(A)  0
51 
52 #define _coap_is_mcast_impl(Address) uip_is_addr_mcast(&((Address)->addr))
53 #endif /* WITH_CONTIKI */
54 
55 #ifdef WITH_POSIX
56 /** multi-purpose address abstraction */
57 typedef struct coap_address_t {
58   socklen_t size;           /**< size of addr */
59   union {
60     struct sockaddr         sa;
61     struct sockaddr_storage st;
62     struct sockaddr_in      sin;
63     struct sockaddr_in6     sin6;
64   } addr;
65 } coap_address_t;
66 
67 /**
68  * Compares given address objects @p a and @p b. This function returns @c 1 if
69  * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
70  * @c NULL;
71  */
72 int coap_address_equals(const coap_address_t *a, const coap_address_t *b);
73 
74 static inline int
_coap_address_isany_impl(const coap_address_t * a)75 _coap_address_isany_impl(const coap_address_t *a) {
76   /* need to compare only relevant parts of sockaddr_in6 */
77   switch (a->addr.sa.sa_family) {
78   case AF_INET:
79     return a->addr.sin.sin_addr.s_addr == INADDR_ANY;
80   case AF_INET6:
81     return memcmp(&in6addr_any,
82                   &a->addr.sin6.sin6_addr,
83                   sizeof(in6addr_any)) == 0;
84   default:
85     ;
86   }
87 
88   return 0;
89 }
90 
91 static inline int
_coap_is_mcast_impl(const coap_address_t * a)92 _coap_is_mcast_impl(const coap_address_t *a) {
93   if (!a)
94     return 0;
95 
96  switch (a->addr.sa.sa_family) {
97  case AF_INET:
98    return IN_MULTICAST(a->addr.sin.sin_addr.s_addr);
99  case  AF_INET6:
100    return IN6_IS_ADDR_MULTICAST(&a->addr.sin6.sin6_addr);
101  default:  /* fall through and signal error */
102    ;
103   }
104  return 0;
105 }
106 #endif /* WITH_POSIX */
107 
108 /**
109  * Resets the given coap_address_t object @p addr to its default values. In
110  * particular, the member size must be initialized to the available size for
111  * storing addresses.
112  *
113  * @param addr The coap_address_t object to initialize.
114  */
115 static inline void
coap_address_init(coap_address_t * addr)116 coap_address_init(coap_address_t *addr) {
117   assert(addr);
118   memset(addr, 0, sizeof(coap_address_t));
119 #ifdef WITH_POSIX
120   /* lwip and Contiki have constant address sizes and doesn't need the .size part */
121   addr->size = sizeof(addr->addr);
122 #endif
123 }
124 
125 #ifndef WITH_POSIX
126 /**
127  * Compares given address objects @p a and @p b. This function returns @c 1 if
128  * addresses are equal, @c 0 otherwise. The parameters @p a and @p b must not be
129  * @c NULL;
130  */
131 static inline int
coap_address_equals(const coap_address_t * a,const coap_address_t * b)132 coap_address_equals(const coap_address_t *a, const coap_address_t *b) {
133   assert(a); assert(b);
134   return _coap_address_equals_impl(a, b);
135 }
136 #endif
137 
138 /**
139  * Checks if given address object @p a denotes the wildcard address. This
140  * function returns @c 1 if this is the case, @c 0 otherwise. The parameters @p
141  * a must not be @c NULL;
142  */
143 static inline int
coap_address_isany(const coap_address_t * a)144 coap_address_isany(const coap_address_t *a) {
145   assert(a);
146   return _coap_address_isany_impl(a);
147 }
148 
149 /**
150  * Checks if given address @p a denotes a multicast address. This function
151  * returns @c 1 if @p a is multicast, @c 0 otherwise.
152  */
153 static inline int
coap_is_mcast(const coap_address_t * a)154 coap_is_mcast(const coap_address_t *a) {
155   return a && _coap_is_mcast_impl(a);
156 }
157 
158 #endif /* _COAP_ADDRESS_H_ */
159