File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / tests / bgp_capability_test.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:12 2016 UTC (7 years, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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>