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: *
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:
22: #include <zebra.h>
23:
24: #include "vty.h"
25: #include "stream.h"
26: #include "privs.h"
27: #include "memory.h"
28: #include "filter.h"
29:
30: #include "bgpd/bgpd.h"
31: #include "bgpd/bgp_open.h"
32: #include "bgpd/bgp_debug.h"
33: #include "bgpd/bgp_packet.h"
34:
35: #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:
41: #define CAPABILITY 0
42: #define DYNCAP 1
43: #define OPT_PARAM 2
44:
45: /* need these to link in libbgp */
46: struct zebra_privs_t *bgpd_privs = NULL;
47: struct thread_master *master = NULL;
48:
49: static int failed = 0;
50: static int tty = 0;
51:
52: /* test segments to parse and validate, and use for other tests */
53: static 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 */
61: as_t peek_for; /* what peek_for_as4_capability should say */
62:
63: /* 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;
70: } 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: },
96: { NULL, NULL, {0}, 0, 0},
97: };
98:
99: static struct test_segment mp_segments[] =
100: {
101: { "MP4",
102: "MP IP/Uni",
103: { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
104: 6, SHOULD_PARSE, 0,
105: 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
106: },
107: { "MPv6",
108: "MP IPv6/Uni",
109: { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
110: 6, SHOULD_PARSE, 0,
111: 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
112: },
113: /* 5 */
114: { "MP2",
115: "MP IP/Multicast",
116: { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
117: 6, SHOULD_PARSE, 0,
118: 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
119: },
120: /* 6 */
121: { "MP3",
122: "MP IP6/MPLS-labeled VPN",
123: { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
124: 6, SHOULD_PARSE, 0,
125: 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
126: },
127: /* 7 */
128: { "MP5",
129: "MP IP6/MPLS-VPN",
130: { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
131: 6, SHOULD_PARSE, 0,
132: 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
133: },
134: /* 8 */
135: { "MP6",
136: "MP IP4/MPLS-laveled VPN",
137: { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
138: 6, SHOULD_PARSE, 0,
139: 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
140: },
141: /* 10 */
142: { "MP8",
143: "MP unknown AFI/SAFI",
144: { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
145: 6, SHOULD_PARSE, 0,
146: 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
147: },
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 },
158: 6, SHOULD_ERR, 0,
159: 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
160: },
161: { NULL, NULL, {0}, 0, 0}
162: };
163:
164: static struct test_segment misc_segments[] =
165: {
166: /* 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",
312: { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
313: 6, SHOULD_PARSE, 2882400018,
314: },
315: { "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: },
325: { "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: },
341: { "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: },
355: 15 /* array is 16 though */, SHOULD_ERR,
356: },
357: { "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,
369: /* flags */ 0x01,
370: },
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: },
389: { "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: },
419: { "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:
427: /* DYNAMIC message */
428: struct 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: };
457:
458: /* Entire Optional-Parameters block */
459: struct 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:
530: /* basic parsing test */
531: static void
532: parse_test (struct peer *peer, struct test_segment *t, int type)
533: {
534: int ret;
535: int capability = 0;
536: as_t as4 = 0;
537: int oldfailed = failed;
538: int len = t->len;
539: #define RANDOM_FUZZ 35
540:
541: stream_reset (peer->ibuf);
542: stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
543: stream_set_getp (peer->ibuf, RANDOM_FUZZ);
544:
545: switch (type)
546: {
547: case CAPABILITY:
548: 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);
561:
562: switch (type)
563: {
564: 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);
575: 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:
584: 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:
606: if (as4 != t->peek_for)
607: {
608: printf ("as4 %u != %u\n", as4, t->peek_for);
609: failed++;
610: }
611:
612: printf ("parsed?: %s\n", ret ? "no" : "yes");
613:
614: if (ret != t->parses)
615: failed++;
616:
617: if (tty)
618: printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
619: : VT100_GREEN "OK" VT100_RESET);
620: else
621: printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
622:
623: if (failed)
624: printf (" (%u)", failed);
625:
626: printf ("\n\n");
627: }
628:
629: static struct bgp *bgp;
630: static as_t asn = 100;
631:
632: int
633: main (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;
642: conf_bgp_debug_as4 = -1UL;
643: term_bgp_debug_fsm = -1UL;
644: term_bgp_debug_events = -1UL;
645: term_bgp_debug_packet = -1UL;
646: term_bgp_debug_normal = -1UL;
647: term_bgp_debug_as4 = -1UL;
648:
649: master = thread_master_create ();
650: bgp_master_init ();
651: bgp_option_set (BGP_OPT_NO_LISTEN);
652:
653: if (fileno (stdout) >= 0)
654: tty = isatty (fileno (stdout));
655:
656: if (bgp_get (&bgp, &asn, NULL))
657: return -1;
658:
659: peer = peer_create_accept (bgp);
660: peer->host = (char *) "foo";
661:
662: for (i = AFI_IP; i < AFI_MAX; i++)
663: for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
664: {
665: peer->afc[i][j] = 1;
666: peer->afc_adv[i][j] = 1;
667: }
668:
669: i = 0;
670: while (mp_segments[i].name)
671: parse_test (peer, &mp_segments[i++], CAPABILITY);
672:
673: /* These tests assume mp_segments tests set at least
674: * one of the afc_nego's
675: */
676: i = 0;
677: while (test_segments[i].name)
678: parse_test (peer, &test_segments[i++], CAPABILITY);
679:
680: i = 0;
681: while (misc_segments[i].name)
682: 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);
687:
688: 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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>