fe7c1ca5de78e0c560e0409d7d7a4b6b25f94ef8
[oonf.git] / src-api / common / netaddr.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4  * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 /**
43  * @file
44  */
45
46 #ifndef NETADDR_H_
47 #define NETADDR_H_
48
49 #ifndef _WIN32
50 #include <arpa/inet.h>
51 #include <net/if.h>
52 #include <netinet/if_ether.h>
53 #include <netinet/ip.h>
54 #else
55 #include <winsock2.h>
56 #include <ws2tcpip.h>
57
58 #define IF_NAMESIZE 16
59 #endif
60
61 #include <string.h>
62
63 #include "common/autobuf.h"
64 #include "common/common_types.h"
65
66 enum
67 {
68   /*! address family for 48-bit mac address */
69   AF_MAC48 = AF_MAX + 1,
70
71   /*! address family for 64-bit EUI-64 address */
72   AF_EUI64 = AF_MAX + 2,
73
74   /*! universal unique identifier (UUID) */
75   AF_UUID = AF_MAX + 3,
76 };
77
78 enum
79 {
80   /*! maximum length of a network address in octets */
81   NETADDR_MAX_LENGTH = 16
82 };
83
84 /*! text name for IPv4_ANY prefix */
85 #define NETADDR_STR_ANY4 "any4"
86
87 /*! text name for IPv6 ANY prefix */
88 #define NETADDR_STR_ANY6 "any6"
89
90 /*! text name for IPv4 linklocal prefix */
91 #define NETADDR_STR_LINKLOCAL4 "linklocal4"
92
93 /*! text name for IPv6 linklocal prefix */
94 #define NETADDR_STR_LINKLOCAL6 "linklocal6"
95
96 /*! text name for IPv6 unique local prefix */
97 #define NETADDR_STR_ULA "ula"
98
99 /**
100  * Representation of an address including address type
101  * At the moment we support AF_INET, AF_INET6 and AF_MAC48
102  */
103 struct netaddr {
104   /*! 16 bytes of memory for address */
105   uint8_t _addr[NETADDR_MAX_LENGTH];
106
107   /*! address type */
108   uint8_t _type;
109
110   /*! address prefix length */
111   uint8_t _prefix_len;
112 };
113
114 /**
115  * Representation of a sockaddr object. Allows access
116  * to all variants without casting and compiler warnings.
117  */
118 union netaddr_socket {
119   /*! IPv4 sockaddr */
120   struct sockaddr_in v4;
121
122   /*! IPv6 sockaddr */
123   struct sockaddr_in6 v6;
124
125   /*! generic sockaddr */
126   struct sockaddr std;
127
128   /*! storage object for sockaddr */
129   struct sockaddr_storage storage;
130 };
131
132 /**
133  * Maximum text length of netaddr_to_string
134  *
135  * INET_ADDRSTRLEN and INET6_ADDRSTRLEN have been defined
136  * in netinet/in.h, which has been included by this file
137  */
138 enum
139 {
140   MAC48_ADDRSTRLEN = 18,
141   MAC48_PREFIXSTRLEN = MAC48_ADDRSTRLEN + 3,
142   EUI64_ADDRSTRLEN = 24,
143   EUI64_PREFIXSTRLEN = EUI64_ADDRSTRLEN + 3,
144   INET_PREFIXSTRLEN = INET_ADDRSTRLEN + 3,
145   INET6_PREFIXSTRLEN = INET6_ADDRSTRLEN + 4,
146 };
147
148 /**
149  * Buffer for writing string representation of netaddr
150  * and netaddr_socket objects
151  */
152 struct netaddr_str {
153   /*! buffer for maximum length netaddr string representation */
154   char buf[INET6_ADDRSTRLEN + 16];
155 };
156
157 EXPORT extern const struct netaddr NETADDR_UNSPEC;
158
159 EXPORT extern const struct netaddr NETADDR_IPV4_ANY;
160 EXPORT extern const struct netaddr NETADDR_IPV4_BINDTO_ANY;
161 EXPORT extern const struct netaddr NETADDR_IPV4_MULTICAST;
162 EXPORT extern const struct netaddr NETADDR_IPV4_LINKLOCAL;
163 EXPORT extern const struct netaddr NETADDR_IPV4_LOOPBACK_NET;
164
165 EXPORT extern const struct netaddr NETADDR_IPV6_ANY;
166 EXPORT extern const struct netaddr NETADDR_IPV6_BINDTO_ANY;
167 EXPORT extern const struct netaddr NETADDR_IPV6_MULTICAST;
168 EXPORT extern const struct netaddr NETADDR_IPV6_LINKLOCAL;
169 EXPORT extern const struct netaddr NETADDR_IPV6_ULA;
170 EXPORT extern const struct netaddr NETADDR_IPV6_GLOBAL;
171 EXPORT extern const struct netaddr NETADDR_IPV6_IPV4COMPATIBLE;
172 EXPORT extern const struct netaddr NETADDR_IPV6_IPV4MAPPED;
173 EXPORT extern const struct netaddr NETADDR_IPV6_LOOPBACK;
174 EXPORT extern const struct netaddr NETADDR_MAC48_BROADCAST;
175
176 EXPORT extern const union netaddr_socket NETADDR_SOCKET_IPV4_ANY;
177 EXPORT extern const union netaddr_socket NETADDR_SOCKET_IPV6_ANY;
178
179 EXPORT int netaddr_from_binary_prefix(
180   struct netaddr *dst, const void *binary, size_t len, uint8_t addr_type, uint8_t prefix_len);
181 EXPORT int netaddr_to_binary(void *dst, const struct netaddr *src, size_t len);
182 EXPORT int netaddr_from_socket(struct netaddr *dst, const union netaddr_socket *src);
183 EXPORT int netaddr_to_socket(union netaddr_socket *dst, const struct netaddr *src);
184 EXPORT int netaddr_to_autobuf(struct autobuf *, const struct netaddr *src);
185 EXPORT int netaddr_create_host_bin(
186   struct netaddr *host, const struct netaddr *netmask, const void *number, size_t num_length);
187 EXPORT int netaddr_create_prefix(
188   struct netaddr *prefix, const struct netaddr *host, const struct netaddr *netmask, bool truncate);
189 EXPORT void netaddr_truncate(struct netaddr *dst, const struct netaddr *src);
190
191 EXPORT int netaddr_socket_init(
192   union netaddr_socket *combined, const struct netaddr *addr, uint16_t port, unsigned if_index);
193 EXPORT uint16_t netaddr_socket_get_port(const union netaddr_socket *sock);
194 EXPORT const char *netaddr_to_prefixstring(struct netaddr_str *dst, const struct netaddr *src, bool forceprefix);
195 EXPORT int netaddr_from_string(struct netaddr *, const char *) __attribute__((warn_unused_result));
196 EXPORT const char *netaddr_socket_to_string(struct netaddr_str *, const union netaddr_socket *);
197
198 EXPORT int netaddr_cmp_to_socket(const struct netaddr *, const union netaddr_socket *);
199 EXPORT bool netaddr_isequal_binary(
200   const struct netaddr *addr, const void *bin, size_t len, uint16_t af, uint8_t prefix_len);
201 EXPORT bool netaddr_is_in_subnet(const struct netaddr *subnet, const struct netaddr *addr);
202 EXPORT bool netaddr_binary_is_in_subnet(const struct netaddr *subnet, const void *bin, size_t len, uint8_t af_family);
203
204 EXPORT uint8_t netaddr_get_af_maxprefix(const uint32_t);
205
206 EXPORT int netaddr_avlcmp(const void *, const void *);
207 EXPORT int netaddr_socket_avlcmp(const void *, const void *);
208
209 #ifdef WIN32
210 EXPORT const char *inet_ntop(int af, const void *src, char *dst, int cnt);
211 EXPORT int inet_pton(int af, const char *cp, void *buf);
212 #endif
213
214 /**
215  * Sets the address type of a netaddr object to AF_UNSPEC
216  * @param addr netaddr object
217  */
218 static INLINE void
219 netaddr_invalidate(struct netaddr *addr) {
220   memset(addr, 0, sizeof(*addr));
221 }
222
223 /**
224  * Sets the address type of a netaddr object to AF_UNSPEC
225  * @param sock netaddr socket object
226  */
227 static INLINE void
228 netaddr_socket_invalidate(union netaddr_socket *sock) {
229   memset(sock, 0, sizeof(*sock));
230 }
231
232 /**
233  * @param addr netaddr object
234  * @return true if address is AF_UNSPEC, false otherwise
235  */
236 static INLINE bool
237 netaddr_is_unspec(const struct netaddr *addr) {
238   return addr->_type == AF_UNSPEC;
239 }
240
241 /**
242  * @param sock netaddr socket object
243  * @return true if address is AF_UNSPEC, false otherwise
244  */
245 static INLINE bool
246 netaddr_socket_is_unspec(const union netaddr_socket *sock) {
247   return sock->std.sa_family == AF_UNSPEC;
248 }
249
250 /**
251  * Calculates the maximum prefix length of an address type
252  * @param addr netaddr object
253  * @return prefix length, 0 if unknown address family
254  */
255 static INLINE uint8_t
256 netaddr_get_maxprefix(const struct netaddr *addr) {
257   return netaddr_get_af_maxprefix(addr->_type);
258 }
259
260 /**
261  * Check if an address has the maximum prefix length
262  * @param addr netaddr object
263  * @return true if prefix length is maximum, false otherwise
264  */
265 static INLINE bool
266 netaddr_is_host(const struct netaddr *addr) {
267   return netaddr_get_maxprefix(addr) == addr->_prefix_len;
268 }
269
270 /**
271  * Converts a netaddr object into a string.
272  * Prefix will be added if necessary.
273  * @param dst target buffer
274  * @param src netaddr source
275  * @return pointer to target buffer, NULL if an error happened
276  */
277 static INLINE const char *
278 netaddr_to_string(struct netaddr_str *dst, const struct netaddr *src) {
279   return netaddr_to_prefixstring(dst, src, false);
280 }
281
282 /**
283  * Creates a host address from a netmask and a host number part. This function
284  * will copy the netmask and then overwrite the bits after the prefix length
285  * with the one from the host number.
286  * @param host target buffer
287  * @param netmask prefix of result
288  * @param host_number postfix of result
289  * @return -1 if an error happened, 0 otherwise
290  */
291 static INLINE int
292 netaddr_create_host(struct netaddr *host, const struct netaddr *netmask, const struct netaddr *host_number) {
293   return netaddr_create_host_bin(host, netmask, host_number->_addr, netaddr_get_maxprefix(host_number) / 8);
294 }
295
296 /**
297  * Embed an IPv4 address into an IPv6 IPv4-compatible address
298  * @param dst target IPv6 address
299  * @param src source IPv4 address
300  */
301 static INLINE void
302 netaddr_embed_ipv4_compatible(struct netaddr *dst, const struct netaddr *src) {
303   memcpy(&dst->_addr[0], &NETADDR_IPV6_IPV4COMPATIBLE._addr[0], 12);
304   memcpy(&dst->_addr[12], &src->_addr[0], 4);
305   dst->_type = AF_INET6;
306   dst->_prefix_len = src->_prefix_len + 96;
307 }
308
309 /**
310  * Extract an IPv4 address from an IPv6 IPv4-compatible address
311  * @param dst target IPv4 address
312  * @param src source IPv6 address
313  */
314 static INLINE void
315 netaddr_extract_ipv4_compatible(struct netaddr *dst, const struct netaddr *src) {
316   memcpy(&dst->_addr[0], &src->_addr[12], 4);
317   memset(&dst->_addr[4], 0, 12);
318   dst->_type = AF_INET;
319   dst->_prefix_len = src->_prefix_len - 96;
320 }
321
322 /**
323  * Read the binary representation of an address into a netaddr object
324  * @param dst pointer to netaddr object
325  * @param binary source pointer
326  * @param len length of source buffer
327  * @param addr_type address type of source,
328  *   0 for autodetection based on length
329  * @return 0 if successful read binary data, -1 otherwise
330  */
331 static INLINE int
332 netaddr_from_binary(struct netaddr *dst, const void *binary, size_t len, uint8_t addr_type) {
333   return netaddr_from_binary_prefix(dst, binary, len, addr_type, 255);
334 }
335
336 /**
337  * Compares two addresses.
338  * Address type will be compared last.
339  * @param a1 address 1
340  * @param a2 address 2
341  * @return >0 if a1>a2, <0 if a1<a2, 0 otherwise
342  */
343 static INLINE int
344 netaddr_cmp(const struct netaddr *a1, const struct netaddr *a2) {
345   return memcmp(a1, a2, sizeof(*a1));
346 }
347
348 /**
349  * Compares two sockets.
350  * @param s1 socket address port 1
351  * @param s2 socket address/port 2
352  * @return >0 if s1>s2, <0 if s1<s2, 0 otherwise
353  */
354 static INLINE int
355 netaddr_socket_cmp(const union netaddr_socket *s1, const union netaddr_socket *s2) {
356   return memcmp(s1, s2, sizeof(*s1));
357 }
358
359 /**
360  * @param n pointer to netaddr
361  * @return pointer to start of binary address
362  */
363 static INLINE const void *
364 netaddr_get_binptr(const struct netaddr *n) {
365   return &n->_addr[0];
366 }
367
368 /**
369  * @param n pointer to netaddr
370  * @return number of bytes of binary address
371  */
372 static INLINE size_t
373 netaddr_get_binlength(const struct netaddr *n) {
374   return netaddr_get_maxprefix(n) >> 3;
375 }
376
377 /**
378  * @param n pointer to netaddr
379  * @return address family
380  */
381 static INLINE uint8_t
382 netaddr_get_address_family(const struct netaddr *n) {
383   return n->_type;
384 }
385
386 /**
387  * @param n pointer to netaddr
388  * @return prefix length
389  */
390 static INLINE uint8_t
391 netaddr_get_prefix_length(const struct netaddr *n) {
392   return n->_prefix_len;
393 }
394
395 /**
396  * @param n pointer to netaddr
397  * @param prefix_len new prefix length
398  */
399 static INLINE void
400 netaddr_set_prefix_length(struct netaddr *n, uint8_t prefix_len) {
401   n->_prefix_len = prefix_len;
402 }
403
404 /**
405  * @param s pointer to netaddr socket
406  * @return address family of socket
407  */
408 static INLINE sa_family_t
409 netaddr_socket_get_addressfamily(const union netaddr_socket *s) {
410   return s->std.sa_family;
411 }
412
413 #endif /* NETADDR_H_ */