blob: 0dbf4fb95615baf548d354e7f1d1b8f4f6eb4646 [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",
99 "MP IP6/VPNv4",
100 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000101 6, SHOULD_PARSE, 0, /* parses, but invalid afi,safi */
Paul Jakmae08286b2007-09-18 12:11:26 +0000102 1, AFI_IP6, BGP_SAFI_VPNV4, INVALID_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",
113 "MP IP4/VPNv4",
114 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000115 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000116 1, AFI_IP, BGP_SAFI_VPNV4, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000117 },
118 /* 9 */
119 { "MP7",
120 "MP IP4/VPNv6",
121 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x81 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000122 6, SHOULD_PARSE, 0, /* parses, but invalid afi,safi tuple */
Paul Jakmae08286b2007-09-18 12:11:26 +0000123 1, AFI_IP, BGP_SAFI_VPNV6, INVALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000124 },
125 /* 10 */
126 { "MP8",
127 "MP unknown AFI",
128 { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000129 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000130 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000131 },
132 /* 11 */
133 { "MP-short",
134 "MP IP4/Unicast, length too short (< minimum)",
135 { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
136 6, SHOULD_ERR,
137 },
138 /* 12 */
139 { "MP-overflow",
140 "MP IP4/Unicast, length too long",
141 { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000142 6, SHOULD_ERR, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000143 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000144 },
Paul Jakmae08286b2007-09-18 12:11:26 +0000145 { NULL, NULL, {0}, 0, 0}
146};
147
148static struct test_segment misc_segments[] =
149{
Paul Jakmaed6ef902007-08-08 14:13:03 +0000150 /* 13 */
151 { "ORF",
152 "ORF, simple, single entry, single tuple",
153 { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
154 /* mpc */ 0x0, 0x1, 0x0, 0x1,
155 /* num */ 0x1,
156 /* tuples */ 0x40, 0x3
157 },
158 9, SHOULD_PARSE,
159 },
160 /* 14 */
161 { "ORF-many",
162 "ORF, multi entry/tuple",
163 { /* hdr */ CAPABILITY_CODE_ORF, 0x21,
164 /* mpc */ 0x0, 0x1, 0x0, 0x1,
165 /* num */ 0x3,
166 /* tuples */ 0x40, ORF_MODE_BOTH,
167 0x80, ORF_MODE_RECEIVE,
168 0x80, ORF_MODE_SEND,
169 /* mpc */ 0x0, 0x2, 0x0, 0x1,
170 /* num */ 0x3,
171 /* tuples */ 0x40, ORF_MODE_BOTH,
172 0x80, ORF_MODE_RECEIVE,
173 0x80, ORF_MODE_SEND,
174 /* mpc */ 0x0, 0x2, 0x0, 0x2,
175 /* num */ 0x3,
176 /* tuples */ 0x40, ORF_MODE_RECEIVE,
177 0x80, ORF_MODE_SEND,
178 0x80, ORF_MODE_BOTH,
179 },
180 35, SHOULD_PARSE,
181 },
182 /* 15 */
183 { "ORFlo",
184 "ORF, multi entry/tuple, hdr length too short",
185 { /* hdr */ CAPABILITY_CODE_ORF, 0x15,
186 /* mpc */ 0x0, 0x1, 0x0, 0x1,
187 /* num */ 0x3,
188 /* tuples */ 0x40, 0x3,
189 0x80, 0x1,
190 0x80, 0x2,
191 /* mpc */ 0x0, 0x1, 0x0, 0x1,
192 /* num */ 0x3,
193 /* tuples */ 0x40, 0x3,
194 0x80, 0x1,
195 0x80, 0x2,
196 /* mpc */ 0x0, 0x2, 0x0, 0x2,
197 /* num */ 0x3,
198 /* tuples */ 0x40, 0x3,
199 0x80, 0x1,
200 0x80, 0x2,
201 },
202 35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
203 },
204 /* 16 */
205 { "ORFlu",
206 "ORF, multi entry/tuple, length too long",
207 { /* hdr */ 0x3, 0x22,
208 /* mpc */ 0x0, 0x1, 0x0, 0x1,
209 /* num */ 0x3,
210 /* tuples */ 0x40, 0x3,
211 0x80, 0x1,
212 0x80, 0x2,
213 /* mpc */ 0x0, 0x2, 0x0, 0x1,
214 /* num */ 0x3,
215 /* tuples */ 0x40, 0x3,
216 0x80, 0x1,
217 0x80, 0x2,
218 /* mpc */ 0x0, 0x2, 0x0, 0x2,
219 /* num */ 0x3,
220 /* tuples */ 0x40, 0x3,
221 0x80, 0x1,
222 0x80, 0x2,
223 },
224 35, SHOULD_ERR
225 },
226 /* 17 */
227 { "ORFnu",
228 "ORF, multi entry/tuple, entry number too long",
229 { /* hdr */ 0x3, 0x21,
230 /* mpc */ 0x0, 0x1, 0x0, 0x1,
231 /* num */ 0x3,
232 /* tuples */ 0x40, 0x3,
233 0x80, 0x1,
234 0x80, 0x2,
235 /* mpc */ 0x0, 0x2, 0x0, 0x1,
236 /* num */ 0x4,
237 /* tuples */ 0x40, 0x3,
238 0x80, 0x1,
239 0x80, 0x2,
240 /* mpc */ 0x0, 0x2, 0x0, 0x2,
241 /* num */ 0x3,
242 /* tuples */ 0x40, 0x3,
243 0x80, 0x1,
244 0x80, 0x2,
245 },
246 35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
247 },
248 /* 18 */
249 { "ORFno",
250 "ORF, multi entry/tuple, entry number too short",
251 { /* hdr */ 0x3, 0x21,
252 /* mpc */ 0x0, 0x1, 0x0, 0x1,
253 /* num */ 0x3,
254 /* tuples */ 0x40, 0x3,
255 0x80, 0x1,
256 0x80, 0x2,
257 /* mpc */ 0x0, 0x2, 0x0, 0x1,
258 /* num */ 0x1,
259 /* tuples */ 0x40, 0x3,
260 0x80, 0x1,
261 0x80, 0x2,
262 /* mpc */ 0x0, 0x2, 0x0, 0x2,
263 /* num */ 0x3,
264 /* tuples */ 0x40, 0x3,
265 0x80, 0x1,
266 0x80, 0x2,
267 },
268 35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
269 },
270 /* 17 */
271 { "ORFpad",
272 "ORF, multi entry/tuple, padded to align",
273 { /* hdr */ 0x3, 0x22,
274 /* mpc */ 0x0, 0x1, 0x0, 0x1,
275 /* num */ 0x3,
276 /* tuples */ 0x40, 0x3,
277 0x80, 0x1,
278 0x80, 0x2,
279 /* mpc */ 0x0, 0x2, 0x0, 0x1,
280 /* num */ 0x3,
281 /* tuples */ 0x40, 0x3,
282 0x80, 0x1,
283 0x80, 0x2,
284 /* mpc */ 0x0, 0x2, 0x0, 0x2,
285 /* num */ 0x3,
286 /* tuples */ 0x40, 0x3,
287 0x80, 0x1,
288 0x80, 0x2,
289 0x00,
290 },
291 36, SHOULD_PARSE,
292 },
293 /* 19 */
294 { "AS4",
295 "AS4 capability",
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000296 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
297 6, SHOULD_PARSE, 2882400018,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000298 },
299 /* 20 */
300 { "GR",
301 "GR capability",
302 { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
303 /* R-bit, time */ 0xf1, 0x12,
304 /* afi */ 0x0, 0x1,
305 /* safi */ 0x1,
306 /* flags */ 0xf,
307 /* afi */ 0x0, 0x2,
308 /* safi */ 0x1,
309 /* flags */ 0x0,
310 /* afi */ 0x0, 0x2,
311 /* safi */ 0x2,
312 /* flags */ 0x1,
313 },
314 16, SHOULD_PARSE,
315 },
316 /* 21 */
317 { "GR-short",
318 "GR capability, but header length too short",
319 { /* hdr */ 0x40, 0xa,
320 /* R-bit, time */ 0xf1, 0x12,
321 /* afi */ 0x0, 0x1,
322 /* safi */ 0x1,
323 /* flags */ 0xf,
324 /* afi */ 0x0, 0x2,
325 /* safi */ 0x1,
326 /* flags */ 0x0,
327 /* afi */ 0x0, 0x2,
328 /* safi */ 0x2,
329 /* flags */ 0x1,
330 },
331 16, SHOULD_PARSE,
332 },
333 /* 22 */
334 { "GR-long",
335 "GR capability, but header length too long",
336 { /* hdr */ 0x40, 0xf,
337 /* R-bit, time */ 0xf1, 0x12,
338 /* afi */ 0x0, 0x1,
339 /* safi */ 0x1,
340 /* flags */ 0xf,
341 /* afi */ 0x0, 0x2,
342 /* safi */ 0x1,
343 /* flags */ 0x0,
344 /* afi */ 0x0, 0x2,
345 /* safi */ 0x2,
346 },
347 16, SHOULD_ERR,
348 },
349 { "GR-trunc",
350 "GR capability, but truncated",
351 { /* hdr */ 0x40, 0xf,
352 /* R-bit, time */ 0xf1, 0x12,
353 /* afi */ 0x0, 0x1,
354 /* safi */ 0x1,
355 /* flags */ 0xf,
356 /* afi */ 0x0, 0x2,
357 /* safi */ 0x1,
358 /* flags */ 0x0,
359 /* afi */ 0x0, 0x2,
360 /* safi */ 0x2,
361 /* flags */ 0x1,
362 },
363 15, SHOULD_ERR,
364 },
Paul Jakma370b64a2007-12-22 16:49:52 +0000365 { "GR-empty",
366 "GR capability, but empty.",
367 { /* hdr */ 0x40, 0x0,
368 },
369 2, SHOULD_ERR,
370 },
371 { "MP-empty",
372 "MP capability, but empty.",
373 { /* hdr */ 0x1, 0x0,
374 },
375 2, SHOULD_ERR,
376 },
377 { "ORF-empty",
378 "ORF capability, but empty.",
379 { /* hdr */ 0x3, 0x0,
380 },
381 2, SHOULD_ERR,
382 },
383 { "AS4-empty",
384 "AS4 capability, but empty.",
385 { /* hdr */ 0x41, 0x0,
386 },
387 2, SHOULD_ERR,
388 },
389 { "dyn-empty",
390 "Dynamic capability, but empty.",
391 { /* hdr */ 0x42, 0x0,
392 },
393 2, SHOULD_PARSE,
394 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000395 { "dyn-old",
396 "Dynamic capability (deprecated version)",
397 { CAPABILITY_CODE_DYNAMIC, 0x0 },
398 2, SHOULD_PARSE,
399 },
400 { NULL, NULL, {0}, 0, 0}
401};
402
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000403/* DYNAMIC message */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000404struct test_segment dynamic_cap_msgs[] =
405{
406 { "DynCap",
407 "Dynamic Capability Message, IP/Multicast",
408 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
409 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
410 },
411 { "DynCapLong",
412 "Dynamic Capability Message, IP/Multicast, truncated",
413 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
414 5, SHOULD_ERR,
415 },
416 { "DynCapPadded",
417 "Dynamic Capability Message, IP/Multicast, padded",
418 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
419 8, SHOULD_ERR, /* No way to tell padding from data.. */
420 },
421 { "DynCapMPCpadded",
422 "Dynamic Capability Message, IP/Multicast, cap data padded",
423 { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
424 8, SHOULD_PARSE, /* You can though add padding to the capability data */
425 },
426 { "DynCapMPCoverflow",
427 "Dynamic Capability Message, IP/Multicast, cap data != length",
428 { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
429 8, SHOULD_ERR,
430 },
431 { NULL, NULL, {0}, 0, 0}
432};
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000433
434/* Entire Optional-Parameters block */
435struct test_segment opt_params[] =
436{
437 { "Cap-singlets",
438 "One capability per Optional-Param",
439 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
440 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
441 0x02, 0x02, 0x80, 0x00, /* RR (old) */
442 0x02, 0x02, 0x02, 0x00, /* RR */
443 },
444 24, SHOULD_PARSE,
445 },
446 { "Cap-series",
447 "Series of capability, one Optional-Param",
448 { 0x02, 0x10,
449 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
450 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
451 0x80, 0x00, /* RR (old) */
452 0x02, 0x00, /* RR */
453 },
454 18, SHOULD_PARSE,
455 },
456 { "AS4more",
457 "AS4 capability after other caps (singlets)",
458 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
459 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
460 0x02, 0x02, 0x80, 0x00, /* RR (old) */
461 0x02, 0x02, 0x02, 0x00, /* RR */
462 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
463 },
464 32, SHOULD_PARSE, 196614,
465 },
466 { "AS4series",
467 "AS4 capability, in series of capabilities",
468 { 0x02, 0x16,
469 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
470 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
471 0x80, 0x00, /* RR (old) */
472 0x02, 0x00, /* RR */
473 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
474 },
475 24, SHOULD_PARSE, 196614,
476 },
477 { "AS4real",
478 "AS4 capability, in series of capabilities",
479 {
480 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
481 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
482 0x02, 0x02, 0x80, 0x00, /* RR old */
483 0x02, 0x02, 0x02, 0x00, /* RR */
484 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
485 },
486 32, SHOULD_PARSE, 196614,
487 },
488 { "AS4real2",
489 "AS4 capability, in series of capabilities",
490 {
491 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
492 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
493 0x02, 0x02, 0x80, 0x00,
494 0x02, 0x02, 0x02, 0x00,
495 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
496 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
497 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
498 0x02, 0x02, 0x42, 0x00,
499 },
500 58, SHOULD_PARSE, 64515,
501 },
502
503 { NULL, NULL, {0}, 0, 0}
504};
505
Paul Jakmaed6ef902007-08-08 14:13:03 +0000506/* basic parsing test */
507static void
508parse_test (struct peer *peer, struct test_segment *t, int type)
509{
510 int ret;
511 int capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000512 as_t as4 = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +0000513 int oldfailed = failed;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000514 int len = t->len;
515#define RANDOM_FUZZ 35
Paul Jakmaed6ef902007-08-08 14:13:03 +0000516
517 stream_reset (peer->ibuf);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000518 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
519 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
520
Paul Jakmaed6ef902007-08-08 14:13:03 +0000521 switch (type)
522 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000523 case CAPABILITY:
Paul Jakmaed6ef902007-08-08 14:13:03 +0000524 stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
525 stream_putc (peer->ibuf, t->len);
526 break;
527 case DYNCAP:
528/* for (i = 0; i < BGP_MARKER_SIZE; i++)
529 stream_putc (peer->, 0xff);
530 stream_putw (s, 0);
531 stream_putc (s, BGP_MSG_CAPABILITY);*/
532 break;
533 }
534 stream_write (peer->ibuf, t->data, t->len);
535
536 printf ("%s: %s\n", t->name, t->desc);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000537
Paul Jakmaed6ef902007-08-08 14:13:03 +0000538 switch (type)
539 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000540 case CAPABILITY:
541 len += 2; /* to cover the OPT-Param header */
542 case OPT_PARAM:
543 printf ("len: %u\n", len);
544 /* peek_for_as4 wants getp at capibility*/
545 as4 = peek_for_as4_capability (peer, len);
546 printf ("peek_for_as4: as4 is %u\n", as4);
547 /* and it should leave getp as it found it */
548 assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
549
550 ret = bgp_open_option_parse (peer, len, &capability);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000551 break;
552 case DYNCAP:
553 ret = bgp_capability_receive (peer, t->len);
554 break;
555 default:
556 printf ("unknown type %u\n", type);
557 exit(1);
558 }
559
Paul Jakmae08286b2007-09-18 12:11:26 +0000560 if (!ret && t->validate_afi)
561 {
562 safi_t safi = t->safi;
563
564 if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
565 failed++;
566
567 printf ("MP: %u/%u (%u): recv %u, nego %u\n",
568 t->afi, t->safi, safi,
569 peer->afc_recv[t->afi][safi],
570 peer->afc_nego[t->afi][safi]);
571
572 if (t->afi_valid == VALID_AFI)
573 {
574
575 if (!peer->afc_recv[t->afi][safi])
576 failed++;
577 if (!peer->afc_nego[t->afi][safi])
578 failed++;
579 }
580 }
581
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000582 if (as4 != t->peek_for)
583 {
584 printf ("as4 %u != %u\n", as4, t->peek_for);
585 failed++;
586 }
587
Paul Jakmaed6ef902007-08-08 14:13:03 +0000588 printf ("parsed?: %s\n", ret ? "no" : "yes");
589
Paul Jakmae08286b2007-09-18 12:11:26 +0000590 if (ret != t->parses)
591 failed++;
592
593 if (tty)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000594 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
Paul Jakmae08286b2007-09-18 12:11:26 +0000595 : VT100_GREEN "OK" VT100_RESET);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000596 else
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000597 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
Paul Jakmaed6ef902007-08-08 14:13:03 +0000598
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000599 if (failed)
600 printf (" (%u)", failed);
601
602 printf ("\n\n");
Paul Jakmaed6ef902007-08-08 14:13:03 +0000603}
604
605static struct bgp *bgp;
606static as_t asn = 100;
607
608int
609main (void)
610{
611 struct peer *peer;
612 int i, j;
613
614 conf_bgp_debug_fsm = -1UL;
615 conf_bgp_debug_events = -1UL;
616 conf_bgp_debug_packet = -1UL;
617 conf_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000618 conf_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000619 term_bgp_debug_fsm = -1UL;
620 term_bgp_debug_events = -1UL;
621 term_bgp_debug_packet = -1UL;
622 term_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000623 term_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000624
625 master = thread_master_create ();
626 bgp_master_init ();
627
Paul Jakmae08286b2007-09-18 12:11:26 +0000628 if (fileno (stdout) >= 0)
629 tty = isatty (fileno (stdout));
630
Paul Jakmaed6ef902007-08-08 14:13:03 +0000631 if (bgp_get (&bgp, &asn, NULL))
632 return -1;
633
634 peer = peer_create_accept (bgp);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000635 peer->host = "foo";
Paul Jakmaed6ef902007-08-08 14:13:03 +0000636
637 for (i = AFI_IP; i < AFI_MAX; i++)
638 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
Paul Jakmae08286b2007-09-18 12:11:26 +0000639 {
640 peer->afc[i][j] = 1;
641 peer->afc_adv[i][j] = 1;
642 }
Paul Jakmaed6ef902007-08-08 14:13:03 +0000643
Paul Jakmae08286b2007-09-18 12:11:26 +0000644 i = 0;
645 while (mp_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000646 parse_test (peer, &mp_segments[i++], CAPABILITY);
Paul Jakmae08286b2007-09-18 12:11:26 +0000647
648 /* These tests assume mp_segments tests set at least
649 * one of the afc_nego's
650 */
651 i = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000652 while (test_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000653 parse_test (peer, &test_segments[i++], CAPABILITY);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000654
Paul Jakmae08286b2007-09-18 12:11:26 +0000655 i = 0;
656 while (misc_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000657 parse_test (peer, &misc_segments[i++], CAPABILITY);
658
659 i = 0;
660 while (opt_params[i].name)
661 parse_test (peer, &opt_params[i++], OPT_PARAM);
Paul Jakmae08286b2007-09-18 12:11:26 +0000662
Paul Jakmaed6ef902007-08-08 14:13:03 +0000663 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
664 peer->status = Established;
665
666 i = 0;
667 while (dynamic_cap_msgs[i].name)
668 parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
669
670 printf ("failures: %d\n", failed);
671 return failed;
672}