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