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>