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