blob: 9b43159c7c03f1a38b15d0c0aa322879f7d16efe [file] [log] [blame]
Paul Jakmaed6ef902007-08-08 14:13:03 +00001#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
Paul Jakmae08286b2007-09-18 12:11:26 +000012#define VT100_RESET "\x1b[0m"
13#define VT100_RED "\x1b[31m"
14#define VT100_GREEN "\x1b[32m"
15#define VT100_YELLOW "\x1b[33m"
16
17
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000018#define CAPABILITY 0
19#define DYNCAP 1
20#define OPT_PARAM 2
Paul Jakmaed6ef902007-08-08 14:13:03 +000021
22/* need these to link in libbgp */
23struct zebra_privs_t *bgpd_privs = NULL;
24struct thread_master *master = NULL;
25
26static int failed = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +000027static int tty = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +000028
29/* test segments to parse and validate, and use for other tests */
30static struct test_segment {
31 const char *name;
32 const char *desc;
33 const u_char data[1024];
34 int len;
35#define SHOULD_PARSE 0
36#define SHOULD_ERR -1
37 int parses; /* whether it should parse or not */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000038 int peek_for; /* what peek_for_as4_capability should say */
39
Paul Jakmae08286b2007-09-18 12:11:26 +000040 /* AFI/SAFI validation */
41 int validate_afi;
42 afi_t afi;
43 safi_t safi;
44#define VALID_AFI 1
45#define INVALID_AFI 0
46 int afi_valid;
Paul Jakmaed6ef902007-08-08 14:13:03 +000047} test_segments [] =
48{
49 /* 0 */
50 { "caphdr",
51 "capability header, and no more",
52 { CAPABILITY_CODE_REFRESH, 0x0 },
53 2, SHOULD_PARSE,
54 },
55 /* 1 */
56 { "nodata",
57 "header, no data but length says there is",
58 { 0x1, 0xa },
59 2, SHOULD_ERR,
60 },
61 /* 2 */
62 { "padded",
63 "valid, with padding",
64 { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
65 4, SHOULD_PARSE,
66 },
67 /* 3 */
68 { "minsize",
69 "violates minsize requirement",
70 { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
71 4, SHOULD_ERR,
72 },
Paul Jakmae08286b2007-09-18 12:11:26 +000073 { NULL, NULL, {0}, 0, 0},
74};
75
76static struct test_segment mp_segments[] =
77{
78 { "MP4",
Paul Jakmaed6ef902007-08-08 14:13:03 +000079 "MP IP/Uni",
80 { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000081 6, SHOULD_PARSE, 0,
82 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmae08286b2007-09-18 12:11:26 +000083 },
84 { "MPv6",
85 "MP IPv6/Uni",
86 { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000087 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +000088 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +000089 },
90 /* 5 */
91 { "MP2",
92 "MP IP/Multicast",
93 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000094 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +000095 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +000096 },
97 /* 6 */
98 { "MP3",
Denis Ovsienkoe81537d2011-07-14 12:36:19 +040099 "MP IP6/MPLS-labeled VPN",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000100 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
Denis Ovsienkoe81537d2011-07-14 12:36:19 +0400101 6, SHOULD_PARSE, 0,
102 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000103 },
104 /* 7 */
105 { "MP5",
106 "MP IP6/MPLS-VPN",
107 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000108 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000109 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000110 },
111 /* 8 */
112 { "MP6",
Denis Ovsienkoe81537d2011-07-14 12:36:19 +0400113 "MP IP4/MPLS-laveled VPN",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000114 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000115 6, SHOULD_PARSE, 0,
Denis Ovsienkoe81537d2011-07-14 12:36:19 +0400116 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000117 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000118 /* 10 */
119 { "MP8",
Denis Ovsienkoe81537d2011-07-14 12:36:19 +0400120 "MP unknown AFI/SAFI",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000121 { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000122 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000123 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000124 },
125 /* 11 */
126 { "MP-short",
127 "MP IP4/Unicast, length too short (< minimum)",
128 { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
129 6, SHOULD_ERR,
130 },
131 /* 12 */
132 { "MP-overflow",
133 "MP IP4/Unicast, length too long",
134 { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000135 6, SHOULD_ERR, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000136 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000137 },
Paul Jakmae08286b2007-09-18 12:11:26 +0000138 { NULL, NULL, {0}, 0, 0}
139};
140
141static struct test_segment misc_segments[] =
142{
Paul Jakmaed6ef902007-08-08 14:13:03 +0000143 /* 13 */
144 { "ORF",
145 "ORF, simple, single entry, single tuple",
146 { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
147 /* mpc */ 0x0, 0x1, 0x0, 0x1,
148 /* num */ 0x1,
149 /* tuples */ 0x40, 0x3
150 },
151 9, SHOULD_PARSE,
152 },
153 /* 14 */
154 { "ORF-many",
155 "ORF, multi entry/tuple",
156 { /* hdr */ CAPABILITY_CODE_ORF, 0x21,
157 /* mpc */ 0x0, 0x1, 0x0, 0x1,
158 /* num */ 0x3,
159 /* tuples */ 0x40, ORF_MODE_BOTH,
160 0x80, ORF_MODE_RECEIVE,
161 0x80, ORF_MODE_SEND,
162 /* mpc */ 0x0, 0x2, 0x0, 0x1,
163 /* num */ 0x3,
164 /* tuples */ 0x40, ORF_MODE_BOTH,
165 0x80, ORF_MODE_RECEIVE,
166 0x80, ORF_MODE_SEND,
167 /* mpc */ 0x0, 0x2, 0x0, 0x2,
168 /* num */ 0x3,
169 /* tuples */ 0x40, ORF_MODE_RECEIVE,
170 0x80, ORF_MODE_SEND,
171 0x80, ORF_MODE_BOTH,
172 },
173 35, SHOULD_PARSE,
174 },
175 /* 15 */
176 { "ORFlo",
177 "ORF, multi entry/tuple, hdr length too short",
178 { /* hdr */ CAPABILITY_CODE_ORF, 0x15,
179 /* mpc */ 0x0, 0x1, 0x0, 0x1,
180 /* num */ 0x3,
181 /* tuples */ 0x40, 0x3,
182 0x80, 0x1,
183 0x80, 0x2,
184 /* mpc */ 0x0, 0x1, 0x0, 0x1,
185 /* num */ 0x3,
186 /* tuples */ 0x40, 0x3,
187 0x80, 0x1,
188 0x80, 0x2,
189 /* mpc */ 0x0, 0x2, 0x0, 0x2,
190 /* num */ 0x3,
191 /* tuples */ 0x40, 0x3,
192 0x80, 0x1,
193 0x80, 0x2,
194 },
195 35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
196 },
197 /* 16 */
198 { "ORFlu",
199 "ORF, multi entry/tuple, length too long",
200 { /* hdr */ 0x3, 0x22,
201 /* mpc */ 0x0, 0x1, 0x0, 0x1,
202 /* num */ 0x3,
203 /* tuples */ 0x40, 0x3,
204 0x80, 0x1,
205 0x80, 0x2,
206 /* mpc */ 0x0, 0x2, 0x0, 0x1,
207 /* num */ 0x3,
208 /* tuples */ 0x40, 0x3,
209 0x80, 0x1,
210 0x80, 0x2,
211 /* mpc */ 0x0, 0x2, 0x0, 0x2,
212 /* num */ 0x3,
213 /* tuples */ 0x40, 0x3,
214 0x80, 0x1,
215 0x80, 0x2,
216 },
217 35, SHOULD_ERR
218 },
219 /* 17 */
220 { "ORFnu",
221 "ORF, multi entry/tuple, entry number too long",
222 { /* hdr */ 0x3, 0x21,
223 /* mpc */ 0x0, 0x1, 0x0, 0x1,
224 /* num */ 0x3,
225 /* tuples */ 0x40, 0x3,
226 0x80, 0x1,
227 0x80, 0x2,
228 /* mpc */ 0x0, 0x2, 0x0, 0x1,
229 /* num */ 0x4,
230 /* tuples */ 0x40, 0x3,
231 0x80, 0x1,
232 0x80, 0x2,
233 /* mpc */ 0x0, 0x2, 0x0, 0x2,
234 /* num */ 0x3,
235 /* tuples */ 0x40, 0x3,
236 0x80, 0x1,
237 0x80, 0x2,
238 },
239 35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
240 },
241 /* 18 */
242 { "ORFno",
243 "ORF, multi entry/tuple, entry number too short",
244 { /* hdr */ 0x3, 0x21,
245 /* mpc */ 0x0, 0x1, 0x0, 0x1,
246 /* num */ 0x3,
247 /* tuples */ 0x40, 0x3,
248 0x80, 0x1,
249 0x80, 0x2,
250 /* mpc */ 0x0, 0x2, 0x0, 0x1,
251 /* num */ 0x1,
252 /* tuples */ 0x40, 0x3,
253 0x80, 0x1,
254 0x80, 0x2,
255 /* mpc */ 0x0, 0x2, 0x0, 0x2,
256 /* num */ 0x3,
257 /* tuples */ 0x40, 0x3,
258 0x80, 0x1,
259 0x80, 0x2,
260 },
261 35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
262 },
263 /* 17 */
264 { "ORFpad",
265 "ORF, multi entry/tuple, padded to align",
266 { /* hdr */ 0x3, 0x22,
267 /* mpc */ 0x0, 0x1, 0x0, 0x1,
268 /* num */ 0x3,
269 /* tuples */ 0x40, 0x3,
270 0x80, 0x1,
271 0x80, 0x2,
272 /* mpc */ 0x0, 0x2, 0x0, 0x1,
273 /* num */ 0x3,
274 /* tuples */ 0x40, 0x3,
275 0x80, 0x1,
276 0x80, 0x2,
277 /* mpc */ 0x0, 0x2, 0x0, 0x2,
278 /* num */ 0x3,
279 /* tuples */ 0x40, 0x3,
280 0x80, 0x1,
281 0x80, 0x2,
282 0x00,
283 },
284 36, SHOULD_PARSE,
285 },
286 /* 19 */
287 { "AS4",
288 "AS4 capability",
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000289 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
290 6, SHOULD_PARSE, 2882400018,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000291 },
292 /* 20 */
293 { "GR",
294 "GR capability",
295 { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
296 /* R-bit, time */ 0xf1, 0x12,
297 /* afi */ 0x0, 0x1,
298 /* safi */ 0x1,
299 /* flags */ 0xf,
300 /* afi */ 0x0, 0x2,
301 /* safi */ 0x1,
302 /* flags */ 0x0,
303 /* afi */ 0x0, 0x2,
304 /* safi */ 0x2,
305 /* flags */ 0x1,
306 },
307 16, SHOULD_PARSE,
308 },
309 /* 21 */
310 { "GR-short",
311 "GR capability, but header length too short",
312 { /* hdr */ 0x40, 0xa,
313 /* R-bit, time */ 0xf1, 0x12,
314 /* afi */ 0x0, 0x1,
315 /* safi */ 0x1,
316 /* flags */ 0xf,
317 /* afi */ 0x0, 0x2,
318 /* safi */ 0x1,
319 /* flags */ 0x0,
320 /* afi */ 0x0, 0x2,
321 /* safi */ 0x2,
322 /* flags */ 0x1,
323 },
324 16, SHOULD_PARSE,
325 },
326 /* 22 */
327 { "GR-long",
328 "GR capability, but header length too long",
329 { /* hdr */ 0x40, 0xf,
330 /* R-bit, time */ 0xf1, 0x12,
331 /* afi */ 0x0, 0x1,
332 /* safi */ 0x1,
333 /* flags */ 0xf,
334 /* afi */ 0x0, 0x2,
335 /* safi */ 0x1,
336 /* flags */ 0x0,
337 /* afi */ 0x0, 0x2,
338 /* safi */ 0x2,
339 },
340 16, SHOULD_ERR,
341 },
342 { "GR-trunc",
343 "GR capability, but truncated",
344 { /* hdr */ 0x40, 0xf,
345 /* R-bit, time */ 0xf1, 0x12,
346 /* afi */ 0x0, 0x1,
347 /* safi */ 0x1,
348 /* flags */ 0xf,
349 /* afi */ 0x0, 0x2,
350 /* safi */ 0x1,
351 /* flags */ 0x0,
352 /* afi */ 0x0, 0x2,
353 /* safi */ 0x2,
354 /* flags */ 0x1,
355 },
356 15, SHOULD_ERR,
357 },
Paul Jakma370b64a2007-12-22 16:49:52 +0000358 { "GR-empty",
359 "GR capability, but empty.",
360 { /* hdr */ 0x40, 0x0,
361 },
362 2, SHOULD_ERR,
363 },
364 { "MP-empty",
365 "MP capability, but empty.",
366 { /* hdr */ 0x1, 0x0,
367 },
368 2, SHOULD_ERR,
369 },
370 { "ORF-empty",
371 "ORF capability, but empty.",
372 { /* hdr */ 0x3, 0x0,
373 },
374 2, SHOULD_ERR,
375 },
376 { "AS4-empty",
377 "AS4 capability, but empty.",
378 { /* hdr */ 0x41, 0x0,
379 },
380 2, SHOULD_ERR,
381 },
382 { "dyn-empty",
383 "Dynamic capability, but empty.",
384 { /* hdr */ 0x42, 0x0,
385 },
386 2, SHOULD_PARSE,
387 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000388 { "dyn-old",
389 "Dynamic capability (deprecated version)",
390 { CAPABILITY_CODE_DYNAMIC, 0x0 },
391 2, SHOULD_PARSE,
392 },
393 { NULL, NULL, {0}, 0, 0}
394};
395
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000396/* DYNAMIC message */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000397struct test_segment dynamic_cap_msgs[] =
398{
399 { "DynCap",
400 "Dynamic Capability Message, IP/Multicast",
401 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
402 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
403 },
404 { "DynCapLong",
405 "Dynamic Capability Message, IP/Multicast, truncated",
406 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
407 5, SHOULD_ERR,
408 },
409 { "DynCapPadded",
410 "Dynamic Capability Message, IP/Multicast, padded",
411 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
412 8, SHOULD_ERR, /* No way to tell padding from data.. */
413 },
414 { "DynCapMPCpadded",
415 "Dynamic Capability Message, IP/Multicast, cap data padded",
416 { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
417 8, SHOULD_PARSE, /* You can though add padding to the capability data */
418 },
419 { "DynCapMPCoverflow",
420 "Dynamic Capability Message, IP/Multicast, cap data != length",
421 { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
422 8, SHOULD_ERR,
423 },
424 { NULL, NULL, {0}, 0, 0}
425};
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000426
427/* Entire Optional-Parameters block */
428struct test_segment opt_params[] =
429{
430 { "Cap-singlets",
431 "One capability per Optional-Param",
432 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
433 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
434 0x02, 0x02, 0x80, 0x00, /* RR (old) */
435 0x02, 0x02, 0x02, 0x00, /* RR */
436 },
437 24, SHOULD_PARSE,
438 },
439 { "Cap-series",
440 "Series of capability, one Optional-Param",
441 { 0x02, 0x10,
442 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
443 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
444 0x80, 0x00, /* RR (old) */
445 0x02, 0x00, /* RR */
446 },
447 18, SHOULD_PARSE,
448 },
449 { "AS4more",
450 "AS4 capability after other caps (singlets)",
451 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
452 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
453 0x02, 0x02, 0x80, 0x00, /* RR (old) */
454 0x02, 0x02, 0x02, 0x00, /* RR */
455 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
456 },
457 32, SHOULD_PARSE, 196614,
458 },
459 { "AS4series",
460 "AS4 capability, in series of capabilities",
461 { 0x02, 0x16,
462 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
463 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
464 0x80, 0x00, /* RR (old) */
465 0x02, 0x00, /* RR */
466 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
467 },
468 24, SHOULD_PARSE, 196614,
469 },
470 { "AS4real",
471 "AS4 capability, in series of capabilities",
472 {
473 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
474 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
475 0x02, 0x02, 0x80, 0x00, /* RR old */
476 0x02, 0x02, 0x02, 0x00, /* RR */
477 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
478 },
479 32, SHOULD_PARSE, 196614,
480 },
481 { "AS4real2",
482 "AS4 capability, in series of capabilities",
483 {
484 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
485 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
486 0x02, 0x02, 0x80, 0x00,
487 0x02, 0x02, 0x02, 0x00,
488 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
489 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
490 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
491 0x02, 0x02, 0x42, 0x00,
492 },
493 58, SHOULD_PARSE, 64515,
494 },
495
496 { NULL, NULL, {0}, 0, 0}
497};
498
Paul Jakmaed6ef902007-08-08 14:13:03 +0000499/* basic parsing test */
500static void
501parse_test (struct peer *peer, struct test_segment *t, int type)
502{
503 int ret;
504 int capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000505 as_t as4 = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +0000506 int oldfailed = failed;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000507 int len = t->len;
508#define RANDOM_FUZZ 35
Paul Jakmaed6ef902007-08-08 14:13:03 +0000509
510 stream_reset (peer->ibuf);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000511 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
512 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
513
Paul Jakmaed6ef902007-08-08 14:13:03 +0000514 switch (type)
515 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000516 case CAPABILITY:
Paul Jakmaed6ef902007-08-08 14:13:03 +0000517 stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
518 stream_putc (peer->ibuf, t->len);
519 break;
520 case DYNCAP:
521/* for (i = 0; i < BGP_MARKER_SIZE; i++)
522 stream_putc (peer->, 0xff);
523 stream_putw (s, 0);
524 stream_putc (s, BGP_MSG_CAPABILITY);*/
525 break;
526 }
527 stream_write (peer->ibuf, t->data, t->len);
528
529 printf ("%s: %s\n", t->name, t->desc);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000530
Paul Jakmaed6ef902007-08-08 14:13:03 +0000531 switch (type)
532 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000533 case CAPABILITY:
534 len += 2; /* to cover the OPT-Param header */
535 case OPT_PARAM:
536 printf ("len: %u\n", len);
537 /* peek_for_as4 wants getp at capibility*/
538 as4 = peek_for_as4_capability (peer, len);
539 printf ("peek_for_as4: as4 is %u\n", as4);
540 /* and it should leave getp as it found it */
541 assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
542
543 ret = bgp_open_option_parse (peer, len, &capability);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000544 break;
545 case DYNCAP:
546 ret = bgp_capability_receive (peer, t->len);
547 break;
548 default:
549 printf ("unknown type %u\n", type);
550 exit(1);
551 }
552
Paul Jakmae08286b2007-09-18 12:11:26 +0000553 if (!ret && t->validate_afi)
554 {
555 safi_t safi = t->safi;
556
557 if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
558 failed++;
559
560 printf ("MP: %u/%u (%u): recv %u, nego %u\n",
561 t->afi, t->safi, safi,
562 peer->afc_recv[t->afi][safi],
563 peer->afc_nego[t->afi][safi]);
564
565 if (t->afi_valid == VALID_AFI)
566 {
567
568 if (!peer->afc_recv[t->afi][safi])
569 failed++;
570 if (!peer->afc_nego[t->afi][safi])
571 failed++;
572 }
573 }
574
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000575 if (as4 != t->peek_for)
576 {
577 printf ("as4 %u != %u\n", as4, t->peek_for);
578 failed++;
579 }
580
Paul Jakmaed6ef902007-08-08 14:13:03 +0000581 printf ("parsed?: %s\n", ret ? "no" : "yes");
582
Paul Jakmae08286b2007-09-18 12:11:26 +0000583 if (ret != t->parses)
584 failed++;
585
586 if (tty)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000587 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
Paul Jakmae08286b2007-09-18 12:11:26 +0000588 : VT100_GREEN "OK" VT100_RESET);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000589 else
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000590 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
Paul Jakmaed6ef902007-08-08 14:13:03 +0000591
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000592 if (failed)
593 printf (" (%u)", failed);
594
595 printf ("\n\n");
Paul Jakmaed6ef902007-08-08 14:13:03 +0000596}
597
598static struct bgp *bgp;
599static as_t asn = 100;
600
601int
602main (void)
603{
604 struct peer *peer;
605 int i, j;
606
607 conf_bgp_debug_fsm = -1UL;
608 conf_bgp_debug_events = -1UL;
609 conf_bgp_debug_packet = -1UL;
610 conf_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000611 conf_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000612 term_bgp_debug_fsm = -1UL;
613 term_bgp_debug_events = -1UL;
614 term_bgp_debug_packet = -1UL;
615 term_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000616 term_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000617
618 master = thread_master_create ();
619 bgp_master_init ();
620
Paul Jakmae08286b2007-09-18 12:11:26 +0000621 if (fileno (stdout) >= 0)
622 tty = isatty (fileno (stdout));
623
Paul Jakmaed6ef902007-08-08 14:13:03 +0000624 if (bgp_get (&bgp, &asn, NULL))
625 return -1;
626
627 peer = peer_create_accept (bgp);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000628 peer->host = "foo";
Paul Jakmaed6ef902007-08-08 14:13:03 +0000629
630 for (i = AFI_IP; i < AFI_MAX; i++)
631 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
Paul Jakmae08286b2007-09-18 12:11:26 +0000632 {
633 peer->afc[i][j] = 1;
634 peer->afc_adv[i][j] = 1;
635 }
Paul Jakmaed6ef902007-08-08 14:13:03 +0000636
Paul Jakmae08286b2007-09-18 12:11:26 +0000637 i = 0;
638 while (mp_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000639 parse_test (peer, &mp_segments[i++], CAPABILITY);
Paul Jakmae08286b2007-09-18 12:11:26 +0000640
641 /* These tests assume mp_segments tests set at least
642 * one of the afc_nego's
643 */
644 i = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000645 while (test_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000646 parse_test (peer, &test_segments[i++], CAPABILITY);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000647
Paul Jakmae08286b2007-09-18 12:11:26 +0000648 i = 0;
649 while (misc_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000650 parse_test (peer, &misc_segments[i++], CAPABILITY);
651
652 i = 0;
653 while (opt_params[i].name)
654 parse_test (peer, &opt_params[i++], OPT_PARAM);
Paul Jakmae08286b2007-09-18 12:11:26 +0000655
Paul Jakmaed6ef902007-08-08 14:13:03 +0000656 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
657 peer->status = Established;
658
659 i = 0;
660 while (dynamic_cap_msgs[i].name)
661 parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
662
663 printf ("failures: %d\n", failed);
664 return failed;
665}