Annotation of embedaddon/strongswan/src/libstrongswan/networking/host.c, revision 1.1.1.1
1.1 misho 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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>