Annotation of embedaddon/bird2/lib/flowspec_test.c, revision 1.1
1.1 ! misho 1: /*
! 2: * BIRD Library -- Flow specification (RFC 5575) Tests
! 3: *
! 4: * (c) 2016 CZ.NIC z.s.p.o.
! 5: *
! 6: * Can be freely distributed and used under the terms of the GNU GPL.
! 7: */
! 8:
! 9: #include "test/birdtest.h"
! 10: #include "lib/flowspec.h"
! 11:
! 12: #define NET_ADDR_FLOW4_(what,prefix,pxlen,data_) \
! 13: do \
! 14: { \
! 15: what = alloca(sizeof(net_addr_flow4) + 128); \
! 16: *what = NET_ADDR_FLOW4(prefix, pxlen, sizeof(data_)); \
! 17: memcpy(what->data, &(data_), sizeof(data_)); \
! 18: } while(0)
! 19:
! 20: #define NET_ADDR_FLOW6_(what,prefix,pxlen,data_) \
! 21: do \
! 22: { \
! 23: what = alloca(sizeof(net_addr_flow6) + 128); \
! 24: *what = NET_ADDR_FLOW6(prefix, pxlen, sizeof(data_)); \
! 25: memcpy(what->data, &(data_), sizeof(data_)); \
! 26: } while(0)
! 27:
! 28: static int
! 29: t_read_length(void)
! 30: {
! 31: byte data[] = { 0xcc, 0xcc, 0xcc };
! 32:
! 33: for (uint expect = 0; expect < 0xf0; expect++)
! 34: {
! 35: *data = expect;
! 36: uint get = flow_read_length(data);
! 37: bt_assert_msg(get == expect, "Testing get length 0x%02x (get 0x%02x)", expect, get);
! 38: }
! 39:
! 40: for (uint expect = 0; expect <= 0xfff; expect++)
! 41: {
! 42: put_u16(data, expect | 0xf000);
! 43: uint get = flow_read_length(data);
! 44: bt_assert_msg(get == expect, "Testing get length 0x%03x (get 0x%03x)", expect, get);
! 45: }
! 46:
! 47: return 1;
! 48: }
! 49:
! 50: static int
! 51: t_write_length(void)
! 52: {
! 53: byte data[] = { 0xcc, 0xcc, 0xcc };
! 54:
! 55: for (uint expect = 0; expect <= 0xfff; expect++)
! 56: {
! 57: uint offset = flow_write_length(data, expect);
! 58:
! 59: uint set = (expect < 0xf0) ? *data : (get_u16(data) & 0x0fff);
! 60: bt_assert_msg(set == expect, "Testing set length 0x%03x (set 0x%03x)", expect, set);
! 61: bt_assert(offset == (expect < 0xf0 ? 1 : 2));
! 62: }
! 63:
! 64: return 1;
! 65: }
! 66:
! 67: static int
! 68: t_first_part(void)
! 69: {
! 70: net_addr_flow4 *f;
! 71: NET_ADDR_FLOW4_(f, ip4_build(10,0,0,1), 24, ((byte[]) { 0x00, 0x00, 0xab }));
! 72:
! 73: const byte *under240 = &f->data[1];
! 74: const byte *above240 = &f->data[2];
! 75:
! 76: /* Case 0x00 0x00 */
! 77: bt_assert(flow4_first_part(f) == NULL);
! 78:
! 79: /* Case 0x01 0x00 */
! 80: f->data[0] = 0x01;
! 81: bt_assert(flow4_first_part(f) == under240);
! 82:
! 83: /* Case 0xef 0x00 */
! 84: f->data[0] = 0xef;
! 85: bt_assert(flow4_first_part(f) == under240);
! 86:
! 87: /* Case 0xf0 0x00 */
! 88: f->data[0] = 0xf0;
! 89: bt_assert(flow4_first_part(f) == NULL);
! 90:
! 91: /* Case 0xf0 0x01 */
! 92: f->data[1] = 0x01;
! 93: bt_assert(flow4_first_part(f) == above240);
! 94:
! 95: /* Case 0xff 0xff */
! 96: f->data[0] = 0xff;
! 97: f->data[1] = 0xff;
! 98: bt_assert(flow4_first_part(f) == above240);
! 99:
! 100: return 1;
! 101: }
! 102:
! 103: static int
! 104: t_iterators4(void)
! 105: {
! 106: net_addr_flow4 *f;
! 107: NET_ADDR_FLOW4_(f, ip4_build(5,6,7,0), 24, ((byte[]) {
! 108: 25, /* Length */
! 109: FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
! 110: FLOW_TYPE_SRC_PREFIX, 32, 10, 11, 12, 13,
! 111: FLOW_TYPE_IP_PROTOCOL, 0x81, 0x06,
! 112: FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
! 113: FLOW_TYPE_TCP_FLAGS, 0x80, 0x55,
! 114: }));
! 115:
! 116: const byte *start = f->data;
! 117: const byte *p1_dst_pfx = &f->data[1];
! 118: const byte *p2_src_pfx = &f->data[6];
! 119: const byte *p3_ip_proto = &f->data[12];
! 120: const byte *p4_port = &f->data[15];
! 121: const byte *p5_tcp_flags = &f->data[23];
! 122: const byte *end = &f->data[25];
! 123:
! 124: bt_assert(flow_read_length(f->data) == (end-start));
! 125: bt_assert(flow4_first_part(f) == p1_dst_pfx);
! 126:
! 127: bt_assert(flow4_next_part(p1_dst_pfx, end) == p2_src_pfx);
! 128: bt_assert(flow4_next_part(p2_src_pfx, end) == p3_ip_proto);
! 129: bt_assert(flow4_next_part(p3_ip_proto, end) == p4_port);
! 130: bt_assert(flow4_next_part(p4_port, end) == p5_tcp_flags);
! 131: bt_assert(flow4_next_part(p5_tcp_flags, end) == NULL);
! 132:
! 133: return 1;
! 134: }
! 135:
! 136: static int
! 137: t_iterators6(void)
! 138: {
! 139: net_addr_flow6 *f;
! 140: NET_ADDR_FLOW6_(f, ip6_build(0,0,0x12345678,0x9a000000), 64, ((byte[]) {
! 141: 26, /* Length */
! 142: FLOW_TYPE_DST_PREFIX, 0x68, 0x40, 0x12, 0x34, 0x56, 0x78, 0x9a,
! 143: FLOW_TYPE_SRC_PREFIX, 0x08, 0x0, 0xc0,
! 144: FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
! 145: FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
! 146: FLOW_TYPE_LABEL, 0x80, 0x55,
! 147: }));
! 148:
! 149: const byte *start = f->data;
! 150: const byte *p1_dst_pfx = &f->data[1];
! 151: const byte *p2_src_pfx = &f->data[9];
! 152: const byte *p3_next_header = &f->data[13];
! 153: const byte *p4_port = &f->data[16];
! 154: const byte *p5_label = &f->data[24];
! 155: const byte *end = &f->data[26];
! 156:
! 157: bt_assert(flow_read_length(f->data) == (end-start));
! 158: bt_assert(flow6_first_part(f) == p1_dst_pfx);
! 159:
! 160: bt_assert(flow6_next_part(p1_dst_pfx, end) == p2_src_pfx);
! 161: bt_assert(flow6_next_part(p2_src_pfx, end) == p3_next_header);
! 162: bt_assert(flow6_next_part(p3_next_header, end) == p4_port);
! 163: bt_assert(flow6_next_part(p4_port, end) == p5_label);
! 164: bt_assert(flow6_next_part(p5_label, end) == NULL);
! 165:
! 166: return 1;
! 167: }
! 168:
! 169: static int
! 170: t_validation4(void)
! 171: {
! 172: enum flow_validated_state res;
! 173:
! 174: byte nlri1[] = {
! 175: FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
! 176: FLOW_TYPE_SRC_PREFIX, 32, 10, 11, 12, 13,
! 177: FLOW_TYPE_IP_PROTOCOL, 0x81, 0x06,
! 178: FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
! 179: FLOW_TYPE_TCP_FLAGS, 0x80, 0x55,
! 180: };
! 181:
! 182: /* Isn't included destination prefix */
! 183: res = flow4_validate(nlri1, 0);
! 184: bt_assert(res == FLOW_ST_DEST_PREFIX_REQUIRED);
! 185: res = flow4_validate(&nlri1[5], sizeof(nlri1)-5);
! 186: bt_assert(res == FLOW_ST_DEST_PREFIX_REQUIRED);
! 187:
! 188: /* Valid / Not Complete testing */
! 189: uint valid_sizes[] = {5, 11, 14, 22, 25, 0};
! 190: uint valid_idx = 0;
! 191: for (uint size = 1; size <= sizeof(nlri1); size++)
! 192: {
! 193: res = flow4_validate(nlri1, size);
! 194: bt_debug("size %u, result: %s\n", size, flow_validated_state_str(res));
! 195: if (size == valid_sizes[valid_idx])
! 196: {
! 197: valid_idx++;
! 198: bt_assert(res == FLOW_ST_VALID);
! 199: }
! 200: else
! 201: {
! 202: bt_assert(res == FLOW_ST_NOT_COMPLETE);
! 203: }
! 204: }
! 205:
! 206: /* Misc err tests */
! 207:
! 208: struct tset {
! 209: enum flow_validated_state expect;
! 210: char *description;
! 211: u16 size;
! 212: byte *nlri;
! 213: };
! 214:
! 215: #define TS(type, msg, data) ((struct tset) {type, msg, sizeof(data), (data)})
! 216: struct tset tset[] = {
! 217: TS(
! 218: FLOW_ST_EXCEED_MAX_PREFIX_LENGTH,
! 219: "33-length IPv4 prefix",
! 220: ((byte []) {
! 221: FLOW_TYPE_DST_PREFIX, 33, 5, 6, 7, 8, 9
! 222: })
! 223: ),
! 224: TS(
! 225: FLOW_ST_BAD_TYPE_ORDER,
! 226: "Bad flowspec component type order",
! 227: ((byte []) {
! 228: FLOW_TYPE_SRC_PREFIX, 32, 10, 11, 12, 13,
! 229: FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
! 230: })
! 231: ),
! 232: TS(
! 233: FLOW_ST_BAD_TYPE_ORDER,
! 234: "Doubled destination prefix component",
! 235: ((byte []) {
! 236: FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
! 237: FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
! 238: })
! 239: ),
! 240: TS(
! 241: FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
! 242: "The first numeric operator has set the AND bit",
! 243: ((byte []) {
! 244: FLOW_TYPE_PORT, 0x43, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
! 245: })
! 246: ),
! 247: TS(
! 248: FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
! 249: "Set zero bit in operand to one",
! 250: ((byte []) {
! 251: FLOW_TYPE_IP_PROTOCOL, 0x89, 0x06,
! 252: })
! 253: ),
! 254: TS(
! 255: FLOW_ST_UNKNOWN_COMPONENT,
! 256: "Unknown component of type number 13",
! 257: ((byte []) {
! 258: FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
! 259: FLOW_TYPE_TCP_FLAGS, 0x80, 0x55,
! 260: 13 /*something new*/, 0x80, 0x55,
! 261: })
! 262: ),
! 263: };
! 264: #undef TS
! 265:
! 266: for (uint tcase = 0; tcase < ARRAY_SIZE(tset); tcase++)
! 267: {
! 268: res = flow4_validate(tset[tcase].nlri, tset[tcase].size);
! 269: bt_assert_msg(res == tset[tcase].expect, "Assertion (%s == %s) %s", flow_validated_state_str(res), flow_validated_state_str(tset[tcase].expect), tset[tcase].description);
! 270: }
! 271:
! 272: return 1;
! 273: }
! 274:
! 275: static int
! 276: t_validation6(void)
! 277: {
! 278: enum flow_validated_state res;
! 279:
! 280: byte nlri1[] = {
! 281: FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
! 282: FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
! 283: FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
! 284: FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
! 285: FLOW_TYPE_LABEL, 0x80, 0x55,
! 286: };
! 287:
! 288: /* Isn't included destination prefix */
! 289: res = flow6_validate(nlri1, 0);
! 290: bt_assert(res == FLOW_ST_VALID);
! 291:
! 292: /* Valid / Not Complete testing */
! 293: uint valid_sizes[] = {0, 9, 13, 16, 24, 27, 0};
! 294: uint valid_idx = 0;
! 295: for (uint size = 0; size <= sizeof(nlri1); size++)
! 296: {
! 297: res = flow6_validate(nlri1, size);
! 298: bt_debug("size %u, result: %s\n", size, flow_validated_state_str(res));
! 299: if (size == valid_sizes[valid_idx])
! 300: {
! 301: valid_idx++;
! 302: bt_assert(res == FLOW_ST_VALID);
! 303: }
! 304: else
! 305: {
! 306: bt_assert(res == FLOW_ST_NOT_COMPLETE);
! 307: }
! 308: }
! 309:
! 310: /* Misc err tests */
! 311:
! 312: struct tset {
! 313: enum flow_validated_state expect;
! 314: char *description;
! 315: u16 size;
! 316: byte *nlri;
! 317: };
! 318:
! 319: #define TS(type, msg, data) ((struct tset) {type, msg, sizeof(data), (data)})
! 320: struct tset tset[] = {
! 321: TS(
! 322: FLOW_ST_EXCEED_MAX_PREFIX_LENGTH,
! 323: "129-length IPv6 prefix",
! 324: ((byte []) {
! 325: FLOW_TYPE_DST_PREFIX, 129, 64, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
! 326: })
! 327: ),
! 328: TS(
! 329: FLOW_ST_EXCEED_MAX_PREFIX_OFFSET,
! 330: "Prefix offset is higher than prefix length",
! 331: ((byte []) {
! 332: FLOW_TYPE_DST_PREFIX, 48, 64, 0x40, 0x12, 0x34
! 333: })
! 334: ),
! 335: TS(
! 336: FLOW_ST_BAD_TYPE_ORDER,
! 337: "Bad flowspec component type order",
! 338: ((byte []) {
! 339: FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
! 340: FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
! 341: })
! 342: ),
! 343: TS(
! 344: FLOW_ST_BAD_TYPE_ORDER,
! 345: "Doubled destination prefix component",
! 346: ((byte []) {
! 347: FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
! 348: FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
! 349: })
! 350: ),
! 351: TS(
! 352: FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
! 353: "The first numeric operator has set the AND bit",
! 354: ((byte []) {
! 355: FLOW_TYPE_PORT, 0x43, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90
! 356: })
! 357: ),
! 358: TS(
! 359: FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
! 360: "Set zero bit in operand to one",
! 361: ((byte []) {
! 362: FLOW_TYPE_NEXT_HEADER, 0x89, 0x06
! 363: })
! 364: ),
! 365: TS(
! 366: FLOW_ST_VALID,
! 367: "Component of type number 13 (Label) is well-known in IPv6",
! 368: ((byte []) {
! 369: FLOW_TYPE_LABEL, 0x80, 0x55
! 370: })
! 371: ),
! 372: TS(
! 373: FLOW_ST_UNKNOWN_COMPONENT,
! 374: "Unknown component of type number 14",
! 375: ((byte []) {
! 376: FLOW_TYPE_LABEL, 0x80, 0x55,
! 377: 14 /*something new*/, 0x80, 0x55,
! 378: })
! 379: )
! 380: };
! 381: #undef TS
! 382:
! 383: for (uint tcase = 0; tcase < ARRAY_SIZE(tset); tcase++)
! 384: {
! 385: res = flow6_validate(tset[tcase].nlri, tset[tcase].size);
! 386: bt_assert_msg(res == tset[tcase].expect, "Assertion (%s == %s) %s", flow_validated_state_str(res), flow_validated_state_str(tset[tcase].expect), tset[tcase].description);
! 387: }
! 388:
! 389: return 1;
! 390: }
! 391:
! 392:
! 393:
! 394: /*
! 395: * Builder tests
! 396: */
! 397:
! 398: static int
! 399: t_builder4(void)
! 400: {
! 401: resource_init();
! 402:
! 403: struct flow_builder *fb = flow_builder_init(&root_pool);
! 404: linpool *lp = lp_new_default(&root_pool);
! 405:
! 406: /* Expectation */
! 407:
! 408: static byte nlri[] = {
! 409: 25,
! 410: FLOW_TYPE_DST_PREFIX, 24, 5, 6, 7,
! 411: FLOW_TYPE_SRC_PREFIX, 32, 10, 11, 12, 13,
! 412: FLOW_TYPE_IP_PROTOCOL, 0x80, 0x06,
! 413: FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
! 414: FLOW_TYPE_TCP_FLAGS, 0x80, 0x55
! 415: };
! 416:
! 417: net_addr_flow4 *expect;
! 418: NET_ADDR_FLOW4_(expect, ip4_build(5, 6, 7, 0), 24, nlri);
! 419:
! 420: /* Normal order */
! 421:
! 422: net_addr_ip4 n1;
! 423: net_fill_ip4((net_addr *) &n1, ip4_build(5,6,7,0), 24);
! 424: flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
! 425: flow_builder4_add_pfx(fb, &n1);
! 426:
! 427: net_addr_ip4 n2;
! 428: net_fill_ip4((net_addr *) &n2, ip4_build(10,11,12,13), 32);
! 429: flow_builder_set_type(fb, FLOW_TYPE_SRC_PREFIX);
! 430: flow_builder4_add_pfx(fb, &n2);
! 431:
! 432: flow_builder_set_type(fb, FLOW_TYPE_IP_PROTOCOL);
! 433: flow_builder_add_op_val(fb, 0, 0x06);
! 434:
! 435: flow_builder_set_type(fb, FLOW_TYPE_PORT);
! 436: flow_builder_add_op_val(fb, 0x03, 0x89);
! 437: flow_builder_add_op_val(fb, 0x45, 0x8b);
! 438: flow_builder_add_op_val(fb, 0x01, 0x1f90);
! 439:
! 440: /* Try put a component twice time */
! 441: flow_builder_set_type(fb, FLOW_TYPE_IP_PROTOCOL);
! 442: flow_builder_add_op_val(fb, 0, 0x06);
! 443:
! 444: flow_builder_set_type(fb, FLOW_TYPE_TCP_FLAGS);
! 445: flow_builder_add_op_val(fb, 0, 0x55);
! 446:
! 447: net_addr_flow4 *res = flow_builder4_finalize(fb, lp);
! 448:
! 449: bt_assert(memcmp(res, expect, expect->length) == 0);
! 450:
! 451: /* Reverse order */
! 452:
! 453: flow_builder_clear(fb);
! 454:
! 455: flow_builder_set_type(fb, FLOW_TYPE_TCP_FLAGS);
! 456: flow_builder_add_op_val(fb, 0, 0x55);
! 457:
! 458: flow_builder_set_type(fb, FLOW_TYPE_PORT);
! 459: flow_builder_add_op_val(fb, 0x03, 0x89);
! 460: flow_builder_add_op_val(fb, 0x45, 0x8b);
! 461: flow_builder_add_op_val(fb, 0x01, 0x1f90);
! 462:
! 463: flow_builder_set_type(fb, FLOW_TYPE_IP_PROTOCOL);
! 464: flow_builder_add_op_val(fb, 0, 0x06);
! 465:
! 466: net_fill_ip4((net_addr *) &n2, ip4_build(10,11,12,13), 32);
! 467: flow_builder_set_type(fb, FLOW_TYPE_SRC_PREFIX);
! 468: flow_builder4_add_pfx(fb, &n2);
! 469:
! 470: net_fill_ip4((net_addr *) &n1, ip4_build(5,6,7,0), 24);
! 471: flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
! 472: flow_builder4_add_pfx(fb, &n1);
! 473:
! 474: bt_assert(memcmp(res, expect, expect->length) == 0);
! 475:
! 476: return 1;
! 477: }
! 478:
! 479: static int
! 480: t_builder6(void)
! 481: {
! 482: net_addr_ip6 ip;
! 483:
! 484: resource_init();
! 485: linpool *lp = lp_new_default(&root_pool);
! 486: struct flow_builder *fb = flow_builder_init(&root_pool);
! 487: fb->ipv6 = 1;
! 488:
! 489: /* Expectation */
! 490:
! 491: byte nlri[] = {
! 492: 27,
! 493: FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
! 494: FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
! 495: FLOW_TYPE_NEXT_HEADER, 0x80, 0x06,
! 496: FLOW_TYPE_PORT, 0x03, 0x89, 0x45, 0x8b, 0x91, 0x1f, 0x90,
! 497: FLOW_TYPE_LABEL, 0x80, 0x55,
! 498: };
! 499:
! 500: net_addr_flow6 *expect;
! 501: NET_ADDR_FLOW6_(expect, ip6_build(0, 1, 0x12345678, 0x98000000), 103, nlri);
! 502:
! 503: /* Normal order */
! 504:
! 505: net_fill_ip6((net_addr *) &ip, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
! 506: flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
! 507: flow_builder6_add_pfx(fb, &ip, 61);
! 508:
! 509: /* Try put a component twice time */
! 510: net_fill_ip6((net_addr *) &ip, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
! 511: flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
! 512: bt_assert(flow_builder6_add_pfx(fb, &ip, 61) == 0);
! 513:
! 514: net_fill_ip6((net_addr *) &ip, ip6_build(0xc0000000,0,0,0), 8);
! 515: flow_builder_set_type(fb, FLOW_TYPE_SRC_PREFIX);
! 516: flow_builder6_add_pfx(fb, &ip, 0);
! 517:
! 518: flow_builder_set_type(fb, FLOW_TYPE_NEXT_HEADER);
! 519: flow_builder_add_op_val(fb, 0, 0x06);
! 520:
! 521: flow_builder_set_type(fb, FLOW_TYPE_PORT);
! 522: flow_builder_add_op_val(fb, 0x03, 0x89);
! 523: flow_builder_add_op_val(fb, 0x45, 0x8b);
! 524: flow_builder_add_op_val(fb, 0x01, 0x1f90);
! 525:
! 526: flow_builder_set_type(fb, FLOW_TYPE_LABEL);
! 527: flow_builder_add_op_val(fb, 0, 0x55);
! 528:
! 529: net_addr_flow6 *res = flow_builder6_finalize(fb, lp);
! 530: bt_assert(memcmp(res, expect, expect->length) == 0);
! 531:
! 532: /* Reverse order */
! 533:
! 534: flow_builder_clear(fb);
! 535: fb->ipv6 = 1;
! 536:
! 537: flow_builder_set_type(fb, FLOW_TYPE_LABEL);
! 538: flow_builder_add_op_val(fb, 0, 0x55);
! 539:
! 540: flow_builder_set_type(fb, FLOW_TYPE_PORT);
! 541: flow_builder_add_op_val(fb, 0x03, 0x89);
! 542: flow_builder_add_op_val(fb, 0x45, 0x8b);
! 543: flow_builder_add_op_val(fb, 0x01, 0x1f90);
! 544:
! 545: flow_builder_set_type(fb, FLOW_TYPE_NEXT_HEADER);
! 546: flow_builder_add_op_val(fb, 0, 0x06);
! 547:
! 548: net_fill_ip6((net_addr *) &ip, ip6_build(0xc0000000,0,0,0), 8);
! 549: flow_builder_set_type(fb, FLOW_TYPE_SRC_PREFIX);
! 550: flow_builder6_add_pfx(fb, &ip, 0);
! 551:
! 552: net_fill_ip6((net_addr *) &ip, ip6_build(0, 1, 0x12345678, 0x98000000), 103);
! 553: flow_builder_set_type(fb, FLOW_TYPE_DST_PREFIX);
! 554: flow_builder6_add_pfx(fb, &ip, 61);
! 555:
! 556: res = flow_builder6_finalize(fb, lp);
! 557: bt_assert(memcmp(res, expect, expect->length) == 0);
! 558:
! 559: return 1;
! 560: }
! 561:
! 562: static int
! 563: t_formatting4(void)
! 564: {
! 565: char b[1024];
! 566:
! 567: byte nlri[] = {
! 568: 0,
! 569: FLOW_TYPE_DST_PREFIX, 0x08, 10,
! 570: FLOW_TYPE_IP_PROTOCOL, 0x81, 23,
! 571: FLOW_TYPE_DST_PORT, 0x02, 24, 0x44, 30, 0x03, 40, 0x45, 50, 0x03, 60, 0x45, 70, 0x01, 80, 0xc3, 90,
! 572: FLOW_TYPE_SRC_PORT, 0x02, 24, 0x44, 0x1e, 0x01, 0x28, 0x01, 0x32, 0x03, 0x3c, 0x45, 0x46, 0x81, 0x50,
! 573: FLOW_TYPE_ICMP_TYPE, 0x81, 0x50,
! 574: FLOW_TYPE_ICMP_CODE, 0x81, 0x5a,
! 575: FLOW_TYPE_TCP_FLAGS, 0x01, 0x03, 0xc2, 0x0c,
! 576: FLOW_TYPE_PACKET_LENGTH, 0x03, 0, 0xd5, 0xff, 0xff,
! 577: FLOW_TYPE_DSCP, 0x81, 63,
! 578: FLOW_TYPE_FRAGMENT, 0x01, 0x01, 0x82, 0x02
! 579: };
! 580: *nlri = (u8) sizeof(nlri);
! 581:
! 582: net_addr_flow4 *input;
! 583: NET_ADDR_FLOW4_(input, ip4_build(5, 6, 7, 0), 24, nlri);
! 584:
! 585: const char *expect = "flow4 { dst 10.0.0.0/8; proto 23; dport > 24 && < 30 || 40..50,60..70,80 && >= 90; sport > 24 && < 30 || 40,50,60..70,80; icmp type 80; icmp code 90; tcp flags 0x3/0x3,0x0/0xc; length 0..65535; dscp 63; fragment dont_fragment || !is_fragment; }";
! 586:
! 587: bt_assert(flow4_net_format(b, sizeof(b), input) == strlen(expect));
! 588: bt_debug(" expect: '%s',\n output: '%s'\n", expect, b);
! 589: bt_assert(strcmp(b, expect) == 0);
! 590:
! 591: return 1;
! 592: }
! 593:
! 594: static int
! 595: t_formatting6(void)
! 596: {
! 597: char b[1024];
! 598:
! 599: byte nlri[] = {
! 600: 0,
! 601: FLOW_TYPE_DST_PREFIX, 103, 61, 0x01, 0x12, 0x34, 0x56, 0x78, 0x98,
! 602: FLOW_TYPE_SRC_PREFIX, 8, 0, 0xc0,
! 603: FLOW_TYPE_NEXT_HEADER, 0x81, 0x06,
! 604: FLOW_TYPE_PORT, 0x03, 20, 0x45, 40, 0x91, 0x01, 0x11,
! 605: FLOW_TYPE_LABEL, 0xa0, 0x12, 0x34, 0x56, 0x78,
! 606: };
! 607: *nlri = (u8) sizeof(nlri);
! 608:
! 609: net_addr_flow6 *input;
! 610: NET_ADDR_FLOW6_(input, ip6_build(0, 1, 0x12345678, 0x98000000), 103, nlri);
! 611:
! 612: const char *expect = "flow6 { dst ::1:1234:5678:9800:0/103 offset 61; src c000::/8; next header 6; port 20..40,273; label !0x0/0x12345678; }";
! 613:
! 614: bt_assert(flow6_net_format(b, sizeof(b), input) == strlen(expect));
! 615: bt_debug(" expect: '%s',\n output: '%s'\n", expect, b);
! 616: bt_assert(strcmp(b, expect) == 0);
! 617:
! 618: return 1;
! 619: }
! 620:
! 621: int
! 622: main(int argc, char *argv[])
! 623: {
! 624: bt_init(argc, argv);
! 625:
! 626: bt_test_suite(t_read_length, "Testing get NLRI length");
! 627: bt_test_suite(t_write_length, "Testing set NLRI length");
! 628: bt_test_suite(t_first_part, "Searching first part in net_addr_flow");
! 629: bt_test_suite(t_iterators4, "Testing iterators (IPv4)");
! 630: bt_test_suite(t_iterators6, "Testing iterators (IPv6)");
! 631: bt_test_suite(t_validation4, "Testing validation (IPv4)");
! 632: bt_test_suite(t_validation6, "Testing validation (IPv6)");
! 633: bt_test_suite(t_builder4, "Inserting components into existing Flow Specification (IPv4)");
! 634: bt_test_suite(t_builder6, "Inserting components into existing Flow Specification (IPv6)");
! 635: bt_test_suite(t_formatting4, "Formatting Flow Specification (IPv4) into text representation");
! 636: bt_test_suite(t_formatting6, "Formatting Flow Specification (IPv6) into text representation");
! 637:
! 638: return bt_exit_value();
! 639: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>