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