blob: 96f18f01f87d6a08b16595ce752546c73d7c5621 [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 },
314 /* 20 */
315 { "GR",
316 "GR capability",
317 { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
318 /* R-bit, time */ 0xf1, 0x12,
319 /* afi */ 0x0, 0x1,
320 /* safi */ 0x1,
321 /* flags */ 0xf,
322 /* afi */ 0x0, 0x2,
323 /* safi */ 0x1,
324 /* flags */ 0x0,
325 /* afi */ 0x0, 0x2,
326 /* safi */ 0x2,
327 /* flags */ 0x1,
328 },
329 16, SHOULD_PARSE,
330 },
331 /* 21 */
332 { "GR-short",
333 "GR capability, but header length too short",
334 { /* hdr */ 0x40, 0xa,
335 /* R-bit, time */ 0xf1, 0x12,
336 /* afi */ 0x0, 0x1,
337 /* safi */ 0x1,
338 /* flags */ 0xf,
339 /* afi */ 0x0, 0x2,
340 /* safi */ 0x1,
341 /* flags */ 0x0,
342 /* afi */ 0x0, 0x2,
343 /* safi */ 0x2,
344 /* flags */ 0x1,
345 },
346 16, SHOULD_PARSE,
347 },
348 /* 22 */
349 { "GR-long",
350 "GR capability, but header length too long",
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 },
362 16, SHOULD_ERR,
363 },
364 { "GR-trunc",
365 "GR capability, but truncated",
366 { /* hdr */ 0x40, 0xf,
367 /* R-bit, time */ 0xf1, 0x12,
368 /* afi */ 0x0, 0x1,
369 /* safi */ 0x1,
370 /* flags */ 0xf,
371 /* afi */ 0x0, 0x2,
372 /* safi */ 0x1,
373 /* flags */ 0x0,
374 /* afi */ 0x0, 0x2,
375 /* safi */ 0x2,
376 /* flags */ 0x1,
377 },
378 15, SHOULD_ERR,
379 },
Paul Jakma370b64a2007-12-22 16:49:52 +0000380 { "GR-empty",
381 "GR capability, but empty.",
382 { /* hdr */ 0x40, 0x0,
383 },
384 2, SHOULD_ERR,
385 },
386 { "MP-empty",
387 "MP capability, but empty.",
388 { /* hdr */ 0x1, 0x0,
389 },
390 2, SHOULD_ERR,
391 },
392 { "ORF-empty",
393 "ORF capability, but empty.",
394 { /* hdr */ 0x3, 0x0,
395 },
396 2, SHOULD_ERR,
397 },
398 { "AS4-empty",
399 "AS4 capability, but empty.",
400 { /* hdr */ 0x41, 0x0,
401 },
402 2, SHOULD_ERR,
403 },
404 { "dyn-empty",
405 "Dynamic capability, but empty.",
406 { /* hdr */ 0x42, 0x0,
407 },
408 2, SHOULD_PARSE,
409 },
Paul Jakmaed6ef902007-08-08 14:13:03 +0000410 { "dyn-old",
411 "Dynamic capability (deprecated version)",
412 { CAPABILITY_CODE_DYNAMIC, 0x0 },
413 2, SHOULD_PARSE,
414 },
415 { NULL, NULL, {0}, 0, 0}
416};
417
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000418/* DYNAMIC message */
Paul Jakmaed6ef902007-08-08 14:13:03 +0000419struct test_segment dynamic_cap_msgs[] =
420{
421 { "DynCap",
422 "Dynamic Capability Message, IP/Multicast",
423 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
424 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
425 },
426 { "DynCapLong",
427 "Dynamic Capability Message, IP/Multicast, truncated",
428 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
429 5, SHOULD_ERR,
430 },
431 { "DynCapPadded",
432 "Dynamic Capability Message, IP/Multicast, padded",
433 { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
434 8, SHOULD_ERR, /* No way to tell padding from data.. */
435 },
436 { "DynCapMPCpadded",
437 "Dynamic Capability Message, IP/Multicast, cap data padded",
438 { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
439 8, SHOULD_PARSE, /* You can though add padding to the capability data */
440 },
441 { "DynCapMPCoverflow",
442 "Dynamic Capability Message, IP/Multicast, cap data != length",
443 { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
444 8, SHOULD_ERR,
445 },
446 { NULL, NULL, {0}, 0, 0}
447};
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000448
449/* Entire Optional-Parameters block */
450struct test_segment opt_params[] =
451{
452 { "Cap-singlets",
453 "One capability per Optional-Param",
454 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
455 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
456 0x02, 0x02, 0x80, 0x00, /* RR (old) */
457 0x02, 0x02, 0x02, 0x00, /* RR */
458 },
459 24, SHOULD_PARSE,
460 },
461 { "Cap-series",
462 "Series of capability, one Optional-Param",
463 { 0x02, 0x10,
464 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
465 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
466 0x80, 0x00, /* RR (old) */
467 0x02, 0x00, /* RR */
468 },
469 18, SHOULD_PARSE,
470 },
471 { "AS4more",
472 "AS4 capability after other caps (singlets)",
473 { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
474 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
475 0x02, 0x02, 0x80, 0x00, /* RR (old) */
476 0x02, 0x02, 0x02, 0x00, /* RR */
477 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
478 },
479 32, SHOULD_PARSE, 196614,
480 },
481 { "AS4series",
482 "AS4 capability, in series of capabilities",
483 { 0x02, 0x16,
484 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
485 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
486 0x80, 0x00, /* RR (old) */
487 0x02, 0x00, /* RR */
488 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
489 },
490 24, SHOULD_PARSE, 196614,
491 },
492 { "AS4real",
493 "AS4 capability, in series of capabilities",
494 {
495 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
496 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
497 0x02, 0x02, 0x80, 0x00, /* RR old */
498 0x02, 0x02, 0x02, 0x00, /* RR */
499 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
500 },
501 32, SHOULD_PARSE, 196614,
502 },
503 { "AS4real2",
504 "AS4 capability, in series of capabilities",
505 {
506 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
507 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
508 0x02, 0x02, 0x80, 0x00,
509 0x02, 0x02, 0x02, 0x00,
510 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
511 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
512 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
513 0x02, 0x02, 0x42, 0x00,
514 },
515 58, SHOULD_PARSE, 64515,
516 },
517
518 { NULL, NULL, {0}, 0, 0}
519};
520
Paul Jakmaed6ef902007-08-08 14:13:03 +0000521/* basic parsing test */
522static void
523parse_test (struct peer *peer, struct test_segment *t, int type)
524{
525 int ret;
526 int capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000527 as_t as4 = 0;
Paul Jakmae08286b2007-09-18 12:11:26 +0000528 int oldfailed = failed;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000529 int len = t->len;
530#define RANDOM_FUZZ 35
Paul Jakmaed6ef902007-08-08 14:13:03 +0000531
532 stream_reset (peer->ibuf);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000533 stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
534 stream_set_getp (peer->ibuf, RANDOM_FUZZ);
535
Paul Jakmaed6ef902007-08-08 14:13:03 +0000536 switch (type)
537 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000538 case CAPABILITY:
Paul Jakmaed6ef902007-08-08 14:13:03 +0000539 stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
540 stream_putc (peer->ibuf, t->len);
541 break;
542 case DYNCAP:
543/* for (i = 0; i < BGP_MARKER_SIZE; i++)
544 stream_putc (peer->, 0xff);
545 stream_putw (s, 0);
546 stream_putc (s, BGP_MSG_CAPABILITY);*/
547 break;
548 }
549 stream_write (peer->ibuf, t->data, t->len);
550
551 printf ("%s: %s\n", t->name, t->desc);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000552
Paul Jakmaed6ef902007-08-08 14:13:03 +0000553 switch (type)
554 {
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000555 case CAPABILITY:
556 len += 2; /* to cover the OPT-Param header */
557 case OPT_PARAM:
558 printf ("len: %u\n", len);
559 /* peek_for_as4 wants getp at capibility*/
560 as4 = peek_for_as4_capability (peer, len);
561 printf ("peek_for_as4: as4 is %u\n", as4);
562 /* and it should leave getp as it found it */
563 assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
564
565 ret = bgp_open_option_parse (peer, len, &capability);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000566 break;
567 case DYNCAP:
568 ret = bgp_capability_receive (peer, t->len);
569 break;
570 default:
571 printf ("unknown type %u\n", type);
572 exit(1);
573 }
574
Paul Jakmae08286b2007-09-18 12:11:26 +0000575 if (!ret && t->validate_afi)
576 {
577 safi_t safi = t->safi;
578
579 if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
580 failed++;
581
582 printf ("MP: %u/%u (%u): recv %u, nego %u\n",
583 t->afi, t->safi, safi,
584 peer->afc_recv[t->afi][safi],
585 peer->afc_nego[t->afi][safi]);
586
587 if (t->afi_valid == VALID_AFI)
588 {
589
590 if (!peer->afc_recv[t->afi][safi])
591 failed++;
592 if (!peer->afc_nego[t->afi][safi])
593 failed++;
594 }
595 }
596
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000597 if (as4 != t->peek_for)
598 {
599 printf ("as4 %u != %u\n", as4, t->peek_for);
600 failed++;
601 }
602
Paul Jakmaed6ef902007-08-08 14:13:03 +0000603 printf ("parsed?: %s\n", ret ? "no" : "yes");
604
Paul Jakmae08286b2007-09-18 12:11:26 +0000605 if (ret != t->parses)
606 failed++;
607
608 if (tty)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000609 printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
Paul Jakmae08286b2007-09-18 12:11:26 +0000610 : VT100_GREEN "OK" VT100_RESET);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000611 else
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000612 printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
Paul Jakmaed6ef902007-08-08 14:13:03 +0000613
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000614 if (failed)
615 printf (" (%u)", failed);
616
617 printf ("\n\n");
Paul Jakmaed6ef902007-08-08 14:13:03 +0000618}
619
620static struct bgp *bgp;
621static as_t asn = 100;
622
623int
624main (void)
625{
626 struct peer *peer;
627 int i, j;
628
629 conf_bgp_debug_fsm = -1UL;
630 conf_bgp_debug_events = -1UL;
631 conf_bgp_debug_packet = -1UL;
632 conf_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000633 conf_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000634 term_bgp_debug_fsm = -1UL;
635 term_bgp_debug_events = -1UL;
636 term_bgp_debug_packet = -1UL;
637 term_bgp_debug_normal = -1UL;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000638 term_bgp_debug_as4 = -1UL;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000639
640 master = thread_master_create ();
641 bgp_master_init ();
Paul Jakmac9e4f862012-06-14 10:42:39 +0100642 bgp_option_set (BGP_OPT_NO_LISTEN);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000643
Paul Jakmae08286b2007-09-18 12:11:26 +0000644 if (fileno (stdout) >= 0)
645 tty = isatty (fileno (stdout));
646
Paul Jakmaed6ef902007-08-08 14:13:03 +0000647 if (bgp_get (&bgp, &asn, NULL))
648 return -1;
649
650 peer = peer_create_accept (bgp);
Paul Jakma1dba2542012-05-01 16:20:33 +0100651 peer->host = (char *) "foo";
Paul Jakmaed6ef902007-08-08 14:13:03 +0000652
653 for (i = AFI_IP; i < AFI_MAX; i++)
654 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
Paul Jakmae08286b2007-09-18 12:11:26 +0000655 {
656 peer->afc[i][j] = 1;
657 peer->afc_adv[i][j] = 1;
658 }
Paul Jakmaed6ef902007-08-08 14:13:03 +0000659
Paul Jakmae08286b2007-09-18 12:11:26 +0000660 i = 0;
661 while (mp_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000662 parse_test (peer, &mp_segments[i++], CAPABILITY);
Paul Jakmae08286b2007-09-18 12:11:26 +0000663
664 /* These tests assume mp_segments tests set at least
665 * one of the afc_nego's
666 */
667 i = 0;
Paul Jakmaed6ef902007-08-08 14:13:03 +0000668 while (test_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000669 parse_test (peer, &test_segments[i++], CAPABILITY);
Paul Jakmaed6ef902007-08-08 14:13:03 +0000670
Paul Jakmae08286b2007-09-18 12:11:26 +0000671 i = 0;
672 while (misc_segments[i].name)
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000673 parse_test (peer, &misc_segments[i++], CAPABILITY);
674
675 i = 0;
676 while (opt_params[i].name)
677 parse_test (peer, &opt_params[i++], OPT_PARAM);
Paul Jakmae08286b2007-09-18 12:11:26 +0000678
Paul Jakmaed6ef902007-08-08 14:13:03 +0000679 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
680 peer->status = Established;
681
682 i = 0;
683 while (dynamic_cap_msgs[i].name)
684 parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
685
686 printf ("failures: %d\n", failed);
687 return failed;
688}