Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / lib / flowspec_test.c @ 6b3f1a54

History | View | Annotate | Download (17.5 KB)

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
}