~ubuntu-branches/ubuntu/saucy/quagga/saucy

« back to all changes in this revision

Viewing changes to tests/bgp_capability_test.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2007-09-14 09:47:54 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070914094754-kqi815lcg6n8mh51
Tags: 0.99.9-1ubuntu1
* Merged new upstream version (LP: #139376)
  - Merged debian/changelog
* Fixes a DoS and some bugs introduced in 0.99.8
  (see: http://www.quagga.net/news2.php?y=2007&m=9&d=7#id1189190760)
* Remaining Ubuntu Patches:
  - debian/rules: use bash as shell
  - debian/quagga.prerm: handle upgrades more gracefully
  - debian/patches/81_32bit_u64.dpatch: Define __u64 as uint64_t
    before including the netlink headers, since that symbol does not exist
    by default on 32 bit arches. Fixes i386/powerpc FTBFS.
  - debian/patches/83_ifaddr_defs.dpatch:
    zebra/rt_netlink.c: #include <linux/if_addr.h> and define IF[L]A_RTA
    macros, so that the file compiles again with our kernel headers.
  - debian/patches/20_ht-20061217-0.99.6-bgp-md5.dpatch: updated for
    linux kernel 2.6.20.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <zebra.h>
 
2
 
 
3
#include "vty.h"
 
4
#include "stream.h"
 
5
#include "privs.h"
 
6
#include "memory.h"
 
7
 
 
8
#include "bgpd/bgpd.h"
 
9
#include "bgpd/bgp_open.h"
 
10
#include "bgpd/bgp_debug.h"
 
11
 
 
12
#define OPEN    0
 
13
#define DYNCAP  1
 
14
 
 
15
/* need these to link in libbgp */
 
16
struct zebra_privs_t *bgpd_privs = NULL;
 
17
struct thread_master *master = NULL;
 
18
 
 
19
static int failed = 0;
 
20
 
 
21
/* test segments to parse and validate, and use for other tests */
 
22
static struct test_segment {
 
23
  const char *name;
 
24
  const char *desc;
 
25
  const u_char data[1024];
 
26
  int len;
 
27
#define SHOULD_PARSE    0
 
28
#define SHOULD_ERR      -1
 
29
  int parses; /* whether it should parse or not */
 
30
} test_segments [] = 
 
31
{
 
32
  /* 0 */
 
33
  { "caphdr", 
 
34
    "capability header, and no more",
 
35
    { CAPABILITY_CODE_REFRESH, 0x0 },
 
36
    2, SHOULD_PARSE,
 
37
  },
 
38
  /* 1 */
 
39
  { "nodata",
 
40
    "header, no data but length says there is",
 
41
    { 0x1, 0xa },
 
42
    2, SHOULD_ERR,
 
43
  },
 
44
  /* 2 */
 
45
  { "padded",
 
46
    "valid, with padding",
 
47
    { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
 
48
    4, SHOULD_PARSE,
 
49
  },
 
50
  /* 3 */
 
51
  { "minsize",
 
52
    "violates minsize requirement",
 
53
    { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
 
54
    4, SHOULD_ERR,
 
55
  },
 
56
  /* 4 */
 
57
  { "MP1",
 
58
    "MP IP/Uni",
 
59
    { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
 
60
    6, SHOULD_PARSE,
 
61
  },
 
62
  /* 5 */
 
63
  { "MP2",
 
64
    "MP IP/Multicast",
 
65
    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
 
66
    6, SHOULD_PARSE,
 
67
  },
 
68
  /* 6 */
 
69
  { "MP3",
 
70
    "MP IP6/VPNv4",
 
71
    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
 
72
    6, SHOULD_PARSE, /* parses, but invalid afi,safi */
 
73
  },
 
74
  /* 7 */
 
75
  { "MP5",
 
76
    "MP IP6/MPLS-VPN",
 
77
    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
 
78
    6, SHOULD_PARSE,
 
79
  },
 
80
  /* 8 */
 
81
  { "MP6",
 
82
    "MP IP4/VPNv4",
 
83
    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
 
84
    6, SHOULD_PARSE,
 
85
  },  
 
86
  /* 9 */
 
87
  { "MP7",
 
88
    "MP IP4/VPNv6",
 
89
    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x81 },
 
90
    6, SHOULD_PARSE, /* parses, but invalid afi,safi tuple! - manually inspect */
 
91
  },
 
92
  /* 10 */
 
93
  { "MP8",
 
94
    "MP unknown AFI",
 
95
    { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
 
96
    6, SHOULD_PARSE, /* parses, but unknown */
 
97
  },
 
98
  /* 11 */
 
99
  { "MP-short",
 
100
    "MP IP4/Unicast, length too short (< minimum)",
 
101
    { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
 
102
    6, SHOULD_ERR,
 
103
  },
 
104
  /* 12 */
 
105
  { "MP-overflow",
 
106
    "MP IP4/Unicast, length too long",
 
107
    { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
 
108
    6, SHOULD_ERR,
 
109
  },
 
110
  /* 13 */
 
111
  { "ORF",
 
112
    "ORF, simple, single entry, single tuple",
 
113
    { /* hdr */         CAPABILITY_CODE_ORF, 0x7, 
 
114
      /* mpc */         0x0, 0x1, 0x0, 0x1, 
 
115
      /* num */         0x1, 
 
116
      /* tuples */      0x40, 0x3
 
117
    },
 
118
    9, SHOULD_PARSE,
 
119
  },
 
120
  /* 14 */
 
121
  { "ORF-many",
 
122
    "ORF, multi entry/tuple",
 
123
    { /* hdr */         CAPABILITY_CODE_ORF, 0x21,
 
124
      /* mpc */         0x0, 0x1, 0x0, 0x1, 
 
125
      /* num */         0x3, 
 
126
      /* tuples */      0x40, ORF_MODE_BOTH,
 
127
                        0x80, ORF_MODE_RECEIVE,
 
128
                        0x80, ORF_MODE_SEND,
 
129
      /* mpc */         0x0, 0x2, 0x0, 0x1, 
 
130
      /* num */         0x3, 
 
131
      /* tuples */      0x40, ORF_MODE_BOTH,
 
132
                        0x80, ORF_MODE_RECEIVE,
 
133
                        0x80, ORF_MODE_SEND,
 
134
      /* mpc */         0x0, 0x2, 0x0, 0x2,
 
135
      /* num */         0x3, 
 
136
      /* tuples */      0x40, ORF_MODE_RECEIVE,
 
137
                        0x80, ORF_MODE_SEND,
 
138
                        0x80, ORF_MODE_BOTH,
 
139
    },
 
140
    35, SHOULD_PARSE,
 
141
  },
 
142
  /* 15 */
 
143
  { "ORFlo",
 
144
    "ORF, multi entry/tuple, hdr length too short",
 
145
    { /* hdr */         CAPABILITY_CODE_ORF, 0x15,
 
146
      /* mpc */         0x0, 0x1, 0x0, 0x1, 
 
147
      /* num */         0x3, 
 
148
      /* tuples */      0x40, 0x3,
 
149
                        0x80, 0x1,
 
150
                        0x80, 0x2,
 
151
      /* mpc */         0x0, 0x1, 0x0, 0x1, 
 
152
      /* num */         0x3, 
 
153
      /* tuples */      0x40, 0x3,
 
154
                        0x80, 0x1,
 
155
                        0x80, 0x2,
 
156
      /* mpc */         0x0, 0x2, 0x0, 0x2,
 
157
      /* num */         0x3, 
 
158
      /* tuples */      0x40, 0x3,
 
159
                        0x80, 0x1,
 
160
                        0x80, 0x2,
 
161
    },
 
162
    35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
 
163
  },
 
164
  /* 16 */
 
165
  { "ORFlu",
 
166
    "ORF, multi entry/tuple, length too long",
 
167
    { /* hdr */         0x3, 0x22,
 
168
      /* mpc */         0x0, 0x1, 0x0, 0x1, 
 
169
      /* num */         0x3, 
 
170
      /* tuples */      0x40, 0x3,
 
171
                        0x80, 0x1,
 
172
                        0x80, 0x2,
 
173
      /* mpc */         0x0, 0x2, 0x0, 0x1, 
 
174
      /* num */         0x3, 
 
175
      /* tuples */      0x40, 0x3,
 
176
                        0x80, 0x1,
 
177
                        0x80, 0x2,
 
178
      /* mpc */         0x0, 0x2, 0x0, 0x2,
 
179
      /* num */         0x3, 
 
180
      /* tuples */      0x40, 0x3,
 
181
                        0x80, 0x1,
 
182
                        0x80, 0x2,
 
183
    },
 
184
    35, SHOULD_ERR
 
185
  },
 
186
  /* 17 */
 
187
  { "ORFnu",
 
188
    "ORF, multi entry/tuple, entry number too long",
 
189
    { /* hdr */         0x3, 0x21,
 
190
      /* mpc */         0x0, 0x1, 0x0, 0x1, 
 
191
      /* num */         0x3, 
 
192
      /* tuples */      0x40, 0x3,
 
193
                        0x80, 0x1,
 
194
                        0x80, 0x2,
 
195
      /* mpc */         0x0, 0x2, 0x0, 0x1, 
 
196
      /* num */         0x4, 
 
197
      /* tuples */      0x40, 0x3,
 
198
                        0x80, 0x1,
 
199
                        0x80, 0x2,
 
200
      /* mpc */         0x0, 0x2, 0x0, 0x2,
 
201
      /* num */         0x3, 
 
202
      /* tuples */      0x40, 0x3,
 
203
                        0x80, 0x1,
 
204
                        0x80, 0x2,
 
205
    },
 
206
    35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
 
207
  },
 
208
  /* 18 */
 
209
  { "ORFno",
 
210
    "ORF, multi entry/tuple, entry number too short",
 
211
    { /* hdr */         0x3, 0x21,
 
212
      /* mpc */         0x0, 0x1, 0x0, 0x1, 
 
213
      /* num */         0x3, 
 
214
      /* tuples */      0x40, 0x3,
 
215
                        0x80, 0x1,
 
216
                        0x80, 0x2,
 
217
      /* mpc */         0x0, 0x2, 0x0, 0x1, 
 
218
      /* num */         0x1, 
 
219
      /* tuples */      0x40, 0x3,
 
220
                        0x80, 0x1,
 
221
                        0x80, 0x2,
 
222
      /* mpc */         0x0, 0x2, 0x0, 0x2,
 
223
      /* num */         0x3,
 
224
      /* tuples */      0x40, 0x3,
 
225
                        0x80, 0x1,
 
226
                        0x80, 0x2,
 
227
    },
 
228
    35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
 
229
  },
 
230
  /* 17 */
 
231
  { "ORFpad",
 
232
    "ORF, multi entry/tuple, padded to align",
 
233
    { /* hdr */         0x3, 0x22,
 
234
      /* mpc */         0x0, 0x1, 0x0, 0x1, 
 
235
      /* num */         0x3, 
 
236
      /* tuples */      0x40, 0x3,
 
237
                        0x80, 0x1,
 
238
                        0x80, 0x2,
 
239
      /* mpc */         0x0, 0x2, 0x0, 0x1, 
 
240
      /* num */         0x3, 
 
241
      /* tuples */      0x40, 0x3,
 
242
                        0x80, 0x1,
 
243
                        0x80, 0x2,
 
244
      /* mpc */         0x0, 0x2, 0x0, 0x2,
 
245
      /* num */         0x3, 
 
246
      /* tuples */      0x40, 0x3,
 
247
                        0x80, 0x1,
 
248
                        0x80, 0x2,
 
249
                        0x00,
 
250
    },
 
251
    36, SHOULD_PARSE,
 
252
  },
 
253
  /* 19 */
 
254
  { "AS4",
 
255
    "AS4 capability",
 
256
    { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 },
 
257
    6, SHOULD_PARSE,
 
258
  },
 
259
  /* 20 */
 
260
  { "GR",
 
261
    "GR capability",
 
262
    { /* hdr */         CAPABILITY_CODE_RESTART, 0xe,
 
263
      /* R-bit, time */ 0xf1, 0x12,
 
264
      /* afi */         0x0, 0x1,
 
265
      /* safi */        0x1,
 
266
      /* flags */       0xf,
 
267
      /* afi */         0x0, 0x2,
 
268
      /* safi */        0x1,
 
269
      /* flags */       0x0,
 
270
      /* afi */         0x0, 0x2,
 
271
      /* safi */        0x2,
 
272
      /* flags */       0x1,
 
273
    },
 
274
    16, SHOULD_PARSE,
 
275
  },
 
276
  /* 21 */
 
277
  { "GR-short",
 
278
    "GR capability, but header length too short",
 
279
    { /* hdr */         0x40, 0xa,
 
280
      /* R-bit, time */ 0xf1, 0x12,
 
281
      /* afi */         0x0, 0x1,
 
282
      /* safi */        0x1,
 
283
      /* flags */       0xf,
 
284
      /* afi */         0x0, 0x2,
 
285
      /* safi */        0x1,
 
286
      /* flags */       0x0,
 
287
      /* afi */         0x0, 0x2,
 
288
      /* safi */        0x2,
 
289
      /* flags */       0x1,
 
290
    },
 
291
    16, SHOULD_PARSE,
 
292
  },
 
293
  /* 22 */
 
294
  { "GR-long",
 
295
    "GR capability, but header length too long",
 
296
    { /* hdr */         0x40, 0xf,
 
297
      /* R-bit, time */ 0xf1, 0x12,
 
298
      /* afi */         0x0, 0x1,
 
299
      /* safi */        0x1,
 
300
      /* flags */       0xf,
 
301
      /* afi */         0x0, 0x2,
 
302
      /* safi */        0x1,
 
303
      /* flags */       0x0,
 
304
      /* afi */         0x0, 0x2,
 
305
      /* safi */        0x2,
 
306
    },
 
307
    16, SHOULD_ERR,
 
308
  },
 
309
  { "GR-trunc",
 
310
    "GR capability, but truncated",
 
311
    { /* hdr */         0x40, 0xf,
 
312
      /* R-bit, time */ 0xf1, 0x12,
 
313
      /* afi */         0x0, 0x1,
 
314
      /* safi */        0x1,
 
315
      /* flags */       0xf,
 
316
      /* afi */         0x0, 0x2,
 
317
      /* safi */        0x1,
 
318
      /* flags */       0x0,
 
319
      /* afi */         0x0, 0x2,
 
320
      /* safi */        0x2,
 
321
      /* flags */       0x1,
 
322
    },
 
323
    15, SHOULD_ERR,
 
324
  },
 
325
  { "dyn-old",
 
326
    "Dynamic capability (deprecated version)",
 
327
    { CAPABILITY_CODE_DYNAMIC, 0x0 },
 
328
    2, SHOULD_PARSE,
 
329
  },
 
330
  { NULL, NULL, {0}, 0, 0}
 
331
};
 
332
 
 
333
 
 
334
struct test_segment dynamic_cap_msgs[] = 
 
335
{
 
336
  { "DynCap",
 
337
    "Dynamic Capability Message, IP/Multicast",
 
338
    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
 
339
      7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
 
340
  },
 
341
  { "DynCapLong",
 
342
    "Dynamic Capability Message, IP/Multicast, truncated",
 
343
    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
 
344
      5, SHOULD_ERR,
 
345
  },
 
346
  { "DynCapPadded",
 
347
    "Dynamic Capability Message, IP/Multicast, padded",
 
348
    { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
 
349
      8, SHOULD_ERR, /* No way to tell padding from data.. */
 
350
  },
 
351
  { "DynCapMPCpadded",
 
352
    "Dynamic Capability Message, IP/Multicast, cap data padded",
 
353
    { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
 
354
      8, SHOULD_PARSE, /* You can though add padding to the capability data */
 
355
  },
 
356
  { "DynCapMPCoverflow",
 
357
    "Dynamic Capability Message, IP/Multicast, cap data != length",
 
358
    { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
 
359
      8, SHOULD_ERR,
 
360
  },
 
361
  { NULL, NULL, {0}, 0, 0}
 
362
};
 
363
/* basic parsing test */
 
364
static void
 
365
parse_test (struct peer *peer, struct test_segment *t, int type)
 
366
{
 
367
  int ret;
 
368
  int capability = 0;
 
369
  
 
370
  stream_reset (peer->ibuf);
 
371
  switch (type)
 
372
    {
 
373
      case OPEN:
 
374
        stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
 
375
        stream_putc (peer->ibuf, t->len);
 
376
        break;
 
377
      case DYNCAP:
 
378
/*        for (i = 0; i < BGP_MARKER_SIZE; i++)
 
379
          stream_putc (peer->, 0xff);
 
380
        stream_putw (s, 0);
 
381
        stream_putc (s, BGP_MSG_CAPABILITY);*/
 
382
        break;
 
383
    }
 
384
  stream_write (peer->ibuf, t->data, t->len);
 
385
  
 
386
  printf ("%s: %s\n", t->name, t->desc);
 
387
  
 
388
  switch (type)
 
389
    {
 
390
      case OPEN:
 
391
        ret = bgp_open_option_parse (peer, t->len + 2, &capability);
 
392
        break;
 
393
      case DYNCAP:
 
394
        ret = bgp_capability_receive (peer, t->len);
 
395
        break;
 
396
      default:
 
397
        printf ("unknown type %u\n", type);
 
398
        exit(1);
 
399
    }
 
400
  
 
401
  printf ("parsed?: %s\n", ret ? "no" : "yes");
 
402
  
 
403
  if (ret == t->parses)
 
404
    printf ("OK\n");
 
405
  else
 
406
    {
 
407
      printf ("failed\n");
 
408
      failed++;
 
409
    }
 
410
  
 
411
  printf ("\n");
 
412
}
 
413
 
 
414
static struct bgp *bgp;
 
415
static as_t asn = 100;
 
416
 
 
417
int
 
418
main (void)
 
419
{
 
420
  struct peer *peer;
 
421
  int i, j;
 
422
  
 
423
  conf_bgp_debug_fsm = -1UL;
 
424
  conf_bgp_debug_events = -1UL;
 
425
  conf_bgp_debug_packet = -1UL;
 
426
  conf_bgp_debug_normal = -1UL;
 
427
  term_bgp_debug_fsm = -1UL;
 
428
  term_bgp_debug_events = -1UL;
 
429
  term_bgp_debug_packet = -1UL;
 
430
  term_bgp_debug_normal = -1UL;
 
431
  
 
432
  master = thread_master_create ();
 
433
  bgp_master_init ();
 
434
  
 
435
  if (bgp_get (&bgp, &asn, NULL))
 
436
    return -1;
 
437
  
 
438
  peer = peer_create_accept (bgp);
 
439
  
 
440
  for (i = AFI_IP; i < AFI_MAX; i++)
 
441
    for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
 
442
      peer->afc_nego[i][j] = 1;
 
443
  
 
444
  i =0;
 
445
  while (test_segments[i].name)   
 
446
    parse_test (peer, &test_segments[i++], OPEN);
 
447
  
 
448
  SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
 
449
  peer->status = Established;
 
450
  
 
451
  i = 0;
 
452
  while (dynamic_cap_msgs[i].name)
 
453
    parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
 
454
  
 
455
  printf ("failures: %d\n", failed);
 
456
  return failed;
 
457
}