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 #include <config.h> 38 39 #include "netdissect-stdinc.h" 40 41 #include <stdio.h> 42 #include <string.h> 43 44 #include "netdissect.h" 45 #include "addrtoname.h" 46 #include "extract.h" 47 #include "af.h" 48 #include "l2vpn.h" 49 50 struct bgp { 51 nd_byte bgp_marker[16]; 52 nd_uint16_t bgp_len; 53 nd_uint8_t bgp_type; 54 }; 55 #define BGP_SIZE 19 /* unaligned */ 56 57 #define BGP_OPEN 1 58 #define BGP_UPDATE 2 59 #define BGP_NOTIFICATION 3 60 #define BGP_KEEPALIVE 4 61 #define BGP_ROUTE_REFRESH 5 62 63 static const struct tok bgp_msg_values[] = { 64 { BGP_OPEN, "Open"}, 65 { BGP_UPDATE, "Update"}, 66 { BGP_NOTIFICATION, "Notification"}, 67 { BGP_KEEPALIVE, "Keepalive"}, 68 { BGP_ROUTE_REFRESH, "Route Refresh"}, 69 { 0, NULL} 70 }; 71 72 struct bgp_open { 73 nd_byte bgpo_marker[16]; 74 nd_uint16_t bgpo_len; 75 nd_uint8_t bgpo_type; 76 nd_uint8_t bgpo_version; 77 nd_uint16_t bgpo_myas; 78 nd_uint16_t bgpo_holdtime; 79 nd_uint32_t bgpo_id; 80 nd_uint8_t bgpo_optlen; 81 /* options should follow */ 82 }; 83 #define BGP_OPEN_SIZE 29 /* unaligned */ 84 85 struct bgp_opt { 86 nd_uint8_t bgpopt_type; 87 nd_uint8_t bgpopt_len; 88 /* variable length */ 89 }; 90 #define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ 91 #define BGP_CAP_HEADER_SIZE 2 /* some compilers may pad to 4 bytes */ 92 93 struct bgp_notification { 94 nd_byte bgpn_marker[16]; 95 nd_uint16_t bgpn_len; 96 nd_uint8_t bgpn_type; 97 nd_uint8_t bgpn_major; 98 nd_uint8_t bgpn_minor; 99 }; 100 #define BGP_NOTIFICATION_SIZE 21 /* unaligned */ 101 102 struct bgp_route_refresh { 103 nd_byte bgp_marker[16]; 104 nd_uint16_t len; 105 nd_uint8_t type; /* No padding after this; afi is, in fact, not aligned */ 106 nd_uint16_t afi; 107 nd_uint8_t res; 108 nd_uint8_t safi; 109 }; 110 #define BGP_ROUTE_REFRESH_SIZE 23 111 112 #define bgp_attr_lenlen(flags, p) \ 113 (((flags) & 0x10) ? 2U : 1U) 114 #define bgp_attr_len(flags, p) \ 115 (((flags) & 0x10) ? GET_BE_U_2(p) : GET_U_1(p)) 116 117 #define BGPTYPE_ORIGIN 1 118 #define BGPTYPE_AS_PATH 2 119 #define BGPTYPE_NEXT_HOP 3 120 #define BGPTYPE_MULTI_EXIT_DISC 4 121 #define BGPTYPE_LOCAL_PREF 5 122 #define BGPTYPE_ATOMIC_AGGREGATE 6 123 #define BGPTYPE_AGGREGATOR 7 124 #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ 125 #define BGPTYPE_ORIGINATOR_ID 9 /* RFC4456 */ 126 #define BGPTYPE_CLUSTER_LIST 10 /* RFC4456 */ 127 #define BGPTYPE_DPA 11 /* deprecated, draft-ietf-idr-bgp-dpa */ 128 #define BGPTYPE_ADVERTISERS 12 /* deprecated RFC1863 */ 129 #define BGPTYPE_RCID_PATH 13 /* deprecated RFC1863 */ 130 #define BGPTYPE_MP_REACH_NLRI 14 /* RFC4760 */ 131 #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC4760 */ 132 #define BGPTYPE_EXTD_COMMUNITIES 16 /* RFC4360 */ 133 #define BGPTYPE_AS4_PATH 17 /* RFC6793 */ 134 #define BGPTYPE_AGGREGATOR4 18 /* RFC6793 */ 135 #define BGPTYPE_PMSI_TUNNEL 22 /* RFC6514 */ 136 #define BGPTYPE_TUNNEL_ENCAP 23 /* RFC5512 */ 137 #define BGPTYPE_TRAFFIC_ENG 24 /* RFC5543 */ 138 #define BGPTYPE_IPV6_EXTD_COMMUNITIES 25 /* RFC5701 */ 139 #define BGPTYPE_AIGP 26 /* RFC7311 */ 140 #define BGPTYPE_PE_DISTINGUISHER_LABEL 27 /* RFC6514 */ 141 #define BGPTYPE_ENTROPY_LABEL 28 /* RFC6790 */ 142 #define BGPTYPE_LARGE_COMMUNITY 32 /* draft-ietf-idr-large-community-05 */ 143 #define BGPTYPE_ATTR_SET 128 /* RFC6368 */ 144 145 #define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */ 146 147 static const struct tok bgp_attr_values[] = { 148 { BGPTYPE_ORIGIN, "Origin"}, 149 { BGPTYPE_AS_PATH, "AS Path"}, 150 { BGPTYPE_AS4_PATH, "AS4 Path"}, 151 { BGPTYPE_NEXT_HOP, "Next Hop"}, 152 { BGPTYPE_MULTI_EXIT_DISC, "Multi Exit Discriminator"}, 153 { BGPTYPE_LOCAL_PREF, "Local Preference"}, 154 { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"}, 155 { BGPTYPE_AGGREGATOR, "Aggregator"}, 156 { BGPTYPE_AGGREGATOR4, "Aggregator4"}, 157 { BGPTYPE_COMMUNITIES, "Community"}, 158 { BGPTYPE_ORIGINATOR_ID, "Originator ID"}, 159 { BGPTYPE_CLUSTER_LIST, "Cluster List"}, 160 { BGPTYPE_DPA, "DPA"}, 161 { BGPTYPE_ADVERTISERS, "Advertisers"}, 162 { BGPTYPE_RCID_PATH, "RCID Path / Cluster ID"}, 163 { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"}, 164 { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"}, 165 { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"}, 166 { BGPTYPE_PMSI_TUNNEL, "PMSI Tunnel"}, 167 { BGPTYPE_TUNNEL_ENCAP, "Tunnel Encapsulation"}, 168 { BGPTYPE_TRAFFIC_ENG, "Traffic Engineering"}, 169 { BGPTYPE_IPV6_EXTD_COMMUNITIES, "IPv6 Extended Community"}, 170 { BGPTYPE_AIGP, "Accumulated IGP Metric"}, 171 { BGPTYPE_PE_DISTINGUISHER_LABEL, "PE Distinguisher Label"}, 172 { BGPTYPE_ENTROPY_LABEL, "Entropy Label"}, 173 { BGPTYPE_LARGE_COMMUNITY, "Large Community"}, 174 { BGPTYPE_ATTR_SET, "Attribute Set"}, 175 { 255, "Reserved for development"}, 176 { 0, NULL} 177 }; 178 179 #define BGP_AS_SET 1 180 #define BGP_AS_SEQUENCE 2 181 #define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */ 182 #define BGP_CONFED_AS_SET 4 /* draft-ietf-idr-rfc3065bis-01 */ 183 184 #define BGP_AS_SEG_TYPE_MIN BGP_AS_SET 185 #define BGP_AS_SEG_TYPE_MAX BGP_CONFED_AS_SET 186 187 static const struct tok bgp_as_path_segment_open_values[] = { 188 { BGP_AS_SEQUENCE, ""}, 189 { BGP_AS_SET, "{ "}, 190 { BGP_CONFED_AS_SEQUENCE, "( "}, 191 { BGP_CONFED_AS_SET, "({ "}, 192 { 0, NULL} 193 }; 194 195 static const struct tok bgp_as_path_segment_close_values[] = { 196 { BGP_AS_SEQUENCE, ""}, 197 { BGP_AS_SET, "}"}, 198 { BGP_CONFED_AS_SEQUENCE, ")"}, 199 { BGP_CONFED_AS_SET, "})"}, 200 { 0, NULL} 201 }; 202 203 #define BGP_OPT_AUTH 1 204 #define BGP_OPT_CAP 2 205 206 static const struct tok bgp_opt_values[] = { 207 { BGP_OPT_AUTH, "Authentication Information"}, 208 { BGP_OPT_CAP, "Capabilities Advertisement"}, 209 { 0, NULL} 210 }; 211 212 #define BGP_CAPCODE_MP 1 /* RFC2858 */ 213 #define BGP_CAPCODE_RR 2 /* RFC2918 */ 214 #define BGP_CAPCODE_ORF 3 /* RFC5291 */ 215 #define BGP_CAPCODE_MR 4 /* RFC3107 */ 216 #define BGP_CAPCODE_EXT_NH 5 /* RFC5549 */ 217 #define BGP_CAPCODE_ML 8 /* RFC8277 */ 218 #define BGP_CAPCODE_RESTART 64 /* RFC4724 */ 219 #define BGP_CAPCODE_AS_NEW 65 /* RFC6793 */ 220 #define BGP_CAPCODE_DYN_CAP 67 /* draft-ietf-idr-dynamic-cap */ 221 #define BGP_CAPCODE_MULTISESS 68 /* draft-ietf-idr-bgp-multisession */ 222 #define BGP_CAPCODE_ADD_PATH 69 /* RFC7911 */ 223 #define BGP_CAPCODE_ENH_RR 70 /* draft-keyur-bgp-enhanced-route-refresh */ 224 #define BGP_CAPCODE_LLGR 71 /* draft-uttaro-idr-bgp-persistence-05 */ 225 #define BGP_CAPCODE_RR_CISCO 128 226 227 static const struct tok bgp_capcode_values[] = { 228 { BGP_CAPCODE_MP, "Multiprotocol Extensions"}, 229 { BGP_CAPCODE_RR, "Route Refresh"}, 230 { BGP_CAPCODE_ORF, "Cooperative Route Filtering"}, 231 { BGP_CAPCODE_MR, "Multiple Routes to a Destination"}, 232 { BGP_CAPCODE_EXT_NH, "Extended Next Hop Encoding"}, 233 { BGP_CAPCODE_ML, "Multiple Labels"}, 234 { BGP_CAPCODE_RESTART, "Graceful Restart"}, 235 { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"}, 236 { BGP_CAPCODE_DYN_CAP, "Dynamic Capability"}, 237 { BGP_CAPCODE_MULTISESS, "Multisession BGP"}, 238 { BGP_CAPCODE_ADD_PATH, "Multiple Paths"}, 239 { BGP_CAPCODE_ENH_RR, "Enhanced Route Refresh"}, 240 { BGP_CAPCODE_LLGR, "Long-lived Graceful Restart"}, 241 { BGP_CAPCODE_RR_CISCO, "Route Refresh (Cisco)"}, 242 { 0, NULL} 243 }; 244 245 #define BGP_NOTIFY_MAJOR_MSG 1 246 #define BGP_NOTIFY_MAJOR_OPEN 2 247 #define BGP_NOTIFY_MAJOR_UPDATE 3 248 #define BGP_NOTIFY_MAJOR_HOLDTIME 4 249 #define BGP_NOTIFY_MAJOR_FSM 5 250 #define BGP_NOTIFY_MAJOR_CEASE 6 251 #define BGP_NOTIFY_MAJOR_CAP 7 252 253 static const struct tok bgp_notify_major_values[] = { 254 { BGP_NOTIFY_MAJOR_MSG, "Message Header Error"}, 255 { BGP_NOTIFY_MAJOR_OPEN, "OPEN Message Error"}, 256 { BGP_NOTIFY_MAJOR_UPDATE, "UPDATE Message Error"}, 257 { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"}, 258 { BGP_NOTIFY_MAJOR_FSM, "Finite State Machine Error"}, 259 { BGP_NOTIFY_MAJOR_CEASE, "Cease"}, 260 { BGP_NOTIFY_MAJOR_CAP, "Capability Message Error"}, 261 { 0, NULL} 262 }; 263 264 /* RFC 4486 */ 265 #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1 266 #define BGP_NOTIFY_MINOR_CEASE_SHUT 2 267 #define BGP_NOTIFY_MINOR_CEASE_RESET 4 268 static const struct tok bgp_notify_minor_cease_values[] = { 269 { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"}, 270 { BGP_NOTIFY_MINOR_CEASE_SHUT, "Administrative Shutdown"}, 271 { 3, "Peer Unconfigured"}, 272 { BGP_NOTIFY_MINOR_CEASE_RESET, "Administrative Reset"}, 273 { 5, "Connection Rejected"}, 274 { 6, "Other Configuration Change"}, 275 { 7, "Connection Collision Resolution"}, 276 { 0, NULL} 277 }; 278 279 static const struct tok bgp_notify_minor_msg_values[] = { 280 { 1, "Connection Not Synchronized"}, 281 { 2, "Bad Message Length"}, 282 { 3, "Bad Message Type"}, 283 { 0, NULL} 284 }; 285 286 static const struct tok bgp_notify_minor_open_values[] = { 287 { 1, "Unsupported Version Number"}, 288 { 2, "Bad Peer AS"}, 289 { 3, "Bad BGP Identifier"}, 290 { 4, "Unsupported Optional Parameter"}, 291 { 5, "Authentication Failure"}, 292 { 6, "Unacceptable Hold Time"}, 293 { 7, "Capability Message Error"}, 294 { 0, NULL} 295 }; 296 297 static const struct tok bgp_notify_minor_update_values[] = { 298 { 1, "Malformed Attribute List"}, 299 { 2, "Unrecognized Well-known Attribute"}, 300 { 3, "Missing Well-known Attribute"}, 301 { 4, "Attribute Flags Error"}, 302 { 5, "Attribute Length Error"}, 303 { 6, "Invalid ORIGIN Attribute"}, 304 { 7, "AS Routing Loop"}, 305 { 8, "Invalid NEXT_HOP Attribute"}, 306 { 9, "Optional Attribute Error"}, 307 { 10, "Invalid Network Field"}, 308 { 11, "Malformed AS_PATH"}, 309 { 0, NULL} 310 }; 311 312 static const struct tok bgp_notify_minor_fsm_values[] = { 313 { 0, "Unspecified Error"}, 314 { 1, "In OpenSent State"}, 315 { 2, "In OpenConfirm State"}, 316 { 3, "In Established State"}, 317 { 0, NULL } 318 }; 319 320 static const struct tok bgp_notify_minor_cap_values[] = { 321 { 1, "Invalid Action Value" }, 322 { 2, "Invalid Capability Length" }, 323 { 3, "Malformed Capability Value" }, 324 { 4, "Unsupported Capability Code" }, 325 { 0, NULL } 326 }; 327 328 static const struct tok bgp_origin_values[] = { 329 { 0, "IGP"}, 330 { 1, "EGP"}, 331 { 2, "Incomplete"}, 332 { 0, NULL} 333 }; 334 335 #define BGP_PMSI_TUNNEL_RSVP_P2MP 1 336 #define BGP_PMSI_TUNNEL_LDP_P2MP 2 337 #define BGP_PMSI_TUNNEL_PIM_SSM 3 338 #define BGP_PMSI_TUNNEL_PIM_SM 4 339 #define BGP_PMSI_TUNNEL_PIM_BIDIR 5 340 #define BGP_PMSI_TUNNEL_INGRESS 6 341 #define BGP_PMSI_TUNNEL_LDP_MP2MP 7 342 343 static const struct tok bgp_pmsi_tunnel_values[] = { 344 { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"}, 345 { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"}, 346 { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"}, 347 { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"}, 348 { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"}, 349 { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"}, 350 { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"}, 351 { 0, NULL} 352 }; 353 354 static const struct tok bgp_pmsi_flag_values[] = { 355 { 0x01, "Leaf Information required"}, 356 { 0, NULL} 357 }; 358 359 #define BGP_AIGP_TLV 1 360 361 static const struct tok bgp_aigp_values[] = { 362 { BGP_AIGP_TLV, "AIGP"}, 363 { 0, NULL} 364 }; 365 366 /* Subsequent address family identifier, RFC2283 section 7 */ 367 #define SAFNUM_RES 0 368 #define SAFNUM_UNICAST 1 369 #define SAFNUM_MULTICAST 2 370 #define SAFNUM_UNIMULTICAST 3 /* deprecated now */ 371 /* labeled BGP RFC3107 */ 372 #define SAFNUM_LABUNICAST 4 373 /* RFC6514 */ 374 #define SAFNUM_MULTICAST_VPN 5 375 /* draft-nalawade-kapoor-tunnel-safi */ 376 #define SAFNUM_TUNNEL 64 377 /* RFC4761 */ 378 #define SAFNUM_VPLS 65 379 /* RFC6037 */ 380 #define SAFNUM_MDT 66 381 /* RFC7432 */ 382 #define SAFNUM_EVPN 70 383 /* RFC4364 */ 384 #define SAFNUM_VPNUNICAST 128 385 /* RFC6513 */ 386 #define SAFNUM_VPNMULTICAST 129 387 #define SAFNUM_VPNUNIMULTICAST 130 /* deprecated now */ 388 /* RFC4684 */ 389 #define SAFNUM_RT_ROUTING_INFO 132 390 391 #define BGP_VPN_RD_LEN 8 392 393 static const struct tok bgp_safi_values[] = { 394 { SAFNUM_RES, "Reserved"}, 395 { SAFNUM_UNICAST, "Unicast"}, 396 { SAFNUM_MULTICAST, "Multicast"}, 397 { SAFNUM_UNIMULTICAST, "Unicast+Multicast"}, 398 { SAFNUM_LABUNICAST, "labeled Unicast"}, 399 { SAFNUM_TUNNEL, "Tunnel"}, 400 { SAFNUM_VPLS, "VPLS"}, 401 { SAFNUM_MDT, "MDT"}, 402 { SAFNUM_EVPN, "EVPN"}, 403 { SAFNUM_VPNUNICAST, "labeled VPN Unicast"}, 404 { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"}, 405 { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"}, 406 { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"}, 407 { SAFNUM_MULTICAST_VPN, "Multicast VPN"}, 408 { 0, NULL } 409 }; 410 411 /* well-known community */ 412 #define BGP_COMMUNITY_NO_EXPORT 0xffffff01 413 #define BGP_COMMUNITY_NO_ADVERT 0xffffff02 414 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 415 416 /* Extended community type - RFC 4360 */ 417 #define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */ 418 #define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */ 419 #define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AN(4bytes):local(2bytes) */ 420 #define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */ 421 #define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */ 422 #define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AN(4bytes):local(2bytes) */ 423 #define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */ 424 /* rfc2547 bgp-mpls-vpns */ 425 #define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */ 426 #define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatibility */ 427 #define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatibility */ 428 #define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatibility */ 429 430 #define BGP_EXT_COM_OSPF_RTYPE 0x0306 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */ 431 #define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatibility */ 432 #define BGP_EXT_COM_ENCAP 0x030c /* rfc5512 */ 433 434 #define BGP_EXT_COM_OSPF_RID 0x0107 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */ 435 #define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatibility */ 436 437 #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */ 438 439 #define BGP_EXT_COM_SOURCE_AS 0x0009 /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */ 440 #define BGP_EXT_COM_VRF_RT_IMP 0x010b /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */ 441 #define BGP_EXT_COM_L2VPN_RT_0 0x000a /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */ 442 #define BGP_EXT_COM_L2VPN_RT_1 0xF10a /* L2VPN Identifier,Format IP address:AN(2bytes) */ 443 444 /* https://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */ 445 #define BGP_EXT_COM_EIGRP_GEN 0x8800 446 #define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801 447 #define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802 448 #define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803 449 #define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804 450 #define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805 451 452 static const struct tok bgp_extd_comm_flag_values[] = { 453 { 0x8000, "vendor-specific"}, 454 { 0x4000, "non-transitive"}, 455 { 0, NULL}, 456 }; 457 458 static const struct tok bgp_extd_comm_subtype_values[] = { 459 { BGP_EXT_COM_RT_0, "target"}, 460 { BGP_EXT_COM_RT_1, "target"}, 461 { BGP_EXT_COM_RT_2, "target"}, 462 { BGP_EXT_COM_RO_0, "origin"}, 463 { BGP_EXT_COM_RO_1, "origin"}, 464 { BGP_EXT_COM_RO_2, "origin"}, 465 { BGP_EXT_COM_LINKBAND, "link-BW"}, 466 { BGP_EXT_COM_VPN_ORIGIN, "ospf-domain"}, 467 { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"}, 468 { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"}, 469 { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"}, 470 { BGP_EXT_COM_OSPF_RTYPE, "ospf-route-type"}, 471 { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"}, 472 { BGP_EXT_COM_ENCAP, "encapsulation"}, 473 { BGP_EXT_COM_OSPF_RID, "ospf-router-id"}, 474 { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"}, 475 { BGP_EXT_COM_L2INFO, "layer2-info"}, 476 { BGP_EXT_COM_EIGRP_GEN, "eigrp-general-route (flag, tag)" }, 477 { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY, "eigrp-route-metric (AS, delay)" }, 478 { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW, "eigrp-route-metric (reliability, nexthop, bandwidth)" }, 479 { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU, "eigrp-route-metric (load, MTU)" }, 480 { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID, "eigrp-external-route (remote-AS, remote-ID)" }, 481 { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC, "eigrp-external-route (remote-proto, remote-metric)" }, 482 { BGP_EXT_COM_SOURCE_AS, "source-AS" }, 483 { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"}, 484 { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"}, 485 { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"}, 486 { 0, NULL}, 487 }; 488 489 /* RFC RFC5512 BGP Tunnel Encapsulation Attribute Tunnel Types */ 490 #define BGP_ENCAP_TUNNEL_L2TPV3_IP 1 491 #define BGP_ENCAP_TUNNEL_GRE 2 492 #define BGP_ENCAP_TUNNEL_TRANSMIT 3 493 #define BGP_ENCAP_TUNNEL_IPSEC 4 494 #define BGP_ENCAP_TUNNEL_IP_IPSEC 5 495 #define BGP_ENCAP_TUNNEL_MPLS_IP 6 496 #define BGP_ENCAP_TUNNEL_IP_IP 7 497 #define BGP_ENCAP_TUNNEL_VXLAN 8 498 #define BGP_ENCAP_TUNNEL_NVGRE 9 499 #define BGP_ENCAP_TUNNEL_MPLS 10 500 #define BGP_ENCAP_TUNNEL_MPLS_GRE 11 501 #define BGP_ENCAP_TUNNEL_VXLAN_GPE 12 502 #define BGP_ENCAP_TUNNEL_MPLS_UDP 13 503 #define BGP_ENCAP_TUNNEL_IPV6 14 504 #define BGP_ENCAP_TUNNEL_SR_TE 15 505 #define BGP_ENCAP_TUNNEL_BARE 16 506 #define BGP_ENCAP_TUNNEL_SR 17 507 508 static const struct tok bgp_extd_comm_encap_tunnel_values[] = { 509 { BGP_ENCAP_TUNNEL_L2TPV3_IP, "L2TPv3 over IP"}, 510 { BGP_ENCAP_TUNNEL_GRE, "GRE"}, 511 { BGP_ENCAP_TUNNEL_TRANSMIT, "Transmit Tunnel"}, 512 { BGP_ENCAP_TUNNEL_IPSEC, "IPsec"}, 513 { BGP_ENCAP_TUNNEL_IP_IPSEC, "IP in IP with IPsec"}, 514 { BGP_ENCAP_TUNNEL_MPLS_IP, "MPLS in IP with IPsec"}, 515 { BGP_ENCAP_TUNNEL_IP_IP, "IP in IP"}, 516 { BGP_ENCAP_TUNNEL_VXLAN, "VXLAN"}, 517 { BGP_ENCAP_TUNNEL_NVGRE, "NVGRE"}, 518 { BGP_ENCAP_TUNNEL_MPLS, "MPLS"}, 519 { BGP_ENCAP_TUNNEL_MPLS_GRE, "MPLS in GRE"}, 520 { BGP_ENCAP_TUNNEL_VXLAN_GPE, "VXLAN GPE"}, 521 { BGP_ENCAP_TUNNEL_MPLS_UDP, "MPLS in UDP"}, 522 { BGP_ENCAP_TUNNEL_IPV6, "IPv6"}, 523 { BGP_ENCAP_TUNNEL_SR_TE, "SR TE"}, 524 { BGP_ENCAP_TUNNEL_BARE, "Bare"}, 525 { BGP_ENCAP_TUNNEL_SR, "SR"}, 526 { 0, NULL}, 527 }; 528 529 /* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */ 530 #define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */ 531 #define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */ 532 #define BGP_OSPF_RTYPE_SUM 3 /* OSPF Summary LSA */ 533 #define BGP_OSPF_RTYPE_EXT 5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */ 534 #define BGP_OSPF_RTYPE_NSSA 7 /* OSPF NSSA External*/ 535 #define BGP_OSPF_RTYPE_SHAM 129 /* OSPF-MPLS-VPN Sham link */ 536 #define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */ 537 538 static const struct tok bgp_extd_comm_ospf_rtype_values[] = { 539 { BGP_OSPF_RTYPE_RTR, "Router" }, 540 { BGP_OSPF_RTYPE_NET, "Network" }, 541 { BGP_OSPF_RTYPE_SUM, "Summary" }, 542 { BGP_OSPF_RTYPE_EXT, "External" }, 543 { BGP_OSPF_RTYPE_NSSA,"NSSA External" }, 544 { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" }, 545 { 0, NULL }, 546 }; 547 548 /* ADD-PATH Send/Receive field values */ 549 static const struct tok bgp_add_path_recvsend[] = { 550 { 1, "Receive" }, 551 { 2, "Send" }, 552 { 3, "Both" }, 553 { 0, NULL }, 554 }; 555 556 #define AS_STR_SIZE sizeof("xxxxx.xxxxx") 557 558 /* 559 * as_printf 560 * 561 * Convert an AS number into a string and return string pointer. 562 * 563 * Depending on bflag is set or not, AS number is converted into ASDOT notation 564 * or plain number notation. 565 * 566 */ 567 static char * 568 as_printf(netdissect_options *ndo, 569 char *str, size_t size, u_int asnum) 570 { 571 if (!ndo->ndo_bflag || asnum <= 0xFFFF) { 572 snprintf(str, size, "%u", asnum); 573 } else { 574 snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF); 575 } 576 return str; 577 } 578 579 #define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv; 580 581 int 582 decode_prefix4(netdissect_options *ndo, 583 const u_char *pptr, u_int itemlen, char *buf, size_t buflen) 584 { 585 nd_ipv4 addr; 586 u_int plen, plenbytes; 587 588 ITEMCHECK(1); 589 plen = GET_U_1(pptr); 590 if (32 < plen) 591 return -1; 592 itemlen -= 1; 593 594 memset(&addr, 0, sizeof(addr)); 595 plenbytes = (plen + 7) / 8; 596 ITEMCHECK(plenbytes); 597 GET_CPY_BYTES(&addr, pptr + 1, plenbytes); 598 if (plen % 8) { 599 ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); 600 } 601 snprintf(buf, buflen, "%s/%u", ipaddr_string(ndo, (const u_char *)&addr), plen); 602 return 1 + plenbytes; 603 604 badtlv: 605 return -2; 606 } 607 608 static int 609 decode_labeled_prefix4(netdissect_options *ndo, 610 const u_char *pptr, u_int itemlen, char *buf, 611 size_t buflen) 612 { 613 nd_ipv4 addr; 614 u_int plen, plenbytes; 615 616 /* prefix length and label = 4 bytes */ 617 ND_TCHECK_4(pptr); 618 ITEMCHECK(4); 619 plen = GET_U_1(pptr); /* get prefix length */ 620 621 /* this is one of the weirdnesses of rfc3107 622 the label length (actually the label + COS bits) 623 is added to the prefix length; 624 we also do only read out just one label - 625 there is no real application for advertisement of 626 stacked labels in a single BGP message 627 */ 628 629 if (24 > plen) 630 return -1; 631 632 plen-=24; /* adjust prefixlen - labellength */ 633 634 if (32 < plen) 635 return -1; 636 itemlen -= 4; 637 638 memset(&addr, 0, sizeof(addr)); 639 plenbytes = (plen + 7) / 8; 640 ITEMCHECK(plenbytes); 641 GET_CPY_BYTES(&addr, pptr + 4, plenbytes); 642 if (plen % 8) { 643 ((u_char *)&addr)[plenbytes - 1] &= ((0xff00 >> (plen % 8)) & 0xff); 644 } 645 /* the label may get offsetted by 4 bits so lets shift it right */ 646 snprintf(buf, buflen, "%s/%u, label:%u %s", 647 ipaddr_string(ndo, (const u_char *)&addr), 648 plen, 649 GET_BE_U_3(pptr + 1)>>4, 650 ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 651 652 return 4 + plenbytes; 653 654 trunc: 655 return -2; 656 657 badtlv: 658 return -3; 659 } 660 661 /* 662 * bgp_vpn_ip_print 663 * 664 * print an ipv4 or ipv6 address into a buffer dependent on address length. 665 */ 666 static char * 667 bgp_vpn_ip_print(netdissect_options *ndo, 668 const u_char *pptr, u_int addr_length) 669 { 670 671 /* worst case string is s fully formatted v6 address */ 672 static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")]; 673 char *pos = addr; 674 675 switch(addr_length) { 676 case (sizeof(nd_ipv4) << 3): /* 32 */ 677 snprintf(pos, sizeof(addr), "%s", GET_IPADDR_STRING(pptr)); 678 break; 679 case (sizeof(nd_ipv6) << 3): /* 128 */ 680 snprintf(pos, sizeof(addr), "%s", GET_IP6ADDR_STRING(pptr)); 681 break; 682 default: 683 snprintf(pos, sizeof(addr), "bogus address length %u", addr_length); 684 break; 685 } 686 pos += strlen(pos); 687 688 *(pos) = '\0'; 689 return (addr); 690 } 691 692 /* 693 * bgp_vpn_sg_print 694 * 695 * print an multicast s,g entry into a buffer. 696 * the s,g entry is encoded like this. 697 * 698 * +-----------------------------------+ 699 * | Multicast Source Length (1 octet) | 700 * +-----------------------------------+ 701 * | Multicast Source (Variable) | 702 * +-----------------------------------+ 703 * | Multicast Group Length (1 octet) | 704 * +-----------------------------------+ 705 * | Multicast Group (Variable) | 706 * +-----------------------------------+ 707 * 708 * return the number of bytes read from the wire. 709 */ 710 static u_int 711 bgp_vpn_sg_print(netdissect_options *ndo, 712 const u_char *pptr, char *buf, size_t buflen) 713 { 714 uint8_t addr_length; 715 u_int total_length, offset; 716 717 total_length = 0; 718 719 /* Source address length, encoded in bits */ 720 addr_length = GET_U_1(pptr); 721 pptr++; 722 723 /* Source address */ 724 ND_TCHECK_LEN(pptr, (addr_length >> 3)); 725 total_length += (addr_length >> 3) + 1; 726 offset = (u_int)strlen(buf); 727 if (addr_length) { 728 snprintf(buf + offset, buflen - offset, ", Source %s", 729 bgp_vpn_ip_print(ndo, pptr, addr_length)); 730 pptr += (addr_length >> 3); 731 } 732 733 /* Group address length, encoded in bits */ 734 addr_length = GET_U_1(pptr); 735 pptr++; 736 737 /* Group address */ 738 ND_TCHECK_LEN(pptr, (addr_length >> 3)); 739 total_length += (addr_length >> 3) + 1; 740 offset = (u_int)strlen(buf); 741 if (addr_length) { 742 snprintf(buf + offset, buflen - offset, ", Group %s", 743 bgp_vpn_ip_print(ndo, pptr, addr_length)); 744 pptr += (addr_length >> 3); 745 } 746 747 trunc: 748 return (total_length); 749 } 750 751 /* Print an RFC 4364 Route Distinguisher */ 752 const char * 753 bgp_vpn_rd_print(netdissect_options *ndo, 754 const u_char *pptr) 755 { 756 /* allocate space for the largest possible string */ 757 static char rd[sizeof("xxxxx.xxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; 758 char *pos = rd; 759 /* allocate space for the largest possible string */ 760 char astostr[AS_STR_SIZE]; 761 762 /* ok lets load the RD format */ 763 switch (GET_BE_U_2(pptr)) { 764 765 case 0: 766 /* 2-byte-AS:number fmt */ 767 snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)", 768 GET_BE_U_2(pptr + 2), 769 GET_BE_U_4(pptr + 4), 770 GET_U_1(pptr + 4), GET_U_1(pptr + 5), 771 GET_U_1(pptr + 6), GET_U_1(pptr + 7)); 772 break; 773 774 case 1: 775 /* IP-address:AS fmt */ 776 snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u", 777 GET_U_1(pptr + 2), GET_U_1(pptr + 3), 778 GET_U_1(pptr + 4), GET_U_1(pptr + 5), 779 GET_BE_U_2(pptr + 6)); 780 break; 781 782 case 2: 783 /* 4-byte-AS:number fmt */ 784 snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)", 785 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(pptr + 2)), 786 GET_BE_U_2(pptr + 6), GET_U_1(pptr + 2), 787 GET_U_1(pptr + 3), GET_U_1(pptr + 4), 788 GET_U_1(pptr + 5), GET_BE_U_2(pptr + 6)); 789 break; 790 default: 791 snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format"); 792 break; 793 } 794 pos += strlen(pos); 795 *(pos) = '\0'; 796 return (rd); 797 } 798 799 /* 800 * Print an RFC 4360 Extended Community. 801 */ 802 static void 803 bgp_extended_community_print(netdissect_options *ndo, 804 const u_char *pptr) 805 { 806 union { /* copy buffer for bandwidth values */ 807 float f; 808 uint32_t i; 809 } bw; 810 /* allocate space for the largest possible string */ 811 char astostr[AS_STR_SIZE]; 812 813 switch (GET_BE_U_2(pptr)) { 814 815 case BGP_EXT_COM_RT_0: 816 case BGP_EXT_COM_RO_0: 817 case BGP_EXT_COM_L2VPN_RT_0: 818 ND_PRINT("%u:%u (= %s)", 819 GET_BE_U_2(pptr + 2), 820 GET_BE_U_4(pptr + 4), 821 GET_IPADDR_STRING(pptr+4)); 822 break; 823 824 case BGP_EXT_COM_RT_1: 825 case BGP_EXT_COM_RO_1: 826 case BGP_EXT_COM_L2VPN_RT_1: 827 case BGP_EXT_COM_VRF_RT_IMP: 828 ND_PRINT("%s:%u", 829 GET_IPADDR_STRING(pptr+2), 830 GET_BE_U_2(pptr + 6)); 831 break; 832 833 case BGP_EXT_COM_RT_2: 834 case BGP_EXT_COM_RO_2: 835 ND_PRINT("%s:%u", 836 as_printf(ndo, astostr, sizeof(astostr), 837 GET_BE_U_4(pptr + 2)), GET_BE_U_2(pptr + 6)); 838 break; 839 840 case BGP_EXT_COM_LINKBAND: 841 bw.i = GET_BE_U_4(pptr + 4); 842 ND_PRINT("bandwidth: %.3f Mbps", 843 bw.f*8/1000000); 844 break; 845 846 case BGP_EXT_COM_VPN_ORIGIN: 847 case BGP_EXT_COM_VPN_ORIGIN2: 848 case BGP_EXT_COM_VPN_ORIGIN3: 849 case BGP_EXT_COM_VPN_ORIGIN4: 850 case BGP_EXT_COM_OSPF_RID: 851 case BGP_EXT_COM_OSPF_RID2: 852 ND_PRINT("%s", GET_IPADDR_STRING(pptr+2)); 853 break; 854 855 case BGP_EXT_COM_OSPF_RTYPE: 856 case BGP_EXT_COM_OSPF_RTYPE2: 857 ND_PRINT("area:%s, router-type:%s, metric-type:%s%s", 858 GET_IPADDR_STRING(pptr+2), 859 tok2str(bgp_extd_comm_ospf_rtype_values, 860 "unknown (0x%02x)", 861 GET_U_1((pptr + 6))), 862 (GET_U_1(pptr + 7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "", 863 ((GET_U_1(pptr + 6) == BGP_OSPF_RTYPE_EXT) || (GET_U_1(pptr + 6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : ""); 864 break; 865 866 case BGP_EXT_COM_L2INFO: 867 ND_PRINT("%s Control Flags [0x%02x]:MTU %u", 868 tok2str(l2vpn_encaps_values, 869 "unknown encaps", 870 GET_U_1((pptr + 2))), 871 GET_U_1((pptr + 3)), 872 GET_BE_U_2(pptr + 4)); 873 break; 874 875 case BGP_EXT_COM_SOURCE_AS: 876 ND_PRINT("AS %u", GET_BE_U_2(pptr + 2)); 877 break; 878 879 case BGP_EXT_COM_ENCAP: 880 ND_PRINT("Tunnel type: %s", tok2str(bgp_extd_comm_encap_tunnel_values, 881 "unknown encaps", 882 GET_BE_U_2(pptr + 6))); 883 break; 884 885 default: 886 ND_PRINT("%02x%02x%02x%02x%02x%02x", 887 GET_U_1(pptr + 2), 888 GET_U_1(pptr + 3), 889 GET_U_1(pptr + 4), 890 GET_U_1(pptr + 5), 891 GET_U_1(pptr + 6), 892 GET_U_1(pptr + 7)); 893 break; 894 } 895 } 896 897 /* 898 * RFC4684 (Section 4)/RFC2858 (Section 4). 899 * RTC membership prefix is structured as follows 900 * [prefix-len] [origin-as] [route-target] 901 * The route-target is encoded as RT ext-comms. 902 * Prefix-len may be 0, 32..96 903 * 904 * Note that pptr is not packet data - it is 905 * a buffer owned by our caller - therefore GET_* 906 * macros can not be used. 907 */ 908 static char * 909 bgp_rt_prefix_print(netdissect_options *ndo, 910 const u_char *pptr, 911 u_int plen) 912 { 913 /* allocate space for the largest possible string */ 914 char rtc_prefix_in_hex[sizeof("0000 0000 0000 0000")] = ""; 915 u_int rtc_prefix_in_hex_len = 0; 916 static char output[61]; /* max response string */ 917 /* allocate space for the largest possible string */ 918 char astostr[AS_STR_SIZE]; 919 uint16_t ec_type = 0; 920 u_int octet_count; 921 u_int i; 922 923 if (plen == 0) { 924 snprintf(output, sizeof(output), "route-target: 0:0/0"); 925 return (output); 926 } 927 928 /* hex representation of the prefix */ 929 octet_count = (plen+7)/8; 930 for (i=0; i<octet_count; i++) { 931 rtc_prefix_in_hex_len += snprintf(rtc_prefix_in_hex+rtc_prefix_in_hex_len, 932 sizeof(rtc_prefix_in_hex)-rtc_prefix_in_hex_len, 933 "%02x%s", *(pptr+i), 934 ((i%2 == 1) && (i<octet_count-1)) ? " " : ""); 935 } 936 937 if (plen < 16) { 938 /* 939 * The prefix is too short to include the full ext-comm type, 940 * so we have no way to parse it further. 941 */ 942 snprintf(output, sizeof(output), "route-target: partial-type: (%s/%d)", 943 rtc_prefix_in_hex, plen); 944 return (output); 945 } 946 947 /* 948 * get the ext-comm type 949 * Note: pptr references a static 8 octet buffer with unused bits set to 0, 950 * hence EXTRACT_*() macros are safe. 951 */ 952 ec_type = EXTRACT_BE_U_2(pptr); 953 switch (ec_type) { 954 case BGP_EXT_COM_RT_0: 955 /* 2-byte-AS:number fmt */ 956 snprintf(output, sizeof(output), "route-target: %u:%u/%d (%s)", 957 EXTRACT_BE_U_2(pptr+2), 958 EXTRACT_BE_U_4(pptr+4), 959 plen, rtc_prefix_in_hex); 960 break; 961 962 case BGP_EXT_COM_RT_1: 963 /* IP-address:AS fmt */ 964 snprintf(output, sizeof(output), "route-target: %u.%u.%u.%u:%u/%d (%s)", 965 *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), 966 EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex); 967 break; 968 969 case BGP_EXT_COM_RT_2: 970 /* 4-byte-AS:number fmt */ 971 snprintf(output, sizeof(output), "route-target: %s:%u/%d (%s)", 972 as_printf(ndo, astostr, sizeof(astostr), EXTRACT_BE_U_4(pptr+2)), 973 EXTRACT_BE_U_2(pptr+6), plen, rtc_prefix_in_hex); 974 break; 975 976 default: 977 snprintf(output, sizeof(output), "route target: unknown-type(%04x) (%s/%d)", 978 ec_type, 979 rtc_prefix_in_hex, plen); 980 break; 981 } 982 return (output); 983 } 984 985 /* RFC 4684 */ 986 static int 987 decode_rt_routing_info(netdissect_options *ndo, 988 const u_char *pptr) 989 { 990 uint8_t route_target[8]; 991 u_int plen; 992 /* allocate space for the largest possible string */ 993 char astostr[AS_STR_SIZE]; 994 u_int num_octets; 995 996 /* NLRI "prefix length" from RFC 2858 Section 4. */ 997 plen = GET_U_1(pptr); /* get prefix length */ 998 999 /* NLRI "prefix" (ibid), valid lengths are { 0, 32, 33, ..., 96 } bits. 1000 * RFC 4684 Section 4 defines the layout of "origin AS" and "route 1001 * target" fields inside the "prefix" depending on its length. 1002 */ 1003 if (0 == plen) { 1004 /* Without "origin AS", without "route target". */ 1005 ND_PRINT("\n\t default route target"); 1006 return 1; 1007 } 1008 1009 if (32 > plen) { 1010 ND_PRINT("\n\t (illegal prefix length)"); 1011 return -1; 1012 } 1013 1014 /* With at least "origin AS", possibly with "route target". */ 1015 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(pptr + 1)); 1016 1017 plen -= 32; /* adjust prefix length */ 1018 1019 if (64 < plen) { 1020 ND_PRINT("\n\t (illegal prefix length)"); 1021 return -1; 1022 } 1023 1024 /* From now on (plen + 7) / 8 evaluates to { 0, 1, 2, ..., 8 } 1025 * and gives the number of octets in the variable-length "route 1026 * target" field inside this NLRI "prefix". Look for it. 1027 */ 1028 memset(&route_target, 0, sizeof(route_target)); 1029 num_octets = (plen + 7) / 8; 1030 GET_CPY_BYTES(&route_target, pptr + 5, num_octets); 1031 /* If mask-len is not on octet boundary, ensure all extra bits are 0 */ 1032 if (plen % 8) { 1033 ((u_char *)&route_target)[num_octets - 1] &= 1034 ((0xff00 >> (plen % 8)) & 0xff); 1035 } 1036 ND_PRINT("\n\t origin AS: %s, %s", 1037 astostr, 1038 bgp_rt_prefix_print(ndo, (u_char *)&route_target, plen)); 1039 1040 return 5 + num_octets; 1041 } 1042 1043 static int 1044 decode_labeled_vpn_prefix4(netdissect_options *ndo, 1045 const u_char *pptr, char *buf, size_t buflen) 1046 { 1047 nd_ipv4 addr; 1048 u_int plen; 1049 1050 plen = GET_U_1(pptr); /* get prefix length */ 1051 1052 if ((24+64) > plen) 1053 return -1; 1054 1055 plen -= (24+64); /* adjust prefixlen - labellength - RD len*/ 1056 1057 if (32 < plen) 1058 return -1; 1059 1060 memset(&addr, 0, sizeof(addr)); 1061 GET_CPY_BYTES(&addr, pptr + 12, (plen + 7) / 8); 1062 if (plen % 8) { 1063 ((u_char *)&addr)[(plen + 7) / 8 - 1] &= 1064 ((0xff00 >> (plen % 8)) & 0xff); 1065 } 1066 /* the label may get offsetted by 4 bits so lets shift it right */ 1067 snprintf(buf, buflen, "RD: %s, %s/%u, label:%u %s", 1068 bgp_vpn_rd_print(ndo, pptr+4), 1069 ipaddr_string(ndo, (const u_char *)&addr), 1070 plen, 1071 GET_BE_U_3(pptr + 1)>>4, 1072 ((GET_U_1(pptr + 3) & 1) == 0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 1073 1074 return 12 + (plen + 7) / 8; 1075 } 1076 1077 /* 1078 * +-------------------------------+ 1079 * | | 1080 * | RD:IPv4-address (12 octets) | 1081 * | | 1082 * +-------------------------------+ 1083 * | MDT Group-address (4 octets) | 1084 * +-------------------------------+ 1085 */ 1086 1087 #define MDT_VPN_NLRI_LEN 16 1088 1089 static int 1090 decode_mdt_vpn_nlri(netdissect_options *ndo, 1091 const u_char *pptr, char *buf, size_t buflen) 1092 { 1093 const u_char *rd; 1094 const u_char *vpn_ip; 1095 1096 /* if the NLRI is not predefined length, quit.*/ 1097 if (GET_U_1(pptr) != MDT_VPN_NLRI_LEN * 8) 1098 return -1; 1099 pptr++; 1100 1101 /* RD */ 1102 ND_TCHECK_8(pptr); 1103 rd = pptr; 1104 pptr += 8; 1105 1106 /* IPv4 address */ 1107 vpn_ip = pptr; 1108 pptr += sizeof(nd_ipv4); 1109 1110 /* MDT Group Address */ 1111 snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s", 1112 bgp_vpn_rd_print(ndo, rd), GET_IPADDR_STRING(vpn_ip), GET_IPADDR_STRING(pptr)); 1113 1114 return MDT_VPN_NLRI_LEN + 1; 1115 1116 trunc: 1117 return -2; 1118 } 1119 1120 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1 1121 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2 1122 #define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3 1123 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4 1124 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE 5 1125 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN 6 1126 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN 7 1127 1128 static const struct tok bgp_multicast_vpn_route_type_values[] = { 1129 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"}, 1130 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"}, 1131 { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"}, 1132 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"}, 1133 { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"}, 1134 { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"}, 1135 { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"}, 1136 { 0, NULL} 1137 }; 1138 1139 static int 1140 decode_multicast_vpn(netdissect_options *ndo, 1141 const u_char *pptr, char *buf, size_t buflen) 1142 { 1143 /* allocate space for the largest possible string */ 1144 char astostr[AS_STR_SIZE]; 1145 uint8_t route_type, route_length; 1146 u_int addr_length, sg_length; 1147 u_int offset; 1148 1149 route_type = GET_U_1(pptr); 1150 pptr++; 1151 route_length = GET_U_1(pptr); 1152 pptr++; 1153 1154 snprintf(buf, buflen, "Route-Type: %s (%u), length: %u", 1155 tok2str(bgp_multicast_vpn_route_type_values, 1156 "Unknown", route_type), 1157 route_type, route_length); 1158 1159 switch(route_type) { 1160 case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI: 1161 ND_TCHECK_LEN(pptr, BGP_VPN_RD_LEN); 1162 if (route_length < BGP_VPN_RD_LEN) 1163 goto trunc; 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 caller 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 assumption 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, 2235 (len-ND_BYTES_BETWEEN(pptr, tptr)), 32); 2236 add_path6 = check_add_path(ndo, tptr, 2237 (len-ND_BYTES_BETWEEN(pptr, tptr)), 128); 2238 2239 while (tptr < pptr + len) { 2240 advance = bgp_nlri_print(ndo, af, safi, tptr, len, buf, sizeof(buf), 2241 add_path4, add_path6); 2242 if (advance == -2) 2243 goto trunc; 2244 if (advance < 0) 2245 break; 2246 tptr += advance; 2247 } 2248 break; 2249 2250 case BGPTYPE_MP_UNREACH_NLRI: 2251 ND_TCHECK_LEN(tptr, BGP_MP_NLRI_MINSIZE); 2252 ret = bgp_mp_af_print(ndo, tptr, tlen, &af, &safi); 2253 if (ret == -2) 2254 goto trunc; 2255 if (ret < 0) 2256 break; 2257 2258 if (len == BGP_MP_NLRI_MINSIZE) 2259 ND_PRINT("\n\t End-of-Rib Marker (empty NLRI)"); 2260 2261 tptr += 3; 2262 2263 add_path4 = check_add_path(ndo, tptr, 2264 (len-ND_BYTES_BETWEEN(pptr, tptr)), 32); 2265 add_path6 = check_add_path(ndo, tptr, 2266 (len-ND_BYTES_BETWEEN(pptr, tptr)), 128); 2267 2268 while (tptr < pptr + len) { 2269 advance = bgp_nlri_print(ndo, af, safi, tptr, len, buf, sizeof(buf), 2270 add_path4, add_path6); 2271 if (advance == -2) 2272 goto trunc; 2273 if (advance < 0) 2274 break; 2275 tptr += advance; 2276 } 2277 break; 2278 case BGPTYPE_EXTD_COMMUNITIES: 2279 if (len % 8) { 2280 ND_PRINT("invalid len"); 2281 break; 2282 } 2283 while (tlen != 0) { 2284 uint16_t extd_comm; 2285 2286 ND_TCHECK_2(tptr); 2287 if (tlen < 2) 2288 goto trunc; 2289 extd_comm=GET_BE_U_2(tptr); 2290 2291 ND_PRINT("\n\t %s (0x%04x), Flags [%s]", 2292 tok2str(bgp_extd_comm_subtype_values, 2293 "unknown extd community typecode", 2294 extd_comm), 2295 extd_comm, 2296 bittok2str(bgp_extd_comm_flag_values, "none", extd_comm)); 2297 2298 ND_TCHECK_8(tptr); 2299 if (tlen < 8) 2300 goto trunc; 2301 ND_PRINT(": "); 2302 bgp_extended_community_print(ndo, tptr); 2303 tlen -= 8; 2304 tptr += 8; 2305 } 2306 break; 2307 2308 case BGPTYPE_PMSI_TUNNEL: 2309 { 2310 uint8_t tunnel_type, flags; 2311 2312 ND_TCHECK_5(tptr); 2313 if (tlen < 5) 2314 goto trunc; 2315 flags = GET_U_1(tptr); 2316 tunnel_type = GET_U_1(tptr + 1); 2317 2318 ND_PRINT("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", 2319 tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), 2320 tunnel_type, 2321 bittok2str(bgp_pmsi_flag_values, "none", flags), 2322 GET_BE_U_3(tptr + 2)>>4); 2323 2324 tptr +=5; 2325 tlen -= 5; 2326 2327 switch (tunnel_type) { 2328 case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */ 2329 case BGP_PMSI_TUNNEL_PIM_BIDIR: 2330 ND_PRINT("\n\t Sender %s, P-Group %s", 2331 GET_IPADDR_STRING(tptr), 2332 GET_IPADDR_STRING(tptr+4)); 2333 break; 2334 2335 case BGP_PMSI_TUNNEL_PIM_SSM: 2336 ND_PRINT("\n\t Root-Node %s, P-Group %s", 2337 GET_IPADDR_STRING(tptr), 2338 GET_IPADDR_STRING(tptr+4)); 2339 break; 2340 case BGP_PMSI_TUNNEL_INGRESS: 2341 ND_PRINT("\n\t Tunnel-Endpoint %s", 2342 GET_IPADDR_STRING(tptr)); 2343 break; 2344 case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */ 2345 case BGP_PMSI_TUNNEL_LDP_MP2MP: 2346 ND_PRINT("\n\t Root-Node %s, LSP-ID 0x%08x", 2347 GET_IPADDR_STRING(tptr), 2348 GET_BE_U_4(tptr + 4)); 2349 break; 2350 case BGP_PMSI_TUNNEL_RSVP_P2MP: 2351 ND_PRINT("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x", 2352 GET_IPADDR_STRING(tptr), 2353 GET_BE_U_4(tptr + 4)); 2354 break; 2355 default: 2356 if (ndo->ndo_vflag <= 1) { 2357 print_unknown_data(ndo, tptr, "\n\t ", tlen); 2358 } 2359 } 2360 break; 2361 } 2362 case BGPTYPE_AIGP: 2363 { 2364 uint8_t type; 2365 uint16_t length; 2366 2367 while (tlen >= 3) { 2368 type = GET_U_1(tptr); 2369 length = GET_BE_U_2(tptr + 1); 2370 tptr += 3; 2371 tlen -= 3; 2372 2373 ND_PRINT("\n\t %s TLV (%u), length %u", 2374 tok2str(bgp_aigp_values, "Unknown", type), 2375 type, length); 2376 2377 if (length < 3) 2378 goto trunc; 2379 length -= 3; 2380 2381 /* 2382 * Check if we can read the TLV data. 2383 */ 2384 if (tlen < length) 2385 goto trunc; 2386 2387 switch (type) { 2388 2389 case BGP_AIGP_TLV: 2390 if (length < 8) 2391 goto trunc; 2392 ND_PRINT(", metric %" PRIu64, 2393 GET_BE_U_8(tptr)); 2394 break; 2395 2396 default: 2397 if (ndo->ndo_vflag <= 1) { 2398 print_unknown_data(ndo, tptr,"\n\t ", length); 2399 } 2400 } 2401 2402 tptr += length; 2403 tlen -= length; 2404 } 2405 break; 2406 } 2407 case BGPTYPE_ATTR_SET: 2408 ND_TCHECK_4(tptr); 2409 if (len < 4) 2410 goto trunc; 2411 ND_PRINT("\n\t Origin AS: %s", 2412 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_4(tptr))); 2413 tptr += 4; 2414 len -= 4; 2415 2416 while (len) { 2417 u_int aflags, alenlen, alen; 2418 2419 ND_TCHECK_2(tptr); 2420 if (len < 2) { 2421 ND_PRINT(" [path attr too short]"); 2422 tptr += len; 2423 break; 2424 } 2425 aflags = GET_U_1(tptr); 2426 atype = GET_U_1(tptr + 1); 2427 tptr += 2; 2428 len -= 2; 2429 alenlen = bgp_attr_lenlen(aflags, tptr); 2430 ND_TCHECK_LEN(tptr, alenlen); 2431 if (len < alenlen) { 2432 ND_PRINT(" [path attr too short]"); 2433 tptr += len; 2434 break; 2435 } 2436 alen = bgp_attr_len(aflags, tptr); 2437 tptr += alenlen; 2438 len -= alenlen; 2439 2440 ND_PRINT("\n\t %s (%u), length: %u", 2441 tok2str(bgp_attr_values, 2442 "Unknown Attribute", atype), 2443 atype, 2444 alen); 2445 2446 if (aflags) { 2447 ND_PRINT(", Flags [%s%s%s%s", 2448 aflags & 0x80 ? "O" : "", 2449 aflags & 0x40 ? "T" : "", 2450 aflags & 0x20 ? "P" : "", 2451 aflags & 0x10 ? "E" : ""); 2452 if (aflags & 0xf) 2453 ND_PRINT("+%x", aflags & 0xf); 2454 ND_PRINT("]"); 2455 } 2456 ND_PRINT(": "); 2457 if (len < alen) { 2458 ND_PRINT(" [path attr too short]"); 2459 tptr += len; 2460 break; 2461 } 2462 /* 2463 * The protocol encoding per se allows ATTR_SET to be nested 2464 * as many times as the message can accommodate. This printer 2465 * used to be able to recurse into ATTR_SET contents until the 2466 * stack exhaustion, but now there is a limit on that (if live 2467 * protocol exchange goes that many levels deep, something is 2468 * probably wrong anyway). Feel free to refine this value if 2469 * you can find the spec with respective normative text. 2470 */ 2471 if (attr_set_level == 10) 2472 ND_PRINT("(too many nested levels, not recursing)"); 2473 else if (!bgp_attr_print(ndo, atype, tptr, alen, attr_set_level + 1)) 2474 return 0; 2475 tptr += alen; 2476 len -= alen; 2477 } 2478 break; 2479 2480 case BGPTYPE_LARGE_COMMUNITY: 2481 if (len == 0 || len % 12) { 2482 ND_PRINT("invalid len"); 2483 break; 2484 } 2485 ND_PRINT("\n\t "); 2486 while (len != 0) { 2487 ND_PRINT("%u:%u:%u%s", 2488 GET_BE_U_4(tptr), 2489 GET_BE_U_4(tptr + 4), 2490 GET_BE_U_4(tptr + 8), 2491 (len > 12) ? ", " : ""); 2492 tptr += 12; 2493 /* 2494 * len will always be a multiple of 12, as per the above, 2495 * so this will never underflow. 2496 */ 2497 len -= 12; 2498 } 2499 break; 2500 default: 2501 ND_TCHECK_LEN(pptr, len); 2502 ND_PRINT("\n\t no Attribute %u decoder", atype); /* we have no decoder for the attribute */ 2503 if (ndo->ndo_vflag <= 1) 2504 print_unknown_data(ndo, pptr, "\n\t ", len); 2505 break; 2506 } 2507 done: 2508 if (ndo->ndo_vflag > 1 && len) { /* omit zero length attributes*/ 2509 ND_TCHECK_LEN(pptr, len); 2510 print_unknown_data(ndo, pptr, "\n\t ", len); 2511 } 2512 return 1; 2513 2514 trunc: 2515 return 0; 2516 } 2517 2518 static void 2519 bgp_capabilities_print(netdissect_options *ndo, 2520 const u_char *opt, u_int caps_len) 2521 { 2522 /* allocate space for the largest possible string */ 2523 char astostr[AS_STR_SIZE]; 2524 u_int cap_type, cap_len, tcap_len, cap_offset; 2525 u_int i = 0; 2526 2527 while (i < caps_len) { 2528 ND_TCHECK_LEN(opt + i, BGP_CAP_HEADER_SIZE); 2529 cap_type=GET_U_1(opt + i); 2530 cap_len=GET_U_1(opt + i + 1); 2531 ND_PRINT("\n\t %s (%u), length: %u", 2532 tok2str(bgp_capcode_values, "Unknown", cap_type), 2533 cap_type, 2534 cap_len); 2535 ND_TCHECK_LEN(opt + 2 + i, cap_len); 2536 switch (cap_type) { 2537 case BGP_CAPCODE_MP: 2538 /* AFI (16 bits), Reserved (8 bits), SAFI (8 bits) */ 2539 if (cap_len < 4) { 2540 ND_PRINT(" (too short, < 4)"); 2541 return; 2542 } 2543 ND_PRINT("\n\t\tAFI %s (%u), SAFI %s (%u)", 2544 tok2str(af_values, "Unknown", GET_BE_U_2(opt + i + 2)), 2545 GET_BE_U_2(opt + i + 2), 2546 tok2str(bgp_safi_values, "Unknown", GET_U_1(opt + i + 5)), 2547 GET_U_1(opt + i + 5)); 2548 break; 2549 case BGP_CAPCODE_ML: 2550 cap_offset = 2; 2551 tcap_len = cap_len; 2552 while (tcap_len >= 4) { 2553 ND_PRINT( "\n\t\tAFI %s (%u), SAFI %s (%u), Count: %u", 2554 tok2str(af_values, "Unknown", 2555 GET_BE_U_2(opt + i + cap_offset)), 2556 GET_BE_U_2(opt + i + cap_offset), 2557 tok2str(bgp_safi_values, "Unknown", 2558 GET_U_1(opt + i + cap_offset + 2)), 2559 GET_U_1(opt + i + cap_offset + 2), 2560 GET_U_1(opt + i + cap_offset + 3)); 2561 tcap_len -= 4; 2562 cap_offset += 4; 2563 } 2564 break; 2565 case BGP_CAPCODE_RESTART: 2566 /* Restart Flags (4 bits), Restart Time in seconds (12 bits) */ 2567 if (cap_len < 2) { 2568 ND_PRINT(" (too short, < 2)"); 2569 return; 2570 } 2571 tcap_len=cap_len; 2572 ND_PRINT("\n\t\tRestart Flags: [%s], Restart Time %us", 2573 ((GET_U_1(opt + i + 2))&0x80) ? "R" : "none", 2574 GET_BE_U_2(opt + i + 2)&0xfff); 2575 tcap_len-=2; 2576 cap_offset=4; 2577 while(tcap_len>=4) { 2578 ND_PRINT("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", 2579 tok2str(af_values,"Unknown", 2580 GET_BE_U_2(opt + i + cap_offset)), 2581 GET_BE_U_2(opt + i + cap_offset), 2582 tok2str(bgp_safi_values,"Unknown", 2583 GET_U_1(opt + i + cap_offset + 2)), 2584 GET_U_1(opt + (i + cap_offset + 2)), 2585 ((GET_U_1(opt + (i + cap_offset + 3)))&0x80) ? "yes" : "no" ); 2586 tcap_len -= 4; 2587 cap_offset += 4; 2588 } 2589 break; 2590 case BGP_CAPCODE_RR: 2591 case BGP_CAPCODE_LLGR: 2592 case BGP_CAPCODE_RR_CISCO: 2593 break; 2594 case BGP_CAPCODE_AS_NEW: 2595 /* 2596 * Extract the 4 byte AS number encoded. 2597 */ 2598 if (cap_len < 4) { 2599 ND_PRINT(" (too short, < 4)"); 2600 return; 2601 } 2602 ND_PRINT("\n\t\t 4 Byte AS %s", 2603 as_printf(ndo, astostr, sizeof(astostr), 2604 GET_BE_U_4(opt + i + 2))); 2605 break; 2606 case BGP_CAPCODE_ADD_PATH: 2607 if (cap_len == 0) { 2608 ND_PRINT(" (bogus)"); /* length */ 2609 break; 2610 } 2611 tcap_len=cap_len; 2612 cap_offset=2; 2613 while (tcap_len != 0) { 2614 if (tcap_len < 4) { 2615 nd_print_invalid(ndo); 2616 break; 2617 } 2618 ND_PRINT("\n\t\tAFI %s (%u), SAFI %s (%u), Send/Receive: %s", 2619 tok2str(af_values,"Unknown",GET_BE_U_2(opt + i + cap_offset)), 2620 GET_BE_U_2(opt + i + cap_offset), 2621 tok2str(bgp_safi_values,"Unknown",GET_U_1(opt + i + cap_offset + 2)), 2622 GET_U_1(opt + (i + cap_offset + 2)), 2623 tok2str(bgp_add_path_recvsend,"Bogus (0x%02x)",GET_U_1(opt + i + cap_offset + 3)) 2624 ); 2625 tcap_len -= 4; 2626 cap_offset += 4; 2627 } 2628 break; 2629 default: 2630 ND_PRINT("\n\t\tno decoder for Capability %u", 2631 cap_type); 2632 if (ndo->ndo_vflag <= 1) 2633 print_unknown_data(ndo, opt + i + 2, "\n\t\t", 2634 cap_len); 2635 break; 2636 } 2637 if (ndo->ndo_vflag > 1 && cap_len != 0) { 2638 print_unknown_data(ndo, opt + i + 2, "\n\t\t", cap_len); 2639 } 2640 i += BGP_CAP_HEADER_SIZE + cap_len; 2641 } 2642 return; 2643 2644 trunc: 2645 nd_print_trunc(ndo); 2646 } 2647 2648 static void 2649 bgp_open_print(netdissect_options *ndo, 2650 const u_char *dat, u_int length) 2651 { 2652 /* allocate space for the largest possible string */ 2653 char astostr[AS_STR_SIZE]; 2654 const struct bgp_open *bgp_open_header; 2655 u_int optslen; 2656 const struct bgp_opt *bgpopt; 2657 const u_char *opt; 2658 u_int i; 2659 2660 ND_TCHECK_LEN(dat, BGP_OPEN_SIZE); 2661 if (length < BGP_OPEN_SIZE) 2662 goto trunc; 2663 2664 bgp_open_header = (const struct bgp_open *)dat; 2665 2666 ND_PRINT("\n\t Version %u, ", 2667 GET_U_1(bgp_open_header->bgpo_version)); 2668 ND_PRINT("my AS %s, ", 2669 as_printf(ndo, astostr, sizeof(astostr), GET_BE_U_2(bgp_open_header->bgpo_myas))); 2670 ND_PRINT("Holdtime %us, ", 2671 GET_BE_U_2(bgp_open_header->bgpo_holdtime)); 2672 ND_PRINT("ID %s", GET_IPADDR_STRING(bgp_open_header->bgpo_id)); 2673 optslen = GET_U_1(bgp_open_header->bgpo_optlen); 2674 ND_PRINT("\n\t Optional parameters, length: %u", optslen); 2675 2676 opt = dat + BGP_OPEN_SIZE; 2677 length -= BGP_OPEN_SIZE; 2678 2679 i = 0; 2680 while (i < optslen) { 2681 uint8_t opt_type, opt_len; 2682 2683 ND_TCHECK_LEN(opt + i, BGP_OPT_SIZE); 2684 if (length < BGP_OPT_SIZE + i) 2685 goto trunc; 2686 bgpopt = (const struct bgp_opt *)(opt + i); 2687 opt_type = GET_U_1(bgpopt->bgpopt_type); 2688 opt_len = GET_U_1(bgpopt->bgpopt_len); 2689 if (BGP_OPT_SIZE + i + opt_len > optslen) { 2690 ND_PRINT("\n\t Option %u, length: %u, goes past the end of the options", 2691 opt_type, opt_len); 2692 break; 2693 } 2694 2695 ND_PRINT("\n\t Option %s (%u), length: %u", 2696 tok2str(bgp_opt_values,"Unknown",opt_type), 2697 opt_type, 2698 opt_len); 2699 2700 /* now let's decode the options we know*/ 2701 switch(opt_type) { 2702 2703 case BGP_OPT_CAP: 2704 bgp_capabilities_print(ndo, opt + BGP_OPT_SIZE + i, 2705 opt_len); 2706 break; 2707 2708 case BGP_OPT_AUTH: 2709 default: 2710 ND_PRINT("\n\t no decoder for option %u", 2711 opt_type); 2712 break; 2713 } 2714 i += BGP_OPT_SIZE + opt_len; 2715 } 2716 return; 2717 trunc: 2718 nd_print_trunc(ndo); 2719 } 2720 2721 static void 2722 bgp_update_print(netdissect_options *ndo, 2723 const u_char *dat, u_int length) 2724 { 2725 const u_char *p; 2726 u_int withdrawn_routes_len; 2727 char buf[MAXHOSTNAMELEN + 100]; 2728 int wpfx; 2729 u_int len; 2730 int i; 2731 int add_path; 2732 u_int path_id = 0; 2733 2734 ND_TCHECK_LEN(dat, BGP_SIZE); 2735 if (length < BGP_SIZE) 2736 goto trunc; 2737 p = dat + BGP_SIZE; 2738 length -= BGP_SIZE; 2739 2740 /* Unfeasible routes */ 2741 ND_TCHECK_2(p); 2742 if (length < 2) 2743 goto trunc; 2744 withdrawn_routes_len = GET_BE_U_2(p); 2745 p += 2; 2746 length -= 2; 2747 if (withdrawn_routes_len > 1) { 2748 /* 2749 * Without keeping state from the original NLRI message, 2750 * it's not possible to tell if this a v4 or v6 route, 2751 * so only try to decode it if we're not v6 enabled. 2752 */ 2753 ND_TCHECK_LEN(p, withdrawn_routes_len); 2754 if (length < withdrawn_routes_len) 2755 goto trunc; 2756 ND_PRINT("\n\t Withdrawn routes:"); 2757 add_path = check_add_path(ndo, p, withdrawn_routes_len, 32); 2758 while (withdrawn_routes_len != 0) { 2759 if (add_path) { 2760 if (withdrawn_routes_len < 4) { 2761 p += withdrawn_routes_len; 2762 length -= withdrawn_routes_len; 2763 break; 2764 } 2765 path_id = GET_BE_U_4(p); 2766 p += 4; 2767 length -= 4; 2768 withdrawn_routes_len -= 4; 2769 } 2770 wpfx = decode_prefix4(ndo, p, withdrawn_routes_len, buf, sizeof(buf)); 2771 if (wpfx == -1) { 2772 ND_PRINT("\n\t (illegal prefix length)"); 2773 break; 2774 } else if (wpfx == -2) 2775 goto trunc; /* bytes left, but not enough */ 2776 else { 2777 ND_PRINT("\n\t %s", buf); 2778 if (add_path) { 2779 ND_PRINT(" Path Id: %u", path_id); 2780 } 2781 p += wpfx; 2782 length -= wpfx; 2783 withdrawn_routes_len -= wpfx; 2784 } 2785 } 2786 } else { 2787 ND_TCHECK_LEN(p, withdrawn_routes_len); 2788 if (length < withdrawn_routes_len) 2789 goto trunc; 2790 p += withdrawn_routes_len; 2791 length -= withdrawn_routes_len; 2792 } 2793 2794 ND_TCHECK_2(p); 2795 if (length < 2) 2796 goto trunc; 2797 len = GET_BE_U_2(p); 2798 p += 2; 2799 length -= 2; 2800 2801 if (withdrawn_routes_len == 0 && len == 0 && length == 0) { 2802 /* No withdrawn routes, no path attributes, no NLRI */ 2803 ND_PRINT("\n\t End-of-Rib Marker (empty NLRI)"); 2804 return; 2805 } 2806 2807 if (len) { 2808 /* Make sure the path attributes don't go past the end of the packet */ 2809 if (length < len) 2810 goto trunc; 2811 /* do something more useful!*/ 2812 while (len) { 2813 uint8_t aflags, atype, alenlen; 2814 uint16_t alen; 2815 2816 ND_TCHECK_2(p); 2817 if (length < 2) 2818 goto trunc; 2819 if (len < 2) { 2820 ND_PRINT("\n\t [path attrs too short]"); 2821 p += len; 2822 length -= len; 2823 break; 2824 } 2825 aflags = GET_U_1(p); 2826 atype = GET_U_1(p + 1); 2827 p += 2; 2828 len -= 2; 2829 length -= 2; 2830 alenlen = bgp_attr_lenlen(aflags, p); 2831 ND_TCHECK_LEN(p, alenlen); 2832 if (length < alenlen) 2833 goto trunc; 2834 if (len < alenlen) { 2835 ND_PRINT("\n\t [path attrs too short]"); 2836 p += len; 2837 length -= len; 2838 break; 2839 } 2840 alen = bgp_attr_len(aflags, p); 2841 p += alenlen; 2842 len -= alenlen; 2843 length -= alenlen; 2844 2845 ND_PRINT("\n\t %s (%u), length: %u", 2846 tok2str(bgp_attr_values, "Unknown Attribute", atype), 2847 atype, 2848 alen); 2849 2850 if (aflags) { 2851 ND_PRINT(", Flags [%s%s%s%s", 2852 aflags & 0x80 ? "O" : "", 2853 aflags & 0x40 ? "T" : "", 2854 aflags & 0x20 ? "P" : "", 2855 aflags & 0x10 ? "E" : ""); 2856 if (aflags & 0xf) 2857 ND_PRINT("+%x", aflags & 0xf); 2858 ND_PRINT("]: "); 2859 } 2860 if (len < alen) { 2861 ND_PRINT(" [path attrs too short]"); 2862 p += len; 2863 length -= len; 2864 break; 2865 } 2866 if (length < alen) 2867 goto trunc; 2868 if (!bgp_attr_print(ndo, atype, p, alen, 0)) 2869 goto trunc; 2870 p += alen; 2871 len -= alen; 2872 length -= alen; 2873 } 2874 } 2875 2876 if (length) { 2877 add_path = check_add_path(ndo, p, length, 32); 2878 ND_PRINT("\n\t Updated routes:"); 2879 while (length != 0) { 2880 if (add_path) { 2881 ND_TCHECK_4(p); 2882 if (length < 4) 2883 goto trunc; 2884 path_id = GET_BE_U_4(p); 2885 p += 4; 2886 length -= 4; 2887 } 2888 i = decode_prefix4(ndo, p, length, buf, sizeof(buf)); 2889 if (i == -1) { 2890 ND_PRINT("\n\t (illegal prefix length)"); 2891 break; 2892 } else if (i == -2) 2893 goto trunc; /* bytes left, but not enough */ 2894 else { 2895 ND_PRINT("\n\t %s", buf); 2896 if (add_path) { 2897 ND_PRINT(" Path Id: %u", path_id); 2898 } 2899 p += i; 2900 length -= i; 2901 } 2902 } 2903 } 2904 return; 2905 trunc: 2906 nd_print_trunc(ndo); 2907 } 2908 2909 static void 2910 bgp_notification_print(netdissect_options *ndo, 2911 const u_char *dat, u_int length) 2912 { 2913 const struct bgp_notification *bgp_notification_header; 2914 const u_char *tptr; 2915 uint8_t bgpn_major, bgpn_minor; 2916 2917 ND_TCHECK_LEN(dat, BGP_NOTIFICATION_SIZE); 2918 if (length<BGP_NOTIFICATION_SIZE) 2919 return; 2920 2921 bgp_notification_header = (const struct bgp_notification *)dat; 2922 bgpn_major = GET_U_1(bgp_notification_header->bgpn_major); 2923 bgpn_minor = GET_U_1(bgp_notification_header->bgpn_minor); 2924 2925 ND_PRINT(", %s (%u)", 2926 tok2str(bgp_notify_major_values, "Unknown Error", 2927 bgpn_major), 2928 bgpn_major); 2929 2930 switch (bgpn_major) { 2931 2932 case BGP_NOTIFY_MAJOR_MSG: 2933 ND_PRINT(", subcode %s (%u)", 2934 tok2str(bgp_notify_minor_msg_values, "Unknown", 2935 bgpn_minor), 2936 bgpn_minor); 2937 break; 2938 case BGP_NOTIFY_MAJOR_OPEN: 2939 ND_PRINT(", subcode %s (%u)", 2940 tok2str(bgp_notify_minor_open_values, "Unknown", 2941 bgpn_minor), 2942 bgpn_minor); 2943 break; 2944 case BGP_NOTIFY_MAJOR_UPDATE: 2945 ND_PRINT(", subcode %s (%u)", 2946 tok2str(bgp_notify_minor_update_values, "Unknown", 2947 bgpn_minor), 2948 bgpn_minor); 2949 break; 2950 case BGP_NOTIFY_MAJOR_FSM: 2951 ND_PRINT(" subcode %s (%u)", 2952 tok2str(bgp_notify_minor_fsm_values, "Unknown", 2953 bgpn_minor), 2954 bgpn_minor); 2955 break; 2956 case BGP_NOTIFY_MAJOR_CAP: 2957 ND_PRINT(" subcode %s (%u)", 2958 tok2str(bgp_notify_minor_cap_values, "Unknown", 2959 bgpn_minor), 2960 bgpn_minor); 2961 break; 2962 case BGP_NOTIFY_MAJOR_CEASE: 2963 ND_PRINT(", subcode %s (%u)", 2964 tok2str(bgp_notify_minor_cease_values, "Unknown", 2965 bgpn_minor), 2966 bgpn_minor); 2967 2968 /* RFC 4486 mentions optionally 7 bytes 2969 * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES 2970 */ 2971 if(bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) { 2972 tptr = dat + BGP_NOTIFICATION_SIZE; 2973 ND_PRINT(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", 2974 tok2str(af_values, "Unknown", GET_BE_U_2(tptr)), 2975 GET_BE_U_2(tptr), 2976 tok2str(bgp_safi_values, "Unknown", GET_U_1((tptr + 2))), 2977 GET_U_1((tptr + 2)), 2978 GET_BE_U_4(tptr + 3)); 2979 } 2980 /* 2981 * RFC 9003 describes a method to send a communication 2982 * intended for human consumption regarding the Administrative Shutdown 2983 */ 2984 if ((bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT || 2985 bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) && 2986 length >= BGP_NOTIFICATION_SIZE + 1) { 2987 tptr = dat + BGP_NOTIFICATION_SIZE; 2988 uint8_t shutdown_comm_length = GET_U_1(tptr); 2989 uint8_t remainder_offset = 0; 2990 /* garbage, hexdump it all */ 2991 if (shutdown_comm_length > length - (BGP_NOTIFICATION_SIZE + 1)) { 2992 ND_PRINT(", invalid Shutdown Communication length"); 2993 } else if (shutdown_comm_length == 0) { 2994 ND_PRINT(", empty Shutdown Communication"); 2995 remainder_offset += 1; 2996 } 2997 /* a proper shutdown communication */ 2998 else { 2999 ND_PRINT(", Shutdown Communication (length: %u): \"", shutdown_comm_length); 3000 (void)nd_printn(ndo, tptr+1, shutdown_comm_length, NULL); 3001 ND_PRINT("\""); 3002 remainder_offset += shutdown_comm_length + 1; 3003 } 3004 /* if there is trailing data, hexdump it */ 3005 if(length - (remainder_offset + BGP_NOTIFICATION_SIZE) > 0) { 3006 ND_PRINT(", Data: (length: %u)", length - (remainder_offset + BGP_NOTIFICATION_SIZE)); 3007 hex_print(ndo, "\n\t\t", tptr + remainder_offset, length - (remainder_offset + BGP_NOTIFICATION_SIZE)); 3008 } 3009 } 3010 break; 3011 default: 3012 break; 3013 } 3014 3015 return; 3016 trunc: 3017 nd_print_trunc(ndo); 3018 } 3019 3020 static void 3021 bgp_route_refresh_print(netdissect_options *ndo, 3022 const u_char *pptr, u_int len) 3023 { 3024 const struct bgp_route_refresh *bgp_route_refresh_header; 3025 3026 ND_TCHECK_LEN(pptr, BGP_ROUTE_REFRESH_SIZE); 3027 3028 /* some little sanity checking */ 3029 if (len<BGP_ROUTE_REFRESH_SIZE) 3030 return; 3031 3032 bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr; 3033 3034 ND_PRINT("\n\t AFI %s (%u), SAFI %s (%u)", 3035 tok2str(af_values,"Unknown", 3036 GET_BE_U_2(bgp_route_refresh_header->afi)), 3037 GET_BE_U_2(bgp_route_refresh_header->afi), 3038 tok2str(bgp_safi_values,"Unknown", 3039 GET_U_1(bgp_route_refresh_header->safi)), 3040 GET_U_1(bgp_route_refresh_header->safi)); 3041 3042 if (ndo->ndo_vflag > 1) { 3043 ND_TCHECK_LEN(pptr, len); 3044 print_unknown_data(ndo, pptr, "\n\t ", len); 3045 } 3046 3047 return; 3048 trunc: 3049 nd_print_trunc(ndo); 3050 } 3051 3052 static int 3053 bgp_pdu_print(netdissect_options *ndo, 3054 const u_char *dat, u_int length) 3055 { 3056 const struct bgp *bgp_header; 3057 uint8_t bgp_type; 3058 3059 ND_TCHECK_LEN(dat, BGP_SIZE); 3060 bgp_header = (const struct bgp *)dat; 3061 bgp_type = GET_U_1(bgp_header->bgp_type); 3062 3063 ND_PRINT("\n\t%s Message (%u), length: %u", 3064 tok2str(bgp_msg_values, "Unknown", bgp_type), 3065 bgp_type, 3066 length); 3067 3068 switch (bgp_type) { 3069 case BGP_OPEN: 3070 bgp_open_print(ndo, dat, length); 3071 break; 3072 case BGP_UPDATE: 3073 bgp_update_print(ndo, dat, length); 3074 break; 3075 case BGP_NOTIFICATION: 3076 bgp_notification_print(ndo, dat, length); 3077 break; 3078 case BGP_KEEPALIVE: 3079 break; 3080 case BGP_ROUTE_REFRESH: 3081 bgp_route_refresh_print(ndo, dat, length); 3082 break; 3083 default: 3084 /* we have no decoder for the BGP message */ 3085 ND_TCHECK_LEN(dat, length); 3086 ND_PRINT("\n\t no Message %u decoder", bgp_type); 3087 print_unknown_data(ndo, dat, "\n\t ", length); 3088 break; 3089 } 3090 return 1; 3091 trunc: 3092 nd_print_trunc(ndo); 3093 return 0; 3094 } 3095 3096 void 3097 bgp_print(netdissect_options *ndo, 3098 const u_char *dat, u_int length _U_) 3099 { 3100 const u_char *p; 3101 const u_char *ep = ndo->ndo_snapend; 3102 const u_char *start; 3103 const u_char marker[] = { 3104 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 3105 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 3106 }; 3107 const struct bgp *bgp_header; 3108 uint16_t hlen; 3109 3110 ndo->ndo_protocol = "bgp"; 3111 ND_PRINT(": BGP"); 3112 3113 if (ndo->ndo_vflag < 1) /* lets be less chatty */ 3114 return; 3115 3116 p = dat; 3117 start = p; 3118 while (p < ep) { 3119 if (!ND_TTEST_1(p)) 3120 break; 3121 if (GET_U_1(p) != 0xff) { 3122 p++; 3123 continue; 3124 } 3125 3126 if (!ND_TTEST_LEN(p, sizeof(marker))) 3127 break; 3128 if (memcmp(p, marker, sizeof(marker)) != 0) { 3129 p++; 3130 continue; 3131 } 3132 3133 /* found BGP header */ 3134 ND_TCHECK_LEN(p, BGP_SIZE); 3135 bgp_header = (const struct bgp *)p; 3136 3137 if (start != p) 3138 nd_print_trunc(ndo); 3139 3140 hlen = GET_BE_U_2(bgp_header->bgp_len); 3141 if (hlen < BGP_SIZE) { 3142 ND_PRINT("\nmessage length %u < %u", hlen, BGP_SIZE); 3143 nd_print_invalid(ndo); 3144 break; 3145 } 3146 3147 if (ND_TTEST_LEN(p, hlen)) { 3148 if (!bgp_pdu_print(ndo, p, hlen)) 3149 return; 3150 p += hlen; 3151 start = p; 3152 } else { 3153 ND_PRINT("\n[|BGP %s]", 3154 tok2str(bgp_msg_values, 3155 "Unknown Message Type", 3156 GET_U_1(bgp_header->bgp_type))); 3157 break; 3158 } 3159 } 3160 3161 return; 3162 3163 trunc: 3164 nd_print_trunc(ndo); 3165 } 3166