]> git.proxmox.com Git - mirror_frr.git/blame - tests/bgpd/test_capability.c
*: make consistent & update GPLv2 file headers
[mirror_frr.git] / tests / bgpd / test_capability.c
CommitLineData
46f4a4d2
PJ
1/*
2 * Copyright (C) 2007 Sun Microsystems, Inc.
3 *
4 * This file is part of Quagga.
5 *
6 * Quagga is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * Quagga is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
46f4a4d2
PJ
19 */
20
ed6ef902
PJ
21#include <zebra.h>
22
1bf9f027 23#include "qobj.h"
ed6ef902
PJ
24#include "vty.h"
25#include "stream.h"
26#include "privs.h"
27#include "memory.h"
3f9c7369 28#include "queue.h"
039f3a34 29#include "filter.h"
ed6ef902
PJ
30
31#include "bgpd/bgpd.h"
32#include "bgpd/bgp_open.h"
33#include "bgpd/bgp_debug.h"
1dba254e 34#include "bgpd/bgp_packet.h"
ed6ef902 35
e08286bc
PJ
36#define VT100_RESET "\x1b[0m"
37#define VT100_RED "\x1b[31m"
38#define VT100_GREEN "\x1b[32m"
39#define VT100_YELLOW "\x1b[33m"
40
41
0b2aa3a0
PJ
42#define CAPABILITY 0
43#define DYNCAP 1
44#define OPT_PARAM 2
ed6ef902
PJ
45
46/* need these to link in libbgp */
47struct zebra_privs_t *bgpd_privs = NULL;
48struct thread_master *master = NULL;
49
50static int failed = 0;
e08286bc 51static int tty = 0;
ed6ef902
PJ
52
53/* test segments to parse and validate, and use for other tests */
54static struct test_segment {
55 const char *name;
56 const char *desc;
57 const u_char data[1024];
58 int len;
59#define SHOULD_PARSE 0
60#define SHOULD_ERR -1
61 int parses; /* whether it should parse or not */
1dba254e 62 as_t peek_for; /* what peek_for_as4_capability should say */
0b2aa3a0 63
e08286bc
PJ
64 /* AFI/SAFI validation */
65 int validate_afi;
66 afi_t afi;
67 safi_t safi;
68#define VALID_AFI 1
69#define INVALID_AFI 0
70 int afi_valid;
ed6ef902
PJ
71} test_segments [] =
72{
73 /* 0 */
74 { "caphdr",
75 "capability header, and no more",
76 { CAPABILITY_CODE_REFRESH, 0x0 },
77 2, SHOULD_PARSE,
78 },
79 /* 1 */
80 { "nodata",
81 "header, no data but length says there is",
82 { 0x1, 0xa },
83 2, SHOULD_ERR,
84 },
85 /* 2 */
86 { "padded",
87 "valid, with padding",
88 { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
89 4, SHOULD_PARSE,
90 },
91 /* 3 */
92 { "minsize",
93 "violates minsize requirement",
94 { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
95 4, SHOULD_ERR,
96 },
e08286bc
PJ
97 { NULL, NULL, {0}, 0, 0},
98};
99
100static struct test_segment mp_segments[] =
101{
102 { "MP4",
ed6ef902
PJ
103 "MP IP/Uni",
104 { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
0b2aa3a0
PJ
105 6, SHOULD_PARSE, 0,
106 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
e08286bc
PJ
107 },
108 { "MPv6",
109 "MP IPv6/Uni",
110 { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
0b2aa3a0 111 6, SHOULD_PARSE, 0,
e08286bc 112 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
ed6ef902
PJ
113 },
114 /* 5 */
115 { "MP2",
116 "MP IP/Multicast",
117 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
0b2aa3a0 118 6, SHOULD_PARSE, 0,
e08286bc 119 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
ed6ef902
PJ
120 },
121 /* 6 */
122 { "MP3",
42e6d745 123 "MP IP6/MPLS-labeled VPN",
ed6ef902 124 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
42e6d745 125 6, SHOULD_PARSE, 0,
9cabb64b 126 1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI,
ed6ef902
PJ
127 },
128 /* 7 */
129 { "MP5",
130 "MP IP6/MPLS-VPN",
131 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
0b2aa3a0 132 6, SHOULD_PARSE, 0,
9cabb64b 133 1, AFI_IP6, IANA_SAFI_MPLS_VPN, VALID_AFI,
ed6ef902
PJ
134 },
135 /* 8 */
136 { "MP6",
42e6d745 137 "MP IP4/MPLS-laveled VPN",
ed6ef902 138 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
0b2aa3a0 139 6, SHOULD_PARSE, 0,
9cabb64b 140 1, AFI_IP, IANA_SAFI_MPLS_VPN, VALID_AFI,
ed6ef902 141 },
ed6ef902
PJ
142 /* 10 */
143 { "MP8",
42e6d745 144 "MP unknown AFI/SAFI",
ed6ef902 145 { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
0b2aa3a0 146 6, SHOULD_PARSE, 0,
e08286bc 147 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
ed6ef902
PJ
148 },
149 /* 11 */
150 { "MP-short",
151 "MP IP4/Unicast, length too short (< minimum)",
152 { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
153 6, SHOULD_ERR,
154 },
155 /* 12 */
156 { "MP-overflow",
157 "MP IP4/Unicast, length too long",
158 { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
0b2aa3a0 159 6, SHOULD_ERR, 0,
e08286bc 160 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
ed6ef902 161 },
e08286bc
PJ
162 { NULL, NULL, {0}, 0, 0}
163};
164
165static struct test_segment misc_segments[] =
166{
ed6ef902
PJ
167 /* 13 */
168 { "ORF",
169 "ORF, simple, single entry, single tuple",
170 { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
171 /* mpc */ 0x0, 0x1, 0x0, 0x1,
172 /* num */ 0x1,
173 /* tuples */ 0x40, 0x3
174 },
175 9, SHOULD_PARSE,
176 },
177 /* 14 */
178 { "ORF-many",
179 "ORF, multi entry/tuple",
180 { /* hdr */ CAPABILITY_CODE_ORF, 0x21,
181 /* mpc */ 0x0, 0x1, 0x0, 0x1,
182 /* num */ 0x3,
183 /* tuples */ 0x40, ORF_MODE_BOTH,
184 0x80, ORF_MODE_RECEIVE,
185 0x80, ORF_MODE_SEND,
186 /* mpc */ 0x0, 0x2, 0x0, 0x1,
187 /* num */ 0x3,
188 /* tuples */ 0x40, ORF_MODE_BOTH,
189 0x80, ORF_MODE_RECEIVE,
190 0x80, ORF_MODE_SEND,
191 /* mpc */ 0x0, 0x2, 0x0, 0x2,
192 /* num */ 0x3,
193 /* tuples */ 0x40, ORF_MODE_RECEIVE,
194 0x80, ORF_MODE_SEND,
195 0x80, ORF_MODE_BOTH,
196 },
197 35, SHOULD_PARSE,
198 },
199 /* 15 */
200 { "ORFlo",
201 "ORF, multi entry/tuple, hdr length too short",
202 { /* hdr */ CAPABILITY_CODE_ORF, 0x15,
203 /* mpc */ 0x0, 0x1, 0x0, 0x1,
204 /* num */ 0x3,
205 /* tuples */ 0x40, 0x3,
206 0x80, 0x1,
207 0x80, 0x2,
208 /* mpc */ 0x0, 0x1, 0x0, 0x1,
209 /* num */ 0x3,
210 /* tuples */ 0x40, 0x3,
211 0x80, 0x1,
212 0x80, 0x2,
213 /* mpc */ 0x0, 0x2, 0x0, 0x2,
214 /* num */ 0x3,
215 /* tuples */ 0x40, 0x3,
216 0x80, 0x1,
217 0x80, 0x2,
218 },
219 35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
220 },
221 /* 16 */
222 { "ORFlu",
223 "ORF, multi entry/tuple, length too long",
224 { /* hdr */ 0x3, 0x22,
225 /* mpc */ 0x0, 0x1, 0x0, 0x1,
226 /* num */ 0x3,
227 /* tuples */ 0x40, 0x3,
228 0x80, 0x1,
229 0x80, 0x2,
230 /* mpc */ 0x0, 0x2, 0x0, 0x1,
231 /* num */ 0x3,
232 /* tuples */ 0x40, 0x3,
233 0x80, 0x1,
234 0x80, 0x2,
235 /* mpc */ 0x0, 0x2, 0x0, 0x2,
236 /* num */ 0x3,
237 /* tuples */ 0x40, 0x3,
238 0x80, 0x1,
239 0x80, 0x2,
240 },
241 35, SHOULD_ERR
242 },
243 /* 17 */
244 { "ORFnu",
245 "ORF, multi entry/tuple, entry number too long",
246 { /* hdr */ 0x3, 0x21,
247 /* mpc */ 0x0, 0x1, 0x0, 0x1,
248 /* num */ 0x3,
249 /* tuples */ 0x40, 0x3,
250 0x80, 0x1,
251 0x80, 0x2,
252 /* mpc */ 0x0, 0x2, 0x0, 0x1,
253 /* num */ 0x4,
254 /* tuples */ 0x40, 0x3,
255 0x80, 0x1,
256 0x80, 0x2,
257 /* mpc */ 0x0, 0x2, 0x0, 0x2,
258 /* num */ 0x3,
259 /* tuples */ 0x40, 0x3,
260 0x80, 0x1,
261 0x80, 0x2,
262 },
263 35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
264 },
265 /* 18 */
266 { "ORFno",
267 "ORF, multi entry/tuple, entry number too short",
268 { /* hdr */ 0x3, 0x21,
269 /* mpc */ 0x0, 0x1, 0x0, 0x1,
270 /* num */ 0x3,
271 /* tuples */ 0x40, 0x3,
272 0x80, 0x1,
273 0x80, 0x2,
274 /* mpc */ 0x0, 0x2, 0x0, 0x1,
275 /* num */ 0x1,
276 /* tuples */ 0x40, 0x3,
277 0x80, 0x1,
278 0x80, 0x2,
279 /* mpc */ 0x0, 0x2, 0x0, 0x2,
280 /* num */ 0x3,
281 /* tuples */ 0x40, 0x3,
282 0x80, 0x1,
283 0x80, 0x2,
284 },
285 35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
286 },
287 /* 17 */
288 { "ORFpad",
289 "ORF, multi entry/tuple, padded to align",
290 { /* hdr */ 0x3, 0x22,
291 /* mpc */ 0x0, 0x1, 0x0, 0x1,
292 /* num */ 0x3,
293 /* tuples */ 0x40, 0x3,
294 0x80, 0x1,
295 0x80, 0x2,
296 /* mpc */ 0x0, 0x2, 0x0, 0x1,
297 /* num */ 0x3,
298 /* tuples */ 0x40, 0x3,
299 0x80, 0x1,
300 0x80, 0x2,
301 /* mpc */ 0x0, 0x2, 0x0, 0x2,
302 /* num */ 0x3,
303 /* tuples */ 0x40, 0x3,
304 0x80, 0x1,
305 0x80, 0x2,
306 0x00,
307 },
308 36, SHOULD_PARSE,
309 },
310 /* 19 */
311 { "AS4",
312 "AS4 capability",
0b2aa3a0
PJ
313 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
314 6, SHOULD_PARSE, 2882400018,
ed6ef902 315 },
3c88dab5
PJ
316 { "AS4",
317 "AS4 capability: short",
318 { 0x41, 0x4, 0xab, 0xcd, 0xef }, /* AS: 2882400018 */
319 5, SHOULD_ERR,
320 },
321 { "AS4",
322 "AS4 capability: long",
323 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12 },
324 7, SHOULD_ERR, 2882400018,
325 },
ed6ef902
PJ
326 { "GR",
327 "GR capability",
328 { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
329 /* R-bit, time */ 0xf1, 0x12,
330 /* afi */ 0x0, 0x1,
331 /* safi */ 0x1,
332 /* flags */ 0xf,
333 /* afi */ 0x0, 0x2,
334 /* safi */ 0x1,
335 /* flags */ 0x0,
336 /* afi */ 0x0, 0x2,
337 /* safi */ 0x2,
338 /* flags */ 0x1,
339 },
340 16, SHOULD_PARSE,
341 },
ed6ef902
PJ
342 { "GR-short",
343 "GR capability, but header length too short",
344 { /* hdr */ 0x40, 0xa,
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 },
3c88dab5 356 15 /* array is 16 though */, SHOULD_ERR,
ed6ef902 357 },
ed6ef902
PJ
358 { "GR-long",
359 "GR capability, but header length too long",
360 { /* hdr */ 0x40, 0xf,
361 /* R-bit, time */ 0xf1, 0x12,
362 /* afi */ 0x0, 0x1,
363 /* safi */ 0x1,
364 /* flags */ 0xf,
365 /* afi */ 0x0, 0x2,
366 /* safi */ 0x1,
367 /* flags */ 0x0,
368 /* afi */ 0x0, 0x2,
369 /* safi */ 0x2,
3c88dab5 370 /* flags */ 0x01,
ed6ef902
PJ
371 },
372 16, SHOULD_ERR,
373 },
374 { "GR-trunc",
375 "GR capability, but truncated",
376 { /* hdr */ 0x40, 0xf,
377 /* R-bit, time */ 0xf1, 0x12,
378 /* afi */ 0x0, 0x1,
379 /* safi */ 0x1,
380 /* flags */ 0xf,
381 /* afi */ 0x0, 0x2,
382 /* safi */ 0x1,
383 /* flags */ 0x0,
384 /* afi */ 0x0, 0x2,
385 /* safi */ 0x2,
386 /* flags */ 0x1,
387 },
388 15, SHOULD_ERR,
389 },
370b64a2
PJ
390 { "GR-empty",
391 "GR capability, but empty.",
392 { /* hdr */ 0x40, 0x0,
393 },
394 2, SHOULD_ERR,
395 },
396 { "MP-empty",
397 "MP capability, but empty.",
398 { /* hdr */ 0x1, 0x0,
399 },
400 2, SHOULD_ERR,
401 },
402 { "ORF-empty",
403 "ORF capability, but empty.",
404 { /* hdr */ 0x3, 0x0,
405 },
406 2, SHOULD_ERR,
407 },
408 { "AS4-empty",
409 "AS4 capability, but empty.",
410 { /* hdr */ 0x41, 0x0,
411 },
412 2, SHOULD_ERR,
413 },
414 { "dyn-empty",
415 "Dynamic capability, but empty.",
416 { /* hdr */ 0x42, 0x0,
417 },
418 2, SHOULD_PARSE,
419 },
ed6ef902
PJ
420 { "dyn-old",
421 "Dynamic capability (deprecated version)",
422 { CAPABILITY_CODE_DYNAMIC, 0x0 },
423 2, SHOULD_PARSE,
424 },
425 { NULL, NULL, {0}, 0, 0}
426};
427
0b2aa3a0 428/* DYNAMIC message */
ed6ef902
PJ
429struct test_segment dynamic_cap_msgs[] =
430{
431 { "DynCap",
432 "Dynamic Capability Message, IP/Multicast",
433 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
434 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
435 },
436 { "DynCapLong",
437 "Dynamic Capability Message, IP/Multicast, truncated",
438 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
439 5, SHOULD_ERR,
440 },
441 { "DynCapPadded",
442 "Dynamic Capability Message, IP/Multicast, padded",
443 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
444 8, SHOULD_ERR, /* No way to tell padding from data.. */
445 },
446 { "DynCapMPCpadded",
447 "Dynamic Capability Message, IP/Multicast, cap data padded",
448 { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
449 8, SHOULD_PARSE, /* You can though add padding to the capability data */
450 },
451 { "DynCapMPCoverflow",
452 "Dynamic Capability Message, IP/Multicast, cap data != length",
453 { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
454 8, SHOULD_ERR,
455 },
456 { NULL, NULL, {0}, 0, 0}
457};
0b2aa3a0
PJ
458
459/* Entire Optional-Parameters block */
460struct test_segment opt_params[] =
461{
462 { "Cap-singlets",
463 "One capability per Optional-Param",
464 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
465 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
466 0x02, 0x02, 0x80, 0x00, /* RR (old) */
467 0x02, 0x02, 0x02, 0x00, /* RR */
468 },
469 24, SHOULD_PARSE,
470 },
471 { "Cap-series",
472 "Series of capability, one Optional-Param",
473 { 0x02, 0x10,
474 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
475 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
476 0x80, 0x00, /* RR (old) */
477 0x02, 0x00, /* RR */
478 },
479 18, SHOULD_PARSE,
480 },
481 { "AS4more",
482 "AS4 capability after other caps (singlets)",
483 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
484 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
485 0x02, 0x02, 0x80, 0x00, /* RR (old) */
486 0x02, 0x02, 0x02, 0x00, /* RR */
487 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
488 },
489 32, SHOULD_PARSE, 196614,
490 },
491 { "AS4series",
492 "AS4 capability, in series of capabilities",
493 { 0x02, 0x16,
494 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
495 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
496 0x80, 0x00, /* RR (old) */
497 0x02, 0x00, /* RR */
498 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
499 },
500 24, SHOULD_PARSE, 196614,
501 },
502 { "AS4real",
503 "AS4 capability, in series of capabilities",
504 {
505 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
506 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
507 0x02, 0x02, 0x80, 0x00, /* RR old */
508 0x02, 0x02, 0x02, 0x00, /* RR */
509 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
510 },
511 32, SHOULD_PARSE, 196614,
512 },
513 { "AS4real2",
514 "AS4 capability, in series of capabilities",
515 {
516 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
517 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
518 0x02, 0x02, 0x80, 0x00,
519 0x02, 0x02, 0x02, 0x00,
520 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
521 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
522 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
523 0x02, 0x02, 0x42, 0x00,
524 },
525 58, SHOULD_PARSE, 64515,
526 },
527
528 { NULL, NULL, {0}, 0, 0}
529};
530
ed6ef902
PJ
531/* basic parsing test */
532static void
533parse_test (struct peer *peer, struct test_segment *t, int type)
534{
535 int ret;
536 int capability = 0;
0b2aa3a0 537 as_t as4 = 0;
e08286bc 538 int oldfailed = failed;
0b2aa3a0
PJ
539 int len = t->len;
540#define RANDOM_FUZZ 35
ed6ef902
PJ
541
542 stream_reset (peer->ibuf);
0b2aa3a0
PJ
543 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
544 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
545
ed6ef902
PJ
546 switch (type)
547 {
0b2aa3a0 548 case CAPABILITY:
ed6ef902
PJ
549 stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
550 stream_putc (peer->ibuf, t->len);
551 break;
552 case DYNCAP:
553/* for (i = 0; i < BGP_MARKER_SIZE; i++)
554 stream_putc (peer->, 0xff);
555 stream_putw (s, 0);
556 stream_putc (s, BGP_MSG_CAPABILITY);*/
557 break;
558 }
559 stream_write (peer->ibuf, t->data, t->len);
560
561 printf ("%s: %s\n", t->name, t->desc);
0b2aa3a0 562
ed6ef902
PJ
563 switch (type)
564 {
0b2aa3a0
PJ
565 case CAPABILITY:
566 len += 2; /* to cover the OPT-Param header */
567 case OPT_PARAM:
568 printf ("len: %u\n", len);
569 /* peek_for_as4 wants getp at capibility*/
570 as4 = peek_for_as4_capability (peer, len);
571 printf ("peek_for_as4: as4 is %u\n", as4);
572 /* and it should leave getp as it found it */
573 assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
574
575 ret = bgp_open_option_parse (peer, len, &capability);
ed6ef902
PJ
576 break;
577 case DYNCAP:
578 ret = bgp_capability_receive (peer, t->len);
579 break;
580 default:
581 printf ("unknown type %u\n", type);
582 exit(1);
583 }
584
e08286bc
PJ
585 if (!ret && t->validate_afi)
586 {
9cabb64b 587 afi_t afi;
588 safi_t safi;
e08286bc 589
9cabb64b 590 /* Convert AFI, SAFI to internal values, check. */
52e61532 591 if (bgp_map_afi_safi_iana2int (afi_int2iana(t->afi), t->safi, &afi, &safi))
9cabb64b 592 {
593 if (t->afi_valid == VALID_AFI)
594 failed++;
595 }
596 printf ("MP: %u(%u)/%u(%u): recv %u, nego %u\n",
597 t->afi, afi, t->safi, safi,
598 peer->afc_recv[afi][safi],
599 peer->afc_nego[afi][safi]);
e08286bc
PJ
600
601 if (t->afi_valid == VALID_AFI)
602 {
603
9cabb64b 604 if (!peer->afc_recv[afi][safi])
e08286bc 605 failed++;
9cabb64b 606 if (!peer->afc_nego[afi][safi])
e08286bc
PJ
607 failed++;
608 }
609 }
610
0b2aa3a0
PJ
611 if (as4 != t->peek_for)
612 {
613 printf ("as4 %u != %u\n", as4, t->peek_for);
614 failed++;
615 }
616
ed6ef902
PJ
617 printf ("parsed?: %s\n", ret ? "no" : "yes");
618
e08286bc
PJ
619 if (ret != t->parses)
620 failed++;
621
622 if (tty)
0b2aa3a0 623 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
e08286bc 624 : VT100_GREEN "OK" VT100_RESET);
ed6ef902 625 else
0b2aa3a0
PJ
626 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
627
628 if (failed)
629 printf (" (%u)", failed);
ed6ef902 630
0b2aa3a0 631 printf ("\n\n");
ed6ef902
PJ
632}
633
634static struct bgp *bgp;
635static as_t asn = 100;
636
637int
638main (void)
639{
640 struct peer *peer;
641 int i, j;
642
16286195 643 conf_bgp_debug_neighbor_events = -1UL;
ed6ef902 644 conf_bgp_debug_packet = -1UL;
0b2aa3a0 645 conf_bgp_debug_as4 = -1UL;
16286195 646 term_bgp_debug_neighbor_events = -1UL;
ed6ef902 647 term_bgp_debug_packet = -1UL;
0b2aa3a0 648 term_bgp_debug_as4 = -1UL;
ed6ef902 649
1bf9f027 650 qobj_init ();
ed6ef902 651 master = thread_master_create ();
4f04a76b 652 bgp_master_init (master);
ebf00458 653 vrf_init ();
c9e4f862 654 bgp_option_set (BGP_OPT_NO_LISTEN);
ed6ef902 655
e08286bc
PJ
656 if (fileno (stdout) >= 0)
657 tty = isatty (fileno (stdout));
658
ebf00458 659 if (bgp_get (&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT))
ed6ef902
PJ
660 return -1;
661
662 peer = peer_create_accept (bgp);
1dba254e 663 peer->host = (char *) "foo";
ed6ef902
PJ
664
665 for (i = AFI_IP; i < AFI_MAX; i++)
666 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
e08286bc
PJ
667 {
668 peer->afc[i][j] = 1;
669 peer->afc_adv[i][j] = 1;
670 }
ed6ef902 671
e08286bc
PJ
672 i = 0;
673 while (mp_segments[i].name)
0b2aa3a0 674 parse_test (peer, &mp_segments[i++], CAPABILITY);
e08286bc
PJ
675
676 /* These tests assume mp_segments tests set at least
677 * one of the afc_nego's
678 */
679 i = 0;
ed6ef902 680 while (test_segments[i].name)
0b2aa3a0 681 parse_test (peer, &test_segments[i++], CAPABILITY);
ed6ef902 682
e08286bc
PJ
683 i = 0;
684 while (misc_segments[i].name)
0b2aa3a0
PJ
685 parse_test (peer, &misc_segments[i++], CAPABILITY);
686
687 i = 0;
688 while (opt_params[i].name)
689 parse_test (peer, &opt_params[i++], OPT_PARAM);
e08286bc 690
ed6ef902
PJ
691 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
692 peer->status = Established;
693
694 i = 0;
695 while (dynamic_cap_msgs[i].name)
696 parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
697
698 printf ("failures: %d\n", failed);
699 return failed;
700}