blob: a3813518b6a1c995669379c5d1b3d291122c9c45 [file] [log] [blame]
Paul Jakma010ebbb2014-09-16 11:53:49 +01001/*
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 *
16 * You should have received a copy of the GNU General Public License
17 * along with Quagga; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
Paul Jakmaed6ef902007-08-08 14:13:03 +000022#include <zebra.h>
23
24#include "vty.h"
25#include "stream.h"
26#include "privs.h"
27#include "memory.h"
Donald Sharp04907292016-01-07 10:03:01 -050028#include "filter.h"
Paul Jakmaed6ef902007-08-08 14:13:03 +000029
30#include "bgpd/bgpd.h"
31#include "bgpd/bgp_open.h"
32#include "bgpd/bgp_debug.h"
Paul Jakma1dba2542012-05-01 16:20:33 +010033#include "bgpd/bgp_packet.h"
Paul Jakmaed6ef902007-08-08 14:13:03 +000034
Paul Jakmae08286b2007-09-18 12:11:26 +000035#define VT100_RESET "\x1b[0m"
36#define VT100_RED "\x1b[31m"
37#define VT100_GREEN "\x1b[32m"
38#define VT100_YELLOW "\x1b[33m"
39
40
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000041#define CAPABILITY 0
42#define DYNCAP 1
43#define OPT_PARAM 2
Paul Jakmaed6ef902007-08-08 14:13:03 +000044
45/* need these to link in libbgp */
46struct zebra_privs_t *bgpd_privs = NULL;
47struct thread_master *master = NULL;
48
49static int failed = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +000050static int tty = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +000051
52/* test segments to parse and validate, and use for other tests */
53static struct test_segment {
54 const char *name;
55 const char *desc;
56 const u_char data[1024];
57 int len;
58#define SHOULD_PARSE 0
59#define SHOULD_ERR -1
60 int parses; /* whether it should parse or not */
Paul Jakma1dba2542012-05-01 16:20:33 +010061 as_t peek_for; /* what peek_for_as4_capability should say */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000062
Paul Jakmae08286b2007-09-18 12:11:26 +000063 /* AFI/SAFI validation */
64 int validate_afi;
65 afi_t afi;
66 safi_t safi;
67#define VALID_AFI 1
68#define INVALID_AFI 0
69 int afi_valid;
Paul Jakmaed6ef902007-08-08 14:13:03 +000070} test_segments [] =
71{
72 /* 0 */
73 { "caphdr",
74 "capability header, and no more",
75 { CAPABILITY_CODE_REFRESH, 0x0 },
76 2, SHOULD_PARSE,
77 },
78 /* 1 */
79 { "nodata",
80 "header, no data but length says there is",
81 { 0x1, 0xa },
82 2, SHOULD_ERR,
83 },
84 /* 2 */
85 { "padded",
86 "valid, with padding",
87 { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
88 4, SHOULD_PARSE,
89 },
90 /* 3 */
91 { "minsize",
92 "violates minsize requirement",
93 { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
94 4, SHOULD_ERR,
95 },
Paul Jakmae08286b2007-09-18 12:11:26 +000096 { NULL, NULL, {0}, 0, 0},
97};
98
99static struct test_segment mp_segments[] =
100{
101 { "MP4",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000102 "MP IP/Uni",
103 { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000104 6, SHOULD_PARSE, 0,
105 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmae08286b2007-09-18 12:11:26 +0000106 },
107 { "MPv6",
108 "MP IPv6/Uni",
109 { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000110 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000111 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000112 },
113 /* 5 */
114 { "MP2",
115 "MP IP/Multicast",
116 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000117 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000118 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000119 },
120 /* 6 */
121 { "MP3",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400122 "MP IP6/MPLS-labeled VPN",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000123 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400124 6, SHOULD_PARSE, 0,
125 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000126 },
127 /* 7 */
128 { "MP5",
129 "MP IP6/MPLS-VPN",
130 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000131 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000132 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000133 },
134 /* 8 */
135 { "MP6",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400136 "MP IP4/MPLS-laveled VPN",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000137 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000138 6, SHOULD_PARSE, 0,
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400139 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000140 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000141 /* 10 */
142 { "MP8",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400143 "MP unknown AFI/SAFI",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000144 { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000145 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000146 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000147 },
148 /* 11 */
149 { "MP-short",
150 "MP IP4/Unicast, length too short (< minimum)",
151 { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
152 6, SHOULD_ERR,
153 },
154 /* 12 */
155 { "MP-overflow",
156 "MP IP4/Unicast, length too long",
157 { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000158 6, SHOULD_ERR, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000159 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000160 },
Paul Jakmae08286b2007-09-18 12:11:26 +0000161 { NULL, NULL, {0}, 0, 0}
162};
163
164static struct test_segment misc_segments[] =
165{
Paul Jakmaed6ef902007-08-08 14:13:03 +0000166 /* 13 */
167 { "ORF",
168 "ORF, simple, single entry, single tuple",
169 { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
170 /* mpc */ 0x0, 0x1, 0x0, 0x1,
171 /* num */ 0x1,
172 /* tuples */ 0x40, 0x3
173 },
174 9, SHOULD_PARSE,
175 },
176 /* 14 */
177 { "ORF-many",
178 "ORF, multi entry/tuple",
179 { /* hdr */ CAPABILITY_CODE_ORF, 0x21,
180 /* mpc */ 0x0, 0x1, 0x0, 0x1,
181 /* num */ 0x3,
182 /* tuples */ 0x40, ORF_MODE_BOTH,
183 0x80, ORF_MODE_RECEIVE,
184 0x80, ORF_MODE_SEND,
185 /* mpc */ 0x0, 0x2, 0x0, 0x1,
186 /* num */ 0x3,
187 /* tuples */ 0x40, ORF_MODE_BOTH,
188 0x80, ORF_MODE_RECEIVE,
189 0x80, ORF_MODE_SEND,
190 /* mpc */ 0x0, 0x2, 0x0, 0x2,
191 /* num */ 0x3,
192 /* tuples */ 0x40, ORF_MODE_RECEIVE,
193 0x80, ORF_MODE_SEND,
194 0x80, ORF_MODE_BOTH,
195 },
196 35, SHOULD_PARSE,
197 },
198 /* 15 */
199 { "ORFlo",
200 "ORF, multi entry/tuple, hdr length too short",
201 { /* hdr */ CAPABILITY_CODE_ORF, 0x15,
202 /* mpc */ 0x0, 0x1, 0x0, 0x1,
203 /* num */ 0x3,
204 /* tuples */ 0x40, 0x3,
205 0x80, 0x1,
206 0x80, 0x2,
207 /* mpc */ 0x0, 0x1, 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, /* It should error on invalid Route-Refresh.. */
219 },
220 /* 16 */
221 { "ORFlu",
222 "ORF, multi entry/tuple, length too long",
223 { /* hdr */ 0x3, 0x22,
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 */ 0x3,
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_ERR
241 },
242 /* 17 */
243 { "ORFnu",
244 "ORF, multi entry/tuple, entry number too long",
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 */ 0x4,
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 last few tuples should be gibberish */
263 },
264 /* 18 */
265 { "ORFno",
266 "ORF, multi entry/tuple, entry number too short",
267 { /* hdr */ 0x3, 0x21,
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 */ 0x1,
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 },
284 35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
285 },
286 /* 17 */
287 { "ORFpad",
288 "ORF, multi entry/tuple, padded to align",
289 { /* hdr */ 0x3, 0x22,
290 /* mpc */ 0x0, 0x1, 0x0, 0x1,
291 /* num */ 0x3,
292 /* tuples */ 0x40, 0x3,
293 0x80, 0x1,
294 0x80, 0x2,
295 /* mpc */ 0x0, 0x2, 0x0, 0x1,
296 /* num */ 0x3,
297 /* tuples */ 0x40, 0x3,
298 0x80, 0x1,
299 0x80, 0x2,
300 /* mpc */ 0x0, 0x2, 0x0, 0x2,
301 /* num */ 0x3,
302 /* tuples */ 0x40, 0x3,
303 0x80, 0x1,
304 0x80, 0x2,
305 0x00,
306 },
307 36, SHOULD_PARSE,
308 },
309 /* 19 */
310 { "AS4",
311 "AS4 capability",
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000312 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
313 6, SHOULD_PARSE, 2882400018,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000314 },
Paul Jakma321d4132015-11-25 17:14:36 +0000315 { "AS4",
316 "AS4 capability: short",
317 { 0x41, 0x4, 0xab, 0xcd, 0xef }, /* AS: 2882400018 */
318 5, SHOULD_ERR,
319 },
320 { "AS4",
321 "AS4 capability: long",
322 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12 },
323 7, SHOULD_ERR, 2882400018,
324 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000325 { "GR",
326 "GR capability",
327 { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
328 /* R-bit, time */ 0xf1, 0x12,
329 /* afi */ 0x0, 0x1,
330 /* safi */ 0x1,
331 /* flags */ 0xf,
332 /* afi */ 0x0, 0x2,
333 /* safi */ 0x1,
334 /* flags */ 0x0,
335 /* afi */ 0x0, 0x2,
336 /* safi */ 0x2,
337 /* flags */ 0x1,
338 },
339 16, SHOULD_PARSE,
340 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000341 { "GR-short",
342 "GR capability, but header length too short",
343 { /* hdr */ 0x40, 0xa,
344 /* R-bit, time */ 0xf1, 0x12,
345 /* afi */ 0x0, 0x1,
346 /* safi */ 0x1,
347 /* flags */ 0xf,
348 /* afi */ 0x0, 0x2,
349 /* safi */ 0x1,
350 /* flags */ 0x0,
351 /* afi */ 0x0, 0x2,
352 /* safi */ 0x2,
353 /* flags */ 0x1,
354 },
Paul Jakma321d4132015-11-25 17:14:36 +0000355 15 /* array is 16 though */, SHOULD_ERR,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000356 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000357 { "GR-long",
358 "GR capability, but header length too long",
359 { /* hdr */ 0x40, 0xf,
360 /* R-bit, time */ 0xf1, 0x12,
361 /* afi */ 0x0, 0x1,
362 /* safi */ 0x1,
363 /* flags */ 0xf,
364 /* afi */ 0x0, 0x2,
365 /* safi */ 0x1,
366 /* flags */ 0x0,
367 /* afi */ 0x0, 0x2,
368 /* safi */ 0x2,
Paul Jakma321d4132015-11-25 17:14:36 +0000369 /* flags */ 0x01,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000370 },
371 16, SHOULD_ERR,
372 },
373 { "GR-trunc",
374 "GR capability, but truncated",
375 { /* hdr */ 0x40, 0xf,
376 /* R-bit, time */ 0xf1, 0x12,
377 /* afi */ 0x0, 0x1,
378 /* safi */ 0x1,
379 /* flags */ 0xf,
380 /* afi */ 0x0, 0x2,
381 /* safi */ 0x1,
382 /* flags */ 0x0,
383 /* afi */ 0x0, 0x2,
384 /* safi */ 0x2,
385 /* flags */ 0x1,
386 },
387 15, SHOULD_ERR,
388 },
Paul Jakma370b64a2007-12-22 16:49:52 +0000389 { "GR-empty",
390 "GR capability, but empty.",
391 { /* hdr */ 0x40, 0x0,
392 },
393 2, SHOULD_ERR,
394 },
395 { "MP-empty",
396 "MP capability, but empty.",
397 { /* hdr */ 0x1, 0x0,
398 },
399 2, SHOULD_ERR,
400 },
401 { "ORF-empty",
402 "ORF capability, but empty.",
403 { /* hdr */ 0x3, 0x0,
404 },
405 2, SHOULD_ERR,
406 },
407 { "AS4-empty",
408 "AS4 capability, but empty.",
409 { /* hdr */ 0x41, 0x0,
410 },
411 2, SHOULD_ERR,
412 },
413 { "dyn-empty",
414 "Dynamic capability, but empty.",
415 { /* hdr */ 0x42, 0x0,
416 },
417 2, SHOULD_PARSE,
418 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000419 { "dyn-old",
420 "Dynamic capability (deprecated version)",
421 { CAPABILITY_CODE_DYNAMIC, 0x0 },
422 2, SHOULD_PARSE,
423 },
424 { NULL, NULL, {0}, 0, 0}
425};
426
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000427/* DYNAMIC message */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000428struct test_segment dynamic_cap_msgs[] =
429{
430 { "DynCap",
431 "Dynamic Capability Message, IP/Multicast",
432 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
433 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
434 },
435 { "DynCapLong",
436 "Dynamic Capability Message, IP/Multicast, truncated",
437 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
438 5, SHOULD_ERR,
439 },
440 { "DynCapPadded",
441 "Dynamic Capability Message, IP/Multicast, padded",
442 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
443 8, SHOULD_ERR, /* No way to tell padding from data.. */
444 },
445 { "DynCapMPCpadded",
446 "Dynamic Capability Message, IP/Multicast, cap data padded",
447 { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
448 8, SHOULD_PARSE, /* You can though add padding to the capability data */
449 },
450 { "DynCapMPCoverflow",
451 "Dynamic Capability Message, IP/Multicast, cap data != length",
452 { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
453 8, SHOULD_ERR,
454 },
455 { NULL, NULL, {0}, 0, 0}
456};
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000457
458/* Entire Optional-Parameters block */
459struct test_segment opt_params[] =
460{
461 { "Cap-singlets",
462 "One capability per Optional-Param",
463 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
464 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
465 0x02, 0x02, 0x80, 0x00, /* RR (old) */
466 0x02, 0x02, 0x02, 0x00, /* RR */
467 },
468 24, SHOULD_PARSE,
469 },
470 { "Cap-series",
471 "Series of capability, one Optional-Param",
472 { 0x02, 0x10,
473 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
474 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
475 0x80, 0x00, /* RR (old) */
476 0x02, 0x00, /* RR */
477 },
478 18, SHOULD_PARSE,
479 },
480 { "AS4more",
481 "AS4 capability after other caps (singlets)",
482 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
483 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
484 0x02, 0x02, 0x80, 0x00, /* RR (old) */
485 0x02, 0x02, 0x02, 0x00, /* RR */
486 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
487 },
488 32, SHOULD_PARSE, 196614,
489 },
490 { "AS4series",
491 "AS4 capability, in series of capabilities",
492 { 0x02, 0x16,
493 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
494 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
495 0x80, 0x00, /* RR (old) */
496 0x02, 0x00, /* RR */
497 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
498 },
499 24, SHOULD_PARSE, 196614,
500 },
501 { "AS4real",
502 "AS4 capability, in series of capabilities",
503 {
504 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
505 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
506 0x02, 0x02, 0x80, 0x00, /* RR old */
507 0x02, 0x02, 0x02, 0x00, /* RR */
508 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
509 },
510 32, SHOULD_PARSE, 196614,
511 },
512 { "AS4real2",
513 "AS4 capability, in series of capabilities",
514 {
515 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
516 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
517 0x02, 0x02, 0x80, 0x00,
518 0x02, 0x02, 0x02, 0x00,
519 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
520 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
521 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
522 0x02, 0x02, 0x42, 0x00,
523 },
524 58, SHOULD_PARSE, 64515,
525 },
526
527 { NULL, NULL, {0}, 0, 0}
528};
529
Paul Jakmaed6ef902007-08-08 14:13:03 +0000530/* basic parsing test */
531static void
532parse_test (struct peer *peer, struct test_segment *t, int type)
533{
534 int ret;
535 int capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000536 as_t as4 = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +0000537 int oldfailed = failed;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000538 int len = t->len;
539#define RANDOM_FUZZ 35
Paul Jakmaed6ef902007-08-08 14:13:03 +0000540
541 stream_reset (peer->ibuf);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000542 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
543 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
544
Paul Jakmaed6ef902007-08-08 14:13:03 +0000545 switch (type)
546 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000547 case CAPABILITY:
Paul Jakmaed6ef902007-08-08 14:13:03 +0000548 stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
549 stream_putc (peer->ibuf, t->len);
550 break;
551 case DYNCAP:
552/* for (i = 0; i < BGP_MARKER_SIZE; i++)
553 stream_putc (peer->, 0xff);
554 stream_putw (s, 0);
555 stream_putc (s, BGP_MSG_CAPABILITY);*/
556 break;
557 }
558 stream_write (peer->ibuf, t->data, t->len);
559
560 printf ("%s: %s\n", t->name, t->desc);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000561
Paul Jakmaed6ef902007-08-08 14:13:03 +0000562 switch (type)
563 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000564 case CAPABILITY:
565 len += 2; /* to cover the OPT-Param header */
566 case OPT_PARAM:
567 printf ("len: %u\n", len);
568 /* peek_for_as4 wants getp at capibility*/
569 as4 = peek_for_as4_capability (peer, len);
570 printf ("peek_for_as4: as4 is %u\n", as4);
571 /* and it should leave getp as it found it */
572 assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
573
574 ret = bgp_open_option_parse (peer, len, &capability);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000575 break;
576 case DYNCAP:
577 ret = bgp_capability_receive (peer, t->len);
578 break;
579 default:
580 printf ("unknown type %u\n", type);
581 exit(1);
582 }
583
Paul Jakmae08286b2007-09-18 12:11:26 +0000584 if (!ret && t->validate_afi)
585 {
586 safi_t safi = t->safi;
587
588 if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
589 failed++;
590
591 printf ("MP: %u/%u (%u): recv %u, nego %u\n",
592 t->afi, t->safi, safi,
593 peer->afc_recv[t->afi][safi],
594 peer->afc_nego[t->afi][safi]);
595
596 if (t->afi_valid == VALID_AFI)
597 {
598
599 if (!peer->afc_recv[t->afi][safi])
600 failed++;
601 if (!peer->afc_nego[t->afi][safi])
602 failed++;
603 }
604 }
605
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000606 if (as4 != t->peek_for)
607 {
608 printf ("as4 %u != %u\n", as4, t->peek_for);
609 failed++;
610 }
611
Paul Jakmaed6ef902007-08-08 14:13:03 +0000612 printf ("parsed?: %s\n", ret ? "no" : "yes");
613
Paul Jakmae08286b2007-09-18 12:11:26 +0000614 if (ret != t->parses)
615 failed++;
616
617 if (tty)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000618 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
Paul Jakmae08286b2007-09-18 12:11:26 +0000619 : VT100_GREEN "OK" VT100_RESET);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000620 else
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000621 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
Paul Jakmaed6ef902007-08-08 14:13:03 +0000622
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000623 if (failed)
624 printf (" (%u)", failed);
625
626 printf ("\n\n");
Paul Jakmaed6ef902007-08-08 14:13:03 +0000627}
628
629static struct bgp *bgp;
630static as_t asn = 100;
631
632int
633main (void)
634{
635 struct peer *peer;
636 int i, j;
637
638 conf_bgp_debug_fsm = -1UL;
639 conf_bgp_debug_events = -1UL;
640 conf_bgp_debug_packet = -1UL;
641 conf_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000642 conf_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000643 term_bgp_debug_fsm = -1UL;
644 term_bgp_debug_events = -1UL;
645 term_bgp_debug_packet = -1UL;
646 term_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000647 term_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000648
649 master = thread_master_create ();
650 bgp_master_init ();
Paul Jakmac9e4f862012-06-14 10:42:39 +0100651 bgp_option_set (BGP_OPT_NO_LISTEN);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000652
Paul Jakmae08286b2007-09-18 12:11:26 +0000653 if (fileno (stdout) >= 0)
654 tty = isatty (fileno (stdout));
655
Paul Jakmaed6ef902007-08-08 14:13:03 +0000656 if (bgp_get (&bgp, &asn, NULL))
657 return -1;
658
659 peer = peer_create_accept (bgp);
Paul Jakma1dba2542012-05-01 16:20:33 +0100660 peer->host = (char *) "foo";
Paul Jakmaed6ef902007-08-08 14:13:03 +0000661
662 for (i = AFI_IP; i < AFI_MAX; i++)
663 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
Paul Jakmae08286b2007-09-18 12:11:26 +0000664 {
665 peer->afc[i][j] = 1;
666 peer->afc_adv[i][j] = 1;
667 }
Paul Jakmaed6ef902007-08-08 14:13:03 +0000668
Paul Jakmae08286b2007-09-18 12:11:26 +0000669 i = 0;
670 while (mp_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000671 parse_test (peer, &mp_segments[i++], CAPABILITY);
Paul Jakmae08286b2007-09-18 12:11:26 +0000672
673 /* These tests assume mp_segments tests set at least
674 * one of the afc_nego's
675 */
676 i = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000677 while (test_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000678 parse_test (peer, &test_segments[i++], CAPABILITY);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000679
Paul Jakmae08286b2007-09-18 12:11:26 +0000680 i = 0;
681 while (misc_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000682 parse_test (peer, &misc_segments[i++], CAPABILITY);
683
684 i = 0;
685 while (opt_params[i].name)
686 parse_test (peer, &opt_params[i++], OPT_PARAM);
Paul Jakmae08286b2007-09-18 12:11:26 +0000687
Paul Jakmaed6ef902007-08-08 14:13:03 +0000688 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
689 peer->status = Established;
690
691 i = 0;
692 while (dynamic_cap_msgs[i].name)
693 parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
694
695 printf ("failures: %d\n", failed);
696 return failed;
697}