fixed initialization of netbits
[strongswan.git] / src / libstrongswan / selectors / traffic_selector.c
1 /*
2 * Copyright (C) 2007-2009 Tobias Brunner
3 * Copyright (C) 2005-2007 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include <arpa/inet.h>
19 #include <string.h>
20 #include <netdb.h>
21 #include <stdio.h>
22
23 #include "traffic_selector.h"
24
25 #include <utils/linked_list.h>
26 #include <utils/identification.h>
27
28 #define NON_SUBNET_ADDRESS_RANGE 255
29
30 ENUM(ts_type_name, TS_IPV4_ADDR_RANGE, TS_IPV6_ADDR_RANGE,
31 "TS_IPV4_ADDR_RANGE",
32 "TS_IPV6_ADDR_RANGE",
33 );
34
35 typedef struct private_traffic_selector_t private_traffic_selector_t;
36
37 /**
38 * Private data of an traffic_selector_t object
39 */
40 struct private_traffic_selector_t {
41
42 /**
43 * Public part
44 */
45 traffic_selector_t public;
46
47 /**
48 * Type of address
49 */
50 ts_type_t type;
51
52 /**
53 * IP protocol (UDP, TCP, ICMP, ...)
54 */
55 u_int8_t protocol;
56
57 /**
58 * narrow this traffic selector to hosts external ip
59 * if set, from and to have no meaning until set_address() is called
60 */
61 bool dynamic;
62
63 /**
64 * subnet size in CIDR notation, 255 means a non-subnet address range
65 */
66 u_int8_t netbits;
67
68 /**
69 * begin of address range, network order
70 */
71 union {
72 /** dummy char for common address manipulation */
73 char from[0];
74 /** IPv4 address */
75 u_int32_t from4[1];
76 /** IPv6 address */
77 u_int32_t from6[4];
78 };
79
80 /**
81 * end of address range, network order
82 */
83 union {
84 /** dummy char for common address manipulation */
85 char to[0];
86 /** IPv4 address */
87 u_int32_t to4[1];
88 /** IPv6 address */
89 u_int32_t to6[4];
90 };
91
92 /**
93 * begin of port range
94 */
95 u_int16_t from_port;
96
97 /**
98 * end of port range
99 */
100 u_int16_t to_port;
101 };
102
103 /**
104 * calculate the "to"-address for the "from" address and a subnet size
105 */
106 static void calc_range(private_traffic_selector_t *this, u_int8_t netbits)
107 {
108 int byte;
109 size_t size = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
110
111 this->netbits = netbits;
112
113 /* go through the from address, starting at the tail. While we
114 * have not processed the bits belonging to the host, set them to 1 on
115 * the to address. If we reach the bits for the net, copy them from "from". */
116 for (byte = size - 1; byte >= 0; byte--)
117 {
118 u_char mask = 0x00;
119 int shift;
120
121 shift = (byte+1) * 8 - netbits;
122 if (shift > 0)
123 {
124 mask = 1 << shift;
125 if (mask != 0xFF)
126 {
127 mask--;
128 }
129 }
130 this->from[byte] &= ~mask;
131 this->to[byte] = this->from[byte] | mask;
132 }
133 }
134
135 /**
136 * calculate the subnet size from the "to" and "from" addresses
137 */
138 static u_int8_t calc_netbits(private_traffic_selector_t *this)
139 {
140 int byte, bit;
141 u_int8_t netbits;
142 size_t size = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
143 bool prefix = TRUE;
144
145 /* a perfect match results in a single address with a /32 or /128 netmask */
146 netbits = (size * 8);
147 this->netbits = netbits;
148
149 /* go through all bits of the addresses, beginning in the front.
150 * as long as they are equal, the subnet gets larger
151 */
152 for (byte = 0; byte < size; byte++)
153 {
154 for (bit = 7; bit >= 0; bit--)
155 {
156 u_int8_t bitmask = 1 << bit;
157
158 if (prefix)
159 {
160 if ((bitmask & this->from[byte]) != (bitmask & this->to[byte]))
161 {
162 /* store the common prefix which might be a true subnet */
163 netbits = (7 - bit) + (byte * 8);
164 this->netbits = netbits;
165 prefix = FALSE;
166 }
167 }
168 else
169 {
170 if ((bitmask & this->from[byte]) || !(bitmask & this->to[byte]))
171 {
172 this->netbits = NON_SUBNET_ADDRESS_RANGE;
173 return netbits; /* return a pseudo subnet */
174
175 }
176 }
177 }
178 }
179 return netbits; /* return a true subnet */
180 }
181
182 /**
183 * internal generic constructor
184 */
185 static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port);
186
187 /**
188 * Described in header.
189 */
190 int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
191 const void *const *args)
192 {
193 private_traffic_selector_t *this = *((private_traffic_selector_t**)(args[0]));
194 linked_list_t *list = *((linked_list_t**)(args[0]));
195 iterator_t *iterator;
196 char from_str[INET6_ADDRSTRLEN] = "";
197 char to_str[INET6_ADDRSTRLEN] = "";
198 char *serv_proto = NULL;
199 bool has_proto;
200 bool has_ports;
201 size_t written = 0;
202 u_int32_t from[4], to[4];
203
204 if (this == NULL)
205 {
206 return print_in_hook(dst, len, "(null)");
207 }
208
209 if (spec->hash)
210 {
211 iterator = list->create_iterator(list, TRUE);
212 while (iterator->iterate(iterator, (void**)&this))
213 {
214 /* call recursivly */
215 written += print_in_hook(dst, len, "%R ", this);
216 }
217 iterator->destroy(iterator);
218 return written;
219 }
220
221 memset(from, 0, sizeof(from));
222 memset(to, 0xFF, sizeof(to));
223 if (this->dynamic &&
224 memeq(this->from, from, this->type == TS_IPV4_ADDR_RANGE ? 4 : 16) &&
225 memeq(this->to, to, this->type == TS_IPV4_ADDR_RANGE ? 4 : 16))
226 {
227 written += print_in_hook(dst, len, "dynamic");
228 }
229 else
230 {
231 if (this->type == TS_IPV4_ADDR_RANGE)
232 {
233 inet_ntop(AF_INET, &this->from4, from_str, sizeof(from_str));
234 }
235 else
236 {
237 inet_ntop(AF_INET6, &this->from6, from_str, sizeof(from_str));
238 }
239 if (this->netbits == NON_SUBNET_ADDRESS_RANGE)
240 {
241 if (this->type == TS_IPV4_ADDR_RANGE)
242 {
243 inet_ntop(AF_INET, &this->to4, to_str, sizeof(to_str));
244 }
245 else
246 {
247 inet_ntop(AF_INET6, &this->to6, to_str, sizeof(to_str));
248 }
249 written += print_in_hook(dst, len, "%s..%s", from_str, to_str);
250 }
251 else
252 {
253 written += print_in_hook(dst, len, "%s/%d", from_str, this->netbits);
254 }
255 }
256
257 /* check if we have protocol and/or port selectors */
258 has_proto = this->protocol != 0;
259 has_ports = !(this->from_port == 0 && this->to_port == 0xFFFF);
260
261 if (!has_proto && !has_ports)
262 {
263 return written;
264 }
265
266 written += print_in_hook(dst, len, "[");
267
268 /* build protocol string */
269 if (has_proto)
270 {
271 struct protoent *proto = getprotobynumber(this->protocol);
272
273 if (proto)
274 {
275 written += print_in_hook(dst, len, "%s", proto->p_name);
276 serv_proto = proto->p_name;
277 }
278 else
279 {
280 written += print_in_hook(dst, len, "%d", this->protocol);
281 }
282 }
283
284 if (has_proto && has_ports)
285 {
286 written += print_in_hook(dst, len, "/");
287 }
288
289 /* build port string */
290 if (has_ports)
291 {
292 if (this->from_port == this->to_port)
293 {
294 struct servent *serv = getservbyport(htons(this->from_port), serv_proto);
295
296 if (serv)
297 {
298 written += print_in_hook(dst, len, "%s", serv->s_name);
299 }
300 else
301 {
302 written += print_in_hook(dst, len, "%d", this->from_port);
303 }
304 }
305 else
306 {
307 written += print_in_hook(dst, len, "%d-%d", this->from_port, this->to_port);
308 }
309 }
310
311 written += print_in_hook(dst, len, "]");
312
313 return written;
314 }
315
316 /**
317 * implements traffic_selector_t.get_subset
318 */
319 static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_traffic_selector_t *other)
320 {
321 if (this->type == other->type && (this->protocol == other->protocol ||
322 this->protocol == 0 || other->protocol == 0))
323 {
324 u_int16_t from_port, to_port;
325 u_char *from, *to;
326 u_int8_t protocol;
327 size_t size;
328 private_traffic_selector_t *new_ts;
329
330 /* calculate the maximum port range allowed for both */
331 from_port = max(this->from_port, other->from_port);
332 to_port = min(this->to_port, other->to_port);
333 if (from_port > to_port)
334 {
335 return NULL;
336 }
337 /* select protocol, which is not zero */
338 protocol = max(this->protocol, other->protocol);
339
340 switch (this->type)
341 {
342 case TS_IPV4_ADDR_RANGE:
343 size = sizeof(this->from4);
344 break;
345 case TS_IPV6_ADDR_RANGE:
346 size = sizeof(this->from6);
347 break;
348 default:
349 return NULL;
350 }
351
352 /* get higher from-address */
353 if (memcmp(this->from, other->from, size) > 0)
354 {
355 from = this->from;
356 }
357 else
358 {
359 from = other->from;
360 }
361 /* get lower to-address */
362 if (memcmp(this->to, other->to, size) > 0)
363 {
364 to = other->to;
365 }
366 else
367 {
368 to = this->to;
369 }
370 /* if "from" > "to", we don't have a match */
371 if (memcmp(from, to, size) > 0)
372 {
373 return NULL;
374 }
375
376 /* we have a match in protocol, port, and address: return it... */
377 new_ts = traffic_selector_create(protocol, this->type, from_port, to_port);
378 new_ts->dynamic = this->dynamic || other->dynamic;
379 memcpy(new_ts->from, from, size);
380 memcpy(new_ts->to, to, size);
381 calc_netbits(new_ts);
382 return &new_ts->public;
383 }
384 return NULL;
385 }
386
387 /**
388 * implements traffic_selector_t.equals
389 */
390 static bool equals(private_traffic_selector_t *this, private_traffic_selector_t *other)
391 {
392 if (this->type != other->type)
393 {
394 return FALSE;
395 }
396 if (!(this->from_port == other->from_port &&
397 this->to_port == other->to_port &&
398 this->protocol == other->protocol))
399 {
400 return FALSE;
401 }
402 switch (this->type)
403 {
404 case TS_IPV4_ADDR_RANGE:
405 if (memeq(this->from4, other->from4, sizeof(this->from4)))
406 {
407 return TRUE;
408 }
409 break;
410 case TS_IPV6_ADDR_RANGE:
411 if (memeq(this->from6, other->from6, sizeof(this->from6)))
412 {
413 return TRUE;
414 }
415 break;
416 default:
417 break;
418 }
419 return FALSE;
420 }
421
422 /**
423 * Implements traffic_selector_t.get_from_address.
424 */
425 static chunk_t get_from_address(private_traffic_selector_t *this)
426 {
427 switch (this->type)
428 {
429 case TS_IPV4_ADDR_RANGE:
430 return chunk_create(this->from, sizeof(this->from4));
431 case TS_IPV6_ADDR_RANGE:
432 return chunk_create(this->from, sizeof(this->from6));
433 default:
434 return chunk_empty;
435 }
436 }
437
438 /**
439 * Implements traffic_selector_t.get_to_address.
440 */
441 static chunk_t get_to_address(private_traffic_selector_t *this)
442 {
443 switch (this->type)
444 {
445 case TS_IPV4_ADDR_RANGE:
446 return chunk_create(this->to, sizeof(this->to4));
447 case TS_IPV6_ADDR_RANGE:
448 return chunk_create(this->to, sizeof(this->to6));
449 default:
450 return chunk_empty;
451 }
452 }
453
454 /**
455 * Implements traffic_selector_t.get_from_port.
456 */
457 static u_int16_t get_from_port(private_traffic_selector_t *this)
458 {
459 return this->from_port;
460 }
461
462 /**
463 * Implements traffic_selector_t.get_to_port.
464 */
465 static u_int16_t get_to_port(private_traffic_selector_t *this)
466 {
467 return this->to_port;
468 }
469
470 /**
471 * Implements traffic_selector_t.get_type.
472 */
473 static ts_type_t get_type(private_traffic_selector_t *this)
474 {
475 return this->type;
476 }
477
478 /**
479 * Implements traffic_selector_t.get_protocol.
480 */
481 static u_int8_t get_protocol(private_traffic_selector_t *this)
482 {
483 return this->protocol;
484 }
485
486 /**
487 * Implements traffic_selector_t.is_host.
488 */
489 static bool is_host(private_traffic_selector_t *this, host_t *host)
490 {
491 if (host)
492 {
493 chunk_t addr;
494 int family = host->get_family(host);
495
496 if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||
497 (family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))
498 {
499 addr = host->get_address(host);
500 if (memeq(addr.ptr, this->from, addr.len) &&
501 memeq(addr.ptr, this->to, addr.len))
502 {
503 return TRUE;
504 }
505 }
506 }
507 else
508 {
509 size_t length = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
510
511 if (this->dynamic)
512 {
513 return TRUE;
514 }
515
516 if (memeq(this->from, this->to, length))
517 {
518 return TRUE;
519 }
520 }
521 return FALSE;
522 }
523
524 /**
525 * Implementation of traffic_selector_t.is_dynamic
526 */
527 static bool is_dynamic(private_traffic_selector_t *this)
528 {
529 return this->dynamic;
530 }
531
532 /**
533 * Implements traffic_selector_t.set_address.
534 */
535 static void set_address(private_traffic_selector_t *this, host_t *host)
536 {
537 if (this->dynamic)
538 {
539 this->type = host->get_family(host) == AF_INET ?
540 TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE;
541
542 if (host->is_anyaddr(host))
543 {
544 memset(this->from6, 0x00, sizeof(this->from6));
545 memset(this->to6, 0xFF, sizeof(this->to6));
546 }
547 else
548 {
549 chunk_t from = host->get_address(host);
550 memcpy(this->from, from.ptr, from.len);
551 memcpy(this->to, from.ptr, from.len);
552 }
553 }
554 }
555
556 /**
557 * Implements traffic_selector_t.is_contained_in.
558 */
559 static bool is_contained_in(private_traffic_selector_t *this,
560 private_traffic_selector_t *other)
561 {
562 private_traffic_selector_t *subset;
563 bool contained_in = FALSE;
564
565 subset = (private_traffic_selector_t*)get_subset(this, other);
566
567 if (subset)
568 {
569 if (equals(subset, this))
570 {
571 contained_in = TRUE;
572 }
573 free(subset);
574 }
575 return contained_in;
576 }
577
578 /**
579 * Implements traffic_selector_t.includes.
580 */
581 static bool includes(private_traffic_selector_t *this, host_t *host)
582 {
583 chunk_t addr;
584 int family = host->get_family(host);
585
586 if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||
587 (family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))
588 {
589 addr = host->get_address(host);
590
591 return memcmp(this->from, addr.ptr, addr.len) <= 0 &&
592 memcmp(this->to, addr.ptr, addr.len) >= 0;
593 }
594
595 return FALSE;
596 }
597
598 /**
599 * Implements traffic_selector_t.to_subnet.
600 */
601 static void to_subnet(private_traffic_selector_t *this, host_t **net, u_int8_t *mask)
602 {
603 /* there is no way to do this cleanly, as the address range may
604 * be anything else but a subnet. We use from_addr as subnet
605 * and try to calculate a usable subnet mask.
606 */
607 int family, byte;
608 u_int16_t port = 0;
609 chunk_t net_chunk;
610
611 *mask = calc_netbits(this);
612
613 switch (this->type)
614 {
615 case TS_IPV4_ADDR_RANGE:
616 family = AF_INET;
617 net_chunk.len = sizeof(this->from4);
618 break;
619 case TS_IPV6_ADDR_RANGE:
620 family = AF_INET6;
621 net_chunk.len = sizeof(this->from6);
622 break;
623 default:
624 /* unreachable */
625 return;
626 }
627
628 net_chunk.ptr = malloc(net_chunk.len);
629 memcpy(net_chunk.ptr, this->from, net_chunk.len);
630
631 for (byte = net_chunk.len - 1; byte >= (*mask / 8); --byte)
632 {
633 int shift = (byte + 1) * 8 - *mask;
634 net_chunk.ptr[byte] = net_chunk.ptr[byte] & (0xFF << shift);
635 }
636
637 if (this->to_port == this->from_port)
638 {
639 port = this->to_port;
640 }
641
642 *net = host_create_from_chunk(family, net_chunk, port);
643 chunk_free(&net_chunk);
644 }
645
646 /**
647 * Implements traffic_selector_t.clone.
648 */
649 static traffic_selector_t *clone_(private_traffic_selector_t *this)
650 {
651 private_traffic_selector_t *clone;
652
653 clone = traffic_selector_create(this->protocol, this->type,
654 this->from_port, this->to_port);
655 clone->netbits = this->netbits;
656 clone->dynamic = this->dynamic;
657
658 switch (clone->type)
659 {
660 case TS_IPV4_ADDR_RANGE:
661 memcpy(clone->from4, this->from4, sizeof(this->from4));
662 memcpy(clone->to4, this->to4, sizeof(this->to4));
663 return &clone->public;
664 case TS_IPV6_ADDR_RANGE:
665 memcpy(clone->from6, this->from6, sizeof(this->from6));
666 memcpy(clone->to6, this->to6, sizeof(this->to6));
667 return &clone->public;
668 default:
669 /* unreachable */
670 return &clone->public;
671 }
672 }
673
674 /**
675 * Implements traffic_selector_t.destroy.
676 */
677 static void destroy(private_traffic_selector_t *this)
678 {
679 free(this);
680 }
681
682 /*
683 * see header
684 */
685 traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol,
686 ts_type_t type,
687 chunk_t from, u_int16_t from_port,
688 chunk_t to, u_int16_t to_port)
689 {
690 private_traffic_selector_t *this = traffic_selector_create(protocol, type,
691 from_port, to_port);
692
693 switch (type)
694 {
695 case TS_IPV4_ADDR_RANGE:
696 if (from.len != 4 || to.len != 4)
697 {
698 free(this);
699 return NULL;
700 }
701 memcpy(this->from4, from.ptr, from.len);
702 memcpy(this->to4, to.ptr, to.len);
703 break;
704 case TS_IPV6_ADDR_RANGE:
705 if (from.len != 16 || to.len != 16)
706 {
707 free(this);
708 return NULL;
709 }
710 memcpy(this->from6, from.ptr, from.len);
711 memcpy(this->to6, to.ptr, to.len);
712 break;
713 default:
714 free(this);
715 return NULL;
716 }
717 calc_netbits(this);
718 return (&this->public);
719 }
720
721 /*
722 * see header
723 */
724 traffic_selector_t *traffic_selector_create_from_rfc3779_format(ts_type_t type,
725 chunk_t from, chunk_t to)
726 {
727 size_t len;
728 private_traffic_selector_t *this = traffic_selector_create(0, type, 0, 65535);
729
730 switch (type)
731 {
732 case TS_IPV4_ADDR_RANGE:
733 len = 4;
734 break;
735 case TS_IPV6_ADDR_RANGE:
736 len = 16;
737 break;
738 default:
739 free(this);
740 return NULL;
741 }
742 memset(this->from, 0x00, len);
743 memset(this->to , 0xff, len);
744
745 if (from.len > 1)
746 {
747 memcpy(this->from, from.ptr+1, from.len-1);
748 }
749 if (to.len > 1)
750 {
751 memcpy(this->to, to.ptr+1, to.len-1);
752 this->to[to.len-2] |= to.ptr[0] ? (1 << to.ptr[0]) - 1 : 0;
753 }
754 this->netbits = chunk_equals(from, to) ? (from.len-1)*8 - from.ptr[0]
755 : NON_SUBNET_ADDRESS_RANGE;
756 return (&this->public);
757 }
758
759 /*
760 * see header
761 */
762 traffic_selector_t *traffic_selector_create_from_subnet(host_t *net,
763 u_int8_t netbits, u_int8_t protocol, u_int16_t port)
764 {
765 private_traffic_selector_t *this = traffic_selector_create(protocol, 0, 0, 65535);
766
767 switch (net->get_family(net))
768 {
769 case AF_INET:
770 {
771 chunk_t from;
772
773 this->type = TS_IPV4_ADDR_RANGE;
774 from = net->get_address(net);
775 memcpy(this->from4, from.ptr, from.len);
776 if (this->from4[0] == 0)
777 {
778 /* use /0 for 0.0.0.0 */
779 this->to4[0] = ~0;
780 this->netbits = 0;
781 }
782 else
783 {
784 calc_range(this, netbits);
785 }
786 break;
787 }
788 case AF_INET6:
789 {
790 chunk_t from;
791
792 this->type = TS_IPV6_ADDR_RANGE;
793 from = net->get_address(net);
794 memcpy(this->from6, from.ptr, from.len);
795 if (this->from6[0] == 0 && this->from6[1] == 0 &&
796 this->from6[2] == 0 && this->from6[3] == 0)
797 {
798 /* use /0 for ::0 */
799 this->to6[0] = ~0;
800 this->to6[1] = ~0;
801 this->to6[2] = ~0;
802 this->to6[3] = ~0;
803 this->netbits = 0;
804 }
805 else
806 {
807 calc_range(this, netbits);
808 }
809 break;
810 }
811 default:
812 {
813 net->destroy(net);
814 free(this);
815 return NULL;
816 }
817 }
818 if (port)
819 {
820 this->from_port = port;
821 this->to_port = port;
822 }
823 net->destroy(net);
824 return (&this->public);
825 }
826
827 /*
828 * see header
829 */
830 traffic_selector_t *traffic_selector_create_from_string(
831 u_int8_t protocol, ts_type_t type,
832 char *from_addr, u_int16_t from_port,
833 char *to_addr, u_int16_t to_port)
834 {
835 private_traffic_selector_t *this = traffic_selector_create(protocol, type,
836 from_port, to_port);
837
838 switch (type)
839 {
840 case TS_IPV4_ADDR_RANGE:
841 if (inet_pton(AF_INET, from_addr, (struct in_addr*)this->from4) < 0)
842 {
843 free(this);
844 return NULL;
845 }
846 if (inet_pton(AF_INET, to_addr, (struct in_addr*)this->to4) < 0)
847 {
848 free(this);
849 return NULL;
850 }
851 break;
852 case TS_IPV6_ADDR_RANGE:
853 if (inet_pton(AF_INET6, from_addr, (struct in6_addr*)this->from6) < 0)
854 {
855 free(this);
856 return NULL;
857 }
858 if (inet_pton(AF_INET6, to_addr, (struct in6_addr*)this->to6) < 0)
859 {
860 free(this);
861 return NULL;
862 }
863 break;
864 }
865 calc_netbits(this);
866 return (&this->public);
867 }
868
869 /*
870 * see header
871 */
872 traffic_selector_t *traffic_selector_create_dynamic(u_int8_t protocol,
873 u_int16_t from_port, u_int16_t to_port)
874 {
875 private_traffic_selector_t *this = traffic_selector_create(
876 protocol, TS_IPV4_ADDR_RANGE, from_port, to_port);
877
878 memset(this->from6, 0, sizeof(this->from6));
879 memset(this->to6, 0xFF, sizeof(this->to6));
880 this->netbits = 0;
881 this->dynamic = TRUE;
882
883 return &this->public;
884 }
885
886 /*
887 * see declaration
888 */
889 static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol,
890 ts_type_t type, u_int16_t from_port, u_int16_t to_port)
891 {
892 private_traffic_selector_t *this = malloc_thing(private_traffic_selector_t);
893
894 /* public functions */
895 this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
896 this->public.equals = (bool(*)(traffic_selector_t*,traffic_selector_t*))equals;
897 this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address;
898 this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address;
899 this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port;
900 this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port;
901 this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
902 this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
903 this->public.is_host = (bool(*)(traffic_selector_t*,host_t*))is_host;
904 this->public.is_dynamic = (bool(*)(traffic_selector_t*))is_dynamic;
905 this->public.is_contained_in = (bool(*)(traffic_selector_t*,traffic_selector_t*))is_contained_in;
906 this->public.includes = (bool(*)(traffic_selector_t*,host_t*))includes;
907 this->public.set_address = (void(*)(traffic_selector_t*,host_t*))set_address;
908 this->public.to_subnet = (void(*)(traffic_selector_t*,host_t**,u_int8_t*))to_subnet;
909 this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
910 this->public.destroy = (void(*)(traffic_selector_t*))destroy;
911
912 this->from_port = from_port;
913 this->to_port = to_port;
914 this->protocol = protocol;
915 this->type = type;
916 this->dynamic = FALSE;
917
918 return this;
919 }
920