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