Annotation of embedaddon/strongswan/src/libstrongswan/tests/suites/test_traffic_selector.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2015 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * Copyright (C) 2015 Martin Willi
6: * Copyright (C) 2015 revosec AG
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 "test_suite.h"
20:
21: #include <selectors/traffic_selector.h>
22:
23:
24: static void verify(const char *str, const char *alt, traffic_selector_t *ts)
25: {
26: char buf[512];
27:
28: if (!str)
29: {
30: ck_assert_msg(!ts, "traffic selector not null: %R", ts);
31: return;
32: }
33: snprintf(buf, sizeof(buf), "%R", ts);
34: DESTROY_IF(ts);
35: if (!streq(buf, str) && (!alt || !streq(buf, alt)))
36: {
37: fail("%s != %s or %s", buf, str, alt);
38: }
39: }
40:
41: START_TEST(test_create_from_string)
42: {
43: verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]",
44: traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
45: "10.1.0.0", 80, "10.1.255.255", 80));
46: verify("10.1.0.1..10.1.0.99[udp/1234-1235]",
47: "10.1.0.1..10.1.0.99[17/1234-1235]",
48: traffic_selector_create_from_string(IPPROTO_UDP, TS_IPV4_ADDR_RANGE,
49: "10.1.0.1", 1234, "10.1.0.99", 1235));
50: verify("fec1::/64", NULL,
51: traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE,
52: "fec1::", 0, "fec1::ffff:ffff:ffff:ffff", 65535));
53: verify("fec1::1..fec1::ffff:ffff:ffff:ffff", NULL,
54: traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE,
55: "fec1::1", 0, "fec1::ffff:ffff:ffff:ffff", 65535));
56: verify(NULL, NULL,
57: traffic_selector_create_from_string(IPPROTO_TCP, 0,
58: "10.1.0.0", 80, "10.1.255.255", 80));
59: verify(NULL, NULL,
60: traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
61: "a.b.c.d", 80, "10.1.255.255", 80));
62: verify(NULL, NULL,
63: traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
64: "10.1.0.0", 80, "a.b.c.d", 80));
65: }
66: END_TEST
67:
68: START_TEST(test_create_from_cidr)
69: {
70: verify("10.1.0.0/16", NULL,
71: traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535));
72: verify("10.1.0.1/32[udp]", "10.1.0.1/32[17]",
73: traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP,
74: 0, 65535));
75: verify("10.1.0.1/32[0/domain]", "10.1.0.1/32[0/53]",
76: traffic_selector_create_from_cidr("10.1.0.1/32", 0,
77: 53, 53));
78: verify("10.1.0.1/32[udp/1234-1235]", "10.1.0.1/32[17/1234-1235]",
79: traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP,
80: 1234, 1235));
81: verify("10.1.0.0/16[0/OPAQUE]", NULL,
82: traffic_selector_create_from_cidr("10.1.0.0/16", 0, 65535, 0));
83:
84: verify(NULL, NULL,
85: traffic_selector_create_from_cidr("a.b.c.d/16", 0, 0, 65535));
86: }
87: END_TEST
88:
89: START_TEST(test_create_from_bytes)
90: {
91: verify("10.1.0.0/16", NULL,
92: traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
93: chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
94: chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
95: verify(NULL, NULL,
96: traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
97: chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
98: chunk_from_chars(0x0a,0x01,0xff,0xff,0xff), 65535));
99: verify(NULL, NULL,
100: traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
101: chunk_empty, 0,
102: chunk_empty, 65535));
103: verify(NULL, NULL,
104: traffic_selector_create_from_bytes(0, TS_IPV6_ADDR_RANGE,
105: chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
106: chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
107: verify(NULL, NULL,
108: traffic_selector_create_from_bytes(0, 0,
109: chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
110: chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
111: }
112: END_TEST
113:
114: START_TEST(test_create_from_subnet)
115: {
116: verify("10.1.0.0/16", NULL,
117: traffic_selector_create_from_subnet(
118: host_create_from_string("10.1.0.0", 0), 16, 0, 0, 65535));
119: }
120: END_TEST
121:
122: struct {
123: char *net;
124: ts_type_t type;
125: chunk_t enc;
126: } rfc3779_prefix_tests[] = {
127: /* some examples from RFC 3779, for addressPrefix elements we pass the same
128: * value twice to the constructor */
129: { "10.0.0.0/8", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a), },
130: { "10.0.32.0/20", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x00,0x20), },
131: { "10.0.64.0/24", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x00,0x40), },
132: { "10.1.0.0/16", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x01), },
133: { "10.5.0.1/32", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x05,0x00,0x01), },
134: { "10.5.0.0/23", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x01,0x0a,0x05,0x00), },
135: { "10.64.0.0/12", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x40), },
136: { "10.64.0.0/20", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x40,0x00), },
137: { "128.0.0.0/4", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x80), },
138: { "172.16.0.0/12", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0xac,0x10), },
139: { "0.0.0.0/0", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00), },
140: { NULL, 0, chunk_from_chars(0x00), },
141: /* FIXME: not a correct encoding, so we might want to fail here */
142: { "0.0.0.0/0", TS_IPV4_ADDR_RANGE, {NULL, 0}, },
143: { "2001:0:2::/48", TS_IPV6_ADDR_RANGE, chunk_from_chars(0x00,0x20,0x01,0x00,0x00,0x00,0x02),},
144: { "2001:0:200::/39",TS_IPV6_ADDR_RANGE, chunk_from_chars(0x01,0x20,0x01,0x00,0x00,0x02),},
145: { "::/0", TS_IPV6_ADDR_RANGE, chunk_from_chars(0x00), },
146: /* FIXME: not a correct encoding, so we might want to fail here */
147: { "::/0", TS_IPV6_ADDR_RANGE, {NULL, 0}, },
148: };
149:
150: START_TEST(test_create_from_rfc3779_format_prefix)
151: {
152: verify(rfc3779_prefix_tests[_i].net, NULL,
153: traffic_selector_create_from_rfc3779_format(rfc3779_prefix_tests[_i].type,
154: rfc3779_prefix_tests[_i].enc, rfc3779_prefix_tests[_i].enc));
155: }
156: END_TEST
157:
158: START_TEST(test_create_from_rfc3779_format_range)
159: {
160: /* addressRange elements encode a from and to address, which may still
161: * represent prefixes */
162: verify("10.5.0.0/23", NULL,
163: traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
164: chunk_from_chars(0x00,0x0a,0x05),
165: chunk_from_chars(0x01,0x0a,0x05,0x00)));
166: verify("2001:0:200::/39", NULL,
167: traffic_selector_create_from_rfc3779_format(TS_IPV6_ADDR_RANGE,
168: chunk_from_chars(0x01,0x20,0x01,0x00,0x00,0x02),
169: chunk_from_chars(0x02,0x20,0x01,0x00,0x00,0x00)));
170: verify("10.2.48.0..10.2.64.255", NULL,
171: traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
172: chunk_from_chars(0x04,0x0a,0x02,0x30),
173: chunk_from_chars(0x00,0x0a,0x02,0x40)));
174: verify("129.64.0.0..143.255.255.255", NULL,
175: traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
176: chunk_from_chars(0x06,0x81,0x40),
177: chunk_from_chars(0x04,0x80)));
178: }
179: END_TEST
180:
181:
182: static void verify_address(char *addr_from, char *addr_to, traffic_selector_t *ts)
183: {
184: host_t *from, *to;
185:
186: from = host_create_from_string(addr_from, 0);
187: to = host_create_from_string(addr_to, 0);
188:
189: ck_assert_chunk_eq(from->get_address(from), ts->get_from_address(ts));
190: ck_assert_chunk_eq(to->get_address(to), ts->get_to_address(ts));
191: from->destroy(from);
192: to->destroy(to);
193: ts->destroy(ts);
194: }
195:
196: START_TEST(test_get_address_range)
197: {
198: verify_address("10.1.0.1", "10.1.0.10",
199: traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
200: "10.1.0.1", 0, "10.1.0.10", 65535));
201: /* currently not reordered */
202: verify_address("10.1.0.10", "10.1.0.1",
203: traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
204: "10.1.0.10", 0, "10.1.0.1", 65535));
205: }
206: END_TEST
207:
208: START_TEST(test_get_address_cidr)
209: {
210: verify_address("10.1.0.0", "10.1.255.255",
211: traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535));
212: verify_address("fec1::", "fec1::ffff:ffff:ffff:ffff",
213: traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535));
214: }
215: END_TEST
216:
217: struct {
218: ts_type_t type;
219: char *from;
220: char *to;
221: char *net;
222: uint8_t mask;
223: bool exact;
224: } to_subnet_tests[] = {
225: { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.1", "10.0.0.1", 32, TRUE },
226: { TS_IPV4_ADDR_RANGE, "10.0.0.0", "10.255.255.255", "10.0.0.0", 8, TRUE },
227: { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.255", "10.0.0.0", 24, FALSE },
228: { TS_IPV4_ADDR_RANGE, "10.0.0.0", "10.0.0.15", "10.0.0.0", 28, TRUE },
229: { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.15", "10.0.0.0", 28, FALSE },
230: { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.16", "10.0.0.0", 27, FALSE },
231: { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::1", "fec1::1", 128, TRUE },
232: { TS_IPV6_ADDR_RANGE, "fec1::0", "fec1::ffff:ffff:ffff:ffff", "fec1::", 64, TRUE },
233: { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::ffff:ffff:ffff:ffff", "fec1::", 64, FALSE },
234: { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::7fff", "fec1::", 113, FALSE },
235: { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::efff", "fec1::", 112, FALSE },
236: };
237:
238: START_TEST(test_to_subnet)
239: {
240: traffic_selector_t *ts;
241: host_t *net, *exp_net;
242: uint8_t mask;
243:
244: ts = traffic_selector_create_from_string(0, to_subnet_tests[_i].type,
245: to_subnet_tests[_i].from, 0, to_subnet_tests[_i].to, 0);
246: ck_assert(ts->to_subnet(ts, &net, &mask) == to_subnet_tests[_i].exact);
247: exp_net = host_create_from_string(to_subnet_tests[_i].net, 0);
248: ck_assert(exp_net->ip_equals(exp_net, net));
249: ck_assert_int_eq(to_subnet_tests[_i].mask, mask);
250: exp_net->destroy(exp_net);
251: net->destroy(net);
252: ts->destroy(ts);
253: }
254: END_TEST
255:
256: struct {
257: char *cidr;
258: uint16_t from_port;
259: uint16_t to_port;
260: uint16_t port;
261: } to_subnet_port_tests[] = {
262: { "10.0.0.0/8", 0, 0, 0 },
263: { "10.0.0.1/32", 80, 80, 80 },
264: { "10.0.0.1/32", 123, 465, 0 },
265: { "0.0.0.0/0", 0, 65535, 0 },
266: { "fec1::/64", 0, 0, 0 },
267: { "fec1::1/128", 80, 80, 80 },
268: { "fec1::1/128", 123, 465, 0 },
269: { "::/0", 0, 65535, 0 },
270: };
271:
272: START_TEST(test_to_subnet_port)
273: {
274: traffic_selector_t *ts;
275: host_t *net, *exp_net;
276: uint8_t mask;
277: int exp_mask;
278:
279: ts = traffic_selector_create_from_cidr(to_subnet_port_tests[_i].cidr, 0,
280: to_subnet_port_tests[_i].from_port,
281: to_subnet_port_tests[_i].to_port);
282: ck_assert(ts->to_subnet(ts, &net, &mask));
283: exp_net = host_create_from_subnet(to_subnet_port_tests[_i].cidr, &exp_mask);
284: ck_assert(exp_net->ip_equals(exp_net, net));
285: ck_assert_int_eq(exp_mask, mask);
286: ck_assert_int_eq(to_subnet_port_tests[_i].port, net->get_port(net));
287: exp_net->destroy(exp_net);
288: net->destroy(net);
289: ts->destroy(ts);
290: }
291: END_TEST
292:
293: START_TEST(test_subset)
294: {
295: traffic_selector_t *a, *b;
296:
297: a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
298: b = traffic_selector_create_from_cidr("10.1.5.0/24", 0, 0, 65535);
299: verify("10.1.5.0/24", NULL, a->get_subset(a, b));
300: verify("10.1.5.0/24", NULL, b->get_subset(b, a));
301: a->destroy(a);
302: b->destroy(b);
303:
304: a = traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535);
305: b = traffic_selector_create_from_cidr("fec1::1/128", 0, 0, 65535);
306: verify("fec1::1/128", NULL, a->get_subset(a, b));
307: verify("fec1::1/128", NULL, b->get_subset(b, a));
308: a->destroy(a);
309: b->destroy(b);
310: }
311: END_TEST
312:
313: START_TEST(test_subset_port)
314: {
315: traffic_selector_t *a, *b;
316:
317: a = traffic_selector_create_from_cidr("10.0.0.0/8", IPPROTO_TCP, 55, 60);
318: b = traffic_selector_create_from_cidr("10.2.7.16/30", 0, 0, 65535);
319: verify("10.2.7.16/30[tcp/55-60]", "10.2.7.16/30[6/55-60]",
320: a->get_subset(a, b));
321: a->destroy(a);
322: b->destroy(b);
323: }
324: END_TEST
325:
326: START_TEST(test_subset_equal)
327: {
328: traffic_selector_t *a, *b;
329:
330: a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80);
331: b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80);
332: verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]", a->get_subset(a, b));
333: a->destroy(a);
334: b->destroy(b);
335: }
336: END_TEST
337:
338: START_TEST(test_subset_nonet)
339: {
340: traffic_selector_t *a, *b;
341:
342: a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
343: b = traffic_selector_create_from_cidr("10.2.0.0/16", 0, 0, 65535);
344: ck_assert(!a->get_subset(a, b));
345: a->destroy(a);
346: b->destroy(b);
347: }
348: END_TEST
349:
350: START_TEST(test_subset_noport)
351: {
352: traffic_selector_t *a, *b;
353:
354: a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 9999);
355: b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 10000, 65535);
356: ck_assert(!a->get_subset(a, b));
357: a->destroy(a);
358: b->destroy(b);
359: }
360: END_TEST
361:
362: START_TEST(test_subset_noproto)
363: {
364: traffic_selector_t *a, *b;
365:
366: a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 0, 65535);
367: b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_UDP, 0, 65535);
368: ck_assert(!a->get_subset(a, b));
369: a->destroy(a);
370: b->destroy(b);
371: }
372: END_TEST
373:
374: START_TEST(test_subset_nofamily)
375: {
376: traffic_selector_t *a, *b;
377:
378: a = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
379: b = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
380: ck_assert(!a->get_subset(a, b));
381: a->destroy(a);
382: b->destroy(b);
383: }
384: END_TEST
385:
386: START_TEST(test_subset_dynamic)
387: {
388: traffic_selector_t *a, *b;
389:
390: a = traffic_selector_create_dynamic(0, 0, 65535);
391: b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
392: ck_assert(!a->get_subset(a, b));
393: ck_assert(!b->get_subset(b, a));
394: a->destroy(a);
395: b->destroy(b);
396: }
397: END_TEST
398:
399: START_TEST(test_subset_opaque)
400: {
401: traffic_selector_t *a, *b;
402:
403: a = traffic_selector_create_from_cidr("10.0.0.0/8", 0, 65535, 0);
404: b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 80, 80);
405: ck_assert(!a->get_subset(a, b));
406: ck_assert(!b->get_subset(b, a));
407: b->destroy(b);
408:
409: b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 65535, 0);
410: verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", a->get_subset(a, b));
411: verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", b->get_subset(b, a));
412: b->destroy(b);
413:
414: b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 0, 65535);
415: verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", a->get_subset(a, b));
416: verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", b->get_subset(b, a));
417: a->destroy(a);
418: b->destroy(b);
419: }
420: END_TEST
421:
422: struct {
423: char *net;
424: char *host;
425: bool inc;
426: } include_tests[] = {
427: { "0.0.0.0/0", "192.168.1.2", TRUE },
428: { "::/0", "fec2::1", TRUE },
429: { "fec2::/64", "fec2::afaf", TRUE },
430: { "10.1.0.0/16", "10.1.0.1", TRUE },
431: { "10.5.6.7/32", "10.5.6.7", TRUE },
432: { "0.0.0.0/0", "fec2::1", FALSE },
433: { "::/0", "1.2.3.4", FALSE },
434: { "10.0.0.0/16", "10.1.0.0", FALSE },
435: { "10.1.0.0/16", "10.0.255.255", FALSE },
436: { "fec2::/64", "fec2:0:0:1::afaf", FALSE },
437: };
438:
439: START_TEST(test_includes)
440: {
441: traffic_selector_t *ts;
442: host_t *h;
443:
444: ts = traffic_selector_create_from_cidr(include_tests[_i].net, 0, 0, 65535);
445: h = host_create_from_string(include_tests[_i].host, 0);
446: ck_assert(ts->includes(ts, h) == include_tests[_i].inc);
447: ts->destroy(ts);
448: h->destroy(h);
449: }
450: END_TEST
451:
452: struct {
453: bool contained;
454: struct {
455: char *net;
456: uint8_t proto;
457: uint16_t from_port;
458: uint16_t to_port;
459: } a, b;
460: } is_contained_in_tests[] = {
461: { TRUE, { "10.0.0.0/16", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
462: { TRUE, { "10.0.1.0/24", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
463: { TRUE, { "10.0.1.0/24", 17, 123, 456 }, { "10.0.0.0/16", 0, 0, 65535 }, },
464: { TRUE, { "10.0.1.0/24", 17, 123, 456 }, { "10.0.0.0/16", 17, 123, 456 },},
465: { FALSE, { "10.0.0.0/8", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
466: { FALSE, { "10.0.1.0/24", 17, 0, 65535 }, { "10.0.0.0/16", 17, 123, 456 },},
467: { FALSE, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/16", 17, 123, 456 },},
468: };
469:
470: START_TEST(test_is_contained_in)
471: {
472: traffic_selector_t *a, *b;
473:
474: a = traffic_selector_create_from_cidr(
475: is_contained_in_tests[_i].a.net, is_contained_in_tests[_i].a.proto,
476: is_contained_in_tests[_i].a.from_port, is_contained_in_tests[_i].a.to_port);
477: b = traffic_selector_create_from_cidr(
478: is_contained_in_tests[_i].b.net, is_contained_in_tests[_i].b.proto,
479: is_contained_in_tests[_i].b.from_port, is_contained_in_tests[_i].b.to_port);
480: ck_assert(a->is_contained_in(a, b) == is_contained_in_tests[_i].contained);
481: a->destroy(a);
482: b->destroy(b);
483: }
484: END_TEST
485:
486: struct {
487: char *net;
488: char *host;
489: bool is_host;
490: bool when_null;
491: } is_host_tests[] = {
492: { "0.0.0.0/0", "192.168.1.2", FALSE, FALSE },
493: { "::/0", "fec2::1", FALSE, FALSE },
494: { "192.168.1.0/24", "192.168.1.0", FALSE, FALSE },
495: { "192.168.1.2/32", "192.168.1.2", TRUE, TRUE },
496: { "192.168.1.2/32", "192.168.1.1", FALSE, TRUE },
497: { "192.168.1.2/32", "fec2::1", FALSE, TRUE },
498: { "fec2::1/128", "fec2::1", TRUE, TRUE },
499: { "fec2::1/128", "fec2::2", FALSE, TRUE },
500: { "fec2::1/128", "192.168.1.2", FALSE, TRUE },
501: };
502:
503: START_TEST(test_is_host)
504: {
505: traffic_selector_t *ts;
506: host_t *h;
507:
508: ts = traffic_selector_create_from_cidr(is_host_tests[_i].net, 0, 0, 65535);
509: h = host_create_from_string(is_host_tests[_i].host, 0);
510: ck_assert(ts->is_host(ts, h) == is_host_tests[_i].is_host);
511: ck_assert(ts->is_host(ts, NULL) == is_host_tests[_i].when_null);
512: ts->destroy(ts);
513: h->destroy(h);
514: }
515: END_TEST
516:
517: START_TEST(test_is_host_dynamic)
518: {
519: traffic_selector_t *ts;
520: host_t *h;
521:
522: ts = traffic_selector_create_dynamic(0, 0, 65535);
523: h = host_create_from_string(is_host_tests[_i].host, 0);
524: ck_assert(!ts->is_host(ts, h));
525: ck_assert(ts->is_host(ts, NULL));
526: ts->destroy(ts);
527: h->destroy(h);
528: }
529: END_TEST
530:
531:
532: struct {
533: char *orig;
534: char *host;
535: char *after;
536: } set_address_tests[] = {
537: { "0.0.0.0/0", "192.168.1.2", "192.168.1.2/32" },
538: { "::/0", "fec2::1", "fec2::1/128" },
539: { "192.168.1.2/32", "192.168.1.1", "192.168.1.1/32" },
540: { "192.168.1.0/24", "192.168.1.1", "192.168.1.1/32" },
541: { "192.168.1.2/32", "fec2::1", "fec2::1/128" },
542: { "192.168.1.0/24", "fec2::1", "fec2::1/128" },
543: { "192.168.1.2/32", "%any", "0.0.0.0/0" },
544: { "192.168.1.0/24", "%any", "0.0.0.0/0" },
545: { "192.168.1.2/32", "%any6", "::/0" },
546: { "192.168.1.0/24", "%any6", "::/0" },
547: { "fec2::1/128", "192.168.1.1", "192.168.1.1/32" },
548: { "fec2::/64", "192.168.1.1", "192.168.1.1/32" },
549: { "fec2::1/128", "fec2::2", "fec2::2/128" },
550: { "fec2::/64", "fec2::2", "fec2::2/128" },
551: { "fec2::1/128", "%any", "0.0.0.0/0" },
552: { "fec2::/64", "%any", "0.0.0.0/0" },
553: { "fec2::1/128", "%any6", "::/0" },
554: { "fec2::/64", "%any6", "::/0" },
555: { NULL, "192.168.1.1", "192.168.1.1/32" },
556: { NULL, "fec2::1", "fec2::1/128" },
557: { NULL, "%any", "0.0.0.0/0" },
558: { NULL, "%any6", "::/0" },
559: };
560:
561: START_TEST(test_set_address)
562: {
563: traffic_selector_t *ts;
564: host_t *h;
565:
566: if (set_address_tests[_i].orig)
567: {
568: ts = traffic_selector_create_from_cidr(set_address_tests[_i].orig, 0, 0, 65535);
569: ck_assert(!ts->is_dynamic(ts));
570: }
571: else
572: {
573: ts = traffic_selector_create_dynamic(0, 0, 65535);
574: ck_assert(ts->is_dynamic(ts));
575: }
576: h = host_create_from_string(set_address_tests[_i].host, 0);
577: ts->set_address(ts, h);
578: ck_assert(!ts->is_dynamic(ts));
579: verify(set_address_tests[_i].after, NULL, ts);
580: h->destroy(h);
581: }
582: END_TEST
583:
584:
585: struct {
586: int res;
587: struct {
588: char *net;
589: uint8_t proto;
590: uint16_t from_port;
591: uint16_t to_port;
592: } a, b;
593: } cmp_tests[] = {
594: { 0, { "10.0.0.0/8", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, },
595: { 0, { "10.0.0.0/8", 17, 123, 456 }, { "10.0.0.0/8", 17, 123, 456 }, },
596: { 0, { "fec2::/64", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
597: { 0, { "fec2::/64", 4, 0, 65535 }, { "fec2::/64", 4, 0, 65535 }, },
598:
599: { -1, { "1.0.0.0/8", 0, 0, 65535 }, { "2.0.0.0/8", 0, 0, 65535 }, },
600: { 1, { "2.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, },
601: { -1, { "1.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/16", 0, 0, 65535 }, },
602: { 1, { "1.0.0.0/16", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, },
603: { -1, { "fec1::/64", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
604: { 1, { "fec2::/64", 0, 0, 65535 }, { "fec1::/64", 0, 0, 65535 }, },
605: { -1, { "fec1::/48", 0, 0, 65535 }, { "fec1::/64", 0, 0, 65535 }, },
606: { 1, { "fec1::/64", 0, 0, 65535 }, { "fec1::/48", 0, 0, 65535 }, },
607:
608: { -1, { "10.0.0.0/8", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
609: { 1, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, },
610:
611: { -1, { "10.0.0.0/8", 16, 123, 456 }, { "10.0.0.0/8", 17, 123, 456 }, },
612: { 1, { "fec2::/64", 5, 0, 65535 }, { "fec2::/64", 4, 0, 65535 }, },
613:
614: { -1, { "10.0.0.0/8", 17, 111, 456 }, { "10.0.0.0/8", 17, 222, 456 }, },
615: { 1, { "fec2::/64", 17, 555, 65535 }, { "fec2::/64", 17, 444, 65535 },},
616:
617: { -1, { "10.0.0.0/8", 17, 55, 65535 }, { "10.0.0.0/8", 17, 55, 666 }, },
618: { 1, { "fec2::/64", 17, 55, 111 }, { "fec2::/64", 17, 55, 4567 }, },
619:
620: };
621:
622: START_TEST(test_cmp)
623: {
624: traffic_selector_t *a, *b;
625:
626: a = traffic_selector_create_from_cidr(
627: cmp_tests[_i].a.net, cmp_tests[_i].a.proto,
628: cmp_tests[_i].a.from_port, cmp_tests[_i].a.to_port);
629: b = traffic_selector_create_from_cidr(
630: cmp_tests[_i].b.net, cmp_tests[_i].b.proto,
631: cmp_tests[_i].b.from_port, cmp_tests[_i].b.to_port);
632: switch (cmp_tests[_i].res)
633: {
634: case 0:
635: ck_assert(traffic_selector_cmp(a, b, NULL) == 0);
636: ck_assert(a->equals(a, b));
637: break;
638: case 1:
639: ck_assert(traffic_selector_cmp(a, b, NULL) > 0);
640: ck_assert(!a->equals(a, b));
641: break;
642: case -1:
643: ck_assert(traffic_selector_cmp(a, b, NULL) < 0);
644: ck_assert(!a->equals(a, b));
645: break;
646: }
647: a->destroy(a);
648: b->destroy(b);
649: }
650: END_TEST
651:
652: static void verify_clone(traffic_selector_t *ts)
653: {
654: traffic_selector_t *clone;
655:
656: clone = ts->clone(ts);
657: if (!ts->equals(ts, clone))
658: {
659: fail("%R != %R", ts, clone);
660: }
661: /* equals() already compares most of these but not all */
662: ck_assert(ts->get_type(ts) == clone->get_type(clone));
663: ck_assert(ts->get_protocol(ts) == clone->get_protocol(clone));
664: ck_assert(ts->get_from_port(ts) == clone->get_from_port(clone));
665: ck_assert(ts->get_to_port(ts) == clone->get_to_port(clone));
666: ck_assert_chunk_eq(ts->get_from_address(ts), clone->get_from_address(clone));
667: ck_assert_chunk_eq(ts->get_to_address(ts), clone->get_to_address(clone));
668: ck_assert(ts->is_host(ts, NULL) == clone->is_host(clone, NULL));
669: ck_assert(ts->is_dynamic(ts) == clone->is_dynamic(clone));
670: clone->destroy(clone);
671: ts->destroy(ts);
672: }
673:
674: START_TEST(test_clone)
675: {
676: traffic_selector_t *ts;
677: host_t *h;
678:
679: ts = traffic_selector_create_dynamic(0, 0, 0);
680: verify_clone(ts);
681: ts = traffic_selector_create_dynamic(IPPROTO_UDP, 123, 456);
682: verify_clone(ts);
683: ts = traffic_selector_create_dynamic(IPPROTO_UDP, 0, 65535);
684: verify_clone(ts);
685:
686: h = host_create_from_string("192.168.1.1", 0);
687: ts = traffic_selector_create_dynamic(0, 0, 0);
688: ts->set_address(ts, h);
689: verify_clone(ts);
690: ts = traffic_selector_create_dynamic(IPPROTO_UDP, 123, 456);
691: ts->set_address(ts, h);
692: verify_clone(ts);
693: h->destroy(h);
694:
695: ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "10.0.0.1", 0, "10.0.0.16", 65535);
696: verify_clone(ts);
697: ts = traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV6_ADDR_RANGE, "fec1::1", 80, "fec1::1:0000", 80);
698: verify_clone(ts);
699: ts = traffic_selector_create_from_cidr("10.0.0.0/8", 0, 0, 65535);
700: verify_clone(ts);
701: ts = traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535);
702: verify_clone(ts);
703: }
704: END_TEST
705:
706: START_TEST(test_hash)
707: {
708: traffic_selector_t *a, *b;
709: host_t *h;
710:
711: a = traffic_selector_create_dynamic(0, 0, 0);
712: b = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 0);
713: ck_assert(a->hash(a, 0) != a->hash(a, 1));
714: ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
715: ck_assert_int_eq(a->hash(a, 1), b->hash(b, 1));
716:
717: h = host_create_from_string("192.168.1.1", 0);
718: a->set_address(a, h);
719: ck_assert(a->hash(a, 0) != b->hash(b, 0));
720: h->destroy(h);
721:
722: a->destroy(a);
723: a = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "192.168.0.0", 0, "192.168.0.255", 65535);
724: ck_assert(a->hash(a, 0) != b->hash(b, 0));
725: b->destroy(b);
726: b = traffic_selector_create_from_cidr("192.168.0.0/24", 0, 0, 65535);
727: ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
728: b->destroy(b);
729: b = traffic_selector_create_from_cidr("192.168.0.0/24", IPPROTO_TCP, 0, 65535);
730: ck_assert(a->hash(a, 0) != b->hash(b, 0));
731: b->destroy(b);
732: b = traffic_selector_create_from_cidr("192.168.0.0/24", 0, 123, 456);
733: ck_assert(a->hash(a, 0) != b->hash(b, 0));
734: b->destroy(b);
735: a->destroy(a);
736: }
737: END_TEST
738:
739: struct {
740: uint8_t proto;
741: uint16_t from_port;
742: uint16_t to_port;
743: uint8_t from_type;
744: uint8_t from_code;
745: uint8_t to_type;
746: uint8_t to_code;
747: char *str;
748: char *str_alt;
749: } icmp_tests[] = {
750: { IPPROTO_ICMP, 0, 0, 0, 0, 0, 0, "dynamic[icmp/0]", "dynamic[1/0]" },
751: { IPPROTO_ICMP, 3, 3, 3, 0, 3, 0, "dynamic[icmp/3]", "dynamic[1/3]" },
752: { IPPROTO_ICMP, 0x0307, 0x0307, 3, 7, 3, 7, "dynamic[icmp/3(7)]", "dynamic[1/3(7)]" },
753: { IPPROTO_ICMP, 0x0300, 0x040f, 3, 0, 4, 15, "dynamic[icmp/3-4(15)]", "dynamic[1/3-4(15)]" },
754: { IPPROTO_ICMP, 0x0301, 0x040f, 3, 1, 4, 15, "dynamic[icmp/3(1)-4(15)]", "dynamic[1/3(1)-4(15)]" },
755: { IPPROTO_ICMPV6, 0, 0, 0, 0, 0, 0, "dynamic[ipv6-icmp/0]", "dynamic[58/0]" },
756: { IPPROTO_ICMPV6, 1, 1, 1, 0, 1, 0, "dynamic[ipv6-icmp/1]", "dynamic[58/1]" },
757: { IPPROTO_ICMPV6, 0x0104, 0x0104, 1, 4, 1, 4, "dynamic[ipv6-icmp/1(4)]", "dynamic[58/1(4)]" },
758: { IPPROTO_ICMPV6, 0x0100, 0x040f, 1, 0, 4, 15, "dynamic[ipv6-icmp/1-4(15)]", "dynamic[58/1-4(15)]" },
759: { IPPROTO_ICMPV6, 0x0101, 0x040f, 1, 1, 4, 15, "dynamic[ipv6-icmp/1(1)-4(15)]", "dynamic[58/1(1)-4(15)]" },
760: };
761:
762: START_TEST(test_icmp)
763: {
764: traffic_selector_t *ts;
765: uint16_t from, to;
766:
767: ts = traffic_selector_create_dynamic(icmp_tests[_i].proto,
768: icmp_tests[_i].from_port, icmp_tests[_i].to_port);
769: from = ts->get_from_port(ts);
770: to = ts->get_to_port(ts);
771: ck_assert_int_eq(icmp_tests[_i].from_type, traffic_selector_icmp_type(from));
772: ck_assert_int_eq(icmp_tests[_i].from_code, traffic_selector_icmp_code(from));
773: ck_assert_int_eq(icmp_tests[_i].to_type, traffic_selector_icmp_type(to));
774: ck_assert_int_eq(icmp_tests[_i].to_code, traffic_selector_icmp_code(to));
775: verify(icmp_tests[_i].str, icmp_tests[_i].str_alt, ts);
776: }
777: END_TEST
778:
779: static void verify_list(const char *str, const char *alt, linked_list_t *list)
780: {
781: char buf[512];
782:
783: snprintf(buf, sizeof(buf), "%#R", list);
784: list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
785: if (!streq(buf, str) && !streq(buf, alt))
786: {
787: fail("%s != %s or %s", buf, str, alt);
788: }
789: }
790:
791: START_TEST(test_printf_hook_null)
792: {
793: verify("(null)", NULL, NULL);
794: }
795: END_TEST
796:
797: START_TEST(test_printf_hook_hash)
798: {
799: linked_list_t *list;
800:
801: list = linked_list_create_with_items(
802: traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
803: NULL);
804: verify_list("10.1.0.0/16", NULL, list);
805: list = linked_list_create_with_items(
806: traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
807: traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP, 1234, 1235),
808: NULL);
809: verify_list("10.1.0.0/16 10.1.0.1/32[udp/1234-1235]", "10.1.0.0/16 10.1.0.1/32[17/1234-1235]", list);
810: list = linked_list_create_with_items(
811: traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
812: traffic_selector_create_from_string(IPPROTO_UDP, TS_IPV4_ADDR_RANGE, "10.1.0.1", 1234, "10.1.0.99", 1235),
813: NULL);
814: verify_list("10.1.0.0/16 10.1.0.1..10.1.0.99[udp/1234-1235]", "10.1.0.0/16 10.1.0.1..10.1.0.99[17/1234-1235]", list);
815: }
816: END_TEST
817:
818: Suite *traffic_selector_suite_create()
819: {
820: Suite *s;
821: TCase *tc;
822:
823: s = suite_create("traffic selector");
824:
825: tc = tcase_create("create");
826: tcase_add_test(tc, test_create_from_string);
827: tcase_add_test(tc, test_create_from_cidr);
828: tcase_add_test(tc, test_create_from_bytes);
829: tcase_add_test(tc, test_create_from_subnet);
830: tcase_add_loop_test(tc, test_create_from_rfc3779_format_prefix, 0, countof(rfc3779_prefix_tests));
831: tcase_add_test(tc, test_create_from_rfc3779_format_range);
832: suite_add_tcase(s, tc);
833:
834: tc = tcase_create("addresses");
835: tcase_add_test(tc, test_get_address_range);
836: tcase_add_test(tc, test_get_address_cidr);
837: suite_add_tcase(s, tc);
838:
839: tc = tcase_create("to_subnet");
840: tcase_add_loop_test(tc, test_to_subnet, 0, countof(to_subnet_tests));
841: tcase_add_loop_test(tc, test_to_subnet_port, 0, countof(to_subnet_port_tests));
842: suite_add_tcase(s, tc);
843:
844: tc = tcase_create("subset");
845: tcase_add_test(tc, test_subset);
846: tcase_add_test(tc, test_subset_port);
847: tcase_add_test(tc, test_subset_equal);
848: tcase_add_test(tc, test_subset_nonet);
849: tcase_add_test(tc, test_subset_noport);
850: tcase_add_test(tc, test_subset_noproto);
851: tcase_add_test(tc, test_subset_nofamily);
852: tcase_add_test(tc, test_subset_dynamic);
853: tcase_add_test(tc, test_subset_opaque);
854: suite_add_tcase(s, tc);
855:
856: tc = tcase_create("includes");
857: tcase_add_loop_test(tc, test_includes, 0, countof(include_tests));
858: suite_add_tcase(s, tc);
859:
860: tc = tcase_create("is_contained_in");
861: tcase_add_loop_test(tc, test_is_contained_in, 0, countof(is_contained_in_tests));
862: suite_add_tcase(s, tc);
863:
864: tc = tcase_create("is_host");
865: tcase_add_loop_test(tc, test_is_host, 0, countof(is_host_tests));
866: tcase_add_loop_test(tc, test_is_host_dynamic, 0, countof(is_host_tests));
867: suite_add_tcase(s, tc);
868:
869: tc = tcase_create("set_address");
870: tcase_add_loop_test(tc, test_set_address, 0, countof(is_host_tests));
871: suite_add_tcase(s, tc);
872:
873: tc = tcase_create("cmp");
874: tcase_add_loop_test(tc, test_cmp, 0, countof(cmp_tests));
875: suite_add_tcase(s, tc);
876:
877: tc = tcase_create("clone");
878: tcase_add_test(tc, test_clone);
879: suite_add_tcase(s, tc);
880:
881: tc = tcase_create("hash");
882: tcase_add_test(tc, test_hash);
883: suite_add_tcase(s, tc);
884:
885: tc = tcase_create("icmp");
886: tcase_add_loop_test(tc, test_icmp, 0, countof(icmp_tests));
887: suite_add_tcase(s, tc);
888:
889: tc = tcase_create("printf hook");
890: tcase_add_test(tc, test_printf_hook_null);
891: tcase_add_test(tc, test_printf_hook_hash);
892: suite_add_tcase(s, tc);
893:
894: return s;
895: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>