Simplify test case creation
[oonf.git] / include / oonf / libcommon / 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 <oonf/libcommon/autobuf.h>
64 #include <oonf/oonf.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 EXPORT const struct netaddr NETADDR_MAC48_IPV4_MULTICAST;
176 EXPORT const struct netaddr NETADDR_MAC48_IPV6_MULTICAST;
177
178 EXPORT extern const union netaddr_socket NETADDR_SOCKET_IPV4_ANY;
179 EXPORT extern const union netaddr_socket NETADDR_SOCKET_IPV6_ANY;
180
181 EXPORT int netaddr_from_binary_prefix(
182   struct netaddr *dst, const void *binary, size_t len, uint8_t addr_type, uint8_t prefix_len);
183 EXPORT int netaddr_to_binary(void *dst, const struct netaddr *src, size_t len);
184 EXPORT int netaddr_from_socket(struct netaddr *dst, const union netaddr_socket *src);
185 EXPORT int netaddr_to_socket(union netaddr_socket *dst, const struct netaddr *src);
186 EXPORT int netaddr_to_autobuf(struct autobuf *, const struct netaddr *src);
187 EXPORT int netaddr_create_host_bin(
188   struct netaddr *host, const struct netaddr *netmask, const void *number, size_t num_length);
189 EXPORT int netaddr_create_prefix(
190   struct netaddr *prefix, const struct netaddr *host, const struct netaddr *netmask, bool truncate);
191 EXPORT void netaddr_truncate(struct netaddr *dst, const struct netaddr *src);
192
193 EXPORT int netaddr_socket_init(
194   union netaddr_socket *combined, const struct netaddr *addr, uint16_t port, unsigned if_index);
195 EXPORT uint16_t netaddr_socket_get_port(const union netaddr_socket *sock);
196 EXPORT const char *netaddr_to_prefixstring(struct netaddr_str *dst, const struct netaddr *src, bool forceprefix);
197 EXPORT int netaddr_from_string(struct netaddr *, const char *) __attribute__((warn_unused_result));
198 EXPORT const char *netaddr_socket_to_string(struct netaddr_str *, const union netaddr_socket *);
199
200 EXPORT int netaddr_cmp_to_socket(const struct netaddr *, const union netaddr_socket *);
201 EXPORT bool netaddr_isequal_binary(
202   const struct netaddr *addr, const void *bin, size_t len, uint16_t af, uint8_t prefix_len);
203 EXPORT bool netaddr_is_in_subnet(const struct netaddr *subnet, const struct netaddr *addr);
204 EXPORT bool netaddr_binary_is_in_subnet(const struct netaddr *subnet, const void *bin, size_t len, uint8_t af_family);
205
206 EXPORT uint8_t netaddr_get_af_maxprefix(const uint32_t);
207
208 EXPORT int netaddr_avlcmp(const void *, const void *);
209 EXPORT int netaddr_socket_avlcmp(const void *, const void *);
210
211 #ifdef WIN32
212 EXPORT const char *inet_ntop(int af, const void *src, char *dst, int cnt);
213 EXPORT int inet_pton(int af, const char *cp, void *buf);
214 #endif
215
216 /**
217  * Sets the address type of a netaddr object to AF_UNSPEC
218  * @param addr netaddr object
219  */
220 static INLINE void
221 netaddr_invalidate(struct netaddr *addr) {
222   memset(addr, 0, sizeof(*addr));
223 }
224
225 /**
226  * Sets the address type of a netaddr object to AF_UNSPEC
227  * @param sock netaddr socket object
228  */
229 static INLINE void
230 netaddr_socket_invalidate(union netaddr_socket *sock) {
231   memset(sock, 0, sizeof(*sock));
232 }
233
234 /**
235  * @param addr netaddr object (might be NULL)
236  * @return true if address is AF_UNSPEC, false otherwise
237  */
238 static INLINE bool
239 netaddr_is_unspec(const struct netaddr *addr) {
240   return addr == NULL || addr->_type == AF_UNSPEC;
241 }
242
243 /**
244  * @param sock netaddr socket object
245  * @return true if address is AF_UNSPEC, false otherwise
246  */
247 static INLINE bool
248 netaddr_socket_is_unspec(const union netaddr_socket *sock) {
249   return sock->std.sa_family == AF_UNSPEC;
250 }
251
252 /**
253  * Calculates the maximum prefix length of an address type
254  * @param addr netaddr object
255  * @return prefix length, 0 if unknown address family
256  */
257 static INLINE uint8_t
258 netaddr_get_maxprefix(const struct netaddr *addr) {
259   return netaddr_get_af_maxprefix(addr->_type);
260 }
261
262 /**
263  * Check if an address has the maximum prefix length
264  * @param addr netaddr object
265  * @return true if prefix length is maximum, false otherwise
266  */
267 static INLINE bool
268 netaddr_is_host(const struct netaddr *addr) {
269   return netaddr_get_maxprefix(addr) == addr->_prefix_len;
270 }
271
272 /**
273  * @param addr network address
274  * @return true if address is a MAC48 multicast
275  */
276 static INLINE bool
277 netaddr_is_mac48_multicast(const struct netaddr *addr) {
278   return addr->_type == AF_MAC48 && ((addr->_addr[0] & 0x01) == 0x01);
279 }
280
281 /**
282  * Converts a netaddr object into a string.
283  * Prefix will be added if necessary.
284  * @param dst target buffer
285  * @param src netaddr source
286  * @return pointer to target buffer, NULL if an error happened
287  */
288 static INLINE const char *
289 netaddr_to_string(struct netaddr_str *dst, const struct netaddr *src) {
290   return netaddr_to_prefixstring(dst, src, false);
291 }
292
293 /**
294  * Creates a host address from a netmask and a host number part. This function
295  * will copy the netmask and then overwrite the bits after the prefix length
296  * with the one from the host number.
297  * @param host target buffer
298  * @param netmask prefix of result
299  * @param host_number postfix of result
300  * @return -1 if an error happened, 0 otherwise
301  */
302 static INLINE int
303 netaddr_create_host(struct netaddr *host, const struct netaddr *netmask, const struct netaddr *host_number) {
304   return netaddr_create_host_bin(host, netmask, host_number->_addr, netaddr_get_maxprefix(host_number) / 8);
305 }
306
307 /**
308  * Embed an IPv4 address into an IPv6 IPv4-compatible address
309  * @param dst target IPv6 address
310  * @param src source IPv4 address
311  */
312 static INLINE void
313 netaddr_embed_ipv4_compatible(struct netaddr *dst, const struct netaddr *src) {
314   memcpy(&dst->_addr[0], &NETADDR_IPV6_IPV4COMPATIBLE._addr[0], 12);
315   memcpy(&dst->_addr[12], &src->_addr[0], 4);
316   dst->_type = AF_INET6;
317   dst->_prefix_len = src->_prefix_len + 96;
318 }
319
320 /**
321  * Extract an IPv4 address from an IPv6 IPv4-compatible address
322  * @param dst target IPv4 address
323  * @param src source IPv6 address
324  */
325 static INLINE void
326 netaddr_extract_ipv4_compatible(struct netaddr *dst, const struct netaddr *src) {
327   memcpy(&dst->_addr[0], &src->_addr[12], 4);
328   memset(&dst->_addr[4], 0, 12);
329   dst->_type = AF_INET;
330   dst->_prefix_len = src->_prefix_len - 96;
331 }
332
333 /**
334  * Generate a stateless autoconfigured IPv6 address from an IPv6 template and a MAC address.
335  * @param ipv6 generated IPv6 address
336  * @param template original IPv6 address or prefix, lower 8 bytes will be overwritten
337  * @param mac MAC address to generate host part of address
338  */
339 static INLINE void
340 netaddr_get_stateless_ipv6(struct netaddr *ipv6, const struct netaddr *template, const struct netaddr *mac) {
341   memcpy(&ipv6->_addr[0], &template->_addr[0], 8);
342   ipv6->_addr[ 8] = mac->_addr[0] ^ 0x02;
343   ipv6->_addr[ 9] = mac->_addr[1];
344   ipv6->_addr[10] = mac->_addr[2];
345   ipv6->_addr[11] = 0xff;
346   ipv6->_addr[12] = 0xfe;
347   ipv6->_addr[13] = mac->_addr[3];
348   ipv6->_addr[14] = mac->_addr[4];
349   ipv6->_addr[15] = mac->_addr[5];
350   ipv6->_type = AF_INET6;
351   ipv6->_prefix_len = 128;
352 }
353
354 /**
355  * Read the binary representation of an address into a netaddr object
356  * @param dst pointer to netaddr object
357  * @param binary source pointer
358  * @param len length of source buffer
359  * @param addr_type address type of source,
360  *   0 for autodetection based on length
361  * @return 0 if successful read binary data, -1 otherwise
362  */
363 static INLINE int
364 netaddr_from_binary(struct netaddr *dst, const void *binary, size_t len, uint8_t addr_type) {
365   return netaddr_from_binary_prefix(dst, binary, len, addr_type, 255);
366 }
367
368 /**
369  * Compares two addresses.
370  * Address type will be compared last.
371  * @param a1 address 1
372  * @param a2 address 2
373  * @return >0 if a1>a2, <0 if a1<a2, 0 otherwise
374  */
375 static INLINE int
376 netaddr_cmp(const struct netaddr *a1, const struct netaddr *a2) {
377   return memcmp(a1, a2, sizeof(*a1));
378 }
379
380 /**
381  * Compares two sockets.
382  * @param s1 socket address port 1
383  * @param s2 socket address/port 2
384  * @return >0 if s1>s2, <0 if s1<s2, 0 otherwise
385  */
386 static INLINE int
387 netaddr_socket_cmp(const union netaddr_socket *s1, const union netaddr_socket *s2) {
388   return memcmp(s1, s2, sizeof(*s1));
389 }
390
391 /**
392  * @param n pointer to netaddr
393  * @return pointer to start of binary address
394  */
395 static INLINE const void *
396 netaddr_get_binptr(const struct netaddr *n) {
397   return &n->_addr[0];
398 }
399
400 /**
401  * @param n pointer to netaddr
402  * @return number of bytes of binary address
403  */
404 static INLINE size_t
405 netaddr_get_binlength(const struct netaddr *n) {
406   return netaddr_get_maxprefix(n) >> 3;
407 }
408
409 /**
410  * @param n pointer to netaddr
411  * @return address family
412  */
413 static INLINE uint8_t
414 netaddr_get_address_family(const struct netaddr *n) {
415   return n->_type;
416 }
417
418 /**
419  * @param n pointer to netaddr
420  * @return prefix length
421  */
422 static INLINE uint8_t
423 netaddr_get_prefix_length(const struct netaddr *n) {
424   return n->_prefix_len;
425 }
426
427 /**
428  * @param n pointer to netaddr
429  * @param prefix_len new prefix length
430  */
431 static INLINE void
432 netaddr_set_prefix_length(struct netaddr *n, uint8_t prefix_len) {
433   n->_prefix_len = prefix_len;
434 }
435
436 /**
437  * @param s pointer to netaddr socket
438  * @return address family of socket
439  */
440 static INLINE sa_family_t
441 netaddr_socket_get_addressfamily(const union netaddr_socket *s) {
442   return s->std.sa_family;
443 }
444
445 #endif /* NETADDR_H_ */