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