110ece894130457396adb56eb832fe42d4ff0b69
[strongswan.git] / src / libstrongswan / networking / host.c
1 /*
2 * Copyright (C) 2006-2014 Tobias Brunner
3 * Copyright (C) 2006 Daniel Roethlisberger
4 * Copyright (C) 2005-2006 Martin Willi
5 * Copyright (C) 2005 Jan Hutter
6 * HSR Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include "host.h"
20
21 #include <utils/debug.h>
22 #include <library.h>
23
24 #define IPV4_LEN 4
25 #define IPV6_LEN 16
26
27 typedef struct private_host_t private_host_t;
28
29 /**
30 * Private Data of a host object.
31 */
32 struct private_host_t {
33 /**
34 * Public data
35 */
36 host_t public;
37
38 /**
39 * low-lewel structure, which stores the address
40 */
41 union {
42 /** generic type */
43 struct sockaddr address;
44 /** maximum sockaddr size */
45 struct sockaddr_storage address_max;
46 /** IPv4 address */
47 struct sockaddr_in address4;
48 /** IPv6 address */
49 struct sockaddr_in6 address6;
50 };
51 /**
52 * length of address structure
53 */
54 socklen_t socklen;
55 };
56
57 /**
58 * Update the sockaddr internal sa_len option, if available
59 */
60 static inline void update_sa_len(private_host_t *this)
61 {
62 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
63 this->address.sa_len = this->socklen;
64 #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
65 }
66
67 METHOD(host_t, get_sockaddr, sockaddr_t*,
68 private_host_t *this)
69 {
70 return &(this->address);
71 }
72
73 METHOD(host_t, get_sockaddr_len, socklen_t*,
74 private_host_t *this)
75 {
76 return &(this->socklen);
77 }
78
79 METHOD(host_t, is_anyaddr, bool,
80 private_host_t *this)
81 {
82 static const uint8_t zeroes[IPV6_LEN];
83
84 switch (this->address.sa_family)
85 {
86 case AF_INET:
87 {
88 return memeq(zeroes, &(this->address4.sin_addr.s_addr), IPV4_LEN);
89 }
90 case AF_INET6:
91 {
92 return memeq(zeroes, &(this->address6.sin6_addr.s6_addr), IPV6_LEN);
93 }
94 default:
95 {
96 return FALSE;
97 }
98 }
99 }
100
101 /**
102 * Described in header.
103 */
104 int host_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
105 const void *const *args)
106 {
107 private_host_t *this = *((private_host_t**)(args[0]));
108 char buffer[INET6_ADDRSTRLEN + 16];
109
110 if (this == NULL)
111 {
112 snprintf(buffer, sizeof(buffer), "(null)");
113 }
114 else if (is_anyaddr(this) && !spec->plus && !spec->hash)
115 {
116 snprintf(buffer, sizeof(buffer), "%%any%s",
117 this->address.sa_family == AF_INET6 ? "6" : "");
118 }
119 else
120 {
121 void *address;
122 uint16_t port;
123 int len;
124
125 address = &this->address6.sin6_addr;
126 port = this->address6.sin6_port;
127
128 switch (this->address.sa_family)
129 {
130 case AF_INET:
131 address = &this->address4.sin_addr;
132 port = this->address4.sin_port;
133 /* fall */
134 case AF_INET6:
135
136 if (inet_ntop(this->address.sa_family, address,
137 buffer, sizeof(buffer)) == NULL)
138 {
139 snprintf(buffer, sizeof(buffer),
140 "(address conversion failed)");
141 }
142 else if (spec->hash && port)
143 {
144 len = strlen(buffer);
145 snprintf(buffer + len, sizeof(buffer) - len,
146 "[%d]", ntohs(port));
147 }
148 break;
149 default:
150 snprintf(buffer, sizeof(buffer), "(family not supported)");
151 break;
152 }
153 }
154 if (spec->minus)
155 {
156 return print_in_hook(data, "%-*s", spec->width, buffer);
157 }
158 return print_in_hook(data, "%*s", spec->width, buffer);
159 }
160
161 METHOD(host_t, get_address, chunk_t,
162 private_host_t *this)
163 {
164 chunk_t address = chunk_empty;
165
166 switch (this->address.sa_family)
167 {
168 case AF_INET:
169 {
170 address.ptr = (char*)&(this->address4.sin_addr.s_addr);
171 address.len = IPV4_LEN;
172 return address;
173 }
174 case AF_INET6:
175 {
176 address.ptr = (char*)&(this->address6.sin6_addr.s6_addr);
177 address.len = IPV6_LEN;
178 return address;
179 }
180 default:
181 {
182 /* return empty chunk */
183 return address;
184 }
185 }
186 }
187
188 METHOD(host_t, get_family, int,
189 private_host_t *this)
190 {
191 return this->address.sa_family;
192 }
193
194 METHOD(host_t, get_port, uint16_t,
195 private_host_t *this)
196 {
197 switch (this->address.sa_family)
198 {
199 case AF_INET:
200 {
201 return ntohs(this->address4.sin_port);
202 }
203 case AF_INET6:
204 {
205 return ntohs(this->address6.sin6_port);
206 }
207 default:
208 {
209 return 0;
210 }
211 }
212 }
213
214 METHOD(host_t, set_port, void,
215 private_host_t *this, uint16_t port)
216 {
217 switch (this->address.sa_family)
218 {
219 case AF_INET:
220 {
221 this->address4.sin_port = htons(port);
222 break;
223 }
224 case AF_INET6:
225 {
226 this->address6.sin6_port = htons(port);
227 break;
228 }
229 default:
230 {
231 break;
232 }
233 }
234 }
235
236 METHOD(host_t, clone_, host_t*,
237 private_host_t *this)
238 {
239 private_host_t *new;
240
241 new = malloc_thing(private_host_t);
242 memcpy(new, this, sizeof(private_host_t));
243
244 return &new->public;
245 }
246
247 /**
248 * Implements host_t.ip_equals
249 */
250 static bool ip_equals(private_host_t *this, private_host_t *other)
251 {
252 if (this->address.sa_family != other->address.sa_family)
253 {
254 /* 0.0.0.0 and 0::0 are equal */
255 return (is_anyaddr(this) && is_anyaddr(other));
256 }
257
258 switch (this->address.sa_family)
259 {
260 case AF_INET:
261 {
262 return memeq(&this->address4.sin_addr, &other->address4.sin_addr,
263 sizeof(this->address4.sin_addr));
264 }
265 case AF_INET6:
266 {
267 return memeq(&this->address6.sin6_addr, &other->address6.sin6_addr,
268 sizeof(this->address6.sin6_addr));
269 }
270 default:
271 break;
272 }
273 return FALSE;
274 }
275
276 /**
277 * Implements host_t.equals
278 */
279 static bool equals(private_host_t *this, private_host_t *other)
280 {
281 if (!ip_equals(this, other))
282 {
283 return FALSE;
284 }
285
286 switch (this->address.sa_family)
287 {
288 case AF_INET:
289 {
290 return (this->address4.sin_port == other->address4.sin_port);
291 }
292 case AF_INET6:
293 {
294 return (this->address6.sin6_port == other->address6.sin6_port);
295 }
296 default:
297 break;
298 }
299 return FALSE;
300 }
301
302 METHOD(host_t, destroy, void,
303 private_host_t *this)
304 {
305 free(this);
306 }
307
308 /**
309 * Creates an empty host_t object
310 */
311 static private_host_t *host_create_empty(void)
312 {
313 private_host_t *this;
314
315 INIT(this,
316 .public = {
317 .get_sockaddr = _get_sockaddr,
318 .get_sockaddr_len = _get_sockaddr_len,
319 .clone = _clone_,
320 .get_family = _get_family,
321 .get_address = _get_address,
322 .get_port = _get_port,
323 .set_port = _set_port,
324 .ip_equals = (bool (*)(host_t *,host_t *))ip_equals,
325 .equals = (bool (*)(host_t *,host_t *)) equals,
326 .is_anyaddr = _is_anyaddr,
327 .destroy = _destroy,
328 },
329 );
330
331 return this;
332 }
333
334 /*
335 * Create a %any host with port
336 */
337 static host_t *host_create_any_port(int family, uint16_t port)
338 {
339 host_t *this;
340
341 this = host_create_any(family);
342 this->set_port(this, port);
343 return this;
344 }
345
346 /*
347 * Described in header.
348 */
349 host_t *host_create_from_string_and_family(char *string, int family,
350 uint16_t port)
351 {
352 union {
353 struct sockaddr_in v4;
354 struct sockaddr_in6 v6;
355 } addr;
356
357 if (!string)
358 {
359 return NULL;
360 }
361 if (streq(string, "%any"))
362 {
363 return host_create_any_port(family ? family : AF_INET, port);
364 }
365 if (family == AF_UNSPEC || family == AF_INET)
366 {
367 if (streq(string, "%any4") || streq(string, "0.0.0.0"))
368 {
369 return host_create_any_port(AF_INET, port);
370 }
371 }
372 if (family == AF_UNSPEC || family == AF_INET6)
373 {
374 if (streq(string, "%any6") || streq(string, "::"))
375 {
376 return host_create_any_port(AF_INET6, port);
377 }
378 }
379 switch (family)
380 {
381 case AF_UNSPEC:
382 if (strchr(string, '.'))
383 {
384 goto af_inet;
385 }
386 /* FALL */
387 case AF_INET6:
388 memset(&addr.v6, 0, sizeof(addr.v6));
389 if (inet_pton(AF_INET6, string, &addr.v6.sin6_addr) != 1)
390 {
391 return NULL;
392 }
393 addr.v6.sin6_port = htons(port);
394 addr.v6.sin6_family = AF_INET6;
395 return host_create_from_sockaddr((sockaddr_t*)&addr);
396 case AF_INET:
397 if (strchr(string, ':'))
398 { /* do not try to convert v6 addresses for v4 family */
399 return NULL;
400 }
401 af_inet:
402 memset(&addr.v4, 0, sizeof(addr.v4));
403 if (inet_pton(AF_INET, string, &addr.v4.sin_addr) != 1)
404 {
405 return NULL;
406 }
407 addr.v4.sin_port = htons(port);
408 addr.v4.sin_family = AF_INET;
409 return host_create_from_sockaddr((sockaddr_t*)&addr);
410 default:
411 return NULL;
412 }
413 }
414
415 /*
416 * Described in header.
417 */
418 host_t *host_create_from_string(char *string, uint16_t port)
419 {
420 return host_create_from_string_and_family(string, AF_UNSPEC, port);
421 }
422
423 /*
424 * Described in header.
425 */
426 host_t *host_create_from_sockaddr(sockaddr_t *sockaddr)
427 {
428 private_host_t *this = host_create_empty();
429
430 switch (sockaddr->sa_family)
431 {
432 case AF_INET:
433 {
434 memcpy(&this->address4, (struct sockaddr_in*)sockaddr,
435 sizeof(struct sockaddr_in));
436 this->socklen = sizeof(struct sockaddr_in);
437 update_sa_len(this);
438 return &this->public;
439 }
440 case AF_INET6:
441 {
442 memcpy(&this->address6, (struct sockaddr_in6*)sockaddr,
443 sizeof(struct sockaddr_in6));
444 this->socklen = sizeof(struct sockaddr_in6);
445 update_sa_len(this);
446 return &this->public;
447 }
448 default:
449 break;
450 }
451 free(this);
452 return NULL;
453 }
454
455 /*
456 * Described in header.
457 */
458 host_t *host_create_from_dns(char *string, int af, uint16_t port)
459 {
460 host_t *this;
461
462 this = host_create_from_string_and_family(string, af, port);
463 if (!this)
464 {
465 this = lib->hosts->resolve(lib->hosts, string, af);
466 }
467 if (this)
468 {
469 this->set_port(this, port);
470 }
471 return this;
472 }
473
474 /*
475 * Described in header.
476 */
477 host_t *host_create_from_chunk(int family, chunk_t address, uint16_t port)
478 {
479 private_host_t *this;
480
481 switch (family)
482 {
483 case AF_INET:
484 if (address.len < IPV4_LEN)
485 {
486 return NULL;
487 }
488 address.len = IPV4_LEN;
489 break;
490 case AF_INET6:
491 if (address.len < IPV6_LEN)
492 {
493 return NULL;
494 }
495 address.len = IPV6_LEN;
496 break;
497 case AF_UNSPEC:
498 switch (address.len)
499 {
500 case IPV4_LEN:
501 family = AF_INET;
502 break;
503 case IPV6_LEN:
504 family = AF_INET6;
505 break;
506 default:
507 return NULL;
508 }
509 break;
510 default:
511 return NULL;
512 }
513 this = host_create_empty();
514 this->address.sa_family = family;
515 switch (family)
516 {
517 case AF_INET:
518 memcpy(&this->address4.sin_addr.s_addr, address.ptr, address.len);
519 this->address4.sin_port = htons(port);
520 this->socklen = sizeof(struct sockaddr_in);
521 break;
522 case AF_INET6:
523 memcpy(&this->address6.sin6_addr.s6_addr, address.ptr, address.len);
524 this->address6.sin6_port = htons(port);
525 this->socklen = sizeof(struct sockaddr_in6);
526 break;
527 }
528 update_sa_len(this);
529 return &this->public;
530 }
531
532 /*
533 * Described in header.
534 */
535 bool host_create_from_range(char *string, host_t **from, host_t **to)
536 {
537 char *sep, *pos;
538
539 sep = strchr(string, '-');
540 if (!sep)
541 {
542 return FALSE;
543 }
544 for (pos = sep+1; *pos && *pos == ' '; pos++)
545 {
546 /* trim spaces before to address*/
547 }
548 *to = host_create_from_string(pos, 0);
549 if (!*to)
550 {
551 return FALSE;
552 }
553 for (pos = sep-1; pos > string && *pos == ' '; pos--)
554 {
555 /* trim spaces behind from address */
556 }
557 pos = strndup(string, pos - string + 1);
558 *from = host_create_from_string_and_family(pos, (*to)->get_family(*to), 0);
559 free(pos);
560 if (!*from)
561 {
562 (*to)->destroy(*to);
563 return FALSE;
564 }
565 return TRUE;
566 }
567
568 /*
569 * Described in header.
570 */
571 host_t *host_create_from_subnet(char *string, int *bits)
572 {
573 char *pos, buf[64];
574 host_t *net;
575
576 pos = strchr(string, '/');
577 if (pos)
578 {
579 if (pos - string >= sizeof(buf))
580 {
581 return NULL;
582 }
583 strncpy(buf, string, pos - string);
584 buf[pos - string] = '\0';
585 *bits = atoi(pos + 1);
586 return host_create_from_string(buf, 0);
587 }
588 net = host_create_from_string(string, 0);
589 if (net)
590 {
591 if (net->get_family(net) == AF_INET)
592 {
593 *bits = 32;
594 }
595 else
596 {
597 *bits = 128;
598 }
599 }
600 return net;
601 }
602
603 /*
604 * See header.
605 */
606 host_t *host_create_netmask(int family, int netbits)
607 {
608 private_host_t *this;
609 int bits, bytes, len = 0;
610 char *target;
611
612 switch (family)
613 {
614 case AF_INET:
615 if (netbits < 0 || netbits > 32)
616 {
617 return NULL;
618 }
619 this = host_create_empty();
620 this->socklen = sizeof(struct sockaddr_in);
621 target = (char*)&this->address4.sin_addr;
622 len = 4;
623 break;
624 case AF_INET6:
625 if (netbits < 0 || netbits > 128)
626 {
627 return NULL;
628 }
629 this = host_create_empty();
630 this->socklen = sizeof(struct sockaddr_in6);
631 target = (char*)&this->address6.sin6_addr;
632 len = 16;
633 break;
634 default:
635 return NULL;
636 }
637
638 memset(&this->address_max, 0, sizeof(struct sockaddr_storage));
639 this->address.sa_family = family;
640 update_sa_len(this);
641
642 bytes = netbits / 8;
643 bits = 8 - (netbits & 0x07);
644
645 memset(target, 0xff, bytes);
646 if (bytes < len)
647 {
648 memset(target + bytes, 0x00, len - bytes);
649 target[bytes] = (uint8_t)(0xff << bits);
650 }
651 return &this->public;
652 }
653
654 /*
655 * Described in header.
656 */
657 host_t *host_create_any(int family)
658 {
659 private_host_t *this = host_create_empty();
660
661 memset(&this->address_max, 0, sizeof(struct sockaddr_storage));
662 this->address.sa_family = family;
663
664 switch (family)
665 {
666 case AF_INET:
667 {
668 this->socklen = sizeof(struct sockaddr_in);
669 update_sa_len(this);
670 return &(this->public);
671 }
672 case AF_INET6:
673 {
674 this->socklen = sizeof(struct sockaddr_in6);
675 update_sa_len(this);
676 return &this->public;
677 }
678 default:
679 break;
680 }
681 free(this);
682 return NULL;
683 }