blob: 3cfc1987afe09876548a951bfc518f3a290dbdee [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"
28
29#include "bgpd/bgpd.h"
30#include "bgpd/bgp_open.h"
31#include "bgpd/bgp_debug.h"
Paul Jakma1dba2542012-05-01 16:20:33 +010032#include "bgpd/bgp_packet.h"
Paul Jakmaed6ef902007-08-08 14:13:03 +000033
Paul Jakmae08286b2007-09-18 12:11:26 +000034#define VT100_RESET "\x1b[0m"
35#define VT100_RED "\x1b[31m"
36#define VT100_GREEN "\x1b[32m"
37#define VT100_YELLOW "\x1b[33m"
38
39
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000040#define CAPABILITY 0
41#define DYNCAP 1
42#define OPT_PARAM 2
Paul Jakmaed6ef902007-08-08 14:13:03 +000043
44/* need these to link in libbgp */
45struct zebra_privs_t *bgpd_privs = NULL;
46struct thread_master *master = NULL;
47
48static int failed = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +000049static int tty = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +000050
51/* test segments to parse and validate, and use for other tests */
52static struct test_segment {
53 const char *name;
54 const char *desc;
55 const u_char data[1024];
56 int len;
57#define SHOULD_PARSE 0
58#define SHOULD_ERR -1
59 int parses; /* whether it should parse or not */
Paul Jakma1dba2542012-05-01 16:20:33 +010060 as_t peek_for; /* what peek_for_as4_capability should say */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000061
Paul Jakmae08286b2007-09-18 12:11:26 +000062 /* AFI/SAFI validation */
63 int validate_afi;
64 afi_t afi;
65 safi_t safi;
66#define VALID_AFI 1
67#define INVALID_AFI 0
68 int afi_valid;
Paul Jakmaed6ef902007-08-08 14:13:03 +000069} test_segments [] =
70{
71 /* 0 */
72 { "caphdr",
73 "capability header, and no more",
74 { CAPABILITY_CODE_REFRESH, 0x0 },
75 2, SHOULD_PARSE,
76 },
77 /* 1 */
78 { "nodata",
79 "header, no data but length says there is",
80 { 0x1, 0xa },
81 2, SHOULD_ERR,
82 },
83 /* 2 */
84 { "padded",
85 "valid, with padding",
86 { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
87 4, SHOULD_PARSE,
88 },
89 /* 3 */
90 { "minsize",
91 "violates minsize requirement",
92 { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
93 4, SHOULD_ERR,
94 },
Paul Jakmae08286b2007-09-18 12:11:26 +000095 { NULL, NULL, {0}, 0, 0},
96};
97
98static struct test_segment mp_segments[] =
99{
100 { "MP4",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000101 "MP IP/Uni",
102 { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000103 6, SHOULD_PARSE, 0,
104 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmae08286b2007-09-18 12:11:26 +0000105 },
106 { "MPv6",
107 "MP IPv6/Uni",
108 { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000109 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000110 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000111 },
112 /* 5 */
113 { "MP2",
114 "MP IP/Multicast",
115 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000116 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000117 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000118 },
119 /* 6 */
120 { "MP3",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400121 "MP IP6/MPLS-labeled VPN",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000122 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400123 6, SHOULD_PARSE, 0,
124 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000125 },
126 /* 7 */
127 { "MP5",
128 "MP IP6/MPLS-VPN",
129 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000130 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000131 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000132 },
133 /* 8 */
134 { "MP6",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400135 "MP IP4/MPLS-laveled VPN",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000136 { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000137 6, SHOULD_PARSE, 0,
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400138 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000139 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000140 /* 10 */
141 { "MP8",
Denis Ovsienko42e6d742011-07-14 12:36:19 +0400142 "MP unknown AFI/SAFI",
Paul Jakmaed6ef902007-08-08 14:13:03 +0000143 { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000144 6, SHOULD_PARSE, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000145 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000146 },
147 /* 11 */
148 { "MP-short",
149 "MP IP4/Unicast, length too short (< minimum)",
150 { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
151 6, SHOULD_ERR,
152 },
153 /* 12 */
154 { "MP-overflow",
155 "MP IP4/Unicast, length too long",
156 { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000157 6, SHOULD_ERR, 0,
Paul Jakmae08286b2007-09-18 12:11:26 +0000158 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000159 },
Paul Jakmae08286b2007-09-18 12:11:26 +0000160 { NULL, NULL, {0}, 0, 0}
161};
162
163static struct test_segment misc_segments[] =
164{
Paul Jakmaed6ef902007-08-08 14:13:03 +0000165 /* 13 */
166 { "ORF",
167 "ORF, simple, single entry, single tuple",
168 { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
169 /* mpc */ 0x0, 0x1, 0x0, 0x1,
170 /* num */ 0x1,
171 /* tuples */ 0x40, 0x3
172 },
173 9, SHOULD_PARSE,
174 },
175 /* 14 */
176 { "ORF-many",
177 "ORF, multi entry/tuple",
178 { /* hdr */ CAPABILITY_CODE_ORF, 0x21,
179 /* mpc */ 0x0, 0x1, 0x0, 0x1,
180 /* num */ 0x3,
181 /* tuples */ 0x40, ORF_MODE_BOTH,
182 0x80, ORF_MODE_RECEIVE,
183 0x80, ORF_MODE_SEND,
184 /* mpc */ 0x0, 0x2, 0x0, 0x1,
185 /* num */ 0x3,
186 /* tuples */ 0x40, ORF_MODE_BOTH,
187 0x80, ORF_MODE_RECEIVE,
188 0x80, ORF_MODE_SEND,
189 /* mpc */ 0x0, 0x2, 0x0, 0x2,
190 /* num */ 0x3,
191 /* tuples */ 0x40, ORF_MODE_RECEIVE,
192 0x80, ORF_MODE_SEND,
193 0x80, ORF_MODE_BOTH,
194 },
195 35, SHOULD_PARSE,
196 },
197 /* 15 */
198 { "ORFlo",
199 "ORF, multi entry/tuple, hdr length too short",
200 { /* hdr */ CAPABILITY_CODE_ORF, 0x15,
201 /* mpc */ 0x0, 0x1, 0x0, 0x1,
202 /* num */ 0x3,
203 /* tuples */ 0x40, 0x3,
204 0x80, 0x1,
205 0x80, 0x2,
206 /* mpc */ 0x0, 0x1, 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, /* It should error on invalid Route-Refresh.. */
218 },
219 /* 16 */
220 { "ORFlu",
221 "ORF, multi entry/tuple, length too long",
222 { /* hdr */ 0x3, 0x22,
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 */ 0x3,
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_ERR
240 },
241 /* 17 */
242 { "ORFnu",
243 "ORF, multi entry/tuple, entry number too long",
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 */ 0x4,
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 last few tuples should be gibberish */
262 },
263 /* 18 */
264 { "ORFno",
265 "ORF, multi entry/tuple, entry number too short",
266 { /* hdr */ 0x3, 0x21,
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 */ 0x1,
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 },
283 35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
284 },
285 /* 17 */
286 { "ORFpad",
287 "ORF, multi entry/tuple, padded to align",
288 { /* hdr */ 0x3, 0x22,
289 /* mpc */ 0x0, 0x1, 0x0, 0x1,
290 /* num */ 0x3,
291 /* tuples */ 0x40, 0x3,
292 0x80, 0x1,
293 0x80, 0x2,
294 /* mpc */ 0x0, 0x2, 0x0, 0x1,
295 /* num */ 0x3,
296 /* tuples */ 0x40, 0x3,
297 0x80, 0x1,
298 0x80, 0x2,
299 /* mpc */ 0x0, 0x2, 0x0, 0x2,
300 /* num */ 0x3,
301 /* tuples */ 0x40, 0x3,
302 0x80, 0x1,
303 0x80, 0x2,
304 0x00,
305 },
306 36, SHOULD_PARSE,
307 },
308 /* 19 */
309 { "AS4",
310 "AS4 capability",
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000311 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
312 6, SHOULD_PARSE, 2882400018,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000313 },
Paul Jakma321d4132015-11-25 17:14:36 +0000314 { "AS4",
315 "AS4 capability: short",
316 { 0x41, 0x4, 0xab, 0xcd, 0xef }, /* AS: 2882400018 */
317 5, SHOULD_ERR,
318 },
319 { "AS4",
320 "AS4 capability: long",
321 { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12, 0x12 },
322 7, SHOULD_ERR, 2882400018,
323 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000324 { "GR",
325 "GR capability",
326 { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
327 /* R-bit, time */ 0xf1, 0x12,
328 /* afi */ 0x0, 0x1,
329 /* safi */ 0x1,
330 /* flags */ 0xf,
331 /* afi */ 0x0, 0x2,
332 /* safi */ 0x1,
333 /* flags */ 0x0,
334 /* afi */ 0x0, 0x2,
335 /* safi */ 0x2,
336 /* flags */ 0x1,
337 },
338 16, SHOULD_PARSE,
339 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000340 { "GR-short",
341 "GR capability, but header length too short",
342 { /* hdr */ 0x40, 0xa,
343 /* R-bit, time */ 0xf1, 0x12,
344 /* afi */ 0x0, 0x1,
345 /* safi */ 0x1,
346 /* flags */ 0xf,
347 /* afi */ 0x0, 0x2,
348 /* safi */ 0x1,
349 /* flags */ 0x0,
350 /* afi */ 0x0, 0x2,
351 /* safi */ 0x2,
352 /* flags */ 0x1,
353 },
Paul Jakma321d4132015-11-25 17:14:36 +0000354 15 /* array is 16 though */, SHOULD_ERR,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000355 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000356 { "GR-long",
357 "GR capability, but header length too long",
358 { /* hdr */ 0x40, 0xf,
359 /* R-bit, time */ 0xf1, 0x12,
360 /* afi */ 0x0, 0x1,
361 /* safi */ 0x1,
362 /* flags */ 0xf,
363 /* afi */ 0x0, 0x2,
364 /* safi */ 0x1,
365 /* flags */ 0x0,
366 /* afi */ 0x0, 0x2,
367 /* safi */ 0x2,
Paul Jakma321d4132015-11-25 17:14:36 +0000368 /* flags */ 0x01,
Paul Jakmaed6ef902007-08-08 14:13:03 +0000369 },
370 16, SHOULD_ERR,
371 },
372 { "GR-trunc",
373 "GR capability, but truncated",
374 { /* hdr */ 0x40, 0xf,
375 /* R-bit, time */ 0xf1, 0x12,
376 /* afi */ 0x0, 0x1,
377 /* safi */ 0x1,
378 /* flags */ 0xf,
379 /* afi */ 0x0, 0x2,
380 /* safi */ 0x1,
381 /* flags */ 0x0,
382 /* afi */ 0x0, 0x2,
383 /* safi */ 0x2,
384 /* flags */ 0x1,
385 },
386 15, SHOULD_ERR,
387 },
Paul Jakma370b64a2007-12-22 16:49:52 +0000388 { "GR-empty",
389 "GR capability, but empty.",
390 { /* hdr */ 0x40, 0x0,
391 },
392 2, SHOULD_ERR,
393 },
394 { "MP-empty",
395 "MP capability, but empty.",
396 { /* hdr */ 0x1, 0x0,
397 },
398 2, SHOULD_ERR,
399 },
400 { "ORF-empty",
401 "ORF capability, but empty.",
402 { /* hdr */ 0x3, 0x0,
403 },
404 2, SHOULD_ERR,
405 },
406 { "AS4-empty",
407 "AS4 capability, but empty.",
408 { /* hdr */ 0x41, 0x0,
409 },
410 2, SHOULD_ERR,
411 },
412 { "dyn-empty",
413 "Dynamic capability, but empty.",
414 { /* hdr */ 0x42, 0x0,
415 },
416 2, SHOULD_PARSE,
417 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000418 { "dyn-old",
419 "Dynamic capability (deprecated version)",
420 { CAPABILITY_CODE_DYNAMIC, 0x0 },
421 2, SHOULD_PARSE,
422 },
423 { NULL, NULL, {0}, 0, 0}
424};
425
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000426/* DYNAMIC message */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000427struct test_segment dynamic_cap_msgs[] =
428{
429 { "DynCap",
430 "Dynamic Capability Message, IP/Multicast",
431 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
432 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
433 },
434 { "DynCapLong",
435 "Dynamic Capability Message, IP/Multicast, truncated",
436 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
437 5, SHOULD_ERR,
438 },
439 { "DynCapPadded",
440 "Dynamic Capability Message, IP/Multicast, padded",
441 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
442 8, SHOULD_ERR, /* No way to tell padding from data.. */
443 },
444 { "DynCapMPCpadded",
445 "Dynamic Capability Message, IP/Multicast, cap data padded",
446 { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
447 8, SHOULD_PARSE, /* You can though add padding to the capability data */
448 },
449 { "DynCapMPCoverflow",
450 "Dynamic Capability Message, IP/Multicast, cap data != length",
451 { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
452 8, SHOULD_ERR,
453 },
454 { NULL, NULL, {0}, 0, 0}
455};
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000456
457/* Entire Optional-Parameters block */
458struct test_segment opt_params[] =
459{
460 { "Cap-singlets",
461 "One capability per Optional-Param",
462 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
463 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
464 0x02, 0x02, 0x80, 0x00, /* RR (old) */
465 0x02, 0x02, 0x02, 0x00, /* RR */
466 },
467 24, SHOULD_PARSE,
468 },
469 { "Cap-series",
470 "Series of capability, one Optional-Param",
471 { 0x02, 0x10,
472 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
473 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
474 0x80, 0x00, /* RR (old) */
475 0x02, 0x00, /* RR */
476 },
477 18, SHOULD_PARSE,
478 },
479 { "AS4more",
480 "AS4 capability after other caps (singlets)",
481 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
482 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
483 0x02, 0x02, 0x80, 0x00, /* RR (old) */
484 0x02, 0x02, 0x02, 0x00, /* RR */
485 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
486 },
487 32, SHOULD_PARSE, 196614,
488 },
489 { "AS4series",
490 "AS4 capability, in series of capabilities",
491 { 0x02, 0x16,
492 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
493 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
494 0x80, 0x00, /* RR (old) */
495 0x02, 0x00, /* RR */
496 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
497 },
498 24, SHOULD_PARSE, 196614,
499 },
500 { "AS4real",
501 "AS4 capability, in series of capabilities",
502 {
503 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
504 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
505 0x02, 0x02, 0x80, 0x00, /* RR old */
506 0x02, 0x02, 0x02, 0x00, /* RR */
507 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
508 },
509 32, SHOULD_PARSE, 196614,
510 },
511 { "AS4real2",
512 "AS4 capability, in series of capabilities",
513 {
514 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
515 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
516 0x02, 0x02, 0x80, 0x00,
517 0x02, 0x02, 0x02, 0x00,
518 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
519 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
520 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
521 0x02, 0x02, 0x42, 0x00,
522 },
523 58, SHOULD_PARSE, 64515,
524 },
525
526 { NULL, NULL, {0}, 0, 0}
527};
528
Paul Jakmaed6ef902007-08-08 14:13:03 +0000529/* basic parsing test */
530static void
531parse_test (struct peer *peer, struct test_segment *t, int type)
532{
533 int ret;
534 int capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000535 as_t as4 = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +0000536 int oldfailed = failed;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000537 int len = t->len;
538#define RANDOM_FUZZ 35
Paul Jakmaed6ef902007-08-08 14:13:03 +0000539
540 stream_reset (peer->ibuf);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000541 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
542 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
543
Paul Jakmaed6ef902007-08-08 14:13:03 +0000544 switch (type)
545 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000546 case CAPABILITY:
Paul Jakmaed6ef902007-08-08 14:13:03 +0000547 stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
548 stream_putc (peer->ibuf, t->len);
549 break;
550 case DYNCAP:
551/* for (i = 0; i < BGP_MARKER_SIZE; i++)
552 stream_putc (peer->, 0xff);
553 stream_putw (s, 0);
554 stream_putc (s, BGP_MSG_CAPABILITY);*/
555 break;
556 }
557 stream_write (peer->ibuf, t->data, t->len);
558
559 printf ("%s: %s\n", t->name, t->desc);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000560
Paul Jakmaed6ef902007-08-08 14:13:03 +0000561 switch (type)
562 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000563 case CAPABILITY:
564 len += 2; /* to cover the OPT-Param header */
565 case OPT_PARAM:
566 printf ("len: %u\n", len);
567 /* peek_for_as4 wants getp at capibility*/
568 as4 = peek_for_as4_capability (peer, len);
569 printf ("peek_for_as4: as4 is %u\n", as4);
570 /* and it should leave getp as it found it */
571 assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
572
573 ret = bgp_open_option_parse (peer, len, &capability);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000574 break;
575 case DYNCAP:
576 ret = bgp_capability_receive (peer, t->len);
577 break;
578 default:
579 printf ("unknown type %u\n", type);
580 exit(1);
581 }
582
Paul Jakmae08286b2007-09-18 12:11:26 +0000583 if (!ret && t->validate_afi)
584 {
585 safi_t safi = t->safi;
586
587 if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
588 failed++;
589
590 printf ("MP: %u/%u (%u): recv %u, nego %u\n",
591 t->afi, t->safi, safi,
592 peer->afc_recv[t->afi][safi],
593 peer->afc_nego[t->afi][safi]);
594
595 if (t->afi_valid == VALID_AFI)
596 {
597
598 if (!peer->afc_recv[t->afi][safi])
599 failed++;
600 if (!peer->afc_nego[t->afi][safi])
601 failed++;
602 }
603 }
604
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000605 if (as4 != t->peek_for)
606 {
607 printf ("as4 %u != %u\n", as4, t->peek_for);
608 failed++;
609 }
610
Paul Jakmaed6ef902007-08-08 14:13:03 +0000611 printf ("parsed?: %s\n", ret ? "no" : "yes");
612
Paul Jakmae08286b2007-09-18 12:11:26 +0000613 if (ret != t->parses)
614 failed++;
615
616 if (tty)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000617 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
Paul Jakmae08286b2007-09-18 12:11:26 +0000618 : VT100_GREEN "OK" VT100_RESET);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000619 else
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000620 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
Paul Jakmaed6ef902007-08-08 14:13:03 +0000621
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000622 if (failed)
623 printf (" (%u)", failed);
624
625 printf ("\n\n");
Paul Jakmaed6ef902007-08-08 14:13:03 +0000626}
627
628static struct bgp *bgp;
629static as_t asn = 100;
630
631int
632main (void)
633{
634 struct peer *peer;
635 int i, j;
636
637 conf_bgp_debug_fsm = -1UL;
638 conf_bgp_debug_events = -1UL;
639 conf_bgp_debug_packet = -1UL;
640 conf_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000641 conf_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000642 term_bgp_debug_fsm = -1UL;
643 term_bgp_debug_events = -1UL;
644 term_bgp_debug_packet = -1UL;
645 term_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000646 term_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000647
648 master = thread_master_create ();
649 bgp_master_init ();
Paul Jakmac9e4f862012-06-14 10:42:39 +0100650 bgp_option_set (BGP_OPT_NO_LISTEN);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000651
Paul Jakmae08286b2007-09-18 12:11:26 +0000652 if (fileno (stdout) >= 0)
653 tty = isatty (fileno (stdout));
654
Paul Jakmaed6ef902007-08-08 14:13:03 +0000655 if (bgp_get (&bgp, &asn, NULL))
656 return -1;
657
658 peer = peer_create_accept (bgp);
Paul Jakma1dba2542012-05-01 16:20:33 +0100659 peer->host = (char *) "foo";
Paul Jakmaed6ef902007-08-08 14:13:03 +0000660
661 for (i = AFI_IP; i < AFI_MAX; i++)
662 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
Paul Jakmae08286b2007-09-18 12:11:26 +0000663 {
664 peer->afc[i][j] = 1;
665 peer->afc_adv[i][j] = 1;
666 }
Paul Jakmaed6ef902007-08-08 14:13:03 +0000667
Paul Jakmae08286b2007-09-18 12:11:26 +0000668 i = 0;
669 while (mp_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000670 parse_test (peer, &mp_segments[i++], CAPABILITY);
Paul Jakmae08286b2007-09-18 12:11:26 +0000671
672 /* These tests assume mp_segments tests set at least
673 * one of the afc_nego's
674 */
675 i = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000676 while (test_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000677 parse_test (peer, &test_segments[i++], CAPABILITY);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000678
Paul Jakmae08286b2007-09-18 12:11:26 +0000679 i = 0;
680 while (misc_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000681 parse_test (peer, &misc_segments[i++], CAPABILITY);
682
683 i = 0;
684 while (opt_params[i].name)
685 parse_test (peer, &opt_params[i++], OPT_PARAM);
Paul Jakmae08286b2007-09-18 12:11:26 +0000686
Paul Jakmaed6ef902007-08-08 14:13:03 +0000687 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
688 peer->status = Established;
689
690 i = 0;
691 while (dynamic_cap_msgs[i].name)
692 parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
693
694 printf ("failures: %d\n", failed);
695 return failed;
696}