blob: 65c6a7002b65d352659112d81376ea644398580e [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"
Paul Jakma1dba2542012-05-01 16:20:33 +010011#include "bgpd/bgp_packet.h"
Paul Jakmaed6ef902007-08-08 14:13:03 +000012
Paul Jakmae08286b2007-09-18 12:11:26 +000013#define VT100_RESET "\x1b[0m"
14#define VT100_RED "\x1b[31m"
15#define VT100_GREEN "\x1b[32m"
16#define VT100_YELLOW "\x1b[33m"
17
18
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000019#define CAPABILITY 0
20#define DYNCAP 1
21#define OPT_PARAM 2
Paul Jakmaed6ef902007-08-08 14:13:03 +000022
23/* need these to link in libbgp */
24struct zebra_privs_t *bgpd_privs = NULL;
25struct thread_master *master = NULL;
26
27static int failed = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +000028static int tty = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +000029
30/* test segments to parse and validate, and use for other tests */
31static struct test_segment {
32 const char *name;
33 const char *desc;
34 const u_char data[1024];
35 int len;
36#define SHOULD_PARSE 0
37#define SHOULD_ERR -1
38 int parses; /* whether it should parse or not */
Paul Jakma1dba2542012-05-01 16:20:33 +010039 as_t peek_for; /* what peek_for_as4_capability should say */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000040
Paul Jakmae08286b2007-09-18 12:11:26 +000041 /* AFI/SAFI validation */
42 int validate_afi;
43 afi_t afi;
44 safi_t safi;
45#define VALID_AFI 1
46#define INVALID_AFI 0
47 int afi_valid;
Paul Jakmaed6ef902007-08-08 14:13:03 +000048} test_segments [] =
49{
50 /* 0 */
51 { "caphdr",
52 "capability header, and no more",
53 { CAPABILITY_CODE_REFRESH, 0x0 },
54 2, SHOULD_PARSE,
55 },
56 /* 1 */
57 { "nodata",
58 "header, no data but length says there is",
59 { 0x1, 0xa },
60 2, SHOULD_ERR,
61 },
62 /* 2 */
63 { "padded",
64 "valid, with padding",
65 { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
66 4, SHOULD_PARSE,
67 },
68 /* 3 */
69 { "minsize",
70 "violates minsize requirement",
71 { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
72 4, SHOULD_ERR,
73 },
Paul Jakmae08286b2007-09-18 12:11:26 +000074 { NULL, NULL, {0}, 0, 0},
75};
76
77static struct test_segment mp_segments[] =
78{
79 { "MP4",
Paul Jakmaed6ef902007-08-08 14:13:03 +000080 "MP IP/Uni",
81 { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000082 6, SHOULD_PARSE, 0,
83 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmae08286b2007-09-18 12:11:26 +000084 },
85 { "MPv6",
86 "MP IPv6/Uni",
87 { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000088 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +000089 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +000090 },
91 /* 5 */
92 { "MP2",
93 "MP IP/Multicast",
94 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000095 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +000096 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +000097 },
98 /* 6 */
99 { "MP3",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400100 "MP IP6/MPLS-labeled VPN",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000101 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400102 6, SHOULD_PARSE, 0,
103 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000104 },
105 /* 7 */
106 { "MP5",
107 "MP IP6/MPLS-VPN",
108 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000109 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000110 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000111 },
112 /* 8 */
113 { "MP6",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400114 "MP IP4/MPLS-laveled VPN",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000115 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000116 6, SHOULD_PARSE, 0,
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400117 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000118 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000119 /* 10 */
120 { "MP8",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400121 "MP unknown AFI/SAFI",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000122 { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000123 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000124 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000125 },
126 /* 11 */
127 { "MP-short",
128 "MP IP4/Unicast, length too short (< minimum)",
129 { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
130 6, SHOULD_ERR,
131 },
132 /* 12 */
133 { "MP-overflow",
134 "MP IP4/Unicast, length too long",
135 { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000136 6, SHOULD_ERR, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000137 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000138 },
Paul Jakmae08286b2007-09-18 12:11:26 +0000139 { NULL, NULL, {0}, 0, 0}
140};
141
142static struct test_segment misc_segments[] =
143{
Paul Jakmaed6ef902007-08-08 14:13:03 +0000144 /* 13 */
145 { "ORF",
146 "ORF, simple, single entry, single tuple",
147 { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
148 /* mpc */ 0x0, 0x1, 0x0, 0x1,
149 /* num */ 0x1,
150 /* tuples */ 0x40, 0x3
151 },
152 9, SHOULD_PARSE,
153 },
154 /* 14 */
155 { "ORF-many",
156 "ORF, multi entry/tuple",
157 { /* hdr */ CAPABILITY_CODE_ORF, 0x21,
158 /* mpc */ 0x0, 0x1, 0x0, 0x1,
159 /* num */ 0x3,
160 /* tuples */ 0x40, ORF_MODE_BOTH,
161 0x80, ORF_MODE_RECEIVE,
162 0x80, ORF_MODE_SEND,
163 /* mpc */ 0x0, 0x2, 0x0, 0x1,
164 /* num */ 0x3,
165 /* tuples */ 0x40, ORF_MODE_BOTH,
166 0x80, ORF_MODE_RECEIVE,
167 0x80, ORF_MODE_SEND,
168 /* mpc */ 0x0, 0x2, 0x0, 0x2,
169 /* num */ 0x3,
170 /* tuples */ 0x40, ORF_MODE_RECEIVE,
171 0x80, ORF_MODE_SEND,
172 0x80, ORF_MODE_BOTH,
173 },
174 35, SHOULD_PARSE,
175 },
176 /* 15 */
177 { "ORFlo",
178 "ORF, multi entry/tuple, hdr length too short",
179 { /* hdr */ CAPABILITY_CODE_ORF, 0x15,
180 /* mpc */ 0x0, 0x1, 0x0, 0x1,
181 /* num */ 0x3,
182 /* tuples */ 0x40, 0x3,
183 0x80, 0x1,
184 0x80, 0x2,
185 /* mpc */ 0x0, 0x1, 0x0, 0x1,
186 /* num */ 0x3,
187 /* tuples */ 0x40, 0x3,
188 0x80, 0x1,
189 0x80, 0x2,
190 /* mpc */ 0x0, 0x2, 0x0, 0x2,
191 /* num */ 0x3,
192 /* tuples */ 0x40, 0x3,
193 0x80, 0x1,
194 0x80, 0x2,
195 },
196 35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
197 },
198 /* 16 */
199 { "ORFlu",
200 "ORF, multi entry/tuple, length too long",
201 { /* hdr */ 0x3, 0x22,
202 /* mpc */ 0x0, 0x1, 0x0, 0x1,
203 /* num */ 0x3,
204 /* tuples */ 0x40, 0x3,
205 0x80, 0x1,
206 0x80, 0x2,
207 /* mpc */ 0x0, 0x2, 0x0, 0x1,
208 /* num */ 0x3,
209 /* tuples */ 0x40, 0x3,
210 0x80, 0x1,
211 0x80, 0x2,
212 /* mpc */ 0x0, 0x2, 0x0, 0x2,
213 /* num */ 0x3,
214 /* tuples */ 0x40, 0x3,
215 0x80, 0x1,
216 0x80, 0x2,
217 },
218 35, SHOULD_ERR
219 },
220 /* 17 */
221 { "ORFnu",
222 "ORF, multi entry/tuple, entry number too long",
223 { /* hdr */ 0x3, 0x21,
224 /* mpc */ 0x0, 0x1, 0x0, 0x1,
225 /* num */ 0x3,
226 /* tuples */ 0x40, 0x3,
227 0x80, 0x1,
228 0x80, 0x2,
229 /* mpc */ 0x0, 0x2, 0x0, 0x1,
230 /* num */ 0x4,
231 /* tuples */ 0x40, 0x3,
232 0x80, 0x1,
233 0x80, 0x2,
234 /* mpc */ 0x0, 0x2, 0x0, 0x2,
235 /* num */ 0x3,
236 /* tuples */ 0x40, 0x3,
237 0x80, 0x1,
238 0x80, 0x2,
239 },
240 35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
241 },
242 /* 18 */
243 { "ORFno",
244 "ORF, multi entry/tuple, entry number too short",
245 { /* hdr */ 0x3, 0x21,
246 /* mpc */ 0x0, 0x1, 0x0, 0x1,
247 /* num */ 0x3,
248 /* tuples */ 0x40, 0x3,
249 0x80, 0x1,
250 0x80, 0x2,
251 /* mpc */ 0x0, 0x2, 0x0, 0x1,
252 /* num */ 0x1,
253 /* tuples */ 0x40, 0x3,
254 0x80, 0x1,
255 0x80, 0x2,
256 /* mpc */ 0x0, 0x2, 0x0, 0x2,
257 /* num */ 0x3,
258 /* tuples */ 0x40, 0x3,
259 0x80, 0x1,
260 0x80, 0x2,
261 },
262 35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
263 },
264 /* 17 */
265 { "ORFpad",
266 "ORF, multi entry/tuple, padded to align",
267 { /* hdr */ 0x3, 0x22,
268 /* mpc */ 0x0, 0x1, 0x0, 0x1,
269 /* num */ 0x3,
270 /* tuples */ 0x40, 0x3,
271 0x80, 0x1,
272 0x80, 0x2,
273 /* mpc */ 0x0, 0x2, 0x0, 0x1,
274 /* num */ 0x3,
275 /* tuples */ 0x40, 0x3,
276 0x80, 0x1,
277 0x80, 0x2,
278 /* mpc */ 0x0, 0x2, 0x0, 0x2,
279 /* num */ 0x3,
280 /* tuples */ 0x40, 0x3,
281 0x80, 0x1,
282 0x80, 0x2,
283 0x00,
284 },
285 36, SHOULD_PARSE,
286 },
287 /* 19 */
288 { "AS4",
289 "AS4 capability",
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000290 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
291 6, SHOULD_PARSE, 2882400018,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000292 },
293 /* 20 */
294 { "GR",
295 "GR capability",
296 { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
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 /* flags */ 0x1,
307 },
308 16, SHOULD_PARSE,
309 },
310 /* 21 */
311 { "GR-short",
312 "GR capability, but header length too short",
313 { /* hdr */ 0x40, 0xa,
314 /* R-bit, time */ 0xf1, 0x12,
315 /* afi */ 0x0, 0x1,
316 /* safi */ 0x1,
317 /* flags */ 0xf,
318 /* afi */ 0x0, 0x2,
319 /* safi */ 0x1,
320 /* flags */ 0x0,
321 /* afi */ 0x0, 0x2,
322 /* safi */ 0x2,
323 /* flags */ 0x1,
324 },
325 16, SHOULD_PARSE,
326 },
327 /* 22 */
328 { "GR-long",
329 "GR capability, but header length too long",
330 { /* hdr */ 0x40, 0xf,
331 /* R-bit, time */ 0xf1, 0x12,
332 /* afi */ 0x0, 0x1,
333 /* safi */ 0x1,
334 /* flags */ 0xf,
335 /* afi */ 0x0, 0x2,
336 /* safi */ 0x1,
337 /* flags */ 0x0,
338 /* afi */ 0x0, 0x2,
339 /* safi */ 0x2,
340 },
341 16, SHOULD_ERR,
342 },
343 { "GR-trunc",
344 "GR capability, but truncated",
345 { /* hdr */ 0x40, 0xf,
346 /* R-bit, time */ 0xf1, 0x12,
347 /* afi */ 0x0, 0x1,
348 /* safi */ 0x1,
349 /* flags */ 0xf,
350 /* afi */ 0x0, 0x2,
351 /* safi */ 0x1,
352 /* flags */ 0x0,
353 /* afi */ 0x0, 0x2,
354 /* safi */ 0x2,
355 /* flags */ 0x1,
356 },
357 15, SHOULD_ERR,
358 },
Paul Jakma370b64a2007-12-22 16:49:52 +0000359 { "GR-empty",
360 "GR capability, but empty.",
361 { /* hdr */ 0x40, 0x0,
362 },
363 2, SHOULD_ERR,
364 },
365 { "MP-empty",
366 "MP capability, but empty.",
367 { /* hdr */ 0x1, 0x0,
368 },
369 2, SHOULD_ERR,
370 },
371 { "ORF-empty",
372 "ORF capability, but empty.",
373 { /* hdr */ 0x3, 0x0,
374 },
375 2, SHOULD_ERR,
376 },
377 { "AS4-empty",
378 "AS4 capability, but empty.",
379 { /* hdr */ 0x41, 0x0,
380 },
381 2, SHOULD_ERR,
382 },
383 { "dyn-empty",
384 "Dynamic capability, but empty.",
385 { /* hdr */ 0x42, 0x0,
386 },
387 2, SHOULD_PARSE,
388 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000389 { "dyn-old",
390 "Dynamic capability (deprecated version)",
391 { CAPABILITY_CODE_DYNAMIC, 0x0 },
392 2, SHOULD_PARSE,
393 },
394 { NULL, NULL, {0}, 0, 0}
395};
396
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000397/* DYNAMIC message */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000398struct test_segment dynamic_cap_msgs[] =
399{
400 { "DynCap",
401 "Dynamic Capability Message, IP/Multicast",
402 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
403 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
404 },
405 { "DynCapLong",
406 "Dynamic Capability Message, IP/Multicast, truncated",
407 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
408 5, SHOULD_ERR,
409 },
410 { "DynCapPadded",
411 "Dynamic Capability Message, IP/Multicast, padded",
412 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
413 8, SHOULD_ERR, /* No way to tell padding from data.. */
414 },
415 { "DynCapMPCpadded",
416 "Dynamic Capability Message, IP/Multicast, cap data padded",
417 { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
418 8, SHOULD_PARSE, /* You can though add padding to the capability data */
419 },
420 { "DynCapMPCoverflow",
421 "Dynamic Capability Message, IP/Multicast, cap data != length",
422 { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
423 8, SHOULD_ERR,
424 },
425 { NULL, NULL, {0}, 0, 0}
426};
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000427
428/* Entire Optional-Parameters block */
429struct test_segment opt_params[] =
430{
431 { "Cap-singlets",
432 "One capability per Optional-Param",
433 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
434 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
435 0x02, 0x02, 0x80, 0x00, /* RR (old) */
436 0x02, 0x02, 0x02, 0x00, /* RR */
437 },
438 24, SHOULD_PARSE,
439 },
440 { "Cap-series",
441 "Series of capability, one Optional-Param",
442 { 0x02, 0x10,
443 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
444 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
445 0x80, 0x00, /* RR (old) */
446 0x02, 0x00, /* RR */
447 },
448 18, SHOULD_PARSE,
449 },
450 { "AS4more",
451 "AS4 capability after other caps (singlets)",
452 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
453 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
454 0x02, 0x02, 0x80, 0x00, /* RR (old) */
455 0x02, 0x02, 0x02, 0x00, /* RR */
456 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
457 },
458 32, SHOULD_PARSE, 196614,
459 },
460 { "AS4series",
461 "AS4 capability, in series of capabilities",
462 { 0x02, 0x16,
463 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
464 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
465 0x80, 0x00, /* RR (old) */
466 0x02, 0x00, /* RR */
467 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
468 },
469 24, SHOULD_PARSE, 196614,
470 },
471 { "AS4real",
472 "AS4 capability, in series of capabilities",
473 {
474 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
475 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
476 0x02, 0x02, 0x80, 0x00, /* RR old */
477 0x02, 0x02, 0x02, 0x00, /* RR */
478 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
479 },
480 32, SHOULD_PARSE, 196614,
481 },
482 { "AS4real2",
483 "AS4 capability, in series of capabilities",
484 {
485 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
486 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
487 0x02, 0x02, 0x80, 0x00,
488 0x02, 0x02, 0x02, 0x00,
489 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
490 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
491 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
492 0x02, 0x02, 0x42, 0x00,
493 },
494 58, SHOULD_PARSE, 64515,
495 },
496
497 { NULL, NULL, {0}, 0, 0}
498};
499
Paul Jakmaed6ef902007-08-08 14:13:03 +0000500/* basic parsing test */
501static void
502parse_test (struct peer *peer, struct test_segment *t, int type)
503{
504 int ret;
505 int capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000506 as_t as4 = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +0000507 int oldfailed = failed;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000508 int len = t->len;
509#define RANDOM_FUZZ 35
Paul Jakmaed6ef902007-08-08 14:13:03 +0000510
511 stream_reset (peer->ibuf);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000512 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
513 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
514
Paul Jakmaed6ef902007-08-08 14:13:03 +0000515 switch (type)
516 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000517 case CAPABILITY:
Paul Jakmaed6ef902007-08-08 14:13:03 +0000518 stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
519 stream_putc (peer->ibuf, t->len);
520 break;
521 case DYNCAP:
522/* for (i = 0; i < BGP_MARKER_SIZE; i++)
523 stream_putc (peer->, 0xff);
524 stream_putw (s, 0);
525 stream_putc (s, BGP_MSG_CAPABILITY);*/
526 break;
527 }
528 stream_write (peer->ibuf, t->data, t->len);
529
530 printf ("%s: %s\n", t->name, t->desc);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000531
Paul Jakmaed6ef902007-08-08 14:13:03 +0000532 switch (type)
533 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000534 case CAPABILITY:
535 len += 2; /* to cover the OPT-Param header */
536 case OPT_PARAM:
537 printf ("len: %u\n", len);
538 /* peek_for_as4 wants getp at capibility*/
539 as4 = peek_for_as4_capability (peer, len);
540 printf ("peek_for_as4: as4 is %u\n", as4);
541 /* and it should leave getp as it found it */
542 assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
543
544 ret = bgp_open_option_parse (peer, len, &capability);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000545 break;
546 case DYNCAP:
547 ret = bgp_capability_receive (peer, t->len);
548 break;
549 default:
550 printf ("unknown type %u\n", type);
551 exit(1);
552 }
553
Paul Jakmae08286b2007-09-18 12:11:26 +0000554 if (!ret && t->validate_afi)
555 {
556 safi_t safi = t->safi;
557
558 if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
559 failed++;
560
561 printf ("MP: %u/%u (%u): recv %u, nego %u\n",
562 t->afi, t->safi, safi,
563 peer->afc_recv[t->afi][safi],
564 peer->afc_nego[t->afi][safi]);
565
566 if (t->afi_valid == VALID_AFI)
567 {
568
569 if (!peer->afc_recv[t->afi][safi])
570 failed++;
571 if (!peer->afc_nego[t->afi][safi])
572 failed++;
573 }
574 }
575
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000576 if (as4 != t->peek_for)
577 {
578 printf ("as4 %u != %u\n", as4, t->peek_for);
579 failed++;
580 }
581
Paul Jakmaed6ef902007-08-08 14:13:03 +0000582 printf ("parsed?: %s\n", ret ? "no" : "yes");
583
Paul Jakmae08286b2007-09-18 12:11:26 +0000584 if (ret != t->parses)
585 failed++;
586
587 if (tty)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000588 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
Paul Jakmae08286b2007-09-18 12:11:26 +0000589 : VT100_GREEN "OK" VT100_RESET);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000590 else
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000591 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
Paul Jakmaed6ef902007-08-08 14:13:03 +0000592
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000593 if (failed)
594 printf (" (%u)", failed);
595
596 printf ("\n\n");
Paul Jakmaed6ef902007-08-08 14:13:03 +0000597}
598
599static struct bgp *bgp;
600static as_t asn = 100;
601
602int
603main (void)
604{
605 struct peer *peer;
606 int i, j;
607
608 conf_bgp_debug_fsm = -1UL;
609 conf_bgp_debug_events = -1UL;
610 conf_bgp_debug_packet = -1UL;
611 conf_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000612 conf_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000613 term_bgp_debug_fsm = -1UL;
614 term_bgp_debug_events = -1UL;
615 term_bgp_debug_packet = -1UL;
616 term_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000617 term_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000618
619 master = thread_master_create ();
620 bgp_master_init ();
Paul Jakmac9e4f862012-06-14 10:42:39 +0100621 bgp_option_set (BGP_OPT_NO_LISTEN);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000622
Paul Jakmae08286b2007-09-18 12:11:26 +0000623 if (fileno (stdout) >= 0)
624 tty = isatty (fileno (stdout));
625
Paul Jakmaed6ef902007-08-08 14:13:03 +0000626 if (bgp_get (&bgp, &asn, NULL))
627 return -1;
628
629 peer = peer_create_accept (bgp);
Paul Jakma1dba2542012-05-01 16:20:33 +0100630 peer->host = (char *) "foo";
Paul Jakmaed6ef902007-08-08 14:13:03 +0000631
632 for (i = AFI_IP; i < AFI_MAX; i++)
633 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
Paul Jakmae08286b2007-09-18 12:11:26 +0000634 {
635 peer->afc[i][j] = 1;
636 peer->afc_adv[i][j] = 1;
637 }
Paul Jakmaed6ef902007-08-08 14:13:03 +0000638
Paul Jakmae08286b2007-09-18 12:11:26 +0000639 i = 0;
640 while (mp_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000641 parse_test (peer, &mp_segments[i++], CAPABILITY);
Paul Jakmae08286b2007-09-18 12:11:26 +0000642
643 /* These tests assume mp_segments tests set at least
644 * one of the afc_nego's
645 */
646 i = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000647 while (test_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000648 parse_test (peer, &test_segments[i++], CAPABILITY);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000649
Paul Jakmae08286b2007-09-18 12:11:26 +0000650 i = 0;
651 while (misc_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000652 parse_test (peer, &misc_segments[i++], CAPABILITY);
653
654 i = 0;
655 while (opt_params[i].name)
656 parse_test (peer, &opt_params[i++], OPT_PARAM);
Paul Jakmae08286b2007-09-18 12:11:26 +0000657
Paul Jakmaed6ef902007-08-08 14:13:03 +0000658 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
659 peer->status = Established;
660
661 i = 0;
662 while (dynamic_cap_msgs[i].name)
663 parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
664
665 printf ("failures: %d\n", failed);
666 return failed;
667}