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
29#include "bgpd/bgpd.h"
30#include "bgpd/bgp_open.h"
31#include "bgpd/bgp_debug.h"
32#include "bgpd/bgp_packet.h"
33
34#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
40#define CAPABILITY 0
41#define DYNCAP     1
42#define OPT_PARAM  2
43
44/* need these to link in libbgp */
45struct zebra_privs_t *bgpd_privs = NULL;
46struct thread_master *master = NULL;
47
48static int failed = 0;
49static int tty = 0;
50
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 */
60  as_t peek_for; /* what peek_for_as4_capability should say */
61
62  /* 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;
69} 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  },
95  { NULL, NULL, {0}, 0, 0},
96};
97
98static struct test_segment mp_segments[] =
99{
100  { "MP4",
101    "MP IP/Uni",
102    { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
103    6, SHOULD_PARSE, 0,
104    1, AFI_IP, SAFI_UNICAST, VALID_AFI,
105  },
106  { "MPv6",
107    "MP IPv6/Uni",
108    { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
109    6, SHOULD_PARSE, 0,
110    1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
111  },
112  /* 5 */
113  { "MP2",
114    "MP IP/Multicast",
115    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
116    6, SHOULD_PARSE, 0,
117    1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
118  },
119  /* 6 */
120  { "MP3",
121    "MP IP6/MPLS-labeled VPN",
122    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
123    6, SHOULD_PARSE, 0,
124    1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
125  },
126  /* 7 */
127  { "MP5",
128    "MP IP6/MPLS-VPN",
129    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
130    6, SHOULD_PARSE, 0,
131    1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
132  },
133  /* 8 */
134  { "MP6",
135    "MP IP4/MPLS-laveled VPN",
136    { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
137    6, SHOULD_PARSE, 0,
138    1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
139  },
140  /* 10 */
141  { "MP8",
142    "MP unknown AFI/SAFI",
143    { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
144    6, SHOULD_PARSE, 0,
145    1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
146  },
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 },
157    6, SHOULD_ERR, 0,
158    1, AFI_IP, SAFI_UNICAST, VALID_AFI,
159  },
160  { NULL, NULL, {0}, 0, 0}
161};
162
163static struct test_segment misc_segments[] =
164{
165  /* 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",
311    { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
312    6, SHOULD_PARSE, 2882400018,
313  },
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  },
380  { "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  },
410  { "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
418/* DYNAMIC message */
419struct 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};
448
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
521/* basic parsing test */
522static void
523parse_test (struct peer *peer, struct test_segment *t, int type)
524{
525  int ret;
526  int capability = 0;
527  as_t as4 = 0;
528  int oldfailed = failed;
529  int len = t->len;
530#define RANDOM_FUZZ 35
531
532  stream_reset (peer->ibuf);
533  stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
534  stream_set_getp (peer->ibuf, RANDOM_FUZZ);
535
536  switch (type)
537    {
538      case CAPABILITY:
539        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);
552
553  switch (type)
554    {
555      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);
566        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
575  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
597  if (as4 != t->peek_for)
598    {
599      printf ("as4 %u != %u\n", as4, t->peek_for);
600      failed++;
601    }
602
603  printf ("parsed?: %s\n", ret ? "no" : "yes");
604
605  if (ret != t->parses)
606    failed++;
607
608  if (tty)
609    printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
610                                         : VT100_GREEN "OK" VT100_RESET);
611  else
612    printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
613
614  if (failed)
615    printf (" (%u)", failed);
616
617  printf ("\n\n");
618}
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;
633  conf_bgp_debug_as4 = -1UL;
634  term_bgp_debug_fsm = -1UL;
635  term_bgp_debug_events = -1UL;
636  term_bgp_debug_packet = -1UL;
637  term_bgp_debug_normal = -1UL;
638  term_bgp_debug_as4 = -1UL;
639
640  master = thread_master_create ();
641  bgp_master_init ();
642  bgp_option_set (BGP_OPT_NO_LISTEN);
643
644  if (fileno (stdout) >= 0)
645    tty = isatty (fileno (stdout));
646
647  if (bgp_get (&bgp, &asn, NULL))
648    return -1;
649
650  peer = peer_create_accept (bgp);
651  peer->host = (char *) "foo";
652
653  for (i = AFI_IP; i < AFI_MAX; i++)
654    for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
655      {
656        peer->afc[i][j] = 1;
657        peer->afc_adv[i][j] = 1;
658      }
659
660  i = 0;
661  while (mp_segments[i].name)
662    parse_test (peer, &mp_segments[i++], CAPABILITY);
663
664  /* These tests assume mp_segments tests set at least
665   * one of the afc_nego's
666   */
667  i = 0;
668  while (test_segments[i].name)
669    parse_test (peer, &test_segments[i++], CAPABILITY);
670
671  i = 0;
672  while (misc_segments[i].name)
673    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);
678
679  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}
689