Annotation of embedaddon/bird2/lib/flowspec_test.c, revision 1.1.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>