Home | History | Annotate | Download | only in tcpdump
      1 /*
      2  * Copyright (C) 1999 WIDE Project.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. Neither the name of the project nor the names of its contributors
     14  *    may be used to endorse or promote products derived from this software
     15  *    without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  *
     29  * Extensively modified by Hannes Gredler (hannes (at) gredler.at) for more
     30  * complete BGP support.
     31  */
     32 
     33 /* \summary: Border Gateway Protocol (BGP) printer */
     34 
     35 #ifdef HAVE_CONFIG_H
     36 #include "config.h"
     37 #endif
     38 
     39 #include <netdissect-stdinc.h>
     40 
     41 #include <stdio.h>
     42 #include <string.h>
     43 
     44 #include "netdissect.h"
     45 #include "addrtoname.h"
     46 #include "extract.h"
     47 #include "af.h"
     48 #include "l2vpn.h"
     49 
     50 struct bgp {
     51 	uint8_t bgp_marker[16];
     52 	uint16_t bgp_len;
     53 	uint8_t bgp_type;
     54 };
     55 #define BGP_SIZE		19	/* unaligned */
     56 
     57 #define BGP_OPEN		1
     58 #define BGP_UPDATE		2
     59 #define BGP_NOTIFICATION	3
     60 #define BGP_KEEPALIVE		4
     61 #define BGP_ROUTE_REFRESH       5
     62 
     63 static const struct tok bgp_msg_values[] = {
     64     { BGP_OPEN,                 "Open"},
     65     { BGP_UPDATE,               "Update"},
     66     { BGP_NOTIFICATION,         "Notification"},
     67     { BGP_KEEPALIVE,            "Keepalive"},
     68     { BGP_ROUTE_REFRESH,        "Route Refresh"},
     69     { 0, NULL}
     70 };
     71 
     72 struct bgp_open {
     73 	uint8_t bgpo_marker[16];
     74 	uint16_t bgpo_len;
     75 	uint8_t bgpo_type;
     76 	uint8_t bgpo_version;
     77 	uint16_t bgpo_myas;
     78 	uint16_t bgpo_holdtime;
     79 	uint32_t bgpo_id;
     80 	uint8_t bgpo_optlen;
     81 	/* options should follow */
     82 };
     83 #define BGP_OPEN_SIZE		29	/* unaligned */
     84 
     85 struct bgp_opt {
     86 	uint8_t bgpopt_type;
     87 	uint8_t bgpopt_len;
     88 	/* variable length */
     89 };
     90 #define BGP_OPT_SIZE		2	/* some compilers may pad to 4 bytes */
     91 #define BGP_CAP_HEADER_SIZE	2	/* some compilers may pad to 4 bytes */
     92 
     93 struct bgp_notification {
     94 	uint8_t bgpn_marker[16];
     95 	uint16_t bgpn_len;
     96 	uint8_t bgpn_type;
     97 	uint8_t bgpn_major;
     98 	uint8_t bgpn_minor;
     99 };
    100 #define BGP_NOTIFICATION_SIZE		21	/* unaligned */
    101 
    102 struct bgp_route_refresh {
    103     uint8_t  bgp_marker[16];
    104     uint16_t len;
    105     uint8_t  type;
    106     uint8_t  afi[2]; /* the compiler messes this structure up               */
    107     uint8_t  res;    /* when doing misaligned sequences of int8 and int16   */
    108     uint8_t  safi;   /* afi should be int16 - so we have to access it using */
    109 };                    /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh)      */
    110 #define BGP_ROUTE_REFRESH_SIZE          23
    111 
    112 #define bgp_attr_lenlen(flags, p) \
    113 	(((flags) & 0x10) ? 2 : 1)
    114 #define bgp_attr_len(flags, p) \
    115 	(((flags) & 0x10) ? EXTRACT_16BITS(p) : *(p))
    116 
    117 #define BGPTYPE_ORIGIN			1
    118 #define BGPTYPE_AS_PATH			2
    119 #define BGPTYPE_NEXT_HOP		3
    120 #define BGPTYPE_MULTI_EXIT_DISC		4
    121 #define BGPTYPE_LOCAL_PREF		5
    122 #define BGPTYPE_ATOMIC_AGGREGATE	6
    123 #define BGPTYPE_AGGREGATOR		7
    124 #define	BGPTYPE_COMMUNITIES		8	/* RFC1997 */
    125 #define	BGPTYPE_ORIGINATOR_ID		9	/* RFC4456 */
    126 #define	BGPTYPE_CLUSTER_LIST		10	/* RFC4456 */
    127 #define	BGPTYPE_DPA			11	/* deprecated, draft-ietf-idr-bgp-dpa */
    128 #define	BGPTYPE_ADVERTISERS		12	/* deprecated RFC1863 */
    129 #define	BGPTYPE_RCID_PATH		13	/* deprecated RFC1863 */
    130 #define BGPTYPE_MP_REACH_NLRI		14	/* RFC4760 */
    131 #define BGPTYPE_MP_UNREACH_NLRI		15	/* RFC4760 */
    132 #define BGPTYPE_EXTD_COMMUNITIES        16      /* RFC4360 */
    133 #define BGPTYPE_AS4_PATH	        17      /* RFC6793 */
    134 #define BGPTYPE_AGGREGATOR4		18      /* RFC6793 */
    135 #define BGPTYPE_PMSI_TUNNEL             22      /* RFC6514 */
    136 #define BGPTYPE_TUNNEL_ENCAP            23      /* RFC5512 */
    137 #define BGPTYPE_TRAFFIC_ENG             24      /* RFC5543 */
    138 #define BGPTYPE_IPV6_EXTD_COMMUNITIES   25      /* RFC5701 */
    139 #define BGPTYPE_AIGP                    26      /* RFC7311 */
    140 #define BGPTYPE_PE_DISTINGUISHER_LABEL  27      /* RFC6514 */
    141 #define BGPTYPE_ENTROPY_LABEL           28      /* RFC6790 */
    142 #define BGPTYPE_LARGE_COMMUNITY		32	/* draft-ietf-idr-large-community-05 */
    143 #define BGPTYPE_ATTR_SET               128      /* RFC6368 */
    144 
    145 #define BGP_MP_NLRI_MINSIZE              3       /* End of RIB Marker detection */
    146 
    147 static const struct tok bgp_attr_values[] = {
    148     { BGPTYPE_ORIGIN,           "Origin"},
    149     { BGPTYPE_AS_PATH,          "AS Path"},
    150     { BGPTYPE_AS4_PATH,         "AS4 Path"},
    151     { BGPTYPE_NEXT_HOP,         "Next Hop"},
    152     { BGPTYPE_MULTI_EXIT_DISC,  "Multi Exit Discriminator"},
    153     { BGPTYPE_LOCAL_PREF,       "Local Preference"},
    154     { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"},
    155     { BGPTYPE_AGGREGATOR,       "Aggregator"},
    156     { BGPTYPE_AGGREGATOR4,      "Aggregator4"},
    157     { BGPTYPE_COMMUNITIES,      "Community"},
    158     { BGPTYPE_ORIGINATOR_ID,    "Originator ID"},
    159     { BGPTYPE_CLUSTER_LIST,     "Cluster List"},
    160     { BGPTYPE_DPA,              "DPA"},
    161     { BGPTYPE_ADVERTISERS,      "Advertisers"},
    162     { BGPTYPE_RCID_PATH,        "RCID Path / Cluster ID"},
    163     { BGPTYPE_MP_REACH_NLRI,    "Multi-Protocol Reach NLRI"},
    164     { BGPTYPE_MP_UNREACH_NLRI,  "Multi-Protocol Unreach NLRI"},
    165     { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"},
    166     { BGPTYPE_PMSI_TUNNEL,      "PMSI Tunnel"},
    167     { BGPTYPE_TUNNEL_ENCAP,     "Tunnel Encapsulation"},
    168     { BGPTYPE_TRAFFIC_ENG,      "Traffic Engineering"},
    169     { BGPTYPE_IPV6_EXTD_COMMUNITIES, "IPv6 Extended Community"},
    170     { BGPTYPE_AIGP,             "Accumulated IGP Metric"},
    171     { BGPTYPE_PE_DISTINGUISHER_LABEL, "PE Distinguisher Label"},
    172     { BGPTYPE_ENTROPY_LABEL,    "Entropy Label"},
    173     { BGPTYPE_LARGE_COMMUNITY,  "Large Community"},
    174     { BGPTYPE_ATTR_SET,         "Attribute Set"},
    175     { 255,                      "Reserved for development"},
    176     { 0, NULL}
    177 };
    178 
    179 #define BGP_AS_SET             1
    180 #define BGP_AS_SEQUENCE        2
    181 #define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */
    182 #define BGP_CONFED_AS_SET      4 /* draft-ietf-idr-rfc3065bis-01  */
    183 
    184 #define BGP_AS_SEG_TYPE_MIN    BGP_AS_SET
    185 #define BGP_AS_SEG_TYPE_MAX    BGP_CONFED_AS_SET
    186 
    187 static const struct tok bgp_as_path_segment_open_values[] = {
    188     { BGP_AS_SEQUENCE,         ""},
    189     { BGP_AS_SET,              "{ "},
    190     { BGP_CONFED_AS_SEQUENCE,  "( "},
    191     { BGP_CONFED_AS_SET,       "({ "},
    192     { 0, NULL}
    193 };
    194 
    195 static const struct tok bgp_as_path_segment_close_values[] = {
    196     { BGP_AS_SEQUENCE,         ""},
    197     { BGP_AS_SET,              "}"},
    198     { BGP_CONFED_AS_SEQUENCE,  ")"},
    199     { BGP_CONFED_AS_SET,       "})"},
    200     { 0, NULL}
    201 };
    202 
    203 #define BGP_OPT_AUTH                    1
    204 #define BGP_OPT_CAP                     2
    205 
    206 static const struct tok bgp_opt_values[] = {
    207     { BGP_OPT_AUTH,             "Authentication Information"},
    208     { BGP_OPT_CAP,              "Capabilities Advertisement"},
    209     { 0, NULL}
    210 };
    211 
    212 #define BGP_CAPCODE_MP                  1 /* RFC2858 */
    213 #define BGP_CAPCODE_RR                  2 /* RFC2918 */
    214 #define BGP_CAPCODE_ORF                 3 /* RFC5291 */
    215 #define BGP_CAPCODE_MR                  4 /* RFC3107 */
    216 #define BGP_CAPCODE_EXT_NH              5 /* RFC5549 */
    217 #define BGP_CAPCODE_RESTART            64 /* RFC4724  */
    218 #define BGP_CAPCODE_AS_NEW             65 /* RFC6793 */
    219 #define BGP_CAPCODE_DYN_CAP            67 /* draft-ietf-idr-dynamic-cap */
    220 #define BGP_CAPCODE_MULTISESS          68 /* draft-ietf-idr-bgp-multisession */
    221 #define BGP_CAPCODE_ADD_PATH           69 /* RFC7911 */
    222 #define BGP_CAPCODE_ENH_RR             70 /* draft-keyur-bgp-enhanced-route-refresh */
    223 #define BGP_CAPCODE_RR_CISCO          128
    224 
    225 static const struct tok bgp_capcode_values[] = {
    226     { BGP_CAPCODE_MP,           "Multiprotocol Extensions"},
    227     { BGP_CAPCODE_RR,           "Route Refresh"},
    228     { BGP_CAPCODE_ORF,          "Cooperative Route Filtering"},
    229     { BGP_CAPCODE_MR,           "Multiple Routes to a Destination"},
    230     { BGP_CAPCODE_EXT_NH,       "Extended Next Hop Encoding"},
    231     { BGP_CAPCODE_RESTART,      "Graceful Restart"},
    232     { BGP_CAPCODE_AS_NEW,       "32-Bit AS Number"},
    233     { BGP_CAPCODE_DYN_CAP,      "Dynamic Capability"},
    234     { BGP_CAPCODE_MULTISESS,    "Multisession BGP"},
    235     { BGP_CAPCODE_ADD_PATH,     "Multiple Paths"},
    236     { BGP_CAPCODE_ENH_RR,       "Enhanced Route Refresh"},
    237     { BGP_CAPCODE_RR_CISCO,     "Route Refresh (Cisco)"},
    238     { 0, NULL}
    239 };
    240 
    241 #define BGP_NOTIFY_MAJOR_MSG            1
    242 #define BGP_NOTIFY_MAJOR_OPEN           2
    243 #define BGP_NOTIFY_MAJOR_UPDATE         3
    244 #define BGP_NOTIFY_MAJOR_HOLDTIME       4
    245 #define BGP_NOTIFY_MAJOR_FSM            5
    246 #define BGP_NOTIFY_MAJOR_CEASE          6
    247 #define BGP_NOTIFY_MAJOR_CAP            7
    248 
    249 static const struct tok bgp_notify_major_values[] = {
    250     { BGP_NOTIFY_MAJOR_MSG,     "Message Header Error"},
    251     { BGP_NOTIFY_MAJOR_OPEN,    "OPEN Message Error"},
    252     { BGP_NOTIFY_MAJOR_UPDATE,  "UPDATE Message Error"},
    253     { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"},
    254     { BGP_NOTIFY_MAJOR_FSM,     "Finite State Machine Error"},
    255     { BGP_NOTIFY_MAJOR_CEASE,   "Cease"},
    256     { BGP_NOTIFY_MAJOR_CAP,     "Capability Message Error"},
    257     { 0, NULL}
    258 };
    259 
    260 /* draft-ietf-idr-cease-subcode-02 */
    261 #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX  1
    262 static const struct tok bgp_notify_minor_cease_values[] = {
    263     { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"},
    264     { 2,                        "Administratively Shutdown"},
    265     { 3,                        "Peer Unconfigured"},
    266     { 4,                        "Administratively Reset"},
    267     { 5,                        "Connection Rejected"},
    268     { 6,                        "Other Configuration Change"},
    269     { 7,                        "Connection Collision Resolution"},
    270     { 0, NULL}
    271 };
    272 
    273 static const struct tok bgp_notify_minor_msg_values[] = {
    274     { 1,                        "Connection Not Synchronized"},
    275     { 2,                        "Bad Message Length"},
    276     { 3,                        "Bad Message Type"},
    277     { 0, NULL}
    278 };
    279 
    280 static const struct tok bgp_notify_minor_open_values[] = {
    281     { 1,                        "Unsupported Version Number"},
    282     { 2,                        "Bad Peer AS"},
    283     { 3,                        "Bad BGP Identifier"},
    284     { 4,                        "Unsupported Optional Parameter"},
    285     { 5,                        "Authentication Failure"},
    286     { 6,                        "Unacceptable Hold Time"},
    287     { 7,                        "Capability Message Error"},
    288     { 0, NULL}
    289 };
    290 
    291 static const struct tok bgp_notify_minor_update_values[] = {
    292     { 1,                        "Malformed Attribute List"},
    293     { 2,                        "Unrecognized Well-known Attribute"},
    294     { 3,                        "Missing Well-known Attribute"},
    295     { 4,                        "Attribute Flags Error"},
    296     { 5,                        "Attribute Length Error"},
    297     { 6,                        "Invalid ORIGIN Attribute"},
    298     { 7,                        "AS Routing Loop"},
    299     { 8,                        "Invalid NEXT_HOP Attribute"},
    300     { 9,                        "Optional Attribute Error"},
    301     { 10,                       "Invalid Network Field"},
    302     { 11,                       "Malformed AS_PATH"},
    303     { 0, NULL}
    304 };
    305 
    306 static const struct tok bgp_notify_minor_fsm_values[] = {
    307     { 1,                        "In OpenSent State"},
    308     { 2,                        "In OpenConfirm State"},
    309     { 3,                        "In Established State"},
    310     { 0, NULL }
    311 };
    312 
    313 static const struct tok bgp_notify_minor_cap_values[] = {
    314     { 1,                        "Invalid Action Value" },
    315     { 2,                        "Invalid Capability Length" },
    316     { 3,                        "Malformed Capability Value" },
    317     { 4,                        "Unsupported Capability Code" },
    318     { 0, NULL }
    319 };
    320 
    321 static const struct tok bgp_origin_values[] = {
    322     { 0,                        "IGP"},
    323     { 1,                        "EGP"},
    324     { 2,                        "Incomplete"},
    325     { 0, NULL}
    326 };
    327 
    328 #define BGP_PMSI_TUNNEL_RSVP_P2MP 1
    329 #define BGP_PMSI_TUNNEL_LDP_P2MP  2
    330 #define BGP_PMSI_TUNNEL_PIM_SSM   3
    331 #define BGP_PMSI_TUNNEL_PIM_SM    4
    332 #define BGP_PMSI_TUNNEL_PIM_BIDIR 5
    333 #define BGP_PMSI_TUNNEL_INGRESS   6
    334 #define BGP_PMSI_TUNNEL_LDP_MP2MP 7
    335 
    336 static const struct tok bgp_pmsi_tunnel_values[] = {
    337     { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"},
    338     { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"},
    339     { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"},
    340     { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"},
    341     { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"},
    342     { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"},
    343     { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"},
    344     { 0, NULL}
    345 };
    346 
    347 static const struct tok bgp_pmsi_flag_values[] = {
    348     { 0x01, "Leaf Information required"},
    349     { 0, NULL}
    350 };
    351 
    352 #define BGP_AIGP_TLV 1
    353 
    354 static const struct tok bgp_aigp_values[] = {
    355     { BGP_AIGP_TLV, "AIGP"},
    356     { 0, NULL}
    357 };
    358 
    359 /* Subsequent address family identifier, RFC2283 section 7 */
    360 #define SAFNUM_RES                      0
    361 #define SAFNUM_UNICAST                  1
    362 #define SAFNUM_MULTICAST                2
    363 #define SAFNUM_UNIMULTICAST             3       /* deprecated now */
    364 /* labeled BGP RFC3107 */
    365 #define SAFNUM_LABUNICAST               4
    366 /* RFC6514 */
    367 #define SAFNUM_MULTICAST_VPN            5
    368 /* draft-nalawade-kapoor-tunnel-safi */
    369 #define SAFNUM_TUNNEL                   64
    370 /* RFC4761 */
    371 #define SAFNUM_VPLS                     65
    372 /* RFC6037 */
    373 #define SAFNUM_MDT                      66
    374 /* RFC4364 */
    375 #define SAFNUM_VPNUNICAST               128
    376 /* RFC6513 */
    377 #define SAFNUM_VPNMULTICAST             129
    378 #define SAFNUM_VPNUNIMULTICAST          130     /* deprecated now */
    379 /* RFC4684 */
    380 #define SAFNUM_RT_ROUTING_INFO          132
    381 
    382 #define BGP_VPN_RD_LEN                  8
    383 
    384 static const struct tok bgp_safi_values[] = {
    385     { SAFNUM_RES,               "Reserved"},
    386     { SAFNUM_UNICAST,           "Unicast"},
    387     { SAFNUM_MULTICAST,         "Multicast"},
    388     { SAFNUM_UNIMULTICAST,      "Unicast+Multicast"},
    389     { SAFNUM_LABUNICAST,        "labeled Unicast"},
    390     { SAFNUM_TUNNEL,            "Tunnel"},
    391     { SAFNUM_VPLS,              "VPLS"},
    392     { SAFNUM_MDT,               "MDT"},
    393     { SAFNUM_VPNUNICAST,        "labeled VPN Unicast"},
    394     { SAFNUM_VPNMULTICAST,      "labeled VPN Multicast"},
    395     { SAFNUM_VPNUNIMULTICAST,   "labeled VPN Unicast+Multicast"},
    396     { SAFNUM_RT_ROUTING_INFO,   "Route Target Routing Information"},
    397     { SAFNUM_MULTICAST_VPN,     "Multicast VPN"},
    398     { 0, NULL }
    399 };
    400 
    401 /* well-known community */
    402 #define BGP_COMMUNITY_NO_EXPORT			0xffffff01
    403 #define BGP_COMMUNITY_NO_ADVERT			0xffffff02
    404 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED	0xffffff03
    405 
    406 /* Extended community type - draft-ietf-idr-bgp-ext-communities-05 */
    407 #define BGP_EXT_COM_RT_0        0x0002  /* Route Target,Format AS(2bytes):AN(4bytes) */
    408 #define BGP_EXT_COM_RT_1        0x0102  /* Route Target,Format IP address:AN(2bytes) */
    409 #define BGP_EXT_COM_RT_2        0x0202  /* Route Target,Format AN(4bytes):local(2bytes) */
    410 #define BGP_EXT_COM_RO_0        0x0003  /* Route Origin,Format AS(2bytes):AN(4bytes) */
    411 #define BGP_EXT_COM_RO_1        0x0103  /* Route Origin,Format IP address:AN(2bytes) */
    412 #define BGP_EXT_COM_RO_2        0x0203  /* Route Origin,Format AN(4bytes):local(2bytes) */
    413 #define BGP_EXT_COM_LINKBAND    0x4004  /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */
    414                                         /* rfc2547 bgp-mpls-vpns */
    415 #define BGP_EXT_COM_VPN_ORIGIN  0x0005  /* OSPF Domain ID / VPN of Origin  - draft-rosen-vpns-ospf-bgp-mpls */
    416 #define BGP_EXT_COM_VPN_ORIGIN2 0x0105  /* duplicate - keep for backwards compatability */
    417 #define BGP_EXT_COM_VPN_ORIGIN3 0x0205  /* duplicate - keep for backwards compatability */
    418 #define BGP_EXT_COM_VPN_ORIGIN4 0x8005  /* duplicate - keep for backwards compatability */
    419 
    420 #define BGP_EXT_COM_OSPF_RTYPE  0x0306  /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */
    421 #define BGP_EXT_COM_OSPF_RTYPE2 0x8000  /* duplicate - keep for backwards compatability */
    422 
    423 #define BGP_EXT_COM_OSPF_RID    0x0107  /* OSPF Router ID,Format RouterID(4B):Unused(2B) */
    424 #define BGP_EXT_COM_OSPF_RID2   0x8001  /* duplicate - keep for backwards compatability */
    425 
    426 #define BGP_EXT_COM_L2INFO      0x800a  /* draft-kompella-ppvpn-l2vpn */
    427 
    428 #define BGP_EXT_COM_SOURCE_AS   0x0009  /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
    429 #define BGP_EXT_COM_VRF_RT_IMP  0x010b  /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
    430 #define BGP_EXT_COM_L2VPN_RT_0  0x000a  /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */
    431 #define BGP_EXT_COM_L2VPN_RT_1  0xF10a  /* L2VPN Identifier,Format IP address:AN(2bytes) */
    432 
    433 /* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml  */
    434 #define BGP_EXT_COM_EIGRP_GEN   0x8800
    435 #define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY  0x8801
    436 #define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802
    437 #define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU  0x8803
    438 #define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID  0x8804
    439 #define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805
    440 
    441 static const struct tok bgp_extd_comm_flag_values[] = {
    442     { 0x8000,                  "vendor-specific"},
    443     { 0x4000,                  "non-transitive"},
    444     { 0, NULL},
    445 };
    446 
    447 static const struct tok bgp_extd_comm_subtype_values[] = {
    448     { BGP_EXT_COM_RT_0,        "target"},
    449     { BGP_EXT_COM_RT_1,        "target"},
    450     { BGP_EXT_COM_RT_2,        "target"},
    451     { BGP_EXT_COM_RO_0,        "origin"},
    452     { BGP_EXT_COM_RO_1,        "origin"},
    453     { BGP_EXT_COM_RO_2,        "origin"},
    454     { BGP_EXT_COM_LINKBAND,    "link-BW"},
    455     { BGP_EXT_COM_VPN_ORIGIN,  "ospf-domain"},
    456     { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"},
    457     { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"},
    458     { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"},
    459     { BGP_EXT_COM_OSPF_RTYPE,  "ospf-route-type"},
    460     { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"},
    461     { BGP_EXT_COM_OSPF_RID,    "ospf-router-id"},
    462     { BGP_EXT_COM_OSPF_RID2,   "ospf-router-id"},
    463     { BGP_EXT_COM_L2INFO,      "layer2-info"},
    464     { BGP_EXT_COM_EIGRP_GEN , "eigrp-general-route (flag, tag)" },
    465     { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY , "eigrp-route-metric (AS, delay)" },
    466     { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW , "eigrp-route-metric (reliability, nexthop, bandwidth)" },
    467     { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU , "eigrp-route-metric (load, MTU)" },
    468     { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID , "eigrp-external-route (remote-AS, remote-ID)" },
    469     { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" },
    470     { BGP_EXT_COM_SOURCE_AS, "source-AS" },
    471     { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"},
    472     { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"},
    473     { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"},
    474     { 0, NULL},
    475 };
    476 
    477 /* OSPF codes for  BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls  */
    478 #define BGP_OSPF_RTYPE_RTR      1 /* OSPF Router LSA */
    479 #define BGP_OSPF_RTYPE_NET      2 /* OSPF Network LSA */
    480 #define BGP_OSPF_RTYPE_SUM      3 /* OSPF Summary LSA */
    481 #define BGP_OSPF_RTYPE_EXT      5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */
    482 #define BGP_OSPF_RTYPE_NSSA     7 /* OSPF NSSA External*/
    483 #define BGP_OSPF_RTYPE_SHAM     129 /* OSPF-MPLS-VPN Sham link */
    484 #define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */
    485 
    486 static const struct tok bgp_extd_comm_ospf_rtype_values[] = {
    487   { BGP_OSPF_RTYPE_RTR, "Router" },
    488   { BGP_OSPF_RTYPE_NET, "Network" },
    489   { BGP_OSPF_RTYPE_SUM, "Summary" },
    490   { BGP_OSPF_RTYPE_EXT, "External" },
    491   { BGP_OSPF_RTYPE_NSSA,"NSSA External" },
    492   { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" },
    493   { 0, NULL },
    494 };
    495 
    496 /* ADD-PATH Send/Receive field values */
    497 static const struct tok bgp_add_path_recvsend[] = {
    498   { 1, "Receive" },
    499   { 2, "Send" },
    500   { 3, "Both" },
    501   { 0, NULL },
    502 };
    503 
    504 static char astostr[20];
    505 
    506 /*
    507  * as_printf
    508  *
    509  * Convert an AS number into a string and return string pointer.
    510  *
    511  * Depending on bflag is set or not, AS number is converted into ASDOT notation
    512  * or plain number notation.
    513  *
    514  */
    515 static char *
    516 as_printf(netdissect_options *ndo,
    517           char *str, int size, u_int asnum)
    518 {
    519 	if (!ndo->ndo_bflag || asnum <= 0xFFFF) {
    520 		snprintf(str, size, "%u", asnum);
    521 	} else {
    522 		snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF);
    523 	}
    524 	return str;
    525 }
    526 
    527 #define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv;
    528 
    529 int
    530 decode_prefix4(netdissect_options *ndo,
    531                const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
    532 {
    533 	struct in_addr addr;
    534 	u_int plen, plenbytes;
    535 
    536 	ND_TCHECK(pptr[0]);
    537 	ITEMCHECK(1);
    538 	plen = pptr[0];
    539 	if (32 < plen)
    540 		return -1;
    541 	itemlen -= 1;
    542 
    543 	memset(&addr, 0, sizeof(addr));
    544 	plenbytes = (plen + 7) / 8;
    545 	ND_TCHECK2(pptr[1], plenbytes);
    546 	ITEMCHECK(plenbytes);
    547 	memcpy(&addr, &pptr[1], plenbytes);
    548 	if (plen % 8) {
    549 		((u_char *)&addr)[plenbytes - 1] &=
    550 			((0xff00 >> (plen % 8)) & 0xff);
    551 	}
    552 	snprintf(buf, buflen, "%s/%d", ipaddr_string(ndo, &addr), plen);
    553 	return 1 + plenbytes;
    554 
    555 trunc:
    556 	return -2;
    557 
    558 badtlv:
    559 	return -3;
    560 }
    561 
    562 static int
    563 decode_labeled_prefix4(netdissect_options *ndo,
    564                        const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
    565 {
    566 	struct in_addr addr;
    567 	u_int plen, plenbytes;
    568 
    569 	/* prefix length and label = 4 bytes */
    570 	ND_TCHECK2(pptr[0], 4);
    571 	ITEMCHECK(4);
    572 	plen = pptr[0];   /* get prefix length */
    573 
    574         /* this is one of the weirdnesses of rfc3107
    575            the label length (actually the label + COS bits)
    576            is added to the prefix length;
    577            we also do only read out just one label -
    578            there is no real application for advertisement of
    579            stacked labels in a single BGP message
    580         */
    581 
    582 	if (24 > plen)
    583 		return -1;
    584 
    585         plen-=24; /* adjust prefixlen - labellength */
    586 
    587 	if (32 < plen)
    588 		return -1;
    589 	itemlen -= 4;
    590 
    591 	memset(&addr, 0, sizeof(addr));
    592 	plenbytes = (plen + 7) / 8;
    593 	ND_TCHECK2(pptr[4], plenbytes);
    594 	ITEMCHECK(plenbytes);
    595 	memcpy(&addr, &pptr[4], plenbytes);
    596 	if (plen % 8) {
    597 		((u_char *)&addr)[plenbytes - 1] &=
    598 			((0xff00 >> (plen % 8)) & 0xff);
    599 	}
    600         /* the label may get offsetted by 4 bits so lets shift it right */
    601 	snprintf(buf, buflen, "%s/%d, label:%u %s",
    602                  ipaddr_string(ndo, &addr),
    603                  plen,
    604                  EXTRACT_24BITS(pptr+1)>>4,
    605                  ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
    606 
    607 	return 4 + plenbytes;
    608 
    609 trunc:
    610 	return -2;
    611 
    612 badtlv:
    613 	return -3;
    614 }
    615 
    616 /*
    617  * bgp_vpn_ip_print
    618  *
    619  * print an ipv4 or ipv6 address into a buffer dependend on address length.
    620  */
    621 static char *
    622 bgp_vpn_ip_print(netdissect_options *ndo,
    623                  const u_char *pptr, u_int addr_length)
    624 {
    625 
    626     /* worst case string is s fully formatted v6 address */
    627     static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")];
    628     char *pos = addr;
    629 
    630     switch(addr_length) {
    631     case (sizeof(struct in_addr) << 3): /* 32 */
    632         ND_TCHECK2(pptr[0], sizeof(struct in_addr));
    633         snprintf(pos, sizeof(addr), "%s", ipaddr_string(ndo, pptr));
    634         break;
    635     case (sizeof(struct in6_addr) << 3): /* 128 */
    636         ND_TCHECK2(pptr[0], sizeof(struct in6_addr));
    637         snprintf(pos, sizeof(addr), "%s", ip6addr_string(ndo, pptr));
    638         break;
    639     default:
    640         snprintf(pos, sizeof(addr), "bogus address length %u", addr_length);
    641         break;
    642     }
    643     pos += strlen(pos);
    644 
    645 trunc:
    646     *(pos) = '\0';
    647     return (addr);
    648 }
    649 
    650 /*
    651  * bgp_vpn_sg_print
    652  *
    653  * print an multicast s,g entry into a buffer.
    654  * the s,g entry is encoded like this.
    655  *
    656  * +-----------------------------------+
    657  * | Multicast Source Length (1 octet) |
    658  * +-----------------------------------+
    659  * |   Multicast Source (Variable)     |
    660  * +-----------------------------------+
    661  * |  Multicast Group Length (1 octet) |
    662  * +-----------------------------------+
    663  * |  Multicast Group   (Variable)     |
    664  * +-----------------------------------+
    665  *
    666  * return the number of bytes read from the wire.
    667  */
    668 static int
    669 bgp_vpn_sg_print(netdissect_options *ndo,
    670                  const u_char *pptr, char *buf, u_int buflen)
    671 {
    672     uint8_t addr_length;
    673     u_int total_length, offset;
    674 
    675     total_length = 0;
    676 
    677     /* Source address length, encoded in bits */
    678     ND_TCHECK2(pptr[0], 1);
    679     addr_length =  *pptr++;
    680 
    681     /* Source address */
    682     ND_TCHECK2(pptr[0], (addr_length >> 3));
    683     total_length += (addr_length >> 3) + 1;
    684     offset = strlen(buf);
    685     if (addr_length) {
    686         snprintf(buf + offset, buflen - offset, ", Source %s",
    687                  bgp_vpn_ip_print(ndo, pptr, addr_length));
    688         pptr += (addr_length >> 3);
    689     }
    690 
    691     /* Group address length, encoded in bits */
    692     ND_TCHECK2(pptr[0], 1);
    693     addr_length =  *pptr++;
    694 
    695     /* Group address */
    696     ND_TCHECK2(pptr[0], (addr_length >> 3));
    697     total_length += (addr_length >> 3) + 1;
    698     offset = strlen(buf);
    699     if (addr_length) {
    700         snprintf(buf + offset, buflen - offset, ", Group %s",
    701                  bgp_vpn_ip_print(ndo, pptr, addr_length));
    702         pptr += (addr_length >> 3);
    703     }
    704 
    705 trunc:
    706     return (total_length);
    707 }
    708 
    709 /* RDs and RTs share the same semantics
    710  * we use bgp_vpn_rd_print for
    711  * printing route targets inside a NLRI */
    712 char *
    713 bgp_vpn_rd_print(netdissect_options *ndo,
    714                  const u_char *pptr)
    715 {
    716    /* allocate space for the largest possible string */
    717     static char rd[sizeof("xxxxxxxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")];
    718     char *pos = rd;
    719 
    720     /* ok lets load the RD format */
    721     switch (EXTRACT_16BITS(pptr)) {
    722 
    723         /* 2-byte-AS:number fmt*/
    724     case 0:
    725         snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)",
    726                  EXTRACT_16BITS(pptr+2),
    727                  EXTRACT_32BITS(pptr+4),
    728                  *(pptr+4), *(pptr+5), *(pptr+6), *(pptr+7));
    729         break;
    730         /* IP-address:AS fmt*/
    731 
    732     case 1:
    733         snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u",
    734             *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6));
    735         break;
    736 
    737         /* 4-byte-AS:number fmt*/
    738     case 2:
    739 	snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)",
    740 	    as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)),
    741 	    EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4),
    742 	    *(pptr+5), EXTRACT_16BITS(pptr+6));
    743         break;
    744     default:
    745         snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format");
    746         break;
    747     }
    748     pos += strlen(pos);
    749     *(pos) = '\0';
    750     return (rd);
    751 }
    752 
    753 static int
    754 decode_rt_routing_info(netdissect_options *ndo,
    755                        const u_char *pptr, char *buf, u_int buflen)
    756 {
    757 	uint8_t route_target[8];
    758 	u_int plen;
    759 	char asbuf[sizeof(astostr)]; /* bgp_vpn_rd_print() overwrites astostr */
    760 
    761 	/* NLRI "prefix length" from RFC 2858 Section 4. */
    762 	ND_TCHECK(pptr[0]);
    763 	plen = pptr[0];   /* get prefix length */
    764 
    765 	/* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits.
    766 	 * RFC 4684 Section 4 defines the layout of "origin AS" and "route
    767 	 * target" fields inside the "prefix" depending on its length.
    768 	 */
    769 	if (0 == plen) {
    770 		/* Without "origin AS", without "route target". */
    771 		snprintf(buf, buflen, "default route target");
    772 		return 1;
    773 	}
    774 
    775 	if (32 > plen)
    776 		return -1;
    777 
    778 	/* With at least "origin AS", possibly with "route target". */
    779 	ND_TCHECK_32BITS(pptr + 1);
    780 	as_printf(ndo, asbuf, sizeof(asbuf), EXTRACT_32BITS(pptr + 1));
    781 
    782         plen-=32; /* adjust prefix length */
    783 
    784 	if (64 < plen)
    785 		return -1;
    786 
    787 	/* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 }
    788 	 * and gives the number of octets in the variable-length "route
    789 	 * target" field inside this NLRI "prefix". Look for it.
    790 	 */
    791 	memset(&route_target, 0, sizeof(route_target));
    792 	ND_TCHECK2(pptr[5], (plen + 7) / 8);
    793 	memcpy(&route_target, &pptr[5], (plen + 7) / 8);
    794 	/* Which specification says to do this? */
    795 	if (plen % 8) {
    796 		((u_char *)&route_target)[(plen + 7) / 8 - 1] &=
    797 			((0xff00 >> (plen % 8)) & 0xff);
    798 	}
    799 	snprintf(buf, buflen, "origin AS: %s, route target %s",
    800 	    asbuf,
    801 	    bgp_vpn_rd_print(ndo, (u_char *)&route_target));
    802 
    803 	return 5 + (plen + 7) / 8;
    804 
    805 trunc:
    806 	return -2;
    807 }
    808 
    809 static int
    810 decode_labeled_vpn_prefix4(netdissect_options *ndo,
    811                            const u_char *pptr, char *buf, u_int buflen)
    812 {
    813 	struct in_addr addr;
    814 	u_int plen;
    815 
    816 	ND_TCHECK(pptr[0]);
    817 	plen = pptr[0];   /* get prefix length */
    818 
    819 	if ((24+64) > plen)
    820 		return -1;
    821 
    822         plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
    823 
    824 	if (32 < plen)
    825 		return -1;
    826 
    827 	memset(&addr, 0, sizeof(addr));
    828 	ND_TCHECK2(pptr[12], (plen + 7) / 8);
    829 	memcpy(&addr, &pptr[12], (plen + 7) / 8);
    830 	if (plen % 8) {
    831 		((u_char *)&addr)[(plen + 7) / 8 - 1] &=
    832 			((0xff00 >> (plen % 8)) & 0xff);
    833 	}
    834         /* the label may get offsetted by 4 bits so lets shift it right */
    835 	snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
    836                  bgp_vpn_rd_print(ndo, pptr+4),
    837                  ipaddr_string(ndo, &addr),
    838                  plen,
    839                  EXTRACT_24BITS(pptr+1)>>4,
    840                  ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
    841 
    842 	return 12 + (plen + 7) / 8;
    843 
    844 trunc:
    845 	return -2;
    846 }
    847 
    848 /*
    849  * +-------------------------------+
    850  * |                               |
    851  * |  RD:IPv4-address (12 octets)  |
    852  * |                               |
    853  * +-------------------------------+
    854  * |  MDT Group-address (4 octets) |
    855  * +-------------------------------+
    856  */
    857 
    858 #define MDT_VPN_NLRI_LEN 16
    859 
    860 static int
    861 decode_mdt_vpn_nlri(netdissect_options *ndo,
    862                     const u_char *pptr, char *buf, u_int buflen)
    863 {
    864 
    865     const u_char *rd;
    866     const u_char *vpn_ip;
    867 
    868     ND_TCHECK(pptr[0]);
    869 
    870     /* if the NLRI is not predefined length, quit.*/
    871     if (*pptr != MDT_VPN_NLRI_LEN * 8)
    872 	return -1;
    873     pptr++;
    874 
    875     /* RD */
    876     ND_TCHECK2(pptr[0], 8);
    877     rd = pptr;
    878     pptr+=8;
    879 
    880     /* IPv4 address */
    881     ND_TCHECK2(pptr[0], sizeof(struct in_addr));
    882     vpn_ip = pptr;
    883     pptr+=sizeof(struct in_addr);
    884 
    885     /* MDT Group Address */
    886     ND_TCHECK2(pptr[0], sizeof(struct in_addr));
    887 
    888     snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s",
    889 	     bgp_vpn_rd_print(ndo, rd), ipaddr_string(ndo, vpn_ip), ipaddr_string(ndo, pptr));
    890 
    891     return MDT_VPN_NLRI_LEN + 1;
    892 
    893  trunc:
    894 
    895 return -2;
    896 }
    897 
    898 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI   1
    899 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI   2
    900 #define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI            3
    901 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4
    902 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE     5
    903 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN  6
    904 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN  7
    905 
    906 static const struct tok bgp_multicast_vpn_route_type_values[] = {
    907     { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"},
    908     { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"},
    909     { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"},
    910     { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"},
    911     { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"},
    912     { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"},
    913     { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"},
    914     { 0, NULL}
    915 };
    916 
    917 static int
    918 decode_multicast_vpn(netdissect_options *ndo,
    919                      const u_char *pptr, char *buf, u_int buflen)
    920 {
    921         uint8_t route_type, route_length, addr_length, sg_length;
    922         u_int offset;
    923 
    924 	ND_TCHECK2(pptr[0], 2);
    925         route_type = *pptr++;
    926         route_length = *pptr++;
    927 
    928         snprintf(buf, buflen, "Route-Type: %s (%u), length: %u",
    929                  tok2str(bgp_multicast_vpn_route_type_values,
    930                          "Unknown", route_type),
    931                  route_type, route_length);
    932 
    933         switch(route_type) {
    934         case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI:
    935             ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
    936             offset = strlen(buf);
    937             snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s",
    938                      bgp_vpn_rd_print(ndo, pptr),
    939                      bgp_vpn_ip_print(ndo, pptr + BGP_VPN_RD_LEN,
    940                                       (route_length - BGP_VPN_RD_LEN) << 3));
    941             break;
    942         case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI:
    943             ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
    944             offset = strlen(buf);
    945 	    snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
    946 		bgp_vpn_rd_print(ndo, pptr),
    947 		as_printf(ndo, astostr, sizeof(astostr),
    948 		EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
    949             break;
    950 
    951         case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI:
    952             ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
    953             offset = strlen(buf);
    954             snprintf(buf + offset, buflen - offset, ", RD: %s",
    955                      bgp_vpn_rd_print(ndo, pptr));
    956             pptr += BGP_VPN_RD_LEN;
    957 
    958             sg_length = bgp_vpn_sg_print(ndo, pptr, buf, buflen);
    959             addr_length =  route_length - sg_length;
    960 
    961             ND_TCHECK2(pptr[0], addr_length);
    962             offset = strlen(buf);
    963             snprintf(buf + offset, buflen - offset, ", Originator %s",
    964                      bgp_vpn_ip_print(ndo, pptr, addr_length << 3));
    965             break;
    966 
    967         case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE:
    968             ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN);
    969             offset = strlen(buf);
    970             snprintf(buf + offset, buflen - offset, ", RD: %s",
    971                      bgp_vpn_rd_print(ndo, pptr));
    972             pptr += BGP_VPN_RD_LEN;
    973 
    974             bgp_vpn_sg_print(ndo, pptr, buf, buflen);
    975             break;
    976 
    977         case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */
    978         case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
    979             ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
    980             offset = strlen(buf);
    981 	    snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
    982 		bgp_vpn_rd_print(ndo, pptr),
    983 		as_printf(ndo, astostr, sizeof(astostr),
    984 		EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
    985             pptr += BGP_VPN_RD_LEN + 4;
    986 
    987             bgp_vpn_sg_print(ndo, pptr, buf, buflen);
    988             break;
    989 
    990             /*
    991              * no per route-type printing yet.
    992              */
    993         case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF:
    994         default:
    995             break;
    996         }
    997 
    998         return route_length + 2;
    999 
   1000 trunc:
   1001 	return -2;
   1002 }
   1003 
   1004 /*
   1005  * As I remember, some versions of systems have an snprintf() that
   1006  * returns -1 if the buffer would have overflowed.  If the return
   1007  * value is negative, set buflen to 0, to indicate that we've filled
   1008  * the buffer up.
   1009  *
   1010  * If the return value is greater than buflen, that means that
   1011  * the buffer would have overflowed; again, set buflen to 0 in
   1012  * that case.
   1013  */
   1014 #define UPDATE_BUF_BUFLEN(buf, buflen, stringlen) \
   1015     if (stringlen<0) \
   1016        	buflen=0; \
   1017     else if ((u_int)stringlen>buflen) \
   1018         buflen=0; \
   1019     else { \
   1020         buflen-=stringlen; \
   1021 	buf+=stringlen; \
   1022     }
   1023 
   1024 static int
   1025 decode_labeled_vpn_l2(netdissect_options *ndo,
   1026                       const u_char *pptr, char *buf, u_int buflen)
   1027 {
   1028         int plen,tlen,stringlen,tlv_type,tlv_len,ttlv_len;
   1029 
   1030 	ND_TCHECK2(pptr[0], 2);
   1031         plen=EXTRACT_16BITS(pptr);
   1032         tlen=plen;
   1033         pptr+=2;
   1034 	/* Old and new L2VPN NLRI share AFI/SAFI
   1035          *   -> Assume a 12 Byte-length NLRI is auto-discovery-only
   1036          *      and > 17 as old format. Complain for the middle case
   1037          */
   1038         if (plen==12) {
   1039 	    /* assume AD-only with RD, BGPNH */
   1040 	    ND_TCHECK2(pptr[0],12);
   1041 	    buf[0]='\0';
   1042 	    stringlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s",
   1043 			       bgp_vpn_rd_print(ndo, pptr),
   1044 			       ipaddr_string(ndo, pptr+8)
   1045 			       );
   1046 	    UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
   1047 	    pptr+=12;
   1048 	    tlen-=12;
   1049 	    return plen;
   1050         } else if (plen>17) {
   1051 	    /* assume old format */
   1052 	    /* RD, ID, LBLKOFF, LBLBASE */
   1053 
   1054 	    ND_TCHECK2(pptr[0],15);
   1055 	    buf[0]='\0';
   1056 	    stringlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u",
   1057 			       bgp_vpn_rd_print(ndo, pptr),
   1058 			       EXTRACT_16BITS(pptr+8),
   1059 			       EXTRACT_16BITS(pptr+10),
   1060 			       EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */
   1061 	    UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
   1062 	    pptr+=15;
   1063 	    tlen-=15;
   1064 
   1065 	    /* ok now the variable part - lets read out TLVs*/
   1066 	    while (tlen>0) {
   1067 		if (tlen < 3)
   1068 		    return -1;
   1069 		ND_TCHECK2(pptr[0], 3);
   1070 		tlv_type=*pptr++;
   1071 		tlv_len=EXTRACT_16BITS(pptr);
   1072 		ttlv_len=tlv_len;
   1073 		pptr+=2;
   1074 
   1075 		switch(tlv_type) {
   1076 		case 1:
   1077 		    if (buflen!=0) {
   1078 			stringlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x",
   1079 					   tlv_type,
   1080 					   tlv_len);
   1081 			UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
   1082 		    }
   1083 		    ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */
   1084 		    while (ttlv_len>0) {
   1085 			ND_TCHECK(pptr[0]);
   1086 			if (buflen!=0) {
   1087 			    stringlen=snprintf(buf,buflen, "%02x",*pptr++);
   1088 			    UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
   1089 			}
   1090 			ttlv_len--;
   1091 		    }
   1092 		    break;
   1093 		default:
   1094 		    if (buflen!=0) {
   1095 			stringlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u",
   1096 					   tlv_type,
   1097 					   tlv_len);
   1098 			UPDATE_BUF_BUFLEN(buf, buflen, stringlen);
   1099 		    }
   1100 		    break;
   1101 		}
   1102 		tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */
   1103 	    }
   1104 	    return plen+2;
   1105 
   1106         } else {
   1107 	    /* complain bitterly ? */
   1108 	    /* fall through */
   1109             goto trunc;
   1110         }
   1111 
   1112 trunc:
   1113         return -2;
   1114 }
   1115 
   1116 int
   1117 decode_prefix6(netdissect_options *ndo,
   1118                const u_char *pd, u_int itemlen, char *buf, u_int buflen)
   1119 {
   1120 	struct in6_addr addr;
   1121 	u_int plen, plenbytes;
   1122 
   1123 	ND_TCHECK(pd[0]);
   1124 	ITEMCHECK(1);
   1125 	plen = pd[0];
   1126 	if (128 < plen)
   1127 		return -1;
   1128 	itemlen -= 1;
   1129 
   1130 	memset(&addr, 0, sizeof(addr));
   1131 	plenbytes = (plen + 7) / 8;
   1132 	ND_TCHECK2(pd[1], plenbytes);
   1133 	ITEMCHECK(plenbytes);
   1134 	memcpy(&addr, &pd[1], plenbytes);
   1135 	if (plen % 8) {
   1136 		addr.s6_addr[plenbytes - 1] &=
   1137 			((0xff00 >> (plen % 8)) & 0xff);
   1138 	}
   1139 	snprintf(buf, buflen, "%s/%d", ip6addr_string(ndo, &addr), plen);
   1140 	return 1 + plenbytes;
   1141 
   1142 trunc:
   1143 	return -2;
   1144 
   1145 badtlv:
   1146 	return -3;
   1147 }
   1148 
   1149 static int
   1150 decode_labeled_prefix6(netdissect_options *ndo,
   1151                        const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
   1152 {
   1153 	struct in6_addr addr;
   1154 	u_int plen, plenbytes;
   1155 
   1156 	/* prefix length and label = 4 bytes */
   1157 	ND_TCHECK2(pptr[0], 4);
   1158 	ITEMCHECK(4);
   1159 	plen = pptr[0]; /* get prefix length */
   1160 
   1161 	if (24 > plen)
   1162 		return -1;
   1163 
   1164         plen-=24; /* adjust prefixlen - labellength */
   1165 
   1166 	if (128 < plen)
   1167 		return -1;
   1168 	itemlen -= 4;
   1169 
   1170 	memset(&addr, 0, sizeof(addr));
   1171 	plenbytes = (plen + 7) / 8;
   1172 	ND_TCHECK2(pptr[4], plenbytes);
   1173 	memcpy(&addr, &pptr[4], plenbytes);
   1174 	if (plen % 8) {
   1175 		addr.s6_addr[plenbytes - 1] &=
   1176 			((0xff00 >> (plen % 8)) & 0xff);
   1177 	}
   1178         /* the label may get offsetted by 4 bits so lets shift it right */
   1179 	snprintf(buf, buflen, "%s/%d, label:%u %s",
   1180                  ip6addr_string(ndo, &addr),
   1181                  plen,
   1182                  EXTRACT_24BITS(pptr+1)>>4,
   1183                  ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
   1184 
   1185 	return 4 + plenbytes;
   1186 
   1187 trunc:
   1188 	return -2;
   1189 
   1190 badtlv:
   1191 	return -3;
   1192 }
   1193 
   1194 static int
   1195 decode_labeled_vpn_prefix6(netdissect_options *ndo,
   1196                            const u_char *pptr, char *buf, u_int buflen)
   1197 {
   1198 	struct in6_addr addr;
   1199 	u_int plen;
   1200 
   1201 	ND_TCHECK(pptr[0]);
   1202 	plen = pptr[0];   /* get prefix length */
   1203 
   1204 	if ((24+64) > plen)
   1205 		return -1;
   1206 
   1207         plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
   1208 
   1209 	if (128 < plen)
   1210 		return -1;
   1211 
   1212 	memset(&addr, 0, sizeof(addr));
   1213 	ND_TCHECK2(pptr[12], (plen + 7) / 8);
   1214 	memcpy(&addr, &pptr[12], (plen + 7) / 8);
   1215 	if (plen % 8) {
   1216 		addr.s6_addr[(plen + 7) / 8 - 1] &=
   1217 			((0xff00 >> (plen % 8)) & 0xff);
   1218 	}
   1219         /* the label may get offsetted by 4 bits so lets shift it right */
   1220 	snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
   1221                  bgp_vpn_rd_print(ndo, pptr+4),
   1222                  ip6addr_string(ndo, &addr),
   1223                  plen,
   1224                  EXTRACT_24BITS(pptr+1)>>4,
   1225                  ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
   1226 
   1227 	return 12 + (plen + 7) / 8;
   1228 
   1229 trunc:
   1230 	return -2;
   1231 }
   1232 
   1233 static int
   1234 decode_clnp_prefix(netdissect_options *ndo,
   1235                    const u_char *pptr, char *buf, u_int buflen)
   1236 {
   1237         uint8_t addr[19];
   1238 	u_int plen;
   1239 
   1240 	ND_TCHECK(pptr[0]);
   1241 	plen = pptr[0]; /* get prefix length */
   1242 
   1243 	if (152 < plen)
   1244 		return -1;
   1245 
   1246 	memset(&addr, 0, sizeof(addr));
   1247 	ND_TCHECK2(pptr[4], (plen + 7) / 8);
   1248 	memcpy(&addr, &pptr[4], (plen + 7) / 8);
   1249 	if (plen % 8) {
   1250 		addr[(plen + 7) / 8 - 1] &=
   1251 			((0xff00 >> (plen % 8)) & 0xff);
   1252 	}
   1253 	snprintf(buf, buflen, "%s/%d",
   1254                  isonsap_string(ndo, addr,(plen + 7) / 8),
   1255                  plen);
   1256 
   1257 	return 1 + (plen + 7) / 8;
   1258 
   1259 trunc:
   1260 	return -2;
   1261 }
   1262 
   1263 static int
   1264 decode_labeled_vpn_clnp_prefix(netdissect_options *ndo,
   1265                                const u_char *pptr, char *buf, u_int buflen)
   1266 {
   1267         uint8_t addr[19];
   1268 	u_int plen;
   1269 
   1270 	ND_TCHECK(pptr[0]);
   1271 	plen = pptr[0];   /* get prefix length */
   1272 
   1273 	if ((24+64) > plen)
   1274 		return -1;
   1275 
   1276         plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
   1277 
   1278 	if (152 < plen)
   1279 		return -1;
   1280 
   1281 	memset(&addr, 0, sizeof(addr));
   1282 	ND_TCHECK2(pptr[12], (plen + 7) / 8);
   1283 	memcpy(&addr, &pptr[12], (plen + 7) / 8);
   1284 	if (plen % 8) {
   1285 		addr[(plen + 7) / 8 - 1] &=
   1286 			((0xff00 >> (plen % 8)) & 0xff);
   1287 	}
   1288         /* the label may get offsetted by 4 bits so lets shift it right */
   1289 	snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
   1290                  bgp_vpn_rd_print(ndo, pptr+4),
   1291                  isonsap_string(ndo, addr,(plen + 7) / 8),
   1292                  plen,
   1293                  EXTRACT_24BITS(pptr+1)>>4,
   1294                  ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
   1295 
   1296 	return 12 + (plen + 7) / 8;
   1297 
   1298 trunc:
   1299 	return -2;
   1300 }
   1301 
   1302 /*
   1303  * bgp_attr_get_as_size
   1304  *
   1305  * Try to find the size of the ASs encoded in an as-path. It is not obvious, as
   1306  * both Old speakers that do not support 4 byte AS, and the new speakers that do
   1307  * support, exchange AS-Path with the same path-attribute type value 0x02.
   1308  */
   1309 static int
   1310 bgp_attr_get_as_size(netdissect_options *ndo,
   1311                      uint8_t bgpa_type, const u_char *pptr, int len)
   1312 {
   1313     const u_char *tptr = pptr;
   1314 
   1315     /*
   1316      * If the path attribute is the optional AS4 path type, then we already
   1317      * know, that ASs must be encoded in 4 byte format.
   1318      */
   1319     if (bgpa_type == BGPTYPE_AS4_PATH) {
   1320         return 4;
   1321     }
   1322 
   1323     /*
   1324      * Let us assume that ASs are of 2 bytes in size, and check if the AS-Path
   1325      * TLV is good. If not, ask the caller to try with AS encoded as 4 bytes
   1326      * each.
   1327      */
   1328     while (tptr < pptr + len) {
   1329         ND_TCHECK(tptr[0]);
   1330 
   1331         /*
   1332          * If we do not find a valid segment type, our guess might be wrong.
   1333          */
   1334         if (tptr[0] < BGP_AS_SEG_TYPE_MIN || tptr[0] > BGP_AS_SEG_TYPE_MAX) {
   1335             goto trunc;
   1336         }
   1337         ND_TCHECK(tptr[1]);
   1338         tptr += 2 + tptr[1] * 2;
   1339     }
   1340 
   1341     /*
   1342      * If we correctly reached end of the AS path attribute data content,
   1343      * then most likely ASs were indeed encoded as 2 bytes.
   1344      */
   1345     if (tptr == pptr + len) {
   1346         return 2;
   1347     }
   1348 
   1349 trunc:
   1350 
   1351     /*
   1352      * We can come here, either we did not have enough data, or if we
   1353      * try to decode 4 byte ASs in 2 byte format. Either way, return 4,
   1354      * so that calller can try to decode each AS as of 4 bytes. If indeed
   1355      * there was not enough data, it will crib and end the parse anyways.
   1356      */
   1357    return 4;
   1358 }
   1359 
   1360 static int
   1361 bgp_attr_print(netdissect_options *ndo,
   1362                u_int atype, const u_char *pptr, u_int len)
   1363 {
   1364 	int i;
   1365 	uint16_t af;
   1366 	uint8_t safi, snpa, nhlen;
   1367         union { /* copy buffer for bandwidth values */
   1368             float f;
   1369             uint32_t i;
   1370         } bw;
   1371 	int advance;
   1372 	u_int tlen;
   1373 	const u_char *tptr;
   1374 	char buf[MAXHOSTNAMELEN + 100];
   1375         int  as_size;
   1376 
   1377         tptr = pptr;
   1378         tlen=len;
   1379 
   1380 	switch (atype) {
   1381 	case BGPTYPE_ORIGIN:
   1382 		if (len != 1)
   1383 			ND_PRINT((ndo, "invalid len"));
   1384 		else {
   1385 			ND_TCHECK(*tptr);
   1386 			ND_PRINT((ndo, "%s", tok2str(bgp_origin_values,
   1387 						"Unknown Origin Typecode",
   1388 						tptr[0])));
   1389 		}
   1390 		break;
   1391 
   1392         /*
   1393          * Process AS4 byte path and AS2 byte path attributes here.
   1394          */
   1395 	case BGPTYPE_AS4_PATH:
   1396 	case BGPTYPE_AS_PATH:
   1397 		if (len % 2) {
   1398 			ND_PRINT((ndo, "invalid len"));
   1399 			break;
   1400 		}
   1401                 if (!len) {
   1402 			ND_PRINT((ndo, "empty"));
   1403 			break;
   1404                 }
   1405 
   1406                 /*
   1407                  * BGP updates exchanged between New speakers that support 4
   1408                  * byte AS, ASs are always encoded in 4 bytes. There is no
   1409                  * definitive way to find this, just by the packet's
   1410                  * contents. So, check for packet's TLV's sanity assuming
   1411                  * 2 bytes first, and it does not pass, assume that ASs are
   1412                  * encoded in 4 bytes format and move on.
   1413                  */
   1414                 as_size = bgp_attr_get_as_size(ndo, atype, pptr, len);
   1415 
   1416 		while (tptr < pptr + len) {
   1417 			ND_TCHECK(tptr[0]);
   1418                         ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_open_values,
   1419 						"?", tptr[0])));
   1420 			ND_TCHECK(tptr[1]);
   1421                         for (i = 0; i < tptr[1] * as_size; i += as_size) {
   1422                             ND_TCHECK2(tptr[2 + i], as_size);
   1423 			    ND_PRINT((ndo, "%s ",
   1424 				as_printf(ndo, astostr, sizeof(astostr),
   1425 				as_size == 2 ?
   1426 				EXTRACT_16BITS(&tptr[2 + i]) :
   1427 				EXTRACT_32BITS(&tptr[2 + i]))));
   1428                         }
   1429 			ND_TCHECK(tptr[0]);
   1430                         ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_close_values,
   1431 						"?", tptr[0])));
   1432                         ND_TCHECK(tptr[1]);
   1433                         tptr += 2 + tptr[1] * as_size;
   1434 		}
   1435 		break;
   1436 	case BGPTYPE_NEXT_HOP:
   1437 		if (len != 4)
   1438 			ND_PRINT((ndo, "invalid len"));
   1439 		else {
   1440 			ND_TCHECK2(tptr[0], 4);
   1441 			ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr)));
   1442 		}
   1443 		break;
   1444 	case BGPTYPE_MULTI_EXIT_DISC:
   1445 	case BGPTYPE_LOCAL_PREF:
   1446 		if (len != 4)
   1447 			ND_PRINT((ndo, "invalid len"));
   1448 		else {
   1449 			ND_TCHECK2(tptr[0], 4);
   1450 			ND_PRINT((ndo, "%u", EXTRACT_32BITS(tptr)));
   1451 		}
   1452 		break;
   1453 	case BGPTYPE_ATOMIC_AGGREGATE:
   1454 		if (len != 0)
   1455 			ND_PRINT((ndo, "invalid len"));
   1456 		break;
   1457         case BGPTYPE_AGGREGATOR:
   1458 
   1459                 /*
   1460                  * Depending on the AS encoded is of 2 bytes or of 4 bytes,
   1461                  * the length of this PA can be either 6 bytes or 8 bytes.
   1462                  */
   1463                 if (len != 6 && len != 8) {
   1464                     ND_PRINT((ndo, "invalid len"));
   1465                     break;
   1466                 }
   1467                 ND_TCHECK2(tptr[0], len);
   1468                 if (len == 6) {
   1469 		    ND_PRINT((ndo, " AS #%s, origin %s",
   1470 			as_printf(ndo, astostr, sizeof(astostr), EXTRACT_16BITS(tptr)),
   1471 			ipaddr_string(ndo, tptr + 2)));
   1472                 } else {
   1473 		    ND_PRINT((ndo, " AS #%s, origin %s",
   1474 			as_printf(ndo, astostr, sizeof(astostr),
   1475 			EXTRACT_32BITS(tptr)), ipaddr_string(ndo, tptr + 4)));
   1476                 }
   1477                 break;
   1478 	case BGPTYPE_AGGREGATOR4:
   1479 		if (len != 8) {
   1480 			ND_PRINT((ndo, "invalid len"));
   1481 			break;
   1482 		}
   1483 		ND_TCHECK2(tptr[0], 8);
   1484 		ND_PRINT((ndo, " AS #%s, origin %s",
   1485 	   	    as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
   1486 		    ipaddr_string(ndo, tptr + 4)));
   1487 		break;
   1488 	case BGPTYPE_COMMUNITIES:
   1489 		if (len % 4) {
   1490 			ND_PRINT((ndo, "invalid len"));
   1491 			break;
   1492 		}
   1493 		while (tlen>0) {
   1494 			uint32_t comm;
   1495 			ND_TCHECK2(tptr[0], 4);
   1496 			comm = EXTRACT_32BITS(tptr);
   1497 			switch (comm) {
   1498 			case BGP_COMMUNITY_NO_EXPORT:
   1499 				ND_PRINT((ndo, " NO_EXPORT"));
   1500 				break;
   1501 			case BGP_COMMUNITY_NO_ADVERT:
   1502 				ND_PRINT((ndo, " NO_ADVERTISE"));
   1503 				break;
   1504 			case BGP_COMMUNITY_NO_EXPORT_SUBCONFED:
   1505 				ND_PRINT((ndo, " NO_EXPORT_SUBCONFED"));
   1506 				break;
   1507 			default:
   1508 				ND_PRINT((ndo, "%u:%u%s",
   1509                                        (comm >> 16) & 0xffff,
   1510                                        comm & 0xffff,
   1511                                        (tlen>4) ? ", " : ""));
   1512 				break;
   1513 			}
   1514                         tlen -=4;
   1515                         tptr +=4;
   1516 		}
   1517 		break;
   1518         case BGPTYPE_ORIGINATOR_ID:
   1519 		if (len != 4) {
   1520 			ND_PRINT((ndo, "invalid len"));
   1521 			break;
   1522 		}
   1523 		ND_TCHECK2(tptr[0], 4);
   1524                 ND_PRINT((ndo, "%s",ipaddr_string(ndo, tptr)));
   1525                 break;
   1526         case BGPTYPE_CLUSTER_LIST:
   1527 		if (len % 4) {
   1528 			ND_PRINT((ndo, "invalid len"));
   1529 			break;
   1530 		}
   1531                 while (tlen>0) {
   1532 			ND_TCHECK2(tptr[0], 4);
   1533                         ND_PRINT((ndo, "%s%s",
   1534                                ipaddr_string(ndo, tptr),
   1535                                 (tlen>4) ? ", " : ""));
   1536                         tlen -=4;
   1537                         tptr +=4;
   1538                 }
   1539                 break;
   1540 	case BGPTYPE_MP_REACH_NLRI:
   1541 		ND_TCHECK2(tptr[0], 3);
   1542 		af = EXTRACT_16BITS(tptr);
   1543 		safi = tptr[2];
   1544 
   1545                 ND_PRINT((ndo, "\n\t    AFI: %s (%u), %sSAFI: %s (%u)",
   1546                        tok2str(af_values, "Unknown AFI", af),
   1547                        af,
   1548                        (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */
   1549                        tok2str(bgp_safi_values, "Unknown SAFI", safi),
   1550                        safi));
   1551 
   1552                 switch(af<<8 | safi) {
   1553                 case (AFNUM_INET<<8 | SAFNUM_UNICAST):
   1554                 case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
   1555                 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
   1556                 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
   1557                 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
   1558                 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
   1559                 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
   1560                 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
   1561                 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
   1562 		case (AFNUM_INET<<8 | SAFNUM_MDT):
   1563                 case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
   1564                 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
   1565                 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
   1566                 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
   1567                 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
   1568                 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
   1569                 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
   1570                 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
   1571                 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
   1572                 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
   1573                 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
   1574                 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
   1575                 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
   1576                 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
   1577                 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
   1578                 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
   1579                 case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
   1580                     break;
   1581                 default:
   1582                     ND_TCHECK2(tptr[0], tlen);
   1583                     ND_PRINT((ndo, "\n\t    no AFI %u / SAFI %u decoder", af, safi));
   1584                     if (ndo->ndo_vflag <= 1)
   1585                         print_unknown_data(ndo, tptr, "\n\t    ", tlen);
   1586                     goto done;
   1587                     break;
   1588                 }
   1589 
   1590                 tptr +=3;
   1591 
   1592 		ND_TCHECK(tptr[0]);
   1593 		nhlen = tptr[0];
   1594                 tlen = nhlen;
   1595                 tptr++;
   1596 
   1597 		if (tlen) {
   1598                     int nnh = 0;
   1599                     ND_PRINT((ndo, "\n\t    nexthop: "));
   1600                     while (tlen > 0) {
   1601                         if ( nnh++ > 0 ) {
   1602                             ND_PRINT((ndo,  ", " ));
   1603                         }
   1604                         switch(af<<8 | safi) {
   1605                         case (AFNUM_INET<<8 | SAFNUM_UNICAST):
   1606                         case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
   1607                         case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
   1608                         case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
   1609                         case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
   1610                         case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
   1611                         case (AFNUM_INET<<8 | SAFNUM_MDT):
   1612 			    if (tlen < (int)sizeof(struct in_addr)) {
   1613                                 ND_PRINT((ndo, "invalid len"));
   1614                                 tlen = 0;
   1615                             } else {
   1616                                 ND_TCHECK2(tptr[0], sizeof(struct in_addr));
   1617                                 ND_PRINT((ndo, "%s",ipaddr_string(ndo, tptr)));
   1618                                 tlen -= sizeof(struct in_addr);
   1619                                 tptr += sizeof(struct in_addr);
   1620                             }
   1621                             break;
   1622                         case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
   1623                         case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
   1624                         case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
   1625                             if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) {
   1626                                 ND_PRINT((ndo, "invalid len"));
   1627                                 tlen = 0;
   1628                             } else {
   1629                                 ND_TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN);
   1630                                 ND_PRINT((ndo, "RD: %s, %s",
   1631                                        bgp_vpn_rd_print(ndo, tptr),
   1632                                        ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN)));
   1633                                 tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN);
   1634                                 tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN);
   1635                             }
   1636                             break;
   1637                         case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
   1638                         case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
   1639                         case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
   1640                         case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
   1641                             if (tlen < (int)sizeof(struct in6_addr)) {
   1642                                 ND_PRINT((ndo, "invalid len"));
   1643                                 tlen = 0;
   1644                             } else {
   1645                                 ND_TCHECK2(tptr[0], sizeof(struct in6_addr));
   1646                                 ND_PRINT((ndo, "%s", ip6addr_string(ndo, tptr)));
   1647                                 tlen -= sizeof(struct in6_addr);
   1648                                 tptr += sizeof(struct in6_addr);
   1649                             }
   1650                             break;
   1651                         case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
   1652                         case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
   1653                         case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
   1654                             if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) {
   1655                                 ND_PRINT((ndo, "invalid len"));
   1656                                 tlen = 0;
   1657                             } else {
   1658                                 ND_TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
   1659                                 ND_PRINT((ndo, "RD: %s, %s",
   1660                                        bgp_vpn_rd_print(ndo, tptr),
   1661                                        ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN)));
   1662                                 tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
   1663                                 tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
   1664                             }
   1665                             break;
   1666                         case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
   1667                         case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
   1668                         case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
   1669                         case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
   1670                             if (tlen < (int)sizeof(struct in_addr)) {
   1671                                 ND_PRINT((ndo, "invalid len"));
   1672                                 tlen = 0;
   1673                             } else {
   1674                                 ND_TCHECK2(tptr[0], sizeof(struct in_addr));
   1675                                 ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr)));
   1676                                 tlen -= (sizeof(struct in_addr));
   1677                                 tptr += (sizeof(struct in_addr));
   1678                             }
   1679                             break;
   1680                         case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
   1681                         case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
   1682                         case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
   1683                             ND_TCHECK2(tptr[0], tlen);
   1684                             ND_PRINT((ndo, "%s", isonsap_string(ndo, tptr, tlen)));
   1685                             tptr += tlen;
   1686                             tlen = 0;
   1687                             break;
   1688 
   1689                         case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
   1690                         case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
   1691                         case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
   1692                             if (tlen < BGP_VPN_RD_LEN+1) {
   1693                                 ND_PRINT((ndo, "invalid len"));
   1694                                 tlen = 0;
   1695                             } else {
   1696                                 ND_TCHECK2(tptr[0], tlen);
   1697                                 ND_PRINT((ndo, "RD: %s, %s",
   1698                                        bgp_vpn_rd_print(ndo, tptr),
   1699                                        isonsap_string(ndo, tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)));
   1700                                 /* rfc986 mapped IPv4 address ? */
   1701                                 if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) ==  0x47000601)
   1702                                     ND_PRINT((ndo, " = %s", ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN+4)));
   1703                                 /* rfc1888 mapped IPv6 address ? */
   1704                                 else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) ==  0x350000)
   1705                                     ND_PRINT((ndo, " = %s", ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN+3)));
   1706                                 tptr += tlen;
   1707                                 tlen = 0;
   1708                             }
   1709                             break;
   1710                         default:
   1711                             ND_TCHECK2(tptr[0], tlen);
   1712                             ND_PRINT((ndo, "no AFI %u/SAFI %u decoder", af, safi));
   1713                             if (ndo->ndo_vflag <= 1)
   1714                                 print_unknown_data(ndo, tptr, "\n\t    ", tlen);
   1715                             tptr += tlen;
   1716                             tlen = 0;
   1717                             goto done;
   1718                             break;
   1719                         }
   1720                     }
   1721 		}
   1722 		ND_PRINT((ndo, ", nh-length: %u", nhlen));
   1723 		tptr += tlen;
   1724 
   1725 		ND_TCHECK(tptr[0]);
   1726 		snpa = tptr[0];
   1727 		tptr++;
   1728 
   1729 		if (snpa) {
   1730 			ND_PRINT((ndo, "\n\t    %u SNPA", snpa));
   1731 			for (/*nothing*/; snpa > 0; snpa--) {
   1732 				ND_TCHECK(tptr[0]);
   1733 				ND_PRINT((ndo, "\n\t      %d bytes", tptr[0]));
   1734 				tptr += tptr[0] + 1;
   1735 			}
   1736 		} else {
   1737 			ND_PRINT((ndo, ", no SNPA"));
   1738                 }
   1739 
   1740 		while (tptr < pptr + len) {
   1741                     switch (af<<8 | safi) {
   1742                     case (AFNUM_INET<<8 | SAFNUM_UNICAST):
   1743                     case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
   1744                     case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
   1745                         advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf));
   1746                         if (advance == -1)
   1747                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1748                         else if (advance == -2)
   1749                             goto trunc;
   1750                         else if (advance == -3)
   1751                             break; /* bytes left, but not enough */
   1752                         else
   1753                             ND_PRINT((ndo, "\n\t      %s", buf));
   1754                         break;
   1755                     case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
   1756                         advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf));
   1757                         if (advance == -1)
   1758                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1759                         else if (advance == -2)
   1760                             goto trunc;
   1761                         else if (advance == -3)
   1762                             break; /* bytes left, but not enough */
   1763                         else
   1764                             ND_PRINT((ndo, "\n\t      %s", buf));
   1765                         break;
   1766                     case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
   1767                     case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
   1768                     case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
   1769                         advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, sizeof(buf));
   1770                         if (advance == -1)
   1771                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1772                         else if (advance == -2)
   1773                             goto trunc;
   1774                         else
   1775                             ND_PRINT((ndo, "\n\t      %s", buf));
   1776                         break;
   1777                     case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
   1778                         advance = decode_rt_routing_info(ndo, tptr, buf, sizeof(buf));
   1779                         if (advance == -1)
   1780                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1781                         else if (advance == -2)
   1782                             goto trunc;
   1783                         else
   1784                             ND_PRINT((ndo, "\n\t      %s", buf));
   1785                         break;
   1786                     case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
   1787                     case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
   1788                         advance = decode_multicast_vpn(ndo, tptr, buf, sizeof(buf));
   1789                         if (advance == -1)
   1790                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1791                         else if (advance == -2)
   1792                             goto trunc;
   1793                         else
   1794                             ND_PRINT((ndo, "\n\t      %s", buf));
   1795                         break;
   1796 
   1797 		    case (AFNUM_INET<<8 | SAFNUM_MDT):
   1798 		      advance = decode_mdt_vpn_nlri(ndo, tptr, buf, sizeof(buf));
   1799 		      if (advance == -1)
   1800                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1801                         else if (advance == -2)
   1802                             goto trunc;
   1803                         else
   1804                             ND_PRINT((ndo, "\n\t      %s", buf));
   1805 		       break;
   1806                     case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
   1807                     case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
   1808                     case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
   1809                         advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf));
   1810                         if (advance == -1)
   1811                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1812                         else if (advance == -2)
   1813                             goto trunc;
   1814                         else if (advance == -3)
   1815                             break; /* bytes left, but not enough */
   1816                         else
   1817                             ND_PRINT((ndo, "\n\t      %s", buf));
   1818                         break;
   1819                     case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
   1820                         advance = decode_labeled_prefix6(ndo, tptr, len, buf, sizeof(buf));
   1821                         if (advance == -1)
   1822                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1823                         else if (advance == -2)
   1824                             goto trunc;
   1825                         else if (advance == -3)
   1826                             break; /* bytes left, but not enough */
   1827                         else
   1828                             ND_PRINT((ndo, "\n\t      %s", buf));
   1829                         break;
   1830                     case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
   1831                     case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
   1832                     case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
   1833                         advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, sizeof(buf));
   1834                         if (advance == -1)
   1835                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1836                         else if (advance == -2)
   1837                             goto trunc;
   1838                         else
   1839                             ND_PRINT((ndo, "\n\t      %s", buf));
   1840                         break;
   1841                     case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
   1842                     case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
   1843                     case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
   1844                     case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
   1845                         advance = decode_labeled_vpn_l2(ndo, tptr, buf, sizeof(buf));
   1846                         if (advance == -1)
   1847                             ND_PRINT((ndo, "\n\t    (illegal length)"));
   1848                         else if (advance == -2)
   1849                             goto trunc;
   1850                         else
   1851                             ND_PRINT((ndo, "\n\t      %s", buf));
   1852                         break;
   1853                     case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
   1854                     case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
   1855                     case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
   1856                         advance = decode_clnp_prefix(ndo, tptr, buf, sizeof(buf));
   1857                         if (advance == -1)
   1858                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1859                         else if (advance == -2)
   1860                             goto trunc;
   1861                         else
   1862                             ND_PRINT((ndo, "\n\t      %s", buf));
   1863                         break;
   1864                     case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
   1865                     case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
   1866                     case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
   1867                         advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, sizeof(buf));
   1868                         if (advance == -1)
   1869                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1870                         else if (advance == -2)
   1871                             goto trunc;
   1872                         else
   1873                             ND_PRINT((ndo, "\n\t      %s", buf));
   1874                         break;
   1875                     default:
   1876                         ND_TCHECK2(*tptr,tlen);
   1877                         ND_PRINT((ndo, "\n\t    no AFI %u / SAFI %u decoder", af, safi));
   1878                         if (ndo->ndo_vflag <= 1)
   1879                             print_unknown_data(ndo, tptr, "\n\t    ", tlen);
   1880                         advance = 0;
   1881                         tptr = pptr + len;
   1882                         break;
   1883                     }
   1884                     if (advance < 0)
   1885                         break;
   1886                     tptr += advance;
   1887 		}
   1888         done:
   1889 		break;
   1890 
   1891 	case BGPTYPE_MP_UNREACH_NLRI:
   1892 		ND_TCHECK2(tptr[0], BGP_MP_NLRI_MINSIZE);
   1893 		af = EXTRACT_16BITS(tptr);
   1894 		safi = tptr[2];
   1895 
   1896                 ND_PRINT((ndo, "\n\t    AFI: %s (%u), %sSAFI: %s (%u)",
   1897                        tok2str(af_values, "Unknown AFI", af),
   1898                        af,
   1899                        (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */
   1900                        tok2str(bgp_safi_values, "Unknown SAFI", safi),
   1901                        safi));
   1902 
   1903                 if (len == BGP_MP_NLRI_MINSIZE)
   1904                     ND_PRINT((ndo, "\n\t      End-of-Rib Marker (empty NLRI)"));
   1905 
   1906 		tptr += 3;
   1907 
   1908 		while (tptr < pptr + len) {
   1909                     switch (af<<8 | safi) {
   1910                     case (AFNUM_INET<<8 | SAFNUM_UNICAST):
   1911                     case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
   1912                     case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
   1913                         advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf));
   1914                         if (advance == -1)
   1915                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1916                         else if (advance == -2)
   1917                             goto trunc;
   1918                         else if (advance == -3)
   1919                             break; /* bytes left, but not enough */
   1920                         else
   1921                             ND_PRINT((ndo, "\n\t      %s", buf));
   1922                         break;
   1923                     case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
   1924                         advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf));
   1925                         if (advance == -1)
   1926                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1927                         else if (advance == -2)
   1928                             goto trunc;
   1929                         else if (advance == -3)
   1930                             break; /* bytes left, but not enough */
   1931                         else
   1932                             ND_PRINT((ndo, "\n\t      %s", buf));
   1933                         break;
   1934                     case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
   1935                     case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
   1936                     case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
   1937                         advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, sizeof(buf));
   1938                         if (advance == -1)
   1939                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1940                         else if (advance == -2)
   1941                             goto trunc;
   1942                         else
   1943                             ND_PRINT((ndo, "\n\t      %s", buf));
   1944                         break;
   1945                     case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
   1946                     case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
   1947                     case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
   1948                         advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf));
   1949                         if (advance == -1)
   1950                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1951                         else if (advance == -2)
   1952                             goto trunc;
   1953                         else if (advance == -3)
   1954                             break; /* bytes left, but not enough */
   1955                         else
   1956                             ND_PRINT((ndo, "\n\t      %s", buf));
   1957                         break;
   1958                     case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
   1959                         advance = decode_labeled_prefix6(ndo, tptr, len, buf, sizeof(buf));
   1960                         if (advance == -1)
   1961                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1962                         else if (advance == -2)
   1963                             goto trunc;
   1964                         else if (advance == -3)
   1965                             break; /* bytes left, but not enough */
   1966                         else
   1967                             ND_PRINT((ndo, "\n\t      %s", buf));
   1968                         break;
   1969                     case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
   1970                     case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
   1971                     case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
   1972                         advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, sizeof(buf));
   1973                         if (advance == -1)
   1974                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1975                         else if (advance == -2)
   1976                             goto trunc;
   1977                         else
   1978                             ND_PRINT((ndo, "\n\t      %s", buf));
   1979                         break;
   1980                     case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
   1981                     case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
   1982                     case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
   1983                     case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
   1984                         advance = decode_labeled_vpn_l2(ndo, tptr, buf, sizeof(buf));
   1985                         if (advance == -1)
   1986                             ND_PRINT((ndo, "\n\t    (illegal length)"));
   1987                         else if (advance == -2)
   1988                             goto trunc;
   1989                         else
   1990                             ND_PRINT((ndo, "\n\t      %s", buf));
   1991                         break;
   1992                     case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
   1993                     case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
   1994                     case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
   1995                         advance = decode_clnp_prefix(ndo, tptr, buf, sizeof(buf));
   1996                         if (advance == -1)
   1997                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   1998                         else if (advance == -2)
   1999                             goto trunc;
   2000                         else
   2001                             ND_PRINT((ndo, "\n\t      %s", buf));
   2002                         break;
   2003                     case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
   2004                     case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
   2005                     case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
   2006                         advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, sizeof(buf));
   2007                         if (advance == -1)
   2008                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   2009                         else if (advance == -2)
   2010                             goto trunc;
   2011                         else
   2012                             ND_PRINT((ndo, "\n\t      %s", buf));
   2013                         break;
   2014 		    case (AFNUM_INET<<8 | SAFNUM_MDT):
   2015 		      advance = decode_mdt_vpn_nlri(ndo, tptr, buf, sizeof(buf));
   2016 		      if (advance == -1)
   2017                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   2018                         else if (advance == -2)
   2019                             goto trunc;
   2020                         else
   2021                             ND_PRINT((ndo, "\n\t      %s", buf));
   2022 		       break;
   2023                     case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
   2024                     case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
   2025                         advance = decode_multicast_vpn(ndo, tptr, buf, sizeof(buf));
   2026                         if (advance == -1)
   2027                             ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   2028                         else if (advance == -2)
   2029                             goto trunc;
   2030                         else
   2031                             ND_PRINT((ndo, "\n\t      %s", buf));
   2032                         break;
   2033                     default:
   2034                         ND_TCHECK2(*(tptr-3),tlen);
   2035                         ND_PRINT((ndo, "no AFI %u / SAFI %u decoder", af, safi));
   2036                         if (ndo->ndo_vflag <= 1)
   2037                             print_unknown_data(ndo, tptr-3, "\n\t    ", tlen);
   2038                         advance = 0;
   2039                         tptr = pptr + len;
   2040                         break;
   2041                     }
   2042                     if (advance < 0)
   2043                         break;
   2044                     tptr += advance;
   2045 		}
   2046 		break;
   2047         case BGPTYPE_EXTD_COMMUNITIES:
   2048 		if (len % 8) {
   2049 			ND_PRINT((ndo, "invalid len"));
   2050 			break;
   2051 		}
   2052                 while (tlen>0) {
   2053                     uint16_t extd_comm;
   2054 
   2055                     ND_TCHECK2(tptr[0], 2);
   2056                     extd_comm=EXTRACT_16BITS(tptr);
   2057 
   2058 		    ND_PRINT((ndo, "\n\t    %s (0x%04x), Flags [%s]",
   2059 			   tok2str(bgp_extd_comm_subtype_values,
   2060 				      "unknown extd community typecode",
   2061 				      extd_comm),
   2062 			   extd_comm,
   2063 			   bittok2str(bgp_extd_comm_flag_values, "none", extd_comm)));
   2064 
   2065                     ND_TCHECK2(*(tptr+2), 6);
   2066                     switch(extd_comm) {
   2067                     case BGP_EXT_COM_RT_0:
   2068                     case BGP_EXT_COM_RO_0:
   2069                     case BGP_EXT_COM_L2VPN_RT_0:
   2070                         ND_PRINT((ndo, ": %u:%u (= %s)",
   2071                                EXTRACT_16BITS(tptr+2),
   2072                                EXTRACT_32BITS(tptr+4),
   2073                                ipaddr_string(ndo, tptr+4)));
   2074                         break;
   2075                     case BGP_EXT_COM_RT_1:
   2076                     case BGP_EXT_COM_RO_1:
   2077                     case BGP_EXT_COM_L2VPN_RT_1:
   2078                     case BGP_EXT_COM_VRF_RT_IMP:
   2079                         ND_PRINT((ndo, ": %s:%u",
   2080                                ipaddr_string(ndo, tptr+2),
   2081                                EXTRACT_16BITS(tptr+6)));
   2082                         break;
   2083                     case BGP_EXT_COM_RT_2:
   2084                     case BGP_EXT_COM_RO_2:
   2085 			ND_PRINT((ndo, ": %s:%u",
   2086 			    as_printf(ndo, astostr, sizeof(astostr),
   2087 			    EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6)));
   2088 			break;
   2089                     case BGP_EXT_COM_LINKBAND:
   2090 		        bw.i = EXTRACT_32BITS(tptr+2);
   2091                         ND_PRINT((ndo, ": bandwidth: %.3f Mbps",
   2092                                bw.f*8/1000000));
   2093                         break;
   2094                     case BGP_EXT_COM_VPN_ORIGIN:
   2095                     case BGP_EXT_COM_VPN_ORIGIN2:
   2096                     case BGP_EXT_COM_VPN_ORIGIN3:
   2097                     case BGP_EXT_COM_VPN_ORIGIN4:
   2098                     case BGP_EXT_COM_OSPF_RID:
   2099                     case BGP_EXT_COM_OSPF_RID2:
   2100                         ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr+2)));
   2101                         break;
   2102                     case BGP_EXT_COM_OSPF_RTYPE:
   2103                     case BGP_EXT_COM_OSPF_RTYPE2:
   2104                         ND_PRINT((ndo, ": area:%s, router-type:%s, metric-type:%s%s",
   2105                                ipaddr_string(ndo, tptr+2),
   2106                                tok2str(bgp_extd_comm_ospf_rtype_values,
   2107 					  "unknown (0x%02x)",
   2108 					  *(tptr+6)),
   2109                                (*(tptr+7) &  BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "",
   2110                                ((*(tptr+6) == BGP_OSPF_RTYPE_EXT) || (*(tptr+6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : ""));
   2111                         break;
   2112                     case BGP_EXT_COM_L2INFO:
   2113                         ND_PRINT((ndo, ": %s Control Flags [0x%02x]:MTU %u",
   2114                                tok2str(l2vpn_encaps_values,
   2115 					  "unknown encaps",
   2116 					  *(tptr+2)),
   2117                                        *(tptr+3),
   2118                                EXTRACT_16BITS(tptr+4)));
   2119                         break;
   2120                     case BGP_EXT_COM_SOURCE_AS:
   2121                         ND_PRINT((ndo, ": AS %u", EXTRACT_16BITS(tptr+2)));
   2122                         break;
   2123                     default:
   2124                         ND_TCHECK2(*tptr,8);
   2125                         print_unknown_data(ndo, tptr, "\n\t      ", 8);
   2126                         break;
   2127                     }
   2128                     tlen -=8;
   2129                     tptr +=8;
   2130                 }
   2131                 break;
   2132 
   2133         case BGPTYPE_PMSI_TUNNEL:
   2134         {
   2135                 uint8_t tunnel_type, flags;
   2136 
   2137                 ND_TCHECK2(tptr[0], 5);
   2138                 tunnel_type = *(tptr+1);
   2139                 flags = *tptr;
   2140                 tlen = len;
   2141 
   2142                 ND_PRINT((ndo, "\n\t    Tunnel-type %s (%u), Flags [%s], MPLS Label %u",
   2143                        tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type),
   2144                        tunnel_type,
   2145                        bittok2str(bgp_pmsi_flag_values, "none", flags),
   2146                        EXTRACT_24BITS(tptr+2)>>4));
   2147 
   2148                 tptr +=5;
   2149                 tlen -= 5;
   2150 
   2151                 switch (tunnel_type) {
   2152                 case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */
   2153                 case BGP_PMSI_TUNNEL_PIM_BIDIR:
   2154                     ND_TCHECK2(tptr[0], 8);
   2155                     ND_PRINT((ndo, "\n\t      Sender %s, P-Group %s",
   2156                            ipaddr_string(ndo, tptr),
   2157                            ipaddr_string(ndo, tptr+4)));
   2158                     break;
   2159 
   2160                 case BGP_PMSI_TUNNEL_PIM_SSM:
   2161                     ND_TCHECK2(tptr[0], 8);
   2162                     ND_PRINT((ndo, "\n\t      Root-Node %s, P-Group %s",
   2163                            ipaddr_string(ndo, tptr),
   2164                            ipaddr_string(ndo, tptr+4)));
   2165                     break;
   2166                 case BGP_PMSI_TUNNEL_INGRESS:
   2167                     ND_TCHECK2(tptr[0], 4);
   2168                     ND_PRINT((ndo, "\n\t      Tunnel-Endpoint %s",
   2169                            ipaddr_string(ndo, tptr)));
   2170                     break;
   2171                 case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */
   2172                 case BGP_PMSI_TUNNEL_LDP_MP2MP:
   2173                     ND_TCHECK2(tptr[0], 8);
   2174                     ND_PRINT((ndo, "\n\t      Root-Node %s, LSP-ID 0x%08x",
   2175                            ipaddr_string(ndo, tptr),
   2176                            EXTRACT_32BITS(tptr+4)));
   2177                     break;
   2178                 case BGP_PMSI_TUNNEL_RSVP_P2MP:
   2179                     ND_TCHECK2(tptr[0], 8);
   2180                     ND_PRINT((ndo, "\n\t      Extended-Tunnel-ID %s, P2MP-ID 0x%08x",
   2181                            ipaddr_string(ndo, tptr),
   2182                            EXTRACT_32BITS(tptr+4)));
   2183                     break;
   2184                 default:
   2185                     if (ndo->ndo_vflag <= 1) {
   2186                         print_unknown_data(ndo, tptr, "\n\t      ", tlen);
   2187                     }
   2188                 }
   2189                 break;
   2190         }
   2191 	case BGPTYPE_AIGP:
   2192 	{
   2193 		uint8_t type;
   2194 		uint16_t length;
   2195 
   2196 		tlen = len;
   2197 
   2198 		while (tlen >= 3) {
   2199 
   2200 		    ND_TCHECK2(tptr[0], 3);
   2201 
   2202 		    type = *tptr;
   2203 		    length = EXTRACT_16BITS(tptr+1);
   2204 		    tptr += 3;
   2205 		    tlen -= 3;
   2206 
   2207 		    ND_PRINT((ndo, "\n\t    %s TLV (%u), length %u",
   2208 			      tok2str(bgp_aigp_values, "Unknown", type),
   2209 			      type, length));
   2210 
   2211 		    if (length < 3)
   2212 			goto trunc;
   2213 		    length -= 3;
   2214 
   2215 		    /*
   2216 		     * Check if we can read the TLV data.
   2217 		     */
   2218 		    ND_TCHECK2(tptr[3], length);
   2219 
   2220 		    switch (type) {
   2221 
   2222 		    case BGP_AIGP_TLV:
   2223 		        if (length < 8)
   2224 		            goto trunc;
   2225 			ND_PRINT((ndo, ", metric %" PRIu64,
   2226 				  EXTRACT_64BITS(tptr)));
   2227 			break;
   2228 
   2229 		    default:
   2230 			if (ndo->ndo_vflag <= 1) {
   2231 			    print_unknown_data(ndo, tptr,"\n\t      ", length);
   2232 			}
   2233 		    }
   2234 
   2235 		    tptr += length;
   2236 		    tlen -= length;
   2237 		}
   2238 		break;
   2239 	}
   2240         case BGPTYPE_ATTR_SET:
   2241                 ND_TCHECK2(tptr[0], 4);
   2242                 if (len < 4)
   2243                 	goto trunc;
   2244 		ND_PRINT((ndo, "\n\t    Origin AS: %s",
   2245 		    as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr))));
   2246 		tptr+=4;
   2247                 len -=4;
   2248 
   2249                 while (len) {
   2250                     u_int aflags, alenlen, alen;
   2251 
   2252                     ND_TCHECK2(tptr[0], 2);
   2253                     if (len < 2)
   2254                         goto trunc;
   2255                     aflags = *tptr;
   2256                     atype = *(tptr + 1);
   2257                     tptr += 2;
   2258                     len -= 2;
   2259                     alenlen = bgp_attr_lenlen(aflags, tptr);
   2260                     ND_TCHECK2(tptr[0], alenlen);
   2261                     if (len < alenlen)
   2262                         goto trunc;
   2263                     alen = bgp_attr_len(aflags, tptr);
   2264                     tptr += alenlen;
   2265                     len -= alenlen;
   2266 
   2267                     ND_PRINT((ndo, "\n\t      %s (%u), length: %u",
   2268                            tok2str(bgp_attr_values,
   2269                                       "Unknown Attribute", atype),
   2270                            atype,
   2271                            alen));
   2272 
   2273                     if (aflags) {
   2274                         ND_PRINT((ndo, ", Flags [%s%s%s%s",
   2275                                aflags & 0x80 ? "O" : "",
   2276                                aflags & 0x40 ? "T" : "",
   2277                                aflags & 0x20 ? "P" : "",
   2278                                aflags & 0x10 ? "E" : ""));
   2279                         if (aflags & 0xf)
   2280                             ND_PRINT((ndo, "+%x", aflags & 0xf));
   2281                         ND_PRINT((ndo, "]: "));
   2282                     }
   2283                     /* FIXME check for recursion */
   2284                     if (!bgp_attr_print(ndo, atype, tptr, alen))
   2285                         return 0;
   2286                     tptr += alen;
   2287                     len -= alen;
   2288 		}
   2289                 break;
   2290 
   2291 	case BGPTYPE_LARGE_COMMUNITY:
   2292 		if (len == 0 || len % 12) {
   2293 			ND_PRINT((ndo, "invalid len"));
   2294 			break;
   2295 		}
   2296 		ND_PRINT((ndo, "\n\t    "));
   2297 		while (len > 0) {
   2298 			ND_TCHECK2(*tptr, 12);
   2299 			ND_PRINT((ndo, "%u:%u:%u%s",
   2300 				 EXTRACT_32BITS(tptr),
   2301 				 EXTRACT_32BITS(tptr + 4),
   2302 				 EXTRACT_32BITS(tptr + 8),
   2303 				 (len > 12) ? ", " : ""));
   2304                         tptr += 12;
   2305                         len -= 12;
   2306 		}
   2307 		break;
   2308 	default:
   2309 	    ND_TCHECK2(*pptr,len);
   2310             ND_PRINT((ndo, "\n\t    no Attribute %u decoder", atype)); /* we have no decoder for the attribute */
   2311             if (ndo->ndo_vflag <= 1)
   2312                 print_unknown_data(ndo, pptr, "\n\t    ", len);
   2313             break;
   2314 	}
   2315         if (ndo->ndo_vflag > 1 && len) { /* omit zero length attributes*/
   2316             ND_TCHECK2(*pptr,len);
   2317             print_unknown_data(ndo, pptr, "\n\t    ", len);
   2318         }
   2319         return 1;
   2320 
   2321 trunc:
   2322         return 0;
   2323 }
   2324 
   2325 static void
   2326 bgp_capabilities_print(netdissect_options *ndo,
   2327                        const u_char *opt, int caps_len)
   2328 {
   2329 	int cap_type, cap_len, tcap_len, cap_offset;
   2330         int i = 0;
   2331 
   2332         while (i < caps_len) {
   2333                 ND_TCHECK2(opt[i], BGP_CAP_HEADER_SIZE);
   2334                 cap_type=opt[i];
   2335                 cap_len=opt[i+1];
   2336                 tcap_len=cap_len;
   2337                 ND_PRINT((ndo, "\n\t      %s (%u), length: %u",
   2338                        tok2str(bgp_capcode_values, "Unknown",
   2339                                   cap_type),
   2340                        cap_type,
   2341                        cap_len));
   2342                 ND_TCHECK2(opt[i+2], cap_len);
   2343                 switch (cap_type) {
   2344                 case BGP_CAPCODE_MP:
   2345                     ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u)",
   2346                            tok2str(af_values, "Unknown",
   2347                                       EXTRACT_16BITS(opt+i+2)),
   2348                            EXTRACT_16BITS(opt+i+2),
   2349                            tok2str(bgp_safi_values, "Unknown",
   2350                                       opt[i+5]),
   2351                            opt[i+5]));
   2352                     break;
   2353                 case BGP_CAPCODE_RESTART:
   2354                     ND_PRINT((ndo, "\n\t\tRestart Flags: [%s], Restart Time %us",
   2355                            ((opt[i+2])&0x80) ? "R" : "none",
   2356                            EXTRACT_16BITS(opt+i+2)&0xfff));
   2357                     tcap_len-=2;
   2358                     cap_offset=4;
   2359                     while(tcap_len>=4) {
   2360                         ND_PRINT((ndo, "\n\t\t  AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
   2361                                tok2str(af_values,"Unknown",
   2362                                           EXTRACT_16BITS(opt+i+cap_offset)),
   2363                                EXTRACT_16BITS(opt+i+cap_offset),
   2364                                tok2str(bgp_safi_values,"Unknown",
   2365                                           opt[i+cap_offset+2]),
   2366                                opt[i+cap_offset+2],
   2367                                ((opt[i+cap_offset+3])&0x80) ? "yes" : "no" ));
   2368                         tcap_len-=4;
   2369                         cap_offset+=4;
   2370                     }
   2371                     break;
   2372                 case BGP_CAPCODE_RR:
   2373                 case BGP_CAPCODE_RR_CISCO:
   2374                     break;
   2375                 case BGP_CAPCODE_AS_NEW:
   2376 
   2377                     /*
   2378                      * Extract the 4 byte AS number encoded.
   2379                      */
   2380                     if (cap_len == 4) {
   2381                         ND_PRINT((ndo, "\n\t\t 4 Byte AS %s",
   2382                             as_printf(ndo, astostr, sizeof(astostr),
   2383                             EXTRACT_32BITS(opt + i + 2))));
   2384                     }
   2385                     break;
   2386                 case BGP_CAPCODE_ADD_PATH:
   2387                     cap_offset=2;
   2388                     if (tcap_len == 0) {
   2389                         ND_PRINT((ndo, " (bogus)")); /* length */
   2390                         break;
   2391                     }
   2392                     while (tcap_len > 0) {
   2393                         if (tcap_len < 4) {
   2394                             ND_PRINT((ndo, "\n\t\t(invalid)"));
   2395                             break;
   2396                         }
   2397                         ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u), Send/Receive: %s",
   2398                                   tok2str(af_values,"Unknown",EXTRACT_16BITS(opt+i+cap_offset)),
   2399                                   EXTRACT_16BITS(opt+i+cap_offset),
   2400                                   tok2str(bgp_safi_values,"Unknown",opt[i+cap_offset+2]),
   2401                                   opt[i+cap_offset+2],
   2402                                   tok2str(bgp_add_path_recvsend,"Bogus (0x%02x)",opt[i+cap_offset+3])
   2403                         ));
   2404                         tcap_len-=4;
   2405                         cap_offset+=4;
   2406                     }
   2407                     break;
   2408                 default:
   2409                     ND_PRINT((ndo, "\n\t\tno decoder for Capability %u",
   2410                            cap_type));
   2411                     if (ndo->ndo_vflag <= 1)
   2412                         print_unknown_data(ndo, &opt[i+2], "\n\t\t", cap_len);
   2413                     break;
   2414                 }
   2415                 if (ndo->ndo_vflag > 1 && cap_len > 0) {
   2416                     print_unknown_data(ndo, &opt[i+2], "\n\t\t", cap_len);
   2417                 }
   2418                 i += BGP_CAP_HEADER_SIZE + cap_len;
   2419         }
   2420         return;
   2421 
   2422 trunc:
   2423 	ND_PRINT((ndo, "[|BGP]"));
   2424 }
   2425 
   2426 static void
   2427 bgp_open_print(netdissect_options *ndo,
   2428                const u_char *dat, int length)
   2429 {
   2430 	struct bgp_open bgpo;
   2431 	struct bgp_opt bgpopt;
   2432 	const u_char *opt;
   2433 	int i;
   2434 
   2435 	ND_TCHECK2(dat[0], BGP_OPEN_SIZE);
   2436 	memcpy(&bgpo, dat, BGP_OPEN_SIZE);
   2437 
   2438 	ND_PRINT((ndo, "\n\t  Version %d, ", bgpo.bgpo_version));
   2439 	ND_PRINT((ndo, "my AS %s, ",
   2440 	    as_printf(ndo, astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas))));
   2441 	ND_PRINT((ndo, "Holdtime %us, ", ntohs(bgpo.bgpo_holdtime)));
   2442 	ND_PRINT((ndo, "ID %s", ipaddr_string(ndo, &bgpo.bgpo_id)));
   2443 	ND_PRINT((ndo, "\n\t  Optional parameters, length: %u", bgpo.bgpo_optlen));
   2444 
   2445         /* some little sanity checking */
   2446         if (length < bgpo.bgpo_optlen+BGP_OPEN_SIZE)
   2447             return;
   2448 
   2449 	/* ugly! */
   2450 	opt = &((const struct bgp_open *)dat)->bgpo_optlen;
   2451 	opt++;
   2452 
   2453 	i = 0;
   2454 	while (i < bgpo.bgpo_optlen) {
   2455 		ND_TCHECK2(opt[i], BGP_OPT_SIZE);
   2456 		memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE);
   2457 		if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) {
   2458 			ND_PRINT((ndo, "\n\t     Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len));
   2459 			break;
   2460 		}
   2461 
   2462 		ND_PRINT((ndo, "\n\t    Option %s (%u), length: %u",
   2463 		       tok2str(bgp_opt_values,"Unknown",
   2464 				  bgpopt.bgpopt_type),
   2465 		       bgpopt.bgpopt_type,
   2466 		       bgpopt.bgpopt_len));
   2467 
   2468 		/* now let's decode the options we know*/
   2469 		switch(bgpopt.bgpopt_type) {
   2470 
   2471 		case BGP_OPT_CAP:
   2472 			bgp_capabilities_print(ndo, &opt[i+BGP_OPT_SIZE],
   2473 			    bgpopt.bgpopt_len);
   2474 			break;
   2475 
   2476 		case BGP_OPT_AUTH:
   2477 		default:
   2478 		       ND_PRINT((ndo, "\n\t      no decoder for option %u",
   2479 			   bgpopt.bgpopt_type));
   2480 		       break;
   2481 		}
   2482 		i += BGP_OPT_SIZE + bgpopt.bgpopt_len;
   2483 	}
   2484 	return;
   2485 trunc:
   2486 	ND_PRINT((ndo, "[|BGP]"));
   2487 }
   2488 
   2489 static void
   2490 bgp_update_print(netdissect_options *ndo,
   2491                  const u_char *dat, int length)
   2492 {
   2493 	struct bgp bgp;
   2494 	const u_char *p;
   2495 	int withdrawn_routes_len;
   2496 	int len;
   2497 	int i;
   2498 
   2499 	ND_TCHECK2(dat[0], BGP_SIZE);
   2500 	if (length < BGP_SIZE)
   2501 		goto trunc;
   2502 	memcpy(&bgp, dat, BGP_SIZE);
   2503 	p = dat + BGP_SIZE;	/*XXX*/
   2504 	length -= BGP_SIZE;
   2505 
   2506 	/* Unfeasible routes */
   2507 	ND_TCHECK2(p[0], 2);
   2508 	if (length < 2)
   2509 		goto trunc;
   2510 	withdrawn_routes_len = EXTRACT_16BITS(p);
   2511 	p += 2;
   2512 	length -= 2;
   2513 	if (withdrawn_routes_len) {
   2514 		/*
   2515 		 * Without keeping state from the original NLRI message,
   2516 		 * it's not possible to tell if this a v4 or v6 route,
   2517 		 * so only try to decode it if we're not v6 enabled.
   2518 	         */
   2519 		ND_TCHECK2(p[0], withdrawn_routes_len);
   2520 		if (length < withdrawn_routes_len)
   2521 			goto trunc;
   2522 		ND_PRINT((ndo, "\n\t  Withdrawn routes: %d bytes", withdrawn_routes_len));
   2523 		p += withdrawn_routes_len;
   2524 		length -= withdrawn_routes_len;
   2525 	}
   2526 
   2527 	ND_TCHECK2(p[0], 2);
   2528 	if (length < 2)
   2529 		goto trunc;
   2530 	len = EXTRACT_16BITS(p);
   2531 	p += 2;
   2532 	length -= 2;
   2533 
   2534         if (withdrawn_routes_len == 0 && len == 0 && length == 0) {
   2535             /* No withdrawn routes, no path attributes, no NLRI */
   2536             ND_PRINT((ndo, "\n\t  End-of-Rib Marker (empty NLRI)"));
   2537             return;
   2538         }
   2539 
   2540 	if (len) {
   2541 		/* do something more useful!*/
   2542 		while (len) {
   2543 			int aflags, atype, alenlen, alen;
   2544 
   2545 			ND_TCHECK2(p[0], 2);
   2546 			if (len < 2)
   2547 			    goto trunc;
   2548 			if (length < 2)
   2549 			    goto trunc;
   2550 			aflags = *p;
   2551 			atype = *(p + 1);
   2552 			p += 2;
   2553 			len -= 2;
   2554 			length -= 2;
   2555 			alenlen = bgp_attr_lenlen(aflags, p);
   2556 			ND_TCHECK2(p[0], alenlen);
   2557 			if (len < alenlen)
   2558 			    goto trunc;
   2559 			if (length < alenlen)
   2560 			    goto trunc;
   2561 			alen = bgp_attr_len(aflags, p);
   2562 			p += alenlen;
   2563 			len -= alenlen;
   2564 			length -= alenlen;
   2565 
   2566 			ND_PRINT((ndo, "\n\t  %s (%u), length: %u",
   2567                               tok2str(bgp_attr_values, "Unknown Attribute",
   2568 					 atype),
   2569                               atype,
   2570                               alen));
   2571 
   2572 			if (aflags) {
   2573 				ND_PRINT((ndo, ", Flags [%s%s%s%s",
   2574 					aflags & 0x80 ? "O" : "",
   2575 					aflags & 0x40 ? "T" : "",
   2576 					aflags & 0x20 ? "P" : "",
   2577 					aflags & 0x10 ? "E" : ""));
   2578 				if (aflags & 0xf)
   2579 					ND_PRINT((ndo, "+%x", aflags & 0xf));
   2580 				ND_PRINT((ndo, "]: "));
   2581 			}
   2582 			if (len < alen)
   2583 				goto trunc;
   2584 			if (length < alen)
   2585 				goto trunc;
   2586 			if (!bgp_attr_print(ndo, atype, p, alen))
   2587 				goto trunc;
   2588 			p += alen;
   2589 			len -= alen;
   2590 			length -= alen;
   2591 		}
   2592 	}
   2593 
   2594 	if (length) {
   2595 		/*
   2596 		 * XXX - what if they're using the "Advertisement of
   2597 		 * Multiple Paths in BGP" feature:
   2598 		 *
   2599 		 * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/
   2600 		 *
   2601 		 * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06
   2602 		 */
   2603 		ND_PRINT((ndo, "\n\t  Updated routes:"));
   2604 		while (length) {
   2605 			char buf[MAXHOSTNAMELEN + 100];
   2606 			i = decode_prefix4(ndo, p, length, buf, sizeof(buf));
   2607 			if (i == -1) {
   2608 				ND_PRINT((ndo, "\n\t    (illegal prefix length)"));
   2609 				break;
   2610 			} else if (i == -2)
   2611 				goto trunc;
   2612 			else if (i == -3)
   2613 				goto trunc; /* bytes left, but not enough */
   2614 			else {
   2615 				ND_PRINT((ndo, "\n\t    %s", buf));
   2616 				p += i;
   2617 				length -= i;
   2618 			}
   2619 		}
   2620 	}
   2621 	return;
   2622 trunc:
   2623 	ND_PRINT((ndo, "[|BGP]"));
   2624 }
   2625 
   2626 static void
   2627 bgp_notification_print(netdissect_options *ndo,
   2628                        const u_char *dat, int length)
   2629 {
   2630 	struct bgp_notification bgpn;
   2631 	const u_char *tptr;
   2632 
   2633 	ND_TCHECK2(dat[0], BGP_NOTIFICATION_SIZE);
   2634 	memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE);
   2635 
   2636         /* some little sanity checking */
   2637         if (length<BGP_NOTIFICATION_SIZE)
   2638             return;
   2639 
   2640 	ND_PRINT((ndo, ", %s (%u)",
   2641 	       tok2str(bgp_notify_major_values, "Unknown Error",
   2642 			  bgpn.bgpn_major),
   2643 	       bgpn.bgpn_major));
   2644 
   2645         switch (bgpn.bgpn_major) {
   2646 
   2647         case BGP_NOTIFY_MAJOR_MSG:
   2648             ND_PRINT((ndo, ", subcode %s (%u)",
   2649 		   tok2str(bgp_notify_minor_msg_values, "Unknown",
   2650 			      bgpn.bgpn_minor),
   2651 		   bgpn.bgpn_minor));
   2652             break;
   2653         case BGP_NOTIFY_MAJOR_OPEN:
   2654             ND_PRINT((ndo, ", subcode %s (%u)",
   2655 		   tok2str(bgp_notify_minor_open_values, "Unknown",
   2656 			      bgpn.bgpn_minor),
   2657 		   bgpn.bgpn_minor));
   2658             break;
   2659         case BGP_NOTIFY_MAJOR_UPDATE:
   2660             ND_PRINT((ndo, ", subcode %s (%u)",
   2661 		   tok2str(bgp_notify_minor_update_values, "Unknown",
   2662 			      bgpn.bgpn_minor),
   2663 		   bgpn.bgpn_minor));
   2664             break;
   2665         case BGP_NOTIFY_MAJOR_FSM:
   2666             ND_PRINT((ndo, " subcode %s (%u)",
   2667 		   tok2str(bgp_notify_minor_fsm_values, "Unknown",
   2668 			      bgpn.bgpn_minor),
   2669 		   bgpn.bgpn_minor));
   2670             break;
   2671         case BGP_NOTIFY_MAJOR_CAP:
   2672             ND_PRINT((ndo, " subcode %s (%u)",
   2673 		   tok2str(bgp_notify_minor_cap_values, "Unknown",
   2674 			      bgpn.bgpn_minor),
   2675 		   bgpn.bgpn_minor));
   2676             break;
   2677         case BGP_NOTIFY_MAJOR_CEASE:
   2678             ND_PRINT((ndo, ", subcode %s (%u)",
   2679 		   tok2str(bgp_notify_minor_cease_values, "Unknown",
   2680 			      bgpn.bgpn_minor),
   2681 		   bgpn.bgpn_minor));
   2682 
   2683 	    /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes
   2684              * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES
   2685              */
   2686 	    if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) {
   2687 		tptr = dat + BGP_NOTIFICATION_SIZE;
   2688 		ND_TCHECK2(*tptr, 7);
   2689 		ND_PRINT((ndo, ", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u",
   2690 		       tok2str(af_values, "Unknown",
   2691 				  EXTRACT_16BITS(tptr)),
   2692 		       EXTRACT_16BITS(tptr),
   2693 		       tok2str(bgp_safi_values, "Unknown", *(tptr+2)),
   2694 		       *(tptr+2),
   2695 		       EXTRACT_32BITS(tptr+3)));
   2696 	    }
   2697             break;
   2698         default:
   2699             break;
   2700         }
   2701 
   2702 	return;
   2703 trunc:
   2704 	ND_PRINT((ndo, "[|BGP]"));
   2705 }
   2706 
   2707 static void
   2708 bgp_route_refresh_print(netdissect_options *ndo,
   2709                         const u_char *pptr, int len)
   2710 {
   2711         const struct bgp_route_refresh *bgp_route_refresh_header;
   2712 
   2713 	ND_TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE);
   2714 
   2715         /* some little sanity checking */
   2716         if (len<BGP_ROUTE_REFRESH_SIZE)
   2717             return;
   2718 
   2719         bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr;
   2720 
   2721         ND_PRINT((ndo, "\n\t  AFI %s (%u), SAFI %s (%u)",
   2722                tok2str(af_values,"Unknown",
   2723 			  /* this stinks but the compiler pads the structure
   2724 			   * weird */
   2725 			  EXTRACT_16BITS(&bgp_route_refresh_header->afi)),
   2726                EXTRACT_16BITS(&bgp_route_refresh_header->afi),
   2727                tok2str(bgp_safi_values,"Unknown",
   2728 			  bgp_route_refresh_header->safi),
   2729                bgp_route_refresh_header->safi));
   2730 
   2731         if (ndo->ndo_vflag > 1) {
   2732             ND_TCHECK2(*pptr, len);
   2733             print_unknown_data(ndo, pptr, "\n\t  ", len);
   2734         }
   2735 
   2736         return;
   2737 trunc:
   2738 	ND_PRINT((ndo, "[|BGP]"));
   2739 }
   2740 
   2741 static int
   2742 bgp_header_print(netdissect_options *ndo,
   2743                  const u_char *dat, int length)
   2744 {
   2745 	struct bgp bgp;
   2746 
   2747 	ND_TCHECK2(dat[0], BGP_SIZE);
   2748 	memcpy(&bgp, dat, BGP_SIZE);
   2749 	ND_PRINT((ndo, "\n\t%s Message (%u), length: %u",
   2750                tok2str(bgp_msg_values, "Unknown", bgp.bgp_type),
   2751                bgp.bgp_type,
   2752                length));
   2753 
   2754 	switch (bgp.bgp_type) {
   2755 	case BGP_OPEN:
   2756 		bgp_open_print(ndo, dat, length);
   2757 		break;
   2758 	case BGP_UPDATE:
   2759 		bgp_update_print(ndo, dat, length);
   2760 		break;
   2761 	case BGP_NOTIFICATION:
   2762 		bgp_notification_print(ndo, dat, length);
   2763 		break;
   2764         case BGP_KEEPALIVE:
   2765                 break;
   2766         case BGP_ROUTE_REFRESH:
   2767                 bgp_route_refresh_print(ndo, dat, length);
   2768                 break;
   2769         default:
   2770                 /* we have no decoder for the BGP message */
   2771                 ND_TCHECK2(*dat, length);
   2772                 ND_PRINT((ndo, "\n\t  no Message %u decoder", bgp.bgp_type));
   2773                 print_unknown_data(ndo, dat, "\n\t  ", length);
   2774                 break;
   2775 	}
   2776 	return 1;
   2777 trunc:
   2778 	ND_PRINT((ndo, "[|BGP]"));
   2779 	return 0;
   2780 }
   2781 
   2782 void
   2783 bgp_print(netdissect_options *ndo,
   2784           const u_char *dat, int length)
   2785 {
   2786 	const u_char *p;
   2787 	const u_char *ep;
   2788 	const u_char *start;
   2789 	const u_char marker[] = {
   2790 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   2791 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   2792 	};
   2793 	struct bgp bgp;
   2794 	uint16_t hlen;
   2795 
   2796 	ep = dat + length;
   2797 	if (ndo->ndo_snapend < dat + length)
   2798 		ep = ndo->ndo_snapend;
   2799 
   2800 	ND_PRINT((ndo, ": BGP"));
   2801 
   2802         if (ndo->ndo_vflag < 1) /* lets be less chatty */
   2803                 return;
   2804 
   2805 	p = dat;
   2806 	start = p;
   2807 	while (p < ep) {
   2808 		if (!ND_TTEST2(p[0], 1))
   2809 			break;
   2810 		if (p[0] != 0xff) {
   2811 			p++;
   2812 			continue;
   2813 		}
   2814 
   2815 		if (!ND_TTEST2(p[0], sizeof(marker)))
   2816 			break;
   2817 		if (memcmp(p, marker, sizeof(marker)) != 0) {
   2818 			p++;
   2819 			continue;
   2820 		}
   2821 
   2822 		/* found BGP header */
   2823 		ND_TCHECK2(p[0], BGP_SIZE);	/*XXX*/
   2824 		memcpy(&bgp, p, BGP_SIZE);
   2825 
   2826 		if (start != p)
   2827 			ND_PRINT((ndo, " [|BGP]"));
   2828 
   2829 		hlen = ntohs(bgp.bgp_len);
   2830 		if (hlen < BGP_SIZE) {
   2831 			ND_PRINT((ndo, "\n[|BGP Bogus header length %u < %u]", hlen,
   2832 			    BGP_SIZE));
   2833 			break;
   2834 		}
   2835 
   2836 		if (ND_TTEST2(p[0], hlen)) {
   2837 			if (!bgp_header_print(ndo, p, hlen))
   2838 				return;
   2839 			p += hlen;
   2840 			start = p;
   2841 		} else {
   2842 			ND_PRINT((ndo, "\n[|BGP %s]",
   2843 			       tok2str(bgp_msg_values,
   2844 					  "Unknown Message Type",
   2845 					  bgp.bgp_type)));
   2846 			break;
   2847 		}
   2848 	}
   2849 
   2850 	return;
   2851 
   2852 trunc:
   2853 	ND_PRINT((ndo, " [|BGP]"));
   2854 }
   2855 
   2856 /*
   2857  * Local Variables:
   2858  * c-style: whitesmith
   2859  * c-basic-offset: 4
   2860  * End:
   2861  */
   2862