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@juniper.net) 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 760 ND_TCHECK(pptr[0]); 761 plen = pptr[0]; /* get prefix length */ 762 763 if (0 == plen) { 764 snprintf(buf, buflen, "default route target"); 765 return 1; 766 } 767 768 if (32 > plen) 769 return -1; 770 771 plen-=32; /* adjust prefix length */ 772 773 if (64 < plen) 774 return -1; 775 776 memset(&route_target, 0, sizeof(route_target)); 777 ND_TCHECK2(pptr[1], (plen + 7) / 8); 778 memcpy(&route_target, &pptr[1], (plen + 7) / 8); 779 if (plen % 8) { 780 ((u_char *)&route_target)[(plen + 7) / 8 - 1] &= 781 ((0xff00 >> (plen % 8)) & 0xff); 782 } 783 snprintf(buf, buflen, "origin AS: %s, route target %s", 784 as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)), 785 bgp_vpn_rd_print(ndo, (u_char *)&route_target)); 786 787 return 5 + (plen + 7) / 8; 788 789 trunc: 790 return -2; 791 } 792 793 static int 794 decode_labeled_vpn_prefix4(netdissect_options *ndo, 795 const u_char *pptr, char *buf, u_int buflen) 796 { 797 struct in_addr addr; 798 u_int plen; 799 800 ND_TCHECK(pptr[0]); 801 plen = pptr[0]; /* get prefix length */ 802 803 if ((24+64) > plen) 804 return -1; 805 806 plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ 807 808 if (32 < plen) 809 return -1; 810 811 memset(&addr, 0, sizeof(addr)); 812 ND_TCHECK2(pptr[12], (plen + 7) / 8); 813 memcpy(&addr, &pptr[12], (plen + 7) / 8); 814 if (plen % 8) { 815 ((u_char *)&addr)[(plen + 7) / 8 - 1] &= 816 ((0xff00 >> (plen % 8)) & 0xff); 817 } 818 /* the label may get offsetted by 4 bits so lets shift it right */ 819 snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", 820 bgp_vpn_rd_print(ndo, pptr+4), 821 ipaddr_string(ndo, &addr), 822 plen, 823 EXTRACT_24BITS(pptr+1)>>4, 824 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 825 826 return 12 + (plen + 7) / 8; 827 828 trunc: 829 return -2; 830 } 831 832 /* 833 * +-------------------------------+ 834 * | | 835 * | RD:IPv4-address (12 octets) | 836 * | | 837 * +-------------------------------+ 838 * | MDT Group-address (4 octets) | 839 * +-------------------------------+ 840 */ 841 842 #define MDT_VPN_NLRI_LEN 16 843 844 static int 845 decode_mdt_vpn_nlri(netdissect_options *ndo, 846 const u_char *pptr, char *buf, u_int buflen) 847 { 848 849 const u_char *rd; 850 const u_char *vpn_ip; 851 852 ND_TCHECK(pptr[0]); 853 854 /* if the NLRI is not predefined length, quit.*/ 855 if (*pptr != MDT_VPN_NLRI_LEN * 8) 856 return -1; 857 pptr++; 858 859 /* RD */ 860 ND_TCHECK2(pptr[0], 8); 861 rd = pptr; 862 pptr+=8; 863 864 /* IPv4 address */ 865 ND_TCHECK2(pptr[0], sizeof(struct in_addr)); 866 vpn_ip = pptr; 867 pptr+=sizeof(struct in_addr); 868 869 /* MDT Group Address */ 870 ND_TCHECK2(pptr[0], sizeof(struct in_addr)); 871 872 snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s", 873 bgp_vpn_rd_print(ndo, rd), ipaddr_string(ndo, vpn_ip), ipaddr_string(ndo, pptr)); 874 875 return MDT_VPN_NLRI_LEN + 1; 876 877 trunc: 878 879 return -2; 880 } 881 882 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1 883 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2 884 #define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3 885 #define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4 886 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE 5 887 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN 6 888 #define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN 7 889 890 static const struct tok bgp_multicast_vpn_route_type_values[] = { 891 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"}, 892 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"}, 893 { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"}, 894 { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"}, 895 { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"}, 896 { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"}, 897 { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"}, 898 }; 899 900 static int 901 decode_multicast_vpn(netdissect_options *ndo, 902 const u_char *pptr, char *buf, u_int buflen) 903 { 904 uint8_t route_type, route_length, addr_length, sg_length; 905 u_int offset; 906 907 ND_TCHECK2(pptr[0], 2); 908 route_type = *pptr++; 909 route_length = *pptr++; 910 911 snprintf(buf, buflen, "Route-Type: %s (%u), length: %u", 912 tok2str(bgp_multicast_vpn_route_type_values, 913 "Unknown", route_type), 914 route_type, route_length); 915 916 switch(route_type) { 917 case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI: 918 ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN); 919 offset = strlen(buf); 920 snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s", 921 bgp_vpn_rd_print(ndo, pptr), 922 bgp_vpn_ip_print(ndo, pptr + BGP_VPN_RD_LEN, 923 (route_length - BGP_VPN_RD_LEN) << 3)); 924 break; 925 case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI: 926 ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4); 927 offset = strlen(buf); 928 snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", 929 bgp_vpn_rd_print(ndo, pptr), 930 as_printf(ndo, astostr, sizeof(astostr), 931 EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); 932 break; 933 934 case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI: 935 ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN); 936 offset = strlen(buf); 937 snprintf(buf + offset, buflen - offset, ", RD: %s", 938 bgp_vpn_rd_print(ndo, pptr)); 939 pptr += BGP_VPN_RD_LEN; 940 941 sg_length = bgp_vpn_sg_print(ndo, pptr, buf, buflen); 942 addr_length = route_length - sg_length; 943 944 ND_TCHECK2(pptr[0], addr_length); 945 offset = strlen(buf); 946 snprintf(buf + offset, buflen - offset, ", Originator %s", 947 bgp_vpn_ip_print(ndo, pptr, addr_length << 3)); 948 break; 949 950 case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE: 951 ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN); 952 offset = strlen(buf); 953 snprintf(buf + offset, buflen - offset, ", RD: %s", 954 bgp_vpn_rd_print(ndo, pptr)); 955 pptr += BGP_VPN_RD_LEN; 956 957 bgp_vpn_sg_print(ndo, pptr, buf, buflen); 958 break; 959 960 case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */ 961 case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN: 962 ND_TCHECK2(pptr[0], BGP_VPN_RD_LEN); 963 offset = strlen(buf); 964 snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", 965 bgp_vpn_rd_print(ndo, pptr), 966 as_printf(ndo, astostr, sizeof(astostr), 967 EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); 968 pptr += BGP_VPN_RD_LEN; 969 970 bgp_vpn_sg_print(ndo, pptr, buf, buflen); 971 break; 972 973 /* 974 * no per route-type printing yet. 975 */ 976 case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF: 977 default: 978 break; 979 } 980 981 return route_length + 2; 982 983 trunc: 984 return -2; 985 } 986 987 /* 988 * As I remember, some versions of systems have an snprintf() that 989 * returns -1 if the buffer would have overflowed. If the return 990 * value is negative, set buflen to 0, to indicate that we've filled 991 * the buffer up. 992 * 993 * If the return value is greater than buflen, that means that 994 * the buffer would have overflowed; again, set buflen to 0 in 995 * that case. 996 */ 997 #define UPDATE_BUF_BUFLEN(buf, buflen, stringlen) \ 998 if (stringlen<0) \ 999 buflen=0; \ 1000 else if ((u_int)stringlen>buflen) \ 1001 buflen=0; \ 1002 else { \ 1003 buflen-=stringlen; \ 1004 buf+=stringlen; \ 1005 } 1006 1007 static int 1008 decode_labeled_vpn_l2(netdissect_options *ndo, 1009 const u_char *pptr, char *buf, u_int buflen) 1010 { 1011 int plen,tlen,stringlen,tlv_type,tlv_len,ttlv_len; 1012 1013 ND_TCHECK2(pptr[0], 2); 1014 plen=EXTRACT_16BITS(pptr); 1015 tlen=plen; 1016 pptr+=2; 1017 /* Old and new L2VPN NLRI share AFI/SAFI 1018 * -> Assume a 12 Byte-length NLRI is auto-discovery-only 1019 * and > 17 as old format. Complain for the middle case 1020 */ 1021 if (plen==12) { 1022 /* assume AD-only with RD, BGPNH */ 1023 ND_TCHECK2(pptr[0],12); 1024 buf[0]='\0'; 1025 stringlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s", 1026 bgp_vpn_rd_print(ndo, pptr), 1027 ipaddr_string(ndo, pptr+8) 1028 ); 1029 UPDATE_BUF_BUFLEN(buf, buflen, stringlen); 1030 pptr+=12; 1031 tlen-=12; 1032 return plen; 1033 } else if (plen>17) { 1034 /* assume old format */ 1035 /* RD, ID, LBLKOFF, LBLBASE */ 1036 1037 ND_TCHECK2(pptr[0],15); 1038 buf[0]='\0'; 1039 stringlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", 1040 bgp_vpn_rd_print(ndo, pptr), 1041 EXTRACT_16BITS(pptr+8), 1042 EXTRACT_16BITS(pptr+10), 1043 EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */ 1044 UPDATE_BUF_BUFLEN(buf, buflen, stringlen); 1045 pptr+=15; 1046 tlen-=15; 1047 1048 /* ok now the variable part - lets read out TLVs*/ 1049 while (tlen>0) { 1050 if (tlen < 3) 1051 return -1; 1052 ND_TCHECK2(pptr[0], 3); 1053 tlv_type=*pptr++; 1054 tlv_len=EXTRACT_16BITS(pptr); 1055 ttlv_len=tlv_len; 1056 pptr+=2; 1057 1058 switch(tlv_type) { 1059 case 1: 1060 if (buflen!=0) { 1061 stringlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", 1062 tlv_type, 1063 tlv_len); 1064 UPDATE_BUF_BUFLEN(buf, buflen, stringlen); 1065 } 1066 ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */ 1067 while (ttlv_len>0) { 1068 ND_TCHECK(pptr[0]); 1069 if (buflen!=0) { 1070 stringlen=snprintf(buf,buflen, "%02x",*pptr++); 1071 UPDATE_BUF_BUFLEN(buf, buflen, stringlen); 1072 } 1073 ttlv_len--; 1074 } 1075 break; 1076 default: 1077 if (buflen!=0) { 1078 stringlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", 1079 tlv_type, 1080 tlv_len); 1081 UPDATE_BUF_BUFLEN(buf, buflen, stringlen); 1082 } 1083 break; 1084 } 1085 tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */ 1086 } 1087 return plen+2; 1088 1089 } else { 1090 /* complain bitterly ? */ 1091 /* fall through */ 1092 goto trunc; 1093 } 1094 1095 trunc: 1096 return -2; 1097 } 1098 1099 int 1100 decode_prefix6(netdissect_options *ndo, 1101 const u_char *pd, u_int itemlen, char *buf, u_int buflen) 1102 { 1103 struct in6_addr addr; 1104 u_int plen, plenbytes; 1105 1106 ND_TCHECK(pd[0]); 1107 ITEMCHECK(1); 1108 plen = pd[0]; 1109 if (128 < plen) 1110 return -1; 1111 itemlen -= 1; 1112 1113 memset(&addr, 0, sizeof(addr)); 1114 plenbytes = (plen + 7) / 8; 1115 ND_TCHECK2(pd[1], plenbytes); 1116 ITEMCHECK(plenbytes); 1117 memcpy(&addr, &pd[1], plenbytes); 1118 if (plen % 8) { 1119 addr.s6_addr[plenbytes - 1] &= 1120 ((0xff00 >> (plen % 8)) & 0xff); 1121 } 1122 snprintf(buf, buflen, "%s/%d", ip6addr_string(ndo, &addr), plen); 1123 return 1 + plenbytes; 1124 1125 trunc: 1126 return -2; 1127 1128 badtlv: 1129 return -3; 1130 } 1131 1132 static int 1133 decode_labeled_prefix6(netdissect_options *ndo, 1134 const u_char *pptr, u_int itemlen, char *buf, u_int buflen) 1135 { 1136 struct in6_addr addr; 1137 u_int plen, plenbytes; 1138 1139 /* prefix length and label = 4 bytes */ 1140 ND_TCHECK2(pptr[0], 4); 1141 ITEMCHECK(4); 1142 plen = pptr[0]; /* get prefix length */ 1143 1144 if (24 > plen) 1145 return -1; 1146 1147 plen-=24; /* adjust prefixlen - labellength */ 1148 1149 if (128 < plen) 1150 return -1; 1151 itemlen -= 4; 1152 1153 memset(&addr, 0, sizeof(addr)); 1154 plenbytes = (plen + 7) / 8; 1155 ND_TCHECK2(pptr[4], plenbytes); 1156 memcpy(&addr, &pptr[4], plenbytes); 1157 if (plen % 8) { 1158 addr.s6_addr[plenbytes - 1] &= 1159 ((0xff00 >> (plen % 8)) & 0xff); 1160 } 1161 /* the label may get offsetted by 4 bits so lets shift it right */ 1162 snprintf(buf, buflen, "%s/%d, label:%u %s", 1163 ip6addr_string(ndo, &addr), 1164 plen, 1165 EXTRACT_24BITS(pptr+1)>>4, 1166 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 1167 1168 return 4 + plenbytes; 1169 1170 trunc: 1171 return -2; 1172 1173 badtlv: 1174 return -3; 1175 } 1176 1177 static int 1178 decode_labeled_vpn_prefix6(netdissect_options *ndo, 1179 const u_char *pptr, char *buf, u_int buflen) 1180 { 1181 struct in6_addr addr; 1182 u_int plen; 1183 1184 ND_TCHECK(pptr[0]); 1185 plen = pptr[0]; /* get prefix length */ 1186 1187 if ((24+64) > plen) 1188 return -1; 1189 1190 plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ 1191 1192 if (128 < plen) 1193 return -1; 1194 1195 memset(&addr, 0, sizeof(addr)); 1196 ND_TCHECK2(pptr[12], (plen + 7) / 8); 1197 memcpy(&addr, &pptr[12], (plen + 7) / 8); 1198 if (plen % 8) { 1199 addr.s6_addr[(plen + 7) / 8 - 1] &= 1200 ((0xff00 >> (plen % 8)) & 0xff); 1201 } 1202 /* the label may get offsetted by 4 bits so lets shift it right */ 1203 snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", 1204 bgp_vpn_rd_print(ndo, pptr+4), 1205 ip6addr_string(ndo, &addr), 1206 plen, 1207 EXTRACT_24BITS(pptr+1)>>4, 1208 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 1209 1210 return 12 + (plen + 7) / 8; 1211 1212 trunc: 1213 return -2; 1214 } 1215 1216 static int 1217 decode_clnp_prefix(netdissect_options *ndo, 1218 const u_char *pptr, char *buf, u_int buflen) 1219 { 1220 uint8_t addr[19]; 1221 u_int plen; 1222 1223 ND_TCHECK(pptr[0]); 1224 plen = pptr[0]; /* get prefix length */ 1225 1226 if (152 < plen) 1227 return -1; 1228 1229 memset(&addr, 0, sizeof(addr)); 1230 ND_TCHECK2(pptr[4], (plen + 7) / 8); 1231 memcpy(&addr, &pptr[4], (plen + 7) / 8); 1232 if (plen % 8) { 1233 addr[(plen + 7) / 8 - 1] &= 1234 ((0xff00 >> (plen % 8)) & 0xff); 1235 } 1236 snprintf(buf, buflen, "%s/%d", 1237 isonsap_string(ndo, addr,(plen + 7) / 8), 1238 plen); 1239 1240 return 1 + (plen + 7) / 8; 1241 1242 trunc: 1243 return -2; 1244 } 1245 1246 static int 1247 decode_labeled_vpn_clnp_prefix(netdissect_options *ndo, 1248 const u_char *pptr, char *buf, u_int buflen) 1249 { 1250 uint8_t addr[19]; 1251 u_int plen; 1252 1253 ND_TCHECK(pptr[0]); 1254 plen = pptr[0]; /* get prefix length */ 1255 1256 if ((24+64) > plen) 1257 return -1; 1258 1259 plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ 1260 1261 if (152 < plen) 1262 return -1; 1263 1264 memset(&addr, 0, sizeof(addr)); 1265 ND_TCHECK2(pptr[12], (plen + 7) / 8); 1266 memcpy(&addr, &pptr[12], (plen + 7) / 8); 1267 if (plen % 8) { 1268 addr[(plen + 7) / 8 - 1] &= 1269 ((0xff00 >> (plen % 8)) & 0xff); 1270 } 1271 /* the label may get offsetted by 4 bits so lets shift it right */ 1272 snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", 1273 bgp_vpn_rd_print(ndo, pptr+4), 1274 isonsap_string(ndo, addr,(plen + 7) / 8), 1275 plen, 1276 EXTRACT_24BITS(pptr+1)>>4, 1277 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 1278 1279 return 12 + (plen + 7) / 8; 1280 1281 trunc: 1282 return -2; 1283 } 1284 1285 /* 1286 * bgp_attr_get_as_size 1287 * 1288 * Try to find the size of the ASs encoded in an as-path. It is not obvious, as 1289 * both Old speakers that do not support 4 byte AS, and the new speakers that do 1290 * support, exchange AS-Path with the same path-attribute type value 0x02. 1291 */ 1292 static int 1293 bgp_attr_get_as_size(netdissect_options *ndo, 1294 uint8_t bgpa_type, const u_char *pptr, int len) 1295 { 1296 const u_char *tptr = pptr; 1297 1298 /* 1299 * If the path attribute is the optional AS4 path type, then we already 1300 * know, that ASs must be encoded in 4 byte format. 1301 */ 1302 if (bgpa_type == BGPTYPE_AS4_PATH) { 1303 return 4; 1304 } 1305 1306 /* 1307 * Let us assume that ASs are of 2 bytes in size, and check if the AS-Path 1308 * TLV is good. If not, ask the caller to try with AS encoded as 4 bytes 1309 * each. 1310 */ 1311 while (tptr < pptr + len) { 1312 ND_TCHECK(tptr[0]); 1313 1314 /* 1315 * If we do not find a valid segment type, our guess might be wrong. 1316 */ 1317 if (tptr[0] < BGP_AS_SEG_TYPE_MIN || tptr[0] > BGP_AS_SEG_TYPE_MAX) { 1318 goto trunc; 1319 } 1320 ND_TCHECK(tptr[1]); 1321 tptr += 2 + tptr[1] * 2; 1322 } 1323 1324 /* 1325 * If we correctly reached end of the AS path attribute data content, 1326 * then most likely ASs were indeed encoded as 2 bytes. 1327 */ 1328 if (tptr == pptr + len) { 1329 return 2; 1330 } 1331 1332 trunc: 1333 1334 /* 1335 * We can come here, either we did not have enough data, or if we 1336 * try to decode 4 byte ASs in 2 byte format. Either way, return 4, 1337 * so that calller can try to decode each AS as of 4 bytes. If indeed 1338 * there was not enough data, it will crib and end the parse anyways. 1339 */ 1340 return 4; 1341 } 1342 1343 static int 1344 bgp_attr_print(netdissect_options *ndo, 1345 u_int atype, const u_char *pptr, u_int len) 1346 { 1347 int i; 1348 uint16_t af; 1349 uint8_t safi, snpa, nhlen; 1350 union { /* copy buffer for bandwidth values */ 1351 float f; 1352 uint32_t i; 1353 } bw; 1354 int advance; 1355 u_int tlen; 1356 const u_char *tptr; 1357 char buf[MAXHOSTNAMELEN + 100]; 1358 int as_size; 1359 1360 tptr = pptr; 1361 tlen=len; 1362 1363 switch (atype) { 1364 case BGPTYPE_ORIGIN: 1365 if (len != 1) 1366 ND_PRINT((ndo, "invalid len")); 1367 else { 1368 ND_TCHECK(*tptr); 1369 ND_PRINT((ndo, "%s", tok2str(bgp_origin_values, 1370 "Unknown Origin Typecode", 1371 tptr[0]))); 1372 } 1373 break; 1374 1375 /* 1376 * Process AS4 byte path and AS2 byte path attributes here. 1377 */ 1378 case BGPTYPE_AS4_PATH: 1379 case BGPTYPE_AS_PATH: 1380 if (len % 2) { 1381 ND_PRINT((ndo, "invalid len")); 1382 break; 1383 } 1384 if (!len) { 1385 ND_PRINT((ndo, "empty")); 1386 break; 1387 } 1388 1389 /* 1390 * BGP updates exchanged between New speakers that support 4 1391 * byte AS, ASs are always encoded in 4 bytes. There is no 1392 * definitive way to find this, just by the packet's 1393 * contents. So, check for packet's TLV's sanity assuming 1394 * 2 bytes first, and it does not pass, assume that ASs are 1395 * encoded in 4 bytes format and move on. 1396 */ 1397 as_size = bgp_attr_get_as_size(ndo, atype, pptr, len); 1398 1399 while (tptr < pptr + len) { 1400 ND_TCHECK(tptr[0]); 1401 ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_open_values, 1402 "?", tptr[0]))); 1403 for (i = 0; i < tptr[1] * as_size; i += as_size) { 1404 ND_TCHECK2(tptr[2 + i], as_size); 1405 ND_PRINT((ndo, "%s ", 1406 as_printf(ndo, astostr, sizeof(astostr), 1407 as_size == 2 ? 1408 EXTRACT_16BITS(&tptr[2 + i]) : 1409 EXTRACT_32BITS(&tptr[2 + i])))); 1410 } 1411 ND_TCHECK(tptr[0]); 1412 ND_PRINT((ndo, "%s", tok2str(bgp_as_path_segment_close_values, 1413 "?", tptr[0]))); 1414 ND_TCHECK(tptr[1]); 1415 tptr += 2 + tptr[1] * as_size; 1416 } 1417 break; 1418 case BGPTYPE_NEXT_HOP: 1419 if (len != 4) 1420 ND_PRINT((ndo, "invalid len")); 1421 else { 1422 ND_TCHECK2(tptr[0], 4); 1423 ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr))); 1424 } 1425 break; 1426 case BGPTYPE_MULTI_EXIT_DISC: 1427 case BGPTYPE_LOCAL_PREF: 1428 if (len != 4) 1429 ND_PRINT((ndo, "invalid len")); 1430 else { 1431 ND_TCHECK2(tptr[0], 4); 1432 ND_PRINT((ndo, "%u", EXTRACT_32BITS(tptr))); 1433 } 1434 break; 1435 case BGPTYPE_ATOMIC_AGGREGATE: 1436 if (len != 0) 1437 ND_PRINT((ndo, "invalid len")); 1438 break; 1439 case BGPTYPE_AGGREGATOR: 1440 1441 /* 1442 * Depending on the AS encoded is of 2 bytes or of 4 bytes, 1443 * the length of this PA can be either 6 bytes or 8 bytes. 1444 */ 1445 if (len != 6 && len != 8) { 1446 ND_PRINT((ndo, "invalid len")); 1447 break; 1448 } 1449 ND_TCHECK2(tptr[0], len); 1450 if (len == 6) { 1451 ND_PRINT((ndo, " AS #%s, origin %s", 1452 as_printf(ndo, astostr, sizeof(astostr), EXTRACT_16BITS(tptr)), 1453 ipaddr_string(ndo, tptr + 2))); 1454 } else { 1455 ND_PRINT((ndo, " AS #%s, origin %s", 1456 as_printf(ndo, astostr, sizeof(astostr), 1457 EXTRACT_32BITS(tptr)), ipaddr_string(ndo, tptr + 4))); 1458 } 1459 break; 1460 case BGPTYPE_AGGREGATOR4: 1461 if (len != 8) { 1462 ND_PRINT((ndo, "invalid len")); 1463 break; 1464 } 1465 ND_TCHECK2(tptr[0], 8); 1466 ND_PRINT((ndo, " AS #%s, origin %s", 1467 as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), 1468 ipaddr_string(ndo, tptr + 4))); 1469 break; 1470 case BGPTYPE_COMMUNITIES: 1471 if (len % 4) { 1472 ND_PRINT((ndo, "invalid len")); 1473 break; 1474 } 1475 while (tlen>0) { 1476 uint32_t comm; 1477 ND_TCHECK2(tptr[0], 4); 1478 comm = EXTRACT_32BITS(tptr); 1479 switch (comm) { 1480 case BGP_COMMUNITY_NO_EXPORT: 1481 ND_PRINT((ndo, " NO_EXPORT")); 1482 break; 1483 case BGP_COMMUNITY_NO_ADVERT: 1484 ND_PRINT((ndo, " NO_ADVERTISE")); 1485 break; 1486 case BGP_COMMUNITY_NO_EXPORT_SUBCONFED: 1487 ND_PRINT((ndo, " NO_EXPORT_SUBCONFED")); 1488 break; 1489 default: 1490 ND_PRINT((ndo, "%u:%u%s", 1491 (comm >> 16) & 0xffff, 1492 comm & 0xffff, 1493 (tlen>4) ? ", " : "")); 1494 break; 1495 } 1496 tlen -=4; 1497 tptr +=4; 1498 } 1499 break; 1500 case BGPTYPE_ORIGINATOR_ID: 1501 if (len != 4) { 1502 ND_PRINT((ndo, "invalid len")); 1503 break; 1504 } 1505 ND_TCHECK2(tptr[0], 4); 1506 ND_PRINT((ndo, "%s",ipaddr_string(ndo, tptr))); 1507 break; 1508 case BGPTYPE_CLUSTER_LIST: 1509 if (len % 4) { 1510 ND_PRINT((ndo, "invalid len")); 1511 break; 1512 } 1513 while (tlen>0) { 1514 ND_TCHECK2(tptr[0], 4); 1515 ND_PRINT((ndo, "%s%s", 1516 ipaddr_string(ndo, tptr), 1517 (tlen>4) ? ", " : "")); 1518 tlen -=4; 1519 tptr +=4; 1520 } 1521 break; 1522 case BGPTYPE_MP_REACH_NLRI: 1523 ND_TCHECK2(tptr[0], 3); 1524 af = EXTRACT_16BITS(tptr); 1525 safi = tptr[2]; 1526 1527 ND_PRINT((ndo, "\n\t AFI: %s (%u), %sSAFI: %s (%u)", 1528 tok2str(af_values, "Unknown AFI", af), 1529 af, 1530 (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ 1531 tok2str(bgp_safi_values, "Unknown SAFI", safi), 1532 safi)); 1533 1534 switch(af<<8 | safi) { 1535 case (AFNUM_INET<<8 | SAFNUM_UNICAST): 1536 case (AFNUM_INET<<8 | SAFNUM_MULTICAST): 1537 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): 1538 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): 1539 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): 1540 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): 1541 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): 1542 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): 1543 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): 1544 case (AFNUM_INET<<8 | SAFNUM_MDT): 1545 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): 1546 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): 1547 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): 1548 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): 1549 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): 1550 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): 1551 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): 1552 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): 1553 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): 1554 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): 1555 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): 1556 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): 1557 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): 1558 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): 1559 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): 1560 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): 1561 case (AFNUM_VPLS<<8 | SAFNUM_VPLS): 1562 break; 1563 default: 1564 ND_TCHECK2(tptr[0], tlen); 1565 ND_PRINT((ndo, "\n\t no AFI %u / SAFI %u decoder", af, safi)); 1566 if (ndo->ndo_vflag <= 1) 1567 print_unknown_data(ndo, tptr, "\n\t ", tlen); 1568 goto done; 1569 break; 1570 } 1571 1572 tptr +=3; 1573 1574 ND_TCHECK(tptr[0]); 1575 nhlen = tptr[0]; 1576 tlen = nhlen; 1577 tptr++; 1578 1579 if (tlen) { 1580 int nnh = 0; 1581 ND_PRINT((ndo, "\n\t nexthop: ")); 1582 while (tlen > 0) { 1583 if ( nnh++ > 0 ) { 1584 ND_PRINT((ndo, ", " )); 1585 } 1586 switch(af<<8 | safi) { 1587 case (AFNUM_INET<<8 | SAFNUM_UNICAST): 1588 case (AFNUM_INET<<8 | SAFNUM_MULTICAST): 1589 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): 1590 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): 1591 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): 1592 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): 1593 case (AFNUM_INET<<8 | SAFNUM_MDT): 1594 if (tlen < (int)sizeof(struct in_addr)) { 1595 ND_PRINT((ndo, "invalid len")); 1596 tlen = 0; 1597 } else { 1598 ND_TCHECK2(tptr[0], sizeof(struct in_addr)); 1599 ND_PRINT((ndo, "%s",ipaddr_string(ndo, tptr))); 1600 tlen -= sizeof(struct in_addr); 1601 tptr += sizeof(struct in_addr); 1602 } 1603 break; 1604 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): 1605 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): 1606 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): 1607 if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) { 1608 ND_PRINT((ndo, "invalid len")); 1609 tlen = 0; 1610 } else { 1611 ND_TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN); 1612 ND_PRINT((ndo, "RD: %s, %s", 1613 bgp_vpn_rd_print(ndo, tptr), 1614 ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN))); 1615 tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN); 1616 tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN); 1617 } 1618 break; 1619 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): 1620 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): 1621 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): 1622 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): 1623 if (tlen < (int)sizeof(struct in6_addr)) { 1624 ND_PRINT((ndo, "invalid len")); 1625 tlen = 0; 1626 } else { 1627 ND_TCHECK2(tptr[0], sizeof(struct in6_addr)); 1628 ND_PRINT((ndo, "%s", ip6addr_string(ndo, tptr))); 1629 tlen -= sizeof(struct in6_addr); 1630 tptr += sizeof(struct in6_addr); 1631 } 1632 break; 1633 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): 1634 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): 1635 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): 1636 if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) { 1637 ND_PRINT((ndo, "invalid len")); 1638 tlen = 0; 1639 } else { 1640 ND_TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN); 1641 ND_PRINT((ndo, "RD: %s, %s", 1642 bgp_vpn_rd_print(ndo, tptr), 1643 ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN))); 1644 tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); 1645 tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); 1646 } 1647 break; 1648 case (AFNUM_VPLS<<8 | SAFNUM_VPLS): 1649 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): 1650 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): 1651 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): 1652 if (tlen < (int)sizeof(struct in_addr)) { 1653 ND_PRINT((ndo, "invalid len")); 1654 tlen = 0; 1655 } else { 1656 ND_TCHECK2(tptr[0], sizeof(struct in_addr)); 1657 ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr))); 1658 tlen -= (sizeof(struct in_addr)); 1659 tptr += (sizeof(struct in_addr)); 1660 } 1661 break; 1662 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): 1663 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): 1664 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): 1665 ND_TCHECK2(tptr[0], tlen); 1666 ND_PRINT((ndo, "%s", isonsap_string(ndo, tptr, tlen))); 1667 tptr += tlen; 1668 tlen = 0; 1669 break; 1670 1671 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): 1672 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): 1673 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): 1674 if (tlen < BGP_VPN_RD_LEN+1) { 1675 ND_PRINT((ndo, "invalid len")); 1676 tlen = 0; 1677 } else { 1678 ND_TCHECK2(tptr[0], tlen); 1679 ND_PRINT((ndo, "RD: %s, %s", 1680 bgp_vpn_rd_print(ndo, tptr), 1681 isonsap_string(ndo, tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN))); 1682 /* rfc986 mapped IPv4 address ? */ 1683 if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) 1684 ND_PRINT((ndo, " = %s", ipaddr_string(ndo, tptr+BGP_VPN_RD_LEN+4))); 1685 /* rfc1888 mapped IPv6 address ? */ 1686 else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) 1687 ND_PRINT((ndo, " = %s", ip6addr_string(ndo, tptr+BGP_VPN_RD_LEN+3))); 1688 tptr += tlen; 1689 tlen = 0; 1690 } 1691 break; 1692 default: 1693 ND_TCHECK2(tptr[0], tlen); 1694 ND_PRINT((ndo, "no AFI %u/SAFI %u decoder", af, safi)); 1695 if (ndo->ndo_vflag <= 1) 1696 print_unknown_data(ndo, tptr, "\n\t ", tlen); 1697 tptr += tlen; 1698 tlen = 0; 1699 goto done; 1700 break; 1701 } 1702 } 1703 } 1704 ND_PRINT((ndo, ", nh-length: %u", nhlen)); 1705 tptr += tlen; 1706 1707 ND_TCHECK(tptr[0]); 1708 snpa = tptr[0]; 1709 tptr++; 1710 1711 if (snpa) { 1712 ND_PRINT((ndo, "\n\t %u SNPA", snpa)); 1713 for (/*nothing*/; snpa > 0; snpa--) { 1714 ND_TCHECK(tptr[0]); 1715 ND_PRINT((ndo, "\n\t %d bytes", tptr[0])); 1716 tptr += tptr[0] + 1; 1717 } 1718 } else { 1719 ND_PRINT((ndo, ", no SNPA")); 1720 } 1721 1722 while (len - (tptr - pptr) > 0) { 1723 switch (af<<8 | safi) { 1724 case (AFNUM_INET<<8 | SAFNUM_UNICAST): 1725 case (AFNUM_INET<<8 | SAFNUM_MULTICAST): 1726 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): 1727 advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf)); 1728 if (advance == -1) 1729 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1730 else if (advance == -2) 1731 goto trunc; 1732 else if (advance == -3) 1733 break; /* bytes left, but not enough */ 1734 else 1735 ND_PRINT((ndo, "\n\t %s", buf)); 1736 break; 1737 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): 1738 advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf)); 1739 if (advance == -1) 1740 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1741 else if (advance == -2) 1742 goto trunc; 1743 else if (advance == -3) 1744 break; /* bytes left, but not enough */ 1745 else 1746 ND_PRINT((ndo, "\n\t %s", buf)); 1747 break; 1748 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): 1749 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): 1750 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): 1751 advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, sizeof(buf)); 1752 if (advance == -1) 1753 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1754 else if (advance == -2) 1755 goto trunc; 1756 else 1757 ND_PRINT((ndo, "\n\t %s", buf)); 1758 break; 1759 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): 1760 advance = decode_rt_routing_info(ndo, tptr, 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 1766 ND_PRINT((ndo, "\n\t %s", buf)); 1767 break; 1768 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ 1769 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): 1770 advance = decode_multicast_vpn(ndo, tptr, buf, sizeof(buf)); 1771 if (advance == -1) 1772 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1773 else if (advance == -2) 1774 goto trunc; 1775 else 1776 ND_PRINT((ndo, "\n\t %s", buf)); 1777 break; 1778 1779 case (AFNUM_INET<<8 | SAFNUM_MDT): 1780 advance = decode_mdt_vpn_nlri(ndo, tptr, buf, sizeof(buf)); 1781 if (advance == -1) 1782 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1783 else if (advance == -2) 1784 goto trunc; 1785 else 1786 ND_PRINT((ndo, "\n\t %s", buf)); 1787 break; 1788 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): 1789 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): 1790 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): 1791 advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf)); 1792 if (advance == -1) 1793 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1794 else if (advance == -2) 1795 goto trunc; 1796 else if (advance == -3) 1797 break; /* bytes left, but not enough */ 1798 else 1799 ND_PRINT((ndo, "\n\t %s", buf)); 1800 break; 1801 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): 1802 advance = decode_labeled_prefix6(ndo, tptr, len, 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 if (advance == -3) 1808 break; /* bytes left, but not enough */ 1809 else 1810 ND_PRINT((ndo, "\n\t %s", buf)); 1811 break; 1812 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): 1813 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): 1814 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): 1815 advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, sizeof(buf)); 1816 if (advance == -1) 1817 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1818 else if (advance == -2) 1819 goto trunc; 1820 else 1821 ND_PRINT((ndo, "\n\t %s", buf)); 1822 break; 1823 case (AFNUM_VPLS<<8 | SAFNUM_VPLS): 1824 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): 1825 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): 1826 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): 1827 advance = decode_labeled_vpn_l2(ndo, tptr, buf, sizeof(buf)); 1828 if (advance == -1) 1829 ND_PRINT((ndo, "\n\t (illegal length)")); 1830 else if (advance == -2) 1831 goto trunc; 1832 else 1833 ND_PRINT((ndo, "\n\t %s", buf)); 1834 break; 1835 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): 1836 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): 1837 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): 1838 advance = decode_clnp_prefix(ndo, tptr, buf, sizeof(buf)); 1839 if (advance == -1) 1840 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1841 else if (advance == -2) 1842 goto trunc; 1843 else 1844 ND_PRINT((ndo, "\n\t %s", buf)); 1845 break; 1846 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): 1847 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): 1848 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): 1849 advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, sizeof(buf)); 1850 if (advance == -1) 1851 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1852 else if (advance == -2) 1853 goto trunc; 1854 else 1855 ND_PRINT((ndo, "\n\t %s", buf)); 1856 break; 1857 default: 1858 ND_TCHECK2(*tptr,tlen); 1859 ND_PRINT((ndo, "\n\t no AFI %u / SAFI %u decoder", af, safi)); 1860 if (ndo->ndo_vflag <= 1) 1861 print_unknown_data(ndo, tptr, "\n\t ", tlen); 1862 advance = 0; 1863 tptr = pptr + len; 1864 break; 1865 } 1866 if (advance < 0) 1867 break; 1868 tptr += advance; 1869 } 1870 done: 1871 break; 1872 1873 case BGPTYPE_MP_UNREACH_NLRI: 1874 ND_TCHECK2(tptr[0], BGP_MP_NLRI_MINSIZE); 1875 af = EXTRACT_16BITS(tptr); 1876 safi = tptr[2]; 1877 1878 ND_PRINT((ndo, "\n\t AFI: %s (%u), %sSAFI: %s (%u)", 1879 tok2str(af_values, "Unknown AFI", af), 1880 af, 1881 (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ 1882 tok2str(bgp_safi_values, "Unknown SAFI", safi), 1883 safi)); 1884 1885 if (len == BGP_MP_NLRI_MINSIZE) 1886 ND_PRINT((ndo, "\n\t End-of-Rib Marker (empty NLRI)")); 1887 1888 tptr += 3; 1889 1890 while (len - (tptr - pptr) > 0) { 1891 switch (af<<8 | safi) { 1892 case (AFNUM_INET<<8 | SAFNUM_UNICAST): 1893 case (AFNUM_INET<<8 | SAFNUM_MULTICAST): 1894 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): 1895 advance = decode_prefix4(ndo, tptr, len, buf, sizeof(buf)); 1896 if (advance == -1) 1897 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1898 else if (advance == -2) 1899 goto trunc; 1900 else if (advance == -3) 1901 break; /* bytes left, but not enough */ 1902 else 1903 ND_PRINT((ndo, "\n\t %s", buf)); 1904 break; 1905 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): 1906 advance = decode_labeled_prefix4(ndo, tptr, len, buf, sizeof(buf)); 1907 if (advance == -1) 1908 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1909 else if (advance == -2) 1910 goto trunc; 1911 else if (advance == -3) 1912 break; /* bytes left, but not enough */ 1913 else 1914 ND_PRINT((ndo, "\n\t %s", buf)); 1915 break; 1916 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): 1917 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): 1918 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): 1919 advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, sizeof(buf)); 1920 if (advance == -1) 1921 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1922 else if (advance == -2) 1923 goto trunc; 1924 else 1925 ND_PRINT((ndo, "\n\t %s", buf)); 1926 break; 1927 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): 1928 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): 1929 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): 1930 advance = decode_prefix6(ndo, tptr, len, buf, sizeof(buf)); 1931 if (advance == -1) 1932 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1933 else if (advance == -2) 1934 goto trunc; 1935 else if (advance == -3) 1936 break; /* bytes left, but not enough */ 1937 else 1938 ND_PRINT((ndo, "\n\t %s", buf)); 1939 break; 1940 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): 1941 advance = decode_labeled_prefix6(ndo, tptr, len, 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 if (advance == -3) 1947 break; /* bytes left, but not enough */ 1948 else 1949 ND_PRINT((ndo, "\n\t %s", buf)); 1950 break; 1951 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): 1952 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): 1953 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): 1954 advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, sizeof(buf)); 1955 if (advance == -1) 1956 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1957 else if (advance == -2) 1958 goto trunc; 1959 else 1960 ND_PRINT((ndo, "\n\t %s", buf)); 1961 break; 1962 case (AFNUM_VPLS<<8 | SAFNUM_VPLS): 1963 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): 1964 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): 1965 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): 1966 advance = decode_labeled_vpn_l2(ndo, tptr, buf, sizeof(buf)); 1967 if (advance == -1) 1968 ND_PRINT((ndo, "\n\t (illegal length)")); 1969 else if (advance == -2) 1970 goto trunc; 1971 else 1972 ND_PRINT((ndo, "\n\t %s", buf)); 1973 break; 1974 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): 1975 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): 1976 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): 1977 advance = decode_clnp_prefix(ndo, tptr, buf, sizeof(buf)); 1978 if (advance == -1) 1979 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1980 else if (advance == -2) 1981 goto trunc; 1982 else 1983 ND_PRINT((ndo, "\n\t %s", buf)); 1984 break; 1985 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): 1986 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): 1987 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): 1988 advance = decode_labeled_vpn_clnp_prefix(ndo, tptr, buf, sizeof(buf)); 1989 if (advance == -1) 1990 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 1991 else if (advance == -2) 1992 goto trunc; 1993 else 1994 ND_PRINT((ndo, "\n\t %s", buf)); 1995 break; 1996 case (AFNUM_INET<<8 | SAFNUM_MDT): 1997 advance = decode_mdt_vpn_nlri(ndo, tptr, buf, sizeof(buf)); 1998 if (advance == -1) 1999 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 2000 else if (advance == -2) 2001 goto trunc; 2002 else 2003 ND_PRINT((ndo, "\n\t %s", buf)); 2004 break; 2005 case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ 2006 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): 2007 advance = decode_multicast_vpn(ndo, tptr, buf, sizeof(buf)); 2008 if (advance == -1) 2009 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 2010 else if (advance == -2) 2011 goto trunc; 2012 else 2013 ND_PRINT((ndo, "\n\t %s", buf)); 2014 break; 2015 default: 2016 ND_TCHECK2(*(tptr-3),tlen); 2017 ND_PRINT((ndo, "no AFI %u / SAFI %u decoder", af, safi)); 2018 if (ndo->ndo_vflag <= 1) 2019 print_unknown_data(ndo, tptr-3, "\n\t ", tlen); 2020 advance = 0; 2021 tptr = pptr + len; 2022 break; 2023 } 2024 if (advance < 0) 2025 break; 2026 tptr += advance; 2027 } 2028 break; 2029 case BGPTYPE_EXTD_COMMUNITIES: 2030 if (len % 8) { 2031 ND_PRINT((ndo, "invalid len")); 2032 break; 2033 } 2034 while (tlen>0) { 2035 uint16_t extd_comm; 2036 2037 ND_TCHECK2(tptr[0], 2); 2038 extd_comm=EXTRACT_16BITS(tptr); 2039 2040 ND_PRINT((ndo, "\n\t %s (0x%04x), Flags [%s]", 2041 tok2str(bgp_extd_comm_subtype_values, 2042 "unknown extd community typecode", 2043 extd_comm), 2044 extd_comm, 2045 bittok2str(bgp_extd_comm_flag_values, "none", extd_comm))); 2046 2047 ND_TCHECK2(*(tptr+2), 6); 2048 switch(extd_comm) { 2049 case BGP_EXT_COM_RT_0: 2050 case BGP_EXT_COM_RO_0: 2051 case BGP_EXT_COM_L2VPN_RT_0: 2052 ND_PRINT((ndo, ": %u:%u (= %s)", 2053 EXTRACT_16BITS(tptr+2), 2054 EXTRACT_32BITS(tptr+4), 2055 ipaddr_string(ndo, tptr+4))); 2056 break; 2057 case BGP_EXT_COM_RT_1: 2058 case BGP_EXT_COM_RO_1: 2059 case BGP_EXT_COM_L2VPN_RT_1: 2060 case BGP_EXT_COM_VRF_RT_IMP: 2061 ND_PRINT((ndo, ": %s:%u", 2062 ipaddr_string(ndo, tptr+2), 2063 EXTRACT_16BITS(tptr+6))); 2064 break; 2065 case BGP_EXT_COM_RT_2: 2066 case BGP_EXT_COM_RO_2: 2067 ND_PRINT((ndo, ": %s:%u", 2068 as_printf(ndo, astostr, sizeof(astostr), 2069 EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6))); 2070 break; 2071 case BGP_EXT_COM_LINKBAND: 2072 bw.i = EXTRACT_32BITS(tptr+2); 2073 ND_PRINT((ndo, ": bandwidth: %.3f Mbps", 2074 bw.f*8/1000000)); 2075 break; 2076 case BGP_EXT_COM_VPN_ORIGIN: 2077 case BGP_EXT_COM_VPN_ORIGIN2: 2078 case BGP_EXT_COM_VPN_ORIGIN3: 2079 case BGP_EXT_COM_VPN_ORIGIN4: 2080 case BGP_EXT_COM_OSPF_RID: 2081 case BGP_EXT_COM_OSPF_RID2: 2082 ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr+2))); 2083 break; 2084 case BGP_EXT_COM_OSPF_RTYPE: 2085 case BGP_EXT_COM_OSPF_RTYPE2: 2086 ND_PRINT((ndo, ": area:%s, router-type:%s, metric-type:%s%s", 2087 ipaddr_string(ndo, tptr+2), 2088 tok2str(bgp_extd_comm_ospf_rtype_values, 2089 "unknown (0x%02x)", 2090 *(tptr+6)), 2091 (*(tptr+7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "", 2092 ((*(tptr+6) == BGP_OSPF_RTYPE_EXT) || (*(tptr+6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : "")); 2093 break; 2094 case BGP_EXT_COM_L2INFO: 2095 ND_PRINT((ndo, ": %s Control Flags [0x%02x]:MTU %u", 2096 tok2str(l2vpn_encaps_values, 2097 "unknown encaps", 2098 *(tptr+2)), 2099 *(tptr+3), 2100 EXTRACT_16BITS(tptr+4))); 2101 break; 2102 case BGP_EXT_COM_SOURCE_AS: 2103 ND_PRINT((ndo, ": AS %u", EXTRACT_16BITS(tptr+2))); 2104 break; 2105 default: 2106 ND_TCHECK2(*tptr,8); 2107 print_unknown_data(ndo, tptr, "\n\t ", 8); 2108 break; 2109 } 2110 tlen -=8; 2111 tptr +=8; 2112 } 2113 break; 2114 2115 case BGPTYPE_PMSI_TUNNEL: 2116 { 2117 uint8_t tunnel_type, flags; 2118 2119 tunnel_type = *(tptr+1); 2120 flags = *tptr; 2121 tlen = len; 2122 2123 ND_TCHECK2(tptr[0], 5); 2124 ND_PRINT((ndo, "\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", 2125 tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), 2126 tunnel_type, 2127 bittok2str(bgp_pmsi_flag_values, "none", flags), 2128 EXTRACT_24BITS(tptr+2)>>4)); 2129 2130 tptr +=5; 2131 tlen -= 5; 2132 2133 switch (tunnel_type) { 2134 case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */ 2135 case BGP_PMSI_TUNNEL_PIM_BIDIR: 2136 ND_TCHECK2(tptr[0], 8); 2137 ND_PRINT((ndo, "\n\t Sender %s, P-Group %s", 2138 ipaddr_string(ndo, tptr), 2139 ipaddr_string(ndo, tptr+4))); 2140 break; 2141 2142 case BGP_PMSI_TUNNEL_PIM_SSM: 2143 ND_TCHECK2(tptr[0], 8); 2144 ND_PRINT((ndo, "\n\t Root-Node %s, P-Group %s", 2145 ipaddr_string(ndo, tptr), 2146 ipaddr_string(ndo, tptr+4))); 2147 break; 2148 case BGP_PMSI_TUNNEL_INGRESS: 2149 ND_TCHECK2(tptr[0], 4); 2150 ND_PRINT((ndo, "\n\t Tunnel-Endpoint %s", 2151 ipaddr_string(ndo, tptr))); 2152 break; 2153 case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */ 2154 case BGP_PMSI_TUNNEL_LDP_MP2MP: 2155 ND_TCHECK2(tptr[0], 8); 2156 ND_PRINT((ndo, "\n\t Root-Node %s, LSP-ID 0x%08x", 2157 ipaddr_string(ndo, tptr), 2158 EXTRACT_32BITS(tptr+4))); 2159 break; 2160 case BGP_PMSI_TUNNEL_RSVP_P2MP: 2161 ND_TCHECK2(tptr[0], 8); 2162 ND_PRINT((ndo, "\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x", 2163 ipaddr_string(ndo, tptr), 2164 EXTRACT_32BITS(tptr+4))); 2165 break; 2166 default: 2167 if (ndo->ndo_vflag <= 1) { 2168 print_unknown_data(ndo, tptr, "\n\t ", tlen); 2169 } 2170 } 2171 break; 2172 } 2173 case BGPTYPE_AIGP: 2174 { 2175 uint8_t type; 2176 uint16_t length; 2177 2178 ND_TCHECK2(tptr[0], 3); 2179 2180 tlen = len; 2181 2182 while (tlen >= 3) { 2183 2184 type = *tptr; 2185 length = EXTRACT_16BITS(tptr+1); 2186 2187 ND_PRINT((ndo, "\n\t %s TLV (%u), length %u", 2188 tok2str(bgp_aigp_values, "Unknown", type), 2189 type, length)); 2190 2191 /* 2192 * Check if we can read the TLV data. 2193 */ 2194 ND_TCHECK2(tptr[3], length - 3); 2195 2196 switch (type) { 2197 2198 case BGP_AIGP_TLV: 2199 ND_TCHECK2(tptr[3], 8); 2200 ND_PRINT((ndo, ", metric %" PRIu64, 2201 EXTRACT_64BITS(tptr+3))); 2202 break; 2203 2204 default: 2205 if (ndo->ndo_vflag <= 1) { 2206 print_unknown_data(ndo, tptr+3,"\n\t ", length-3); 2207 } 2208 } 2209 2210 tptr += length; 2211 tlen -= length; 2212 } 2213 break; 2214 } 2215 case BGPTYPE_ATTR_SET: 2216 ND_TCHECK2(tptr[0], 4); 2217 if (len < 4) 2218 goto trunc; 2219 ND_PRINT((ndo, "\n\t Origin AS: %s", 2220 as_printf(ndo, astostr, sizeof(astostr), EXTRACT_32BITS(tptr)))); 2221 tptr+=4; 2222 len -=4; 2223 2224 while (len) { 2225 u_int aflags, alenlen, alen; 2226 2227 ND_TCHECK2(tptr[0], 2); 2228 if (len < 2) 2229 goto trunc; 2230 aflags = *tptr; 2231 atype = *(tptr + 1); 2232 tptr += 2; 2233 len -= 2; 2234 alenlen = bgp_attr_lenlen(aflags, tptr); 2235 ND_TCHECK2(tptr[0], alenlen); 2236 if (len < alenlen) 2237 goto trunc; 2238 alen = bgp_attr_len(aflags, tptr); 2239 tptr += alenlen; 2240 len -= alenlen; 2241 2242 ND_PRINT((ndo, "\n\t %s (%u), length: %u", 2243 tok2str(bgp_attr_values, 2244 "Unknown Attribute", atype), 2245 atype, 2246 alen)); 2247 2248 if (aflags) { 2249 ND_PRINT((ndo, ", Flags [%s%s%s%s", 2250 aflags & 0x80 ? "O" : "", 2251 aflags & 0x40 ? "T" : "", 2252 aflags & 0x20 ? "P" : "", 2253 aflags & 0x10 ? "E" : "")); 2254 if (aflags & 0xf) 2255 ND_PRINT((ndo, "+%x", aflags & 0xf)); 2256 ND_PRINT((ndo, "]: ")); 2257 } 2258 /* FIXME check for recursion */ 2259 if (!bgp_attr_print(ndo, atype, tptr, alen)) 2260 return 0; 2261 tptr += alen; 2262 len -= alen; 2263 } 2264 break; 2265 2266 case BGPTYPE_LARGE_COMMUNITY: 2267 if (len == 0 || len % 12) { 2268 ND_PRINT((ndo, "invalid len")); 2269 break; 2270 } 2271 ND_PRINT((ndo, "\n\t ")); 2272 while (len > 0) { 2273 ND_TCHECK2(*tptr, 12); 2274 ND_PRINT((ndo, "%u:%u:%u%s", 2275 EXTRACT_32BITS(tptr), 2276 EXTRACT_32BITS(tptr + 4), 2277 EXTRACT_32BITS(tptr + 8), 2278 (len > 12) ? ", " : "")); 2279 tptr += 12; 2280 len -= 12; 2281 } 2282 break; 2283 default: 2284 ND_TCHECK2(*pptr,len); 2285 ND_PRINT((ndo, "\n\t no Attribute %u decoder", atype)); /* we have no decoder for the attribute */ 2286 if (ndo->ndo_vflag <= 1) 2287 print_unknown_data(ndo, pptr, "\n\t ", len); 2288 break; 2289 } 2290 if (ndo->ndo_vflag > 1 && len) { /* omit zero length attributes*/ 2291 ND_TCHECK2(*pptr,len); 2292 print_unknown_data(ndo, pptr, "\n\t ", len); 2293 } 2294 return 1; 2295 2296 trunc: 2297 return 0; 2298 } 2299 2300 static void 2301 bgp_capabilities_print(netdissect_options *ndo, 2302 const u_char *opt, int caps_len) 2303 { 2304 int cap_type, cap_len, tcap_len, cap_offset; 2305 int i = 0; 2306 2307 while (i < caps_len) { 2308 ND_TCHECK2(opt[i], BGP_CAP_HEADER_SIZE); 2309 cap_type=opt[i]; 2310 cap_len=opt[i+1]; 2311 tcap_len=cap_len; 2312 ND_PRINT((ndo, "\n\t %s (%u), length: %u", 2313 tok2str(bgp_capcode_values, "Unknown", 2314 cap_type), 2315 cap_type, 2316 cap_len)); 2317 ND_TCHECK2(opt[i+2], cap_len); 2318 switch (cap_type) { 2319 case BGP_CAPCODE_MP: 2320 ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u)", 2321 tok2str(af_values, "Unknown", 2322 EXTRACT_16BITS(opt+i+2)), 2323 EXTRACT_16BITS(opt+i+2), 2324 tok2str(bgp_safi_values, "Unknown", 2325 opt[i+5]), 2326 opt[i+5])); 2327 break; 2328 case BGP_CAPCODE_RESTART: 2329 ND_PRINT((ndo, "\n\t\tRestart Flags: [%s], Restart Time %us", 2330 ((opt[i+2])&0x80) ? "R" : "none", 2331 EXTRACT_16BITS(opt+i+2)&0xfff)); 2332 tcap_len-=2; 2333 cap_offset=4; 2334 while(tcap_len>=4) { 2335 ND_PRINT((ndo, "\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", 2336 tok2str(af_values,"Unknown", 2337 EXTRACT_16BITS(opt+i+cap_offset)), 2338 EXTRACT_16BITS(opt+i+cap_offset), 2339 tok2str(bgp_safi_values,"Unknown", 2340 opt[i+cap_offset+2]), 2341 opt[i+cap_offset+2], 2342 ((opt[i+cap_offset+3])&0x80) ? "yes" : "no" )); 2343 tcap_len-=4; 2344 cap_offset+=4; 2345 } 2346 break; 2347 case BGP_CAPCODE_RR: 2348 case BGP_CAPCODE_RR_CISCO: 2349 break; 2350 case BGP_CAPCODE_AS_NEW: 2351 2352 /* 2353 * Extract the 4 byte AS number encoded. 2354 */ 2355 if (cap_len == 4) { 2356 ND_PRINT((ndo, "\n\t\t 4 Byte AS %s", 2357 as_printf(ndo, astostr, sizeof(astostr), 2358 EXTRACT_32BITS(opt + i + 2)))); 2359 } 2360 break; 2361 case BGP_CAPCODE_ADD_PATH: 2362 cap_offset=2; 2363 if (tcap_len == 0) { 2364 ND_PRINT((ndo, " (bogus)")); /* length */ 2365 break; 2366 } 2367 while (tcap_len > 0) { 2368 if (tcap_len < 4) { 2369 ND_PRINT((ndo, "\n\t\t(invalid)")); 2370 break; 2371 } 2372 ND_PRINT((ndo, "\n\t\tAFI %s (%u), SAFI %s (%u), Send/Receive: %s", 2373 tok2str(af_values,"Unknown",EXTRACT_16BITS(opt+i+cap_offset)), 2374 EXTRACT_16BITS(opt+i+cap_offset), 2375 tok2str(bgp_safi_values,"Unknown",opt[i+cap_offset+2]), 2376 opt[i+cap_offset+2], 2377 tok2str(bgp_add_path_recvsend,"Bogus (0x%02x)",opt[i+cap_offset+3]) 2378 )); 2379 tcap_len-=4; 2380 cap_offset+=4; 2381 } 2382 break; 2383 default: 2384 ND_PRINT((ndo, "\n\t\tno decoder for Capability %u", 2385 cap_type)); 2386 if (ndo->ndo_vflag <= 1) 2387 print_unknown_data(ndo, &opt[i+2], "\n\t\t", cap_len); 2388 break; 2389 } 2390 if (ndo->ndo_vflag > 1 && cap_len > 0) { 2391 print_unknown_data(ndo, &opt[i+2], "\n\t\t", cap_len); 2392 } 2393 i += BGP_CAP_HEADER_SIZE + cap_len; 2394 } 2395 return; 2396 2397 trunc: 2398 ND_PRINT((ndo, "[|BGP]")); 2399 } 2400 2401 static void 2402 bgp_open_print(netdissect_options *ndo, 2403 const u_char *dat, int length) 2404 { 2405 struct bgp_open bgpo; 2406 struct bgp_opt bgpopt; 2407 const u_char *opt; 2408 int i; 2409 2410 ND_TCHECK2(dat[0], BGP_OPEN_SIZE); 2411 memcpy(&bgpo, dat, BGP_OPEN_SIZE); 2412 2413 ND_PRINT((ndo, "\n\t Version %d, ", bgpo.bgpo_version)); 2414 ND_PRINT((ndo, "my AS %s, ", 2415 as_printf(ndo, astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas)))); 2416 ND_PRINT((ndo, "Holdtime %us, ", ntohs(bgpo.bgpo_holdtime))); 2417 ND_PRINT((ndo, "ID %s", ipaddr_string(ndo, &bgpo.bgpo_id))); 2418 ND_PRINT((ndo, "\n\t Optional parameters, length: %u", bgpo.bgpo_optlen)); 2419 2420 /* some little sanity checking */ 2421 if (length < bgpo.bgpo_optlen+BGP_OPEN_SIZE) 2422 return; 2423 2424 /* ugly! */ 2425 opt = &((const struct bgp_open *)dat)->bgpo_optlen; 2426 opt++; 2427 2428 i = 0; 2429 while (i < bgpo.bgpo_optlen) { 2430 ND_TCHECK2(opt[i], BGP_OPT_SIZE); 2431 memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE); 2432 if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) { 2433 ND_PRINT((ndo, "\n\t Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len)); 2434 break; 2435 } 2436 2437 ND_PRINT((ndo, "\n\t Option %s (%u), length: %u", 2438 tok2str(bgp_opt_values,"Unknown", 2439 bgpopt.bgpopt_type), 2440 bgpopt.bgpopt_type, 2441 bgpopt.bgpopt_len)); 2442 2443 /* now let's decode the options we know*/ 2444 switch(bgpopt.bgpopt_type) { 2445 2446 case BGP_OPT_CAP: 2447 bgp_capabilities_print(ndo, &opt[i+BGP_OPT_SIZE], 2448 bgpopt.bgpopt_len); 2449 break; 2450 2451 case BGP_OPT_AUTH: 2452 default: 2453 ND_PRINT((ndo, "\n\t no decoder for option %u", 2454 bgpopt.bgpopt_type)); 2455 break; 2456 } 2457 i += BGP_OPT_SIZE + bgpopt.bgpopt_len; 2458 } 2459 return; 2460 trunc: 2461 ND_PRINT((ndo, "[|BGP]")); 2462 } 2463 2464 static void 2465 bgp_update_print(netdissect_options *ndo, 2466 const u_char *dat, int length) 2467 { 2468 struct bgp bgp; 2469 const u_char *p; 2470 int withdrawn_routes_len; 2471 int len; 2472 int i; 2473 2474 ND_TCHECK2(dat[0], BGP_SIZE); 2475 if (length < BGP_SIZE) 2476 goto trunc; 2477 memcpy(&bgp, dat, BGP_SIZE); 2478 p = dat + BGP_SIZE; /*XXX*/ 2479 length -= BGP_SIZE; 2480 2481 /* Unfeasible routes */ 2482 ND_TCHECK2(p[0], 2); 2483 if (length < 2) 2484 goto trunc; 2485 withdrawn_routes_len = EXTRACT_16BITS(p); 2486 p += 2; 2487 length -= 2; 2488 if (withdrawn_routes_len) { 2489 /* 2490 * Without keeping state from the original NLRI message, 2491 * it's not possible to tell if this a v4 or v6 route, 2492 * so only try to decode it if we're not v6 enabled. 2493 */ 2494 ND_TCHECK2(p[0], withdrawn_routes_len); 2495 if (length < withdrawn_routes_len) 2496 goto trunc; 2497 ND_PRINT((ndo, "\n\t Withdrawn routes: %d bytes", withdrawn_routes_len)); 2498 p += withdrawn_routes_len; 2499 length -= withdrawn_routes_len; 2500 } 2501 2502 ND_TCHECK2(p[0], 2); 2503 if (length < 2) 2504 goto trunc; 2505 len = EXTRACT_16BITS(p); 2506 p += 2; 2507 length -= 2; 2508 2509 if (withdrawn_routes_len == 0 && len == 0 && length == 0) { 2510 /* No withdrawn routes, no path attributes, no NLRI */ 2511 ND_PRINT((ndo, "\n\t End-of-Rib Marker (empty NLRI)")); 2512 return; 2513 } 2514 2515 if (len) { 2516 /* do something more useful!*/ 2517 while (len) { 2518 int aflags, atype, alenlen, alen; 2519 2520 ND_TCHECK2(p[0], 2); 2521 if (len < 2) 2522 goto trunc; 2523 if (length < 2) 2524 goto trunc; 2525 aflags = *p; 2526 atype = *(p + 1); 2527 p += 2; 2528 len -= 2; 2529 length -= 2; 2530 alenlen = bgp_attr_lenlen(aflags, p); 2531 ND_TCHECK2(p[0], alenlen); 2532 if (len < alenlen) 2533 goto trunc; 2534 if (length < alenlen) 2535 goto trunc; 2536 alen = bgp_attr_len(aflags, p); 2537 p += alenlen; 2538 len -= alenlen; 2539 length -= alenlen; 2540 2541 ND_PRINT((ndo, "\n\t %s (%u), length: %u", 2542 tok2str(bgp_attr_values, "Unknown Attribute", 2543 atype), 2544 atype, 2545 alen)); 2546 2547 if (aflags) { 2548 ND_PRINT((ndo, ", Flags [%s%s%s%s", 2549 aflags & 0x80 ? "O" : "", 2550 aflags & 0x40 ? "T" : "", 2551 aflags & 0x20 ? "P" : "", 2552 aflags & 0x10 ? "E" : "")); 2553 if (aflags & 0xf) 2554 ND_PRINT((ndo, "+%x", aflags & 0xf)); 2555 ND_PRINT((ndo, "]: ")); 2556 } 2557 if (len < alen) 2558 goto trunc; 2559 if (length < alen) 2560 goto trunc; 2561 if (!bgp_attr_print(ndo, atype, p, alen)) 2562 goto trunc; 2563 p += alen; 2564 len -= alen; 2565 length -= alen; 2566 } 2567 } 2568 2569 if (length) { 2570 /* 2571 * XXX - what if they're using the "Advertisement of 2572 * Multiple Paths in BGP" feature: 2573 * 2574 * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/ 2575 * 2576 * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06 2577 */ 2578 ND_PRINT((ndo, "\n\t Updated routes:")); 2579 while (length) { 2580 char buf[MAXHOSTNAMELEN + 100]; 2581 i = decode_prefix4(ndo, p, length, buf, sizeof(buf)); 2582 if (i == -1) { 2583 ND_PRINT((ndo, "\n\t (illegal prefix length)")); 2584 break; 2585 } else if (i == -2) 2586 goto trunc; 2587 else if (i == -3) 2588 goto trunc; /* bytes left, but not enough */ 2589 else { 2590 ND_PRINT((ndo, "\n\t %s", buf)); 2591 p += i; 2592 length -= i; 2593 } 2594 } 2595 } 2596 return; 2597 trunc: 2598 ND_PRINT((ndo, "[|BGP]")); 2599 } 2600 2601 static void 2602 bgp_notification_print(netdissect_options *ndo, 2603 const u_char *dat, int length) 2604 { 2605 struct bgp_notification bgpn; 2606 const u_char *tptr; 2607 2608 ND_TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); 2609 memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); 2610 2611 /* some little sanity checking */ 2612 if (length<BGP_NOTIFICATION_SIZE) 2613 return; 2614 2615 ND_PRINT((ndo, ", %s (%u)", 2616 tok2str(bgp_notify_major_values, "Unknown Error", 2617 bgpn.bgpn_major), 2618 bgpn.bgpn_major)); 2619 2620 switch (bgpn.bgpn_major) { 2621 2622 case BGP_NOTIFY_MAJOR_MSG: 2623 ND_PRINT((ndo, ", subcode %s (%u)", 2624 tok2str(bgp_notify_minor_msg_values, "Unknown", 2625 bgpn.bgpn_minor), 2626 bgpn.bgpn_minor)); 2627 break; 2628 case BGP_NOTIFY_MAJOR_OPEN: 2629 ND_PRINT((ndo, ", subcode %s (%u)", 2630 tok2str(bgp_notify_minor_open_values, "Unknown", 2631 bgpn.bgpn_minor), 2632 bgpn.bgpn_minor)); 2633 break; 2634 case BGP_NOTIFY_MAJOR_UPDATE: 2635 ND_PRINT((ndo, ", subcode %s (%u)", 2636 tok2str(bgp_notify_minor_update_values, "Unknown", 2637 bgpn.bgpn_minor), 2638 bgpn.bgpn_minor)); 2639 break; 2640 case BGP_NOTIFY_MAJOR_FSM: 2641 ND_PRINT((ndo, " subcode %s (%u)", 2642 tok2str(bgp_notify_minor_fsm_values, "Unknown", 2643 bgpn.bgpn_minor), 2644 bgpn.bgpn_minor)); 2645 break; 2646 case BGP_NOTIFY_MAJOR_CAP: 2647 ND_PRINT((ndo, " subcode %s (%u)", 2648 tok2str(bgp_notify_minor_cap_values, "Unknown", 2649 bgpn.bgpn_minor), 2650 bgpn.bgpn_minor)); 2651 break; 2652 case BGP_NOTIFY_MAJOR_CEASE: 2653 ND_PRINT((ndo, ", subcode %s (%u)", 2654 tok2str(bgp_notify_minor_cease_values, "Unknown", 2655 bgpn.bgpn_minor), 2656 bgpn.bgpn_minor)); 2657 2658 /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes 2659 * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES 2660 */ 2661 if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) { 2662 tptr = dat + BGP_NOTIFICATION_SIZE; 2663 ND_TCHECK2(*tptr, 7); 2664 ND_PRINT((ndo, ", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", 2665 tok2str(af_values, "Unknown", 2666 EXTRACT_16BITS(tptr)), 2667 EXTRACT_16BITS(tptr), 2668 tok2str(bgp_safi_values, "Unknown", *(tptr+2)), 2669 *(tptr+2), 2670 EXTRACT_32BITS(tptr+3))); 2671 } 2672 break; 2673 default: 2674 break; 2675 } 2676 2677 return; 2678 trunc: 2679 ND_PRINT((ndo, "[|BGP]")); 2680 } 2681 2682 static void 2683 bgp_route_refresh_print(netdissect_options *ndo, 2684 const u_char *pptr, int len) 2685 { 2686 const struct bgp_route_refresh *bgp_route_refresh_header; 2687 2688 ND_TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE); 2689 2690 /* some little sanity checking */ 2691 if (len<BGP_ROUTE_REFRESH_SIZE) 2692 return; 2693 2694 bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr; 2695 2696 ND_PRINT((ndo, "\n\t AFI %s (%u), SAFI %s (%u)", 2697 tok2str(af_values,"Unknown", 2698 /* this stinks but the compiler pads the structure 2699 * weird */ 2700 EXTRACT_16BITS(&bgp_route_refresh_header->afi)), 2701 EXTRACT_16BITS(&bgp_route_refresh_header->afi), 2702 tok2str(bgp_safi_values,"Unknown", 2703 bgp_route_refresh_header->safi), 2704 bgp_route_refresh_header->safi)); 2705 2706 if (ndo->ndo_vflag > 1) { 2707 ND_TCHECK2(*pptr, len); 2708 print_unknown_data(ndo, pptr, "\n\t ", len); 2709 } 2710 2711 return; 2712 trunc: 2713 ND_PRINT((ndo, "[|BGP]")); 2714 } 2715 2716 static int 2717 bgp_header_print(netdissect_options *ndo, 2718 const u_char *dat, int length) 2719 { 2720 struct bgp bgp; 2721 2722 ND_TCHECK2(dat[0], BGP_SIZE); 2723 memcpy(&bgp, dat, BGP_SIZE); 2724 ND_PRINT((ndo, "\n\t%s Message (%u), length: %u", 2725 tok2str(bgp_msg_values, "Unknown", bgp.bgp_type), 2726 bgp.bgp_type, 2727 length)); 2728 2729 switch (bgp.bgp_type) { 2730 case BGP_OPEN: 2731 bgp_open_print(ndo, dat, length); 2732 break; 2733 case BGP_UPDATE: 2734 bgp_update_print(ndo, dat, length); 2735 break; 2736 case BGP_NOTIFICATION: 2737 bgp_notification_print(ndo, dat, length); 2738 break; 2739 case BGP_KEEPALIVE: 2740 break; 2741 case BGP_ROUTE_REFRESH: 2742 bgp_route_refresh_print(ndo, dat, length); 2743 break; 2744 default: 2745 /* we have no decoder for the BGP message */ 2746 ND_TCHECK2(*dat, length); 2747 ND_PRINT((ndo, "\n\t no Message %u decoder", bgp.bgp_type)); 2748 print_unknown_data(ndo, dat, "\n\t ", length); 2749 break; 2750 } 2751 return 1; 2752 trunc: 2753 ND_PRINT((ndo, "[|BGP]")); 2754 return 0; 2755 } 2756 2757 void 2758 bgp_print(netdissect_options *ndo, 2759 const u_char *dat, int length) 2760 { 2761 const u_char *p; 2762 const u_char *ep; 2763 const u_char *start; 2764 const u_char marker[] = { 2765 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2766 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 2767 }; 2768 struct bgp bgp; 2769 uint16_t hlen; 2770 2771 ep = dat + length; 2772 if (ndo->ndo_snapend < dat + length) 2773 ep = ndo->ndo_snapend; 2774 2775 ND_PRINT((ndo, ": BGP")); 2776 2777 if (ndo->ndo_vflag < 1) /* lets be less chatty */ 2778 return; 2779 2780 p = dat; 2781 start = p; 2782 while (p < ep) { 2783 if (!ND_TTEST2(p[0], 1)) 2784 break; 2785 if (p[0] != 0xff) { 2786 p++; 2787 continue; 2788 } 2789 2790 if (!ND_TTEST2(p[0], sizeof(marker))) 2791 break; 2792 if (memcmp(p, marker, sizeof(marker)) != 0) { 2793 p++; 2794 continue; 2795 } 2796 2797 /* found BGP header */ 2798 ND_TCHECK2(p[0], BGP_SIZE); /*XXX*/ 2799 memcpy(&bgp, p, BGP_SIZE); 2800 2801 if (start != p) 2802 ND_PRINT((ndo, " [|BGP]")); 2803 2804 hlen = ntohs(bgp.bgp_len); 2805 if (hlen < BGP_SIZE) { 2806 ND_PRINT((ndo, "\n[|BGP Bogus header length %u < %u]", hlen, 2807 BGP_SIZE)); 2808 break; 2809 } 2810 2811 if (ND_TTEST2(p[0], hlen)) { 2812 if (!bgp_header_print(ndo, p, hlen)) 2813 return; 2814 p += hlen; 2815 start = p; 2816 } else { 2817 ND_PRINT((ndo, "\n[|BGP %s]", 2818 tok2str(bgp_msg_values, 2819 "Unknown Message Type", 2820 bgp.bgp_type))); 2821 break; 2822 } 2823 } 2824 2825 return; 2826 2827 trunc: 2828 ND_PRINT((ndo, " [|BGP]")); 2829 } 2830 2831 /* 2832 * Local Variables: 2833 * c-style: whitesmith 2834 * c-basic-offset: 4 2835 * End: 2836 */ 2837