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 #ifdef HAVE_CONFIG_H 34 #include "config.h" 35 #endif 36 37 #ifndef lint 38 static const char rcsid[] _U_ = 39 "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.91.2.6 2005/06/03 07:31:43 hannes Exp $"; 40 #endif 41 42 #include <tcpdump-stdinc.h> 43 44 #include <stdio.h> 45 #include <string.h> 46 47 #include "interface.h" 48 #include "decode_prefix.h" 49 #include "addrtoname.h" 50 #include "extract.h" 51 #include "bgp.h" 52 #include "l2vpn.h" 53 54 struct bgp { 55 u_int8_t bgp_marker[16]; 56 u_int16_t bgp_len; 57 u_int8_t bgp_type; 58 }; 59 #define BGP_SIZE 19 /* unaligned */ 60 61 #define BGP_OPEN 1 62 #define BGP_UPDATE 2 63 #define BGP_NOTIFICATION 3 64 #define BGP_KEEPALIVE 4 65 #define BGP_ROUTE_REFRESH 5 66 67 static struct tok bgp_msg_values[] = { 68 { BGP_OPEN, "Open"}, 69 { BGP_UPDATE, "Update"}, 70 { BGP_NOTIFICATION, "Notification"}, 71 { BGP_KEEPALIVE, "Keepalive"}, 72 { BGP_ROUTE_REFRESH, "Route Refresh"}, 73 { 0, NULL} 74 }; 75 76 struct bgp_open { 77 u_int8_t bgpo_marker[16]; 78 u_int16_t bgpo_len; 79 u_int8_t bgpo_type; 80 u_int8_t bgpo_version; 81 u_int16_t bgpo_myas; 82 u_int16_t bgpo_holdtime; 83 u_int32_t bgpo_id; 84 u_int8_t bgpo_optlen; 85 /* options should follow */ 86 }; 87 #define BGP_OPEN_SIZE 29 /* unaligned */ 88 89 struct bgp_opt { 90 u_int8_t bgpopt_type; 91 u_int8_t bgpopt_len; 92 /* variable length */ 93 }; 94 #define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ 95 96 #define BGP_UPDATE_MINSIZE 23 97 98 struct bgp_notification { 99 u_int8_t bgpn_marker[16]; 100 u_int16_t bgpn_len; 101 u_int8_t bgpn_type; 102 u_int8_t bgpn_major; 103 u_int8_t bgpn_minor; 104 }; 105 #define BGP_NOTIFICATION_SIZE 21 /* unaligned */ 106 107 struct bgp_route_refresh { 108 u_int8_t bgp_marker[16]; 109 u_int16_t len; 110 u_int8_t type; 111 u_int8_t afi[2]; /* the compiler messes this structure up */ 112 u_int8_t res; /* when doing misaligned sequences of int8 and int16 */ 113 u_int8_t safi; /* afi should be int16 - so we have to access it using */ 114 }; /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh) */ 115 #define BGP_ROUTE_REFRESH_SIZE 23 116 117 struct bgp_attr { 118 u_int8_t bgpa_flags; 119 u_int8_t bgpa_type; 120 union { 121 u_int8_t len; 122 u_int16_t elen; 123 } bgpa_len; 124 #define bgp_attr_len(p) \ 125 (((p)->bgpa_flags & 0x10) ? \ 126 EXTRACT_16BITS(&(p)->bgpa_len.elen) : (p)->bgpa_len.len) 127 #define bgp_attr_off(p) \ 128 (((p)->bgpa_flags & 0x10) ? 4 : 3) 129 }; 130 131 #define BGPTYPE_ORIGIN 1 132 #define BGPTYPE_AS_PATH 2 133 #define BGPTYPE_NEXT_HOP 3 134 #define BGPTYPE_MULTI_EXIT_DISC 4 135 #define BGPTYPE_LOCAL_PREF 5 136 #define BGPTYPE_ATOMIC_AGGREGATE 6 137 #define BGPTYPE_AGGREGATOR 7 138 #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ 139 #define BGPTYPE_ORIGINATOR_ID 9 /* RFC1998 */ 140 #define BGPTYPE_CLUSTER_LIST 10 /* RFC1998 */ 141 #define BGPTYPE_DPA 11 /* draft-ietf-idr-bgp-dpa */ 142 #define BGPTYPE_ADVERTISERS 12 /* RFC1863 */ 143 #define BGPTYPE_RCID_PATH 13 /* RFC1863 */ 144 #define BGPTYPE_MP_REACH_NLRI 14 /* RFC2283 */ 145 #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2283 */ 146 #define BGPTYPE_EXTD_COMMUNITIES 16 /* draft-ietf-idr-bgp-ext-communities */ 147 #define BGPTYPE_ATTR_SET 128 /* draft-marques-ppvpn-ibgp */ 148 149 #define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */ 150 151 static struct tok bgp_attr_values[] = { 152 { BGPTYPE_ORIGIN, "Origin"}, 153 { BGPTYPE_AS_PATH, "AS Path"}, 154 { BGPTYPE_NEXT_HOP, "Next Hop"}, 155 { BGPTYPE_MULTI_EXIT_DISC, "Multi Exit Discriminator"}, 156 { BGPTYPE_LOCAL_PREF, "Local Preference"}, 157 { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"}, 158 { BGPTYPE_AGGREGATOR, "Aggregator"}, 159 { BGPTYPE_COMMUNITIES, "Community"}, 160 { BGPTYPE_ORIGINATOR_ID, "Originator ID"}, 161 { BGPTYPE_CLUSTER_LIST, "Cluster List"}, 162 { BGPTYPE_DPA, "DPA"}, 163 { BGPTYPE_ADVERTISERS, "Advertisers"}, 164 { BGPTYPE_RCID_PATH, "RCID Path / Cluster ID"}, 165 { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"}, 166 { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"}, 167 { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"}, 168 { BGPTYPE_ATTR_SET, "Attribute Set"}, 169 { 255, "Reserved for development"}, 170 { 0, NULL} 171 }; 172 173 #define BGP_AS_SET 1 174 #define BGP_AS_SEQUENCE 2 175 #define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */ 176 #define BGP_CONFED_AS_SET 4 /* draft-ietf-idr-rfc3065bis-01 */ 177 178 static struct tok bgp_as_path_segment_open_values[] = { 179 { BGP_AS_SEQUENCE, ""}, 180 { BGP_AS_SET, "{ "}, 181 { BGP_CONFED_AS_SEQUENCE, "( "}, 182 { BGP_CONFED_AS_SET, "({ "}, 183 { 0, NULL} 184 }; 185 186 static struct tok bgp_as_path_segment_close_values[] = { 187 { BGP_AS_SEQUENCE, ""}, 188 { BGP_AS_SET, "}"}, 189 { BGP_CONFED_AS_SEQUENCE, ")"}, 190 { BGP_CONFED_AS_SET, "})"}, 191 { 0, NULL} 192 }; 193 194 #define BGP_OPT_AUTH 1 195 #define BGP_OPT_CAP 2 196 197 198 static struct tok bgp_opt_values[] = { 199 { BGP_OPT_AUTH, "Authentication Information"}, 200 { BGP_OPT_CAP, "Capabilities Advertisement"}, 201 { 0, NULL} 202 }; 203 204 #define BGP_CAPCODE_MP 1 205 #define BGP_CAPCODE_RR 2 206 #define BGP_CAPCODE_ORF 3 /* XXX */ 207 #define BGP_CAPCODE_RESTART 64 /* draft-ietf-idr-restart-05 */ 208 #define BGP_CAPCODE_AS_NEW 65 /* XXX */ 209 #define BGP_CAPCODE_DYN_CAP 67 /* XXX */ 210 #define BGP_CAPCODE_RR_CISCO 128 211 212 static struct tok bgp_capcode_values[] = { 213 { BGP_CAPCODE_MP, "Multiprotocol Extensions"}, 214 { BGP_CAPCODE_RR, "Route Refresh"}, 215 { BGP_CAPCODE_ORF, "Cooperative Route Filtering"}, 216 { BGP_CAPCODE_RESTART, "Graceful Restart"}, 217 { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"}, 218 { BGP_CAPCODE_DYN_CAP, "Dynamic Capability"}, 219 { BGP_CAPCODE_RR_CISCO, "Route Refresh (Cisco)"}, 220 { 0, NULL} 221 }; 222 223 #define BGP_NOTIFY_MAJOR_MSG 1 224 #define BGP_NOTIFY_MAJOR_OPEN 2 225 #define BGP_NOTIFY_MAJOR_UPDATE 3 226 #define BGP_NOTIFY_MAJOR_HOLDTIME 4 227 #define BGP_NOTIFY_MAJOR_FSM 5 228 #define BGP_NOTIFY_MAJOR_CEASE 6 229 #define BGP_NOTIFY_MAJOR_CAP 7 230 231 static struct tok bgp_notify_major_values[] = { 232 { BGP_NOTIFY_MAJOR_MSG, "Message Header Error"}, 233 { BGP_NOTIFY_MAJOR_OPEN, "OPEN Message Error"}, 234 { BGP_NOTIFY_MAJOR_UPDATE, "UPDATE Message Error"}, 235 { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"}, 236 { BGP_NOTIFY_MAJOR_FSM, "Finite State Machine Error"}, 237 { BGP_NOTIFY_MAJOR_CEASE, "Cease"}, 238 { BGP_NOTIFY_MAJOR_CAP, "Capability Message Error"}, 239 { 0, NULL} 240 }; 241 242 /* draft-ietf-idr-cease-subcode-02 */ 243 #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1 244 static struct tok bgp_notify_minor_cease_values[] = { 245 { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"}, 246 { 2, "Administratively Shutdown"}, 247 { 3, "Peer Unconfigured"}, 248 { 4, "Administratively Reset"}, 249 { 5, "Connection Rejected"}, 250 { 6, "Other Configuration Change"}, 251 { 7, "Connection Collision Resolution"}, 252 { 0, NULL} 253 }; 254 255 static struct tok bgp_notify_minor_msg_values[] = { 256 { 1, "Connection Not Synchronized"}, 257 { 2, "Bad Message Length"}, 258 { 3, "Bad Message Type"}, 259 { 0, NULL} 260 }; 261 262 static struct tok bgp_notify_minor_open_values[] = { 263 { 1, "Unsupported Version Number"}, 264 { 2, "Bad Peer AS"}, 265 { 3, "Bad BGP Identifier"}, 266 { 4, "Unsupported Optional Parameter"}, 267 { 5, "Authentication Failure"}, 268 { 6, "Unacceptable Hold Time"}, 269 { 0, NULL} 270 }; 271 272 static struct tok bgp_notify_minor_update_values[] = { 273 { 1, "Malformed Attribute List"}, 274 { 2, "Unrecognized Well-known Attribute"}, 275 { 3, "Missing Well-known Attribute"}, 276 { 4, "Attribute Flags Error"}, 277 { 5, "Attribute Length Error"}, 278 { 6, "Invalid ORIGIN Attribute"}, 279 { 7, "AS Routing Loop"}, 280 { 8, "Invalid NEXT_HOP Attribute"}, 281 { 9, "Optional Attribute Error"}, 282 { 10, "Invalid Network Field"}, 283 { 11, "Malformed AS_PATH"}, 284 { 0, NULL} 285 }; 286 287 static struct tok bgp_notify_minor_cap_values[] = { 288 { 1, "Invalid Action Value" }, 289 { 2, "Invalid Capability Length" }, 290 { 3, "Malformed Capability Value" }, 291 { 4, "Unsupported Capability Code" }, 292 { 0, NULL } 293 }; 294 295 static struct tok bgp_origin_values[] = { 296 { 0, "IGP"}, 297 { 1, "EGP"}, 298 { 2, "Incomplete"}, 299 { 0, NULL} 300 }; 301 302 /* Subsequent address family identifier, RFC2283 section 7 */ 303 #define SAFNUM_RES 0 304 #define SAFNUM_UNICAST 1 305 #define SAFNUM_MULTICAST 2 306 #define SAFNUM_UNIMULTICAST 3 307 /* labeled BGP RFC3107 */ 308 #define SAFNUM_LABUNICAST 4 309 #define SAFNUM_TUNNEL 64 /* XXX */ 310 #define SAFNUM_VPLS 65 /* XXX */ 311 #define SAFNUM_MDT 66 /* XXX */ 312 /* Section 4.3.4 of draft-rosen-rfc2547bis-03.txt */ 313 #define SAFNUM_VPNUNICAST 128 314 #define SAFNUM_VPNMULTICAST 129 315 #define SAFNUM_VPNUNIMULTICAST 130 316 /* draft-marques-ppvpn-rt-constrain-01.txt */ 317 #define SAFNUM_RT_ROUTING_INFO 132 318 319 #define BGP_VPN_RD_LEN 8 320 321 static struct tok bgp_safi_values[] = { 322 { SAFNUM_RES, "Reserved"}, 323 { SAFNUM_UNICAST, "Unicast"}, 324 { SAFNUM_MULTICAST, "Multicast"}, 325 { SAFNUM_UNIMULTICAST, "Unicast+Multicast"}, 326 { SAFNUM_LABUNICAST, "labeled Unicast"}, 327 { SAFNUM_TUNNEL, "Tunnel"}, 328 { SAFNUM_VPLS, "VPLS"}, 329 { SAFNUM_MDT, "MDT"}, 330 { SAFNUM_VPNUNICAST, "labeled VPN Unicast"}, 331 { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"}, 332 { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"}, 333 { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"}, /* draft-marques-ppvpn-rt-constrain-01.txt */ 334 { 0, NULL } 335 }; 336 337 /* well-known community */ 338 #define BGP_COMMUNITY_NO_EXPORT 0xffffff01 339 #define BGP_COMMUNITY_NO_ADVERT 0xffffff02 340 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 341 342 /* RFC1700 address family numbers */ 343 #define AFNUM_INET 1 344 #define AFNUM_INET6 2 345 #define AFNUM_NSAP 3 346 #define AFNUM_HDLC 4 347 #define AFNUM_BBN1822 5 348 #define AFNUM_802 6 349 #define AFNUM_E163 7 350 #define AFNUM_E164 8 351 #define AFNUM_F69 9 352 #define AFNUM_X121 10 353 #define AFNUM_IPX 11 354 #define AFNUM_ATALK 12 355 #define AFNUM_DECNET 13 356 #define AFNUM_BANYAN 14 357 #define AFNUM_E164NSAP 15 358 /* draft-kompella-ppvpn-l2vpn */ 359 #define AFNUM_L2VPN 196 /* still to be approved by IANA */ 360 361 static struct tok bgp_afi_values[] = { 362 { 0, "Reserved"}, 363 { AFNUM_INET, "IPv4"}, 364 { AFNUM_INET6, "IPv6"}, 365 { AFNUM_NSAP, "NSAP"}, 366 { AFNUM_HDLC, "HDLC"}, 367 { AFNUM_BBN1822, "BBN 1822"}, 368 { AFNUM_802, "802"}, 369 { AFNUM_E163, "E.163"}, 370 { AFNUM_E164, "E.164"}, 371 { AFNUM_F69, "F.69"}, 372 { AFNUM_X121, "X.121"}, 373 { AFNUM_IPX, "Novell IPX"}, 374 { AFNUM_ATALK, "Appletalk"}, 375 { AFNUM_DECNET, "Decnet IV"}, 376 { AFNUM_BANYAN, "Banyan Vines"}, 377 { AFNUM_E164NSAP, "E.164 with NSAP subaddress"}, 378 { AFNUM_L2VPN, "Layer-2 VPN"}, 379 { 0, NULL}, 380 }; 381 382 /* Extended community type - draft-ietf-idr-bgp-ext-communities-05 */ 383 #define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */ 384 #define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */ 385 #define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AN(4bytes):local(2bytes) */ 386 #define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */ 387 #define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */ 388 #define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AN(4bytes):local(2bytes) */ 389 #define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */ 390 /* rfc2547 bgp-mpls-vpns */ 391 #define BGP_EXT_COM_CISCO_MCAST 0x0009 /* cisco proprietary */ 392 393 #define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */ 394 #define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatability */ 395 #define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatability */ 396 #define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatability */ 397 398 #define BGP_EXT_COM_OSPF_RTYPE 0x0306 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */ 399 #define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatability */ 400 401 #define BGP_EXT_COM_OSPF_RID 0x0107 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */ 402 #define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatability */ 403 404 #define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */ 405 406 static struct tok bgp_extd_comm_flag_values[] = { 407 { 0x8000, "vendor-specific"}, 408 { 0x4000, "non-transitive"}, 409 { 0, NULL}, 410 }; 411 412 static struct tok bgp_extd_comm_subtype_values[] = { 413 { BGP_EXT_COM_RT_0, "target"}, 414 { BGP_EXT_COM_RT_1, "target"}, 415 { BGP_EXT_COM_RT_2, "target"}, 416 { BGP_EXT_COM_RO_0, "origin"}, 417 { BGP_EXT_COM_RO_1, "origin"}, 418 { BGP_EXT_COM_RO_2, "origin"}, 419 { BGP_EXT_COM_LINKBAND, "link-BW"}, 420 { BGP_EXT_COM_CISCO_MCAST, "mdt-group"}, 421 { BGP_EXT_COM_VPN_ORIGIN, "ospf-domain"}, 422 { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"}, 423 { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"}, 424 { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"}, 425 { BGP_EXT_COM_OSPF_RTYPE, "ospf-route-type"}, 426 { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"}, 427 { BGP_EXT_COM_OSPF_RID, "ospf-router-id"}, 428 { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"}, 429 { BGP_EXT_COM_L2INFO, "layer2-info"}, 430 { 0, NULL}, 431 }; 432 433 /* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */ 434 #define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */ 435 #define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */ 436 #define BGP_OSPF_RTYPE_SUM 3 /* OSPF Summary LSA */ 437 #define BGP_OSPF_RTYPE_EXT 5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */ 438 #define BGP_OSPF_RTYPE_NSSA 7 /* OSPF NSSA External*/ 439 #define BGP_OSPF_RTYPE_SHAM 129 /* OSPF-MPLS-VPN Sham link */ 440 #define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */ 441 442 static struct tok bgp_extd_comm_ospf_rtype_values[] = { 443 { BGP_OSPF_RTYPE_RTR, "Router" }, 444 { BGP_OSPF_RTYPE_NET, "Network" }, 445 { BGP_OSPF_RTYPE_SUM, "Summary" }, 446 { BGP_OSPF_RTYPE_EXT, "External" }, 447 { BGP_OSPF_RTYPE_NSSA,"NSSA External" }, 448 { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" }, 449 { 0, NULL }, 450 }; 451 452 int 453 decode_prefix4(const u_char *pptr, char *buf, u_int buflen) 454 { 455 struct in_addr addr; 456 u_int plen; 457 458 TCHECK(pptr[0]); 459 plen = pptr[0]; 460 if (32 < plen) 461 return -1; 462 463 memset(&addr, 0, sizeof(addr)); 464 TCHECK2(pptr[1], (plen + 7) / 8); 465 memcpy(&addr, &pptr[1], (plen + 7) / 8); 466 if (plen % 8) { 467 ((u_char *)&addr)[(plen + 7) / 8 - 1] &= 468 ((0xff00 >> (plen % 8)) & 0xff); 469 } 470 snprintf(buf, buflen, "%s/%d", getname((u_char *)&addr), plen); 471 return 1 + (plen + 7) / 8; 472 473 trunc: 474 return -2; 475 } 476 477 static int 478 decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen) 479 { 480 struct in_addr addr; 481 u_int plen; 482 483 TCHECK(pptr[0]); 484 plen = pptr[0]; /* get prefix length */ 485 486 /* this is one of the weirdnesses of rfc3107 487 the label length (actually the label + COS bits) 488 is added to the prefix length; 489 we also do only read out just one label - 490 there is no real application for advertisement of 491 stacked labels in a a single BGP message 492 */ 493 494 plen-=24; /* adjust prefixlen - labellength */ 495 496 if (32 < plen) 497 return -1; 498 499 memset(&addr, 0, sizeof(addr)); 500 TCHECK2(pptr[4], (plen + 7) / 8); 501 memcpy(&addr, &pptr[4], (plen + 7) / 8); 502 if (plen % 8) { 503 ((u_char *)&addr)[(plen + 7) / 8 - 1] &= 504 ((0xff00 >> (plen % 8)) & 0xff); 505 } 506 /* the label may get offsetted by 4 bits so lets shift it right */ 507 snprintf(buf, buflen, "%s/%d, label:%u %s", 508 getname((u_char *)&addr), 509 plen, 510 EXTRACT_24BITS(pptr+1)>>4, 511 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 512 513 return 4 + (plen + 7) / 8; 514 515 trunc: 516 return -2; 517 } 518 519 /* RDs and RTs share the same semantics 520 * we use bgp_vpn_rd_print for 521 * printing route targets inside a NLRI */ 522 char * 523 bgp_vpn_rd_print (const u_char *pptr) { 524 525 /* allocate space for the largest possible string */ 526 static char rd[sizeof("xxxxxxxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; 527 char *pos = rd; 528 529 /* ok lets load the RD format */ 530 switch (EXTRACT_16BITS(pptr)) { 531 532 /* AS:IP-address fmt*/ 533 case 0: 534 snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u.%u.%u.%u", 535 EXTRACT_16BITS(pptr+2), *(pptr+4), *(pptr+5), *(pptr+6), *(pptr+7)); 536 break; 537 /* IP-address:AS fmt*/ 538 539 case 1: 540 snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u", 541 *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6)); 542 break; 543 544 /* 4-byte-AS:number fmt*/ 545 case 2: 546 snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (%u.%u.%u.%u:%u)", 547 EXTRACT_32BITS(pptr+2), EXTRACT_16BITS(pptr+6), 548 *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6)); 549 break; 550 default: 551 snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format"); 552 break; 553 } 554 pos += strlen(pos); 555 *(pos) = '\0'; 556 return (rd); 557 } 558 559 static int 560 decode_rt_routing_info(const u_char *pptr, char *buf, u_int buflen) 561 { 562 u_int8_t route_target[8]; 563 u_int plen; 564 565 TCHECK(pptr[0]); 566 plen = pptr[0]; /* get prefix length */ 567 568 plen-=32; /* adjust prefix length */ 569 570 if (0 < plen) 571 return -1; 572 573 memset(&route_target, 0, sizeof(route_target)); 574 TCHECK2(pptr[1], (plen + 7) / 8); 575 memcpy(&route_target, &pptr[1], (plen + 7) / 8); 576 if (plen % 8) { 577 ((u_char *)&route_target)[(plen + 7) / 8 - 1] &= 578 ((0xff00 >> (plen % 8)) & 0xff); 579 } 580 snprintf(buf, buflen, "origin AS: %u, route target %s", 581 EXTRACT_32BITS(pptr+1), 582 bgp_vpn_rd_print((u_char *)&route_target)); 583 584 return 5 + (plen + 7) / 8; 585 586 trunc: 587 return -2; 588 } 589 590 static int 591 decode_labeled_vpn_prefix4(const u_char *pptr, char *buf, u_int buflen) 592 { 593 struct in_addr addr; 594 u_int plen; 595 596 TCHECK(pptr[0]); 597 plen = pptr[0]; /* get prefix length */ 598 599 plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ 600 601 if (32 < plen) 602 return -1; 603 604 memset(&addr, 0, sizeof(addr)); 605 TCHECK2(pptr[12], (plen + 7) / 8); 606 memcpy(&addr, &pptr[12], (plen + 7) / 8); 607 if (plen % 8) { 608 ((u_char *)&addr)[(plen + 7) / 8 - 1] &= 609 ((0xff00 >> (plen % 8)) & 0xff); 610 } 611 /* the label may get offsetted by 4 bits so lets shift it right */ 612 snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", 613 bgp_vpn_rd_print(pptr+4), 614 getname((u_char *)&addr), 615 plen, 616 EXTRACT_24BITS(pptr+1)>>4, 617 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 618 619 return 12 + (plen + 7) / 8; 620 621 trunc: 622 return -2; 623 } 624 625 static int 626 decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen) 627 { 628 int plen,tlen,strlen,tlv_type,tlv_len,ttlv_len; 629 630 TCHECK2(pptr[0], 2); 631 plen=EXTRACT_16BITS(pptr); 632 tlen=plen; 633 pptr+=2; 634 TCHECK2(pptr[0],15); 635 strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", 636 bgp_vpn_rd_print(pptr), 637 EXTRACT_16BITS(pptr+8), 638 EXTRACT_16BITS(pptr+10), 639 EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */ 640 pptr+=15; 641 tlen-=15; 642 643 /* ok now the variable part - lets read out TLVs*/ 644 while (tlen>0) { 645 if (tlen < 3) 646 return -1; 647 TCHECK2(pptr[0], 3); 648 tlv_type=*pptr++; 649 tlv_len=EXTRACT_16BITS(pptr); 650 ttlv_len=tlv_len; 651 pptr+=2; 652 653 switch(tlv_type) { 654 case 1: 655 strlen+=snprintf(buf+strlen,buflen-strlen, "\n\t\tcircuit status vector (%u) length: %u: 0x", 656 tlv_type, 657 tlv_len); 658 ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */ 659 while (ttlv_len>0) { 660 TCHECK(pptr[0]); 661 strlen+=snprintf(buf+strlen,buflen-strlen, "%02x",*pptr++); 662 ttlv_len--; 663 } 664 break; 665 default: 666 snprintf(buf+strlen,buflen-strlen, "\n\t\tunknown TLV #%u, length: %u", 667 tlv_type, 668 tlv_len); 669 break; 670 } 671 tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it tright */ 672 } 673 return plen+2; 674 675 trunc: 676 return -2; 677 } 678 679 #ifdef INET6 680 int 681 decode_prefix6(const u_char *pd, char *buf, u_int buflen) 682 { 683 struct in6_addr addr; 684 u_int plen; 685 686 TCHECK(pd[0]); 687 plen = pd[0]; 688 if (128 < plen) 689 return -1; 690 691 memset(&addr, 0, sizeof(addr)); 692 TCHECK2(pd[1], (plen + 7) / 8); 693 memcpy(&addr, &pd[1], (plen + 7) / 8); 694 if (plen % 8) { 695 addr.s6_addr[(plen + 7) / 8 - 1] &= 696 ((0xff00 >> (plen % 8)) & 0xff); 697 } 698 snprintf(buf, buflen, "%s/%d", getname6((u_char *)&addr), plen); 699 return 1 + (plen + 7) / 8; 700 701 trunc: 702 return -2; 703 } 704 705 static int 706 decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen) 707 { 708 struct in6_addr addr; 709 u_int plen; 710 711 TCHECK(pptr[0]); 712 plen = pptr[0]; /* get prefix length */ 713 plen-=24; /* adjust prefixlen - labellength */ 714 715 if (128 < plen) 716 return -1; 717 718 memset(&addr, 0, sizeof(addr)); 719 TCHECK2(pptr[4], (plen + 7) / 8); 720 memcpy(&addr, &pptr[4], (plen + 7) / 8); 721 if (plen % 8) { 722 addr.s6_addr[(plen + 7) / 8 - 1] &= 723 ((0xff00 >> (plen % 8)) & 0xff); 724 } 725 /* the label may get offsetted by 4 bits so lets shift it right */ 726 snprintf(buf, buflen, "%s/%d, label:%u %s", 727 getname6((u_char *)&addr), 728 plen, 729 EXTRACT_24BITS(pptr+1)>>4, 730 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 731 732 return 4 + (plen + 7) / 8; 733 734 trunc: 735 return -2; 736 } 737 738 static int 739 decode_labeled_vpn_prefix6(const u_char *pptr, char *buf, u_int buflen) 740 { 741 struct in6_addr addr; 742 u_int plen; 743 744 TCHECK(pptr[0]); 745 plen = pptr[0]; /* get prefix length */ 746 747 plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ 748 749 if (128 < plen) 750 return -1; 751 752 memset(&addr, 0, sizeof(addr)); 753 TCHECK2(pptr[12], (plen + 7) / 8); 754 memcpy(&addr, &pptr[12], (plen + 7) / 8); 755 if (plen % 8) { 756 addr.s6_addr[(plen + 7) / 8 - 1] &= 757 ((0xff00 >> (plen % 8)) & 0xff); 758 } 759 /* the label may get offsetted by 4 bits so lets shift it right */ 760 snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", 761 bgp_vpn_rd_print(pptr+4), 762 getname6((u_char *)&addr), 763 plen, 764 EXTRACT_24BITS(pptr+1)>>4, 765 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 766 767 return 12 + (plen + 7) / 8; 768 769 trunc: 770 return -2; 771 } 772 #endif 773 774 static int 775 decode_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) 776 { 777 u_int8_t addr[19]; 778 u_int plen; 779 780 TCHECK(pptr[0]); 781 plen = pptr[0]; /* get prefix length */ 782 783 if (152 < plen) 784 return -1; 785 786 memset(&addr, 0, sizeof(addr)); 787 TCHECK2(pptr[4], (plen + 7) / 8); 788 memcpy(&addr, &pptr[4], (plen + 7) / 8); 789 if (plen % 8) { 790 addr[(plen + 7) / 8 - 1] &= 791 ((0xff00 >> (plen % 8)) & 0xff); 792 } 793 snprintf(buf, buflen, "%s/%d", 794 isonsap_string(addr,(plen + 7) / 8), 795 plen); 796 797 return 1 + (plen + 7) / 8; 798 799 trunc: 800 return -2; 801 } 802 803 static int 804 decode_labeled_vpn_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) 805 { 806 u_int8_t addr[19]; 807 u_int plen; 808 809 TCHECK(pptr[0]); 810 plen = pptr[0]; /* get prefix length */ 811 812 plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ 813 814 if (152 < plen) 815 return -1; 816 817 memset(&addr, 0, sizeof(addr)); 818 TCHECK2(pptr[12], (plen + 7) / 8); 819 memcpy(&addr, &pptr[12], (plen + 7) / 8); 820 if (plen % 8) { 821 addr[(plen + 7) / 8 - 1] &= 822 ((0xff00 >> (plen % 8)) & 0xff); 823 } 824 /* the label may get offsetted by 4 bits so lets shift it right */ 825 snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", 826 bgp_vpn_rd_print(pptr+4), 827 isonsap_string(addr,(plen + 7) / 8), 828 plen, 829 EXTRACT_24BITS(pptr+1)>>4, 830 ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); 831 832 return 12 + (plen + 7) / 8; 833 834 trunc: 835 return -2; 836 } 837 838 static int 839 bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) 840 { 841 int i; 842 u_int16_t af; 843 u_int8_t safi, snpa, nhlen; 844 union { /* copy buffer for bandwidth values */ 845 float f; 846 u_int32_t i; 847 } bw; 848 int advance; 849 int tlen; 850 const u_char *tptr; 851 char buf[MAXHOSTNAMELEN + 100]; 852 char tokbuf[TOKBUFSIZE]; 853 854 tptr = pptr; 855 tlen=len; 856 857 switch (attr->bgpa_type) { 858 case BGPTYPE_ORIGIN: 859 if (len != 1) 860 printf("invalid len"); 861 else { 862 TCHECK(*tptr); 863 printf("%s", tok2strbuf(bgp_origin_values, 864 "Unknown Origin Typecode", 865 tptr[0], 866 tokbuf, sizeof(tokbuf))); 867 } 868 break; 869 870 case BGPTYPE_AS_PATH: 871 if (len % 2) { 872 printf("invalid len"); 873 break; 874 } 875 if (!len) { 876 printf("empty"); 877 break; 878 } 879 880 while (tptr < pptr + len) { 881 TCHECK(tptr[0]); 882 printf("%s", tok2strbuf(bgp_as_path_segment_open_values, 883 "?", tptr[0], 884 tokbuf, sizeof(tokbuf))); 885 for (i = 0; i < tptr[1] * 2; i += 2) { 886 TCHECK2(tptr[2 + i], 2); 887 printf("%u ", EXTRACT_16BITS(&tptr[2 + i])); 888 } 889 TCHECK(tptr[0]); 890 printf("%s", tok2strbuf(bgp_as_path_segment_close_values, 891 "?", tptr[0], 892 tokbuf, sizeof(tokbuf))); 893 TCHECK(tptr[1]); 894 tptr += 2 + tptr[1] * 2; 895 } 896 break; 897 case BGPTYPE_NEXT_HOP: 898 if (len != 4) 899 printf("invalid len"); 900 else { 901 TCHECK2(tptr[0], 4); 902 printf("%s", getname(tptr)); 903 } 904 break; 905 case BGPTYPE_MULTI_EXIT_DISC: 906 case BGPTYPE_LOCAL_PREF: 907 if (len != 4) 908 printf("invalid len"); 909 else { 910 TCHECK2(tptr[0], 4); 911 printf("%u", EXTRACT_32BITS(tptr)); 912 } 913 break; 914 case BGPTYPE_ATOMIC_AGGREGATE: 915 if (len != 0) 916 printf("invalid len"); 917 break; 918 case BGPTYPE_AGGREGATOR: 919 if (len != 6) { 920 printf("invalid len"); 921 break; 922 } 923 TCHECK2(tptr[0], 6); 924 printf(" AS #%u, origin %s", EXTRACT_16BITS(tptr), 925 getname(tptr + 2)); 926 break; 927 case BGPTYPE_COMMUNITIES: 928 if (len % 4) { 929 printf("invalid len"); 930 break; 931 } 932 while (tlen>0) { 933 u_int32_t comm; 934 TCHECK2(tptr[0], 4); 935 comm = EXTRACT_32BITS(tptr); 936 switch (comm) { 937 case BGP_COMMUNITY_NO_EXPORT: 938 printf(" NO_EXPORT"); 939 break; 940 case BGP_COMMUNITY_NO_ADVERT: 941 printf(" NO_ADVERTISE"); 942 break; 943 case BGP_COMMUNITY_NO_EXPORT_SUBCONFED: 944 printf(" NO_EXPORT_SUBCONFED"); 945 break; 946 default: 947 printf("%u:%u%s", 948 (comm >> 16) & 0xffff, 949 comm & 0xffff, 950 (tlen>4) ? ", " : ""); 951 break; 952 } 953 tlen -=4; 954 tptr +=4; 955 } 956 break; 957 case BGPTYPE_ORIGINATOR_ID: 958 if (len != 4) { 959 printf("invalid len"); 960 break; 961 } 962 TCHECK2(tptr[0], 4); 963 printf("%s",getname(tptr)); 964 break; 965 case BGPTYPE_CLUSTER_LIST: 966 if (len % 4) { 967 printf("invalid len"); 968 break; 969 } 970 while (tlen>0) { 971 TCHECK2(tptr[0], 4); 972 printf("%s%s", 973 getname(tptr), 974 (tlen>4) ? ", " : ""); 975 tlen -=4; 976 tptr +=4; 977 } 978 break; 979 case BGPTYPE_MP_REACH_NLRI: 980 TCHECK2(tptr[0], 3); 981 af = EXTRACT_16BITS(tptr); 982 safi = tptr[2]; 983 984 printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)", 985 tok2strbuf(bgp_afi_values, "Unknown AFI", af, 986 tokbuf, sizeof(tokbuf)), 987 af, 988 (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ 989 tok2strbuf(bgp_safi_values, "Unknown SAFI", safi, 990 tokbuf, sizeof(tokbuf)), 991 safi); 992 993 switch(af<<8 | safi) { 994 case (AFNUM_INET<<8 | SAFNUM_UNICAST): 995 case (AFNUM_INET<<8 | SAFNUM_MULTICAST): 996 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): 997 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): 998 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): 999 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): 1000 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): 1001 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): 1002 #ifdef INET6 1003 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): 1004 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): 1005 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): 1006 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): 1007 case (AFNUM_INET6<<8 | SAFNUM_RT_ROUTING_INFO): 1008 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): 1009 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): 1010 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): 1011 #endif 1012 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): 1013 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): 1014 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): 1015 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): 1016 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): 1017 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): 1018 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): 1019 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): 1020 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): 1021 break; 1022 default: 1023 TCHECK2(tptr[0], tlen); 1024 printf("\n\t no AFI %u / SAFI %u decoder",af,safi); 1025 if (vflag <= 1) 1026 print_unknown_data(tptr,"\n\t ",tlen); 1027 goto done; 1028 break; 1029 } 1030 1031 tptr +=3; 1032 1033 TCHECK(tptr[0]); 1034 nhlen = tptr[0]; 1035 tlen = nhlen; 1036 tptr++; 1037 1038 if (tlen) { 1039 printf("\n\t nexthop: "); 1040 while (tlen > 0) { 1041 switch(af<<8 | safi) { 1042 case (AFNUM_INET<<8 | SAFNUM_UNICAST): 1043 case (AFNUM_INET<<8 | SAFNUM_MULTICAST): 1044 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): 1045 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): 1046 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): 1047 if (tlen < (int)sizeof(struct in_addr)) { 1048 printf("invalid len"); 1049 tlen = 0; 1050 } else { 1051 TCHECK2(tptr[0], sizeof(struct in_addr)); 1052 printf("%s",getname(tptr)); 1053 tlen -= sizeof(struct in_addr); 1054 tptr += sizeof(struct in_addr); 1055 } 1056 break; 1057 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): 1058 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): 1059 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): 1060 if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) { 1061 printf("invalid len"); 1062 tlen = 0; 1063 } else { 1064 TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN); 1065 printf("RD: %s, %s", 1066 bgp_vpn_rd_print(tptr), 1067 getname(tptr+BGP_VPN_RD_LEN)); 1068 tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN); 1069 tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN); 1070 } 1071 break; 1072 #ifdef INET6 1073 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): 1074 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): 1075 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): 1076 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): 1077 case (AFNUM_INET6<<8 | SAFNUM_RT_ROUTING_INFO): 1078 if (tlen < (int)sizeof(struct in6_addr)) { 1079 printf("invalid len"); 1080 tlen = 0; 1081 } else { 1082 TCHECK2(tptr[0], sizeof(struct in6_addr)); 1083 printf("%s", getname6(tptr)); 1084 tlen -= sizeof(struct in6_addr); 1085 tptr += sizeof(struct in6_addr); 1086 } 1087 break; 1088 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): 1089 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): 1090 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): 1091 if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) { 1092 printf("invalid len"); 1093 tlen = 0; 1094 } else { 1095 TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN); 1096 printf("RD: %s, %s", 1097 bgp_vpn_rd_print(tptr), 1098 getname6(tptr+BGP_VPN_RD_LEN)); 1099 tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); 1100 tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); 1101 } 1102 break; 1103 #endif 1104 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): 1105 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): 1106 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): 1107 if (tlen < (int)sizeof(struct in_addr)) { 1108 printf("invalid len"); 1109 tlen = 0; 1110 } else { 1111 TCHECK2(tptr[0], sizeof(struct in_addr)); 1112 printf("%s", getname(tptr)); 1113 tlen -= (sizeof(struct in_addr)); 1114 tptr += (sizeof(struct in_addr)); 1115 } 1116 break; 1117 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): 1118 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): 1119 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): 1120 TCHECK2(tptr[0], tlen); 1121 printf("%s",isonsap_string(tptr,tlen)); 1122 tptr += tlen; 1123 tlen = 0; 1124 break; 1125 1126 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): 1127 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): 1128 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): 1129 if (tlen < BGP_VPN_RD_LEN+1) { 1130 printf("invalid len"); 1131 tlen = 0; 1132 } else { 1133 TCHECK2(tptr[0], tlen); 1134 printf("RD: %s, %s", 1135 bgp_vpn_rd_print(tptr), 1136 isonsap_string(tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)); 1137 /* rfc986 mapped IPv4 address ? */ 1138 if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) 1139 printf(" = %s", getname(tptr+BGP_VPN_RD_LEN+4)); 1140 #ifdef INET6 1141 /* rfc1888 mapped IPv6 address ? */ 1142 else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) 1143 printf(" = %s", getname6(tptr+BGP_VPN_RD_LEN+3)); 1144 #endif 1145 tptr += tlen; 1146 tlen = 0; 1147 } 1148 break; 1149 default: 1150 TCHECK2(tptr[0], tlen); 1151 printf("no AFI %u/SAFI %u decoder",af,safi); 1152 if (vflag <= 1) 1153 print_unknown_data(tptr,"\n\t ",tlen); 1154 tptr += tlen; 1155 tlen = 0; 1156 goto done; 1157 break; 1158 } 1159 } 1160 } 1161 printf(", nh-length: %u", nhlen); 1162 tptr += tlen; 1163 1164 TCHECK(tptr[0]); 1165 snpa = tptr[0]; 1166 tptr++; 1167 1168 if (snpa) { 1169 printf("\n\t %u SNPA", snpa); 1170 for (/*nothing*/; snpa > 0; snpa--) { 1171 TCHECK(tptr[0]); 1172 printf("\n\t %d bytes", tptr[0]); 1173 tptr += tptr[0] + 1; 1174 } 1175 } else { 1176 printf(", no SNPA"); 1177 } 1178 1179 while (len - (tptr - pptr) > 0) { 1180 switch (af<<8 | safi) { 1181 case (AFNUM_INET<<8 | SAFNUM_UNICAST): 1182 case (AFNUM_INET<<8 | SAFNUM_MULTICAST): 1183 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): 1184 advance = decode_prefix4(tptr, buf, sizeof(buf)); 1185 if (advance == -1) 1186 printf("\n\t (illegal prefix length)"); 1187 else if (advance == -2) 1188 goto trunc; 1189 else 1190 printf("\n\t %s", buf); 1191 break; 1192 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): 1193 advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); 1194 if (advance == -1) 1195 printf("\n\t (illegal prefix length)"); 1196 else if (advance == -2) 1197 goto trunc; 1198 else 1199 printf("\n\t %s", buf); 1200 break; 1201 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): 1202 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): 1203 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): 1204 advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); 1205 if (advance == -1) 1206 printf("\n\t (illegal prefix length)"); 1207 else if (advance == -2) 1208 goto trunc; 1209 else 1210 printf("\n\t %s", buf); 1211 break; 1212 case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): 1213 advance = decode_rt_routing_info(tptr, buf, sizeof(buf)); 1214 if (advance == -1) 1215 printf("\n\t (illegal prefix length)"); 1216 else if (advance == -2) 1217 goto trunc; 1218 else 1219 printf("\n\t %s", buf); 1220 break; 1221 #ifdef INET6 1222 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): 1223 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): 1224 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): 1225 advance = decode_prefix6(tptr, buf, sizeof(buf)); 1226 if (advance == -1) 1227 printf("\n\t (illegal prefix length)"); 1228 else if (advance == -2) 1229 goto trunc; 1230 else 1231 printf("\n\t %s", buf); 1232 break; 1233 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): 1234 advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); 1235 if (advance == -1) 1236 printf("\n\t (illegal prefix length)"); 1237 else if (advance == -2) 1238 goto trunc; 1239 else 1240 printf("\n\t %s", buf); 1241 break; 1242 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): 1243 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): 1244 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): 1245 advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); 1246 if (advance == -1) 1247 printf("\n\t (illegal prefix length)"); 1248 else if (advance == -2) 1249 goto trunc; 1250 else 1251 printf("\n\t %s", buf); 1252 break; 1253 case (AFNUM_INET6<<8 | SAFNUM_RT_ROUTING_INFO): 1254 advance = decode_rt_routing_info(tptr, buf, sizeof(buf)); 1255 if (advance == -1) 1256 printf("\n\t (illegal prefix length)"); 1257 else if (advance == -2) 1258 goto trunc; 1259 else 1260 printf("\n\t %s", buf); 1261 break; 1262 #endif 1263 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): 1264 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): 1265 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): 1266 advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); 1267 if (advance == -1) 1268 printf("\n\t (illegal length)"); 1269 else if (advance == -2) 1270 goto trunc; 1271 else 1272 printf("\n\t %s", buf); 1273 break; 1274 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): 1275 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): 1276 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): 1277 advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); 1278 if (advance == -1) 1279 printf("\n\t (illegal prefix length)"); 1280 else if (advance == -2) 1281 goto trunc; 1282 else 1283 printf("\n\t %s", buf); 1284 break; 1285 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): 1286 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): 1287 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): 1288 advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf)); 1289 if (advance == -1) 1290 printf("\n\t (illegal prefix length)"); 1291 else if (advance == -2) 1292 goto trunc; 1293 else 1294 printf("\n\t %s", buf); 1295 break; 1296 default: 1297 TCHECK2(*tptr,tlen); 1298 printf("\n\t no AFI %u / SAFI %u decoder",af,safi); 1299 if (vflag <= 1) 1300 print_unknown_data(tptr,"\n\t ",tlen); 1301 advance = 0; 1302 tptr = pptr + len; 1303 break; 1304 } 1305 if (advance < 0) 1306 break; 1307 tptr += advance; 1308 } 1309 done: 1310 break; 1311 1312 case BGPTYPE_MP_UNREACH_NLRI: 1313 TCHECK2(tptr[0], BGP_MP_NLRI_MINSIZE); 1314 af = EXTRACT_16BITS(tptr); 1315 safi = tptr[2]; 1316 1317 printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)", 1318 tok2strbuf(bgp_afi_values, "Unknown AFI", af, 1319 tokbuf, sizeof(tokbuf)), 1320 af, 1321 (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ 1322 tok2strbuf(bgp_safi_values, "Unknown SAFI", safi, 1323 tokbuf, sizeof(tokbuf)), 1324 safi); 1325 1326 if (len == BGP_MP_NLRI_MINSIZE) 1327 printf("\n\t End-of-Rib Marker (empty NLRI)"); 1328 1329 tptr += 3; 1330 1331 while (len - (tptr - pptr) > 0) { 1332 switch (af<<8 | safi) { 1333 case (AFNUM_INET<<8 | SAFNUM_UNICAST): 1334 case (AFNUM_INET<<8 | SAFNUM_MULTICAST): 1335 case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): 1336 advance = decode_prefix4(tptr, buf, sizeof(buf)); 1337 if (advance == -1) 1338 printf("\n\t (illegal prefix length)"); 1339 else if (advance == -2) 1340 goto trunc; 1341 else 1342 printf("\n\t %s", buf); 1343 break; 1344 case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): 1345 advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); 1346 if (advance == -1) 1347 printf("\n\t (illegal prefix length)"); 1348 else if (advance == -2) 1349 goto trunc; 1350 else 1351 printf("\n\t %s", buf); 1352 break; 1353 case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): 1354 case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): 1355 case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): 1356 advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); 1357 if (advance == -1) 1358 printf("\n\t (illegal prefix length)"); 1359 else if (advance == -2) 1360 goto trunc; 1361 else 1362 printf("\n\t %s", buf); 1363 break; 1364 #ifdef INET6 1365 case (AFNUM_INET6<<8 | SAFNUM_UNICAST): 1366 case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): 1367 case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): 1368 advance = decode_prefix6(tptr, buf, sizeof(buf)); 1369 if (advance == -1) 1370 printf("\n\t (illegal prefix length)"); 1371 else if (advance == -2) 1372 goto trunc; 1373 else 1374 printf("\n\t %s", buf); 1375 break; 1376 case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): 1377 advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); 1378 if (advance == -1) 1379 printf("\n\t (illegal prefix length)"); 1380 else if (advance == -2) 1381 goto trunc; 1382 else 1383 printf("\n\t %s", buf); 1384 break; 1385 case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): 1386 case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): 1387 case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): 1388 advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); 1389 if (advance == -1) 1390 printf("\n\t (illegal prefix length)"); 1391 else if (advance == -2) 1392 goto trunc; 1393 else 1394 printf("\n\t %s", buf); 1395 break; 1396 #endif 1397 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): 1398 case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): 1399 case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): 1400 advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); 1401 if (advance == -1) 1402 printf("\n\t (illegal length)"); 1403 else if (advance == -2) 1404 goto trunc; 1405 else 1406 printf("\n\t %s", buf); 1407 break; 1408 case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): 1409 case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): 1410 case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): 1411 advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); 1412 if (advance == -1) 1413 printf("\n\t (illegal prefix length)"); 1414 else if (advance == -2) 1415 goto trunc; 1416 else 1417 printf("\n\t %s", buf); 1418 break; 1419 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): 1420 case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): 1421 case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): 1422 advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf)); 1423 if (advance == -1) 1424 printf("\n\t (illegal prefix length)"); 1425 else if (advance == -2) 1426 goto trunc; 1427 else 1428 printf("\n\t %s", buf); 1429 break; 1430 default: 1431 TCHECK2(*(tptr-3),tlen); 1432 printf("no AFI %u / SAFI %u decoder",af,safi); 1433 if (vflag <= 1) 1434 print_unknown_data(tptr-3,"\n\t ",tlen); 1435 advance = 0; 1436 tptr = pptr + len; 1437 break; 1438 } 1439 if (advance < 0) 1440 break; 1441 tptr += advance; 1442 } 1443 break; 1444 case BGPTYPE_EXTD_COMMUNITIES: 1445 if (len % 8) { 1446 printf("invalid len"); 1447 break; 1448 } 1449 while (tlen>0) { 1450 u_int16_t extd_comm; 1451 1452 TCHECK2(tptr[0], 2); 1453 extd_comm=EXTRACT_16BITS(tptr); 1454 1455 printf("\n\t %s (0x%04x), Flags [%s]", 1456 tok2strbuf(bgp_extd_comm_subtype_values, 1457 "unknown extd community typecode", 1458 extd_comm, tokbuf, sizeof(tokbuf)), 1459 extd_comm, 1460 bittok2str(bgp_extd_comm_flag_values, "none", extd_comm)); 1461 1462 TCHECK2(*(tptr+2), 6); 1463 switch(extd_comm) { 1464 case BGP_EXT_COM_RT_0: 1465 case BGP_EXT_COM_RO_0: 1466 printf(": %u:%s", 1467 EXTRACT_16BITS(tptr+2), 1468 getname(tptr+4)); 1469 break; 1470 case BGP_EXT_COM_RT_1: 1471 case BGP_EXT_COM_RO_1: 1472 printf(": %s:%u", 1473 getname(tptr+2), 1474 EXTRACT_16BITS(tptr+6)); 1475 break; 1476 case BGP_EXT_COM_RT_2: 1477 case BGP_EXT_COM_RO_2: 1478 printf(": %u:%u", 1479 EXTRACT_32BITS(tptr+2), 1480 EXTRACT_16BITS(tptr+6)); 1481 break; 1482 case BGP_EXT_COM_LINKBAND: 1483 bw.i = EXTRACT_32BITS(tptr+2); 1484 printf(": bandwidth: %.3f Mbps", 1485 bw.f*8/1000000); 1486 break; 1487 case BGP_EXT_COM_CISCO_MCAST: 1488 printf(": AS %u, group %s", 1489 EXTRACT_16BITS(tptr+2), 1490 getname(tptr+4)); 1491 break; 1492 case BGP_EXT_COM_VPN_ORIGIN: 1493 case BGP_EXT_COM_VPN_ORIGIN2: 1494 case BGP_EXT_COM_VPN_ORIGIN3: 1495 case BGP_EXT_COM_VPN_ORIGIN4: 1496 case BGP_EXT_COM_OSPF_RID: 1497 case BGP_EXT_COM_OSPF_RID2: 1498 printf("%s", getname(tptr+2)); 1499 break; 1500 case BGP_EXT_COM_OSPF_RTYPE: 1501 case BGP_EXT_COM_OSPF_RTYPE2: 1502 printf(": area:%s, router-type:%s, metric-type:%s%s", 1503 getname(tptr+2), 1504 tok2strbuf(bgp_extd_comm_ospf_rtype_values, 1505 "unknown (0x%02x)", 1506 *(tptr+6), 1507 tokbuf, sizeof(tokbuf)), 1508 (*(tptr+7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "", 1509 (*(tptr+6) == (BGP_OSPF_RTYPE_EXT ||BGP_OSPF_RTYPE_NSSA )) ? "E1" : ""); 1510 break; 1511 case BGP_EXT_COM_L2INFO: 1512 printf(": %s Control Flags [0x%02x]:MTU %u", 1513 tok2strbuf(l2vpn_encaps_values, 1514 "unknown encaps", 1515 *(tptr+2), 1516 tokbuf, sizeof(tokbuf)), 1517 *(tptr+3), 1518 EXTRACT_16BITS(tptr+4)); 1519 break; 1520 default: 1521 TCHECK2(*tptr,8); 1522 print_unknown_data(tptr,"\n\t ",8); 1523 break; 1524 } 1525 tlen -=8; 1526 tptr +=8; 1527 } 1528 break; 1529 1530 case BGPTYPE_ATTR_SET: 1531 TCHECK2(tptr[0], 4); 1532 printf("\n\t Origin AS: %u", EXTRACT_32BITS(tptr)); 1533 tptr+=4; 1534 len -=4; 1535 1536 while (len >= 2 ) { 1537 int alen; 1538 struct bgp_attr bgpa; 1539 1540 TCHECK2(tptr[0], sizeof(bgpa)); 1541 memcpy(&bgpa, tptr, sizeof(bgpa)); 1542 alen = bgp_attr_len(&bgpa); 1543 tptr += bgp_attr_off(&bgpa); 1544 len -= bgp_attr_off(&bgpa); 1545 1546 printf("\n\t %s (%u), length: %u", 1547 tok2strbuf(bgp_attr_values, 1548 "Unknown Attribute", bgpa.bgpa_type, 1549 tokbuf, sizeof(tokbuf)), 1550 bgpa.bgpa_type, 1551 alen); 1552 1553 if (bgpa.bgpa_flags) { 1554 printf(", Flags [%s%s%s%s", 1555 bgpa.bgpa_flags & 0x80 ? "O" : "", 1556 bgpa.bgpa_flags & 0x40 ? "T" : "", 1557 bgpa.bgpa_flags & 0x20 ? "P" : "", 1558 bgpa.bgpa_flags & 0x10 ? "E" : ""); 1559 if (bgpa.bgpa_flags & 0xf) 1560 printf("+%x", bgpa.bgpa_flags & 0xf); 1561 printf("]: "); 1562 } 1563 /* FIXME check for recursion */ 1564 if (!bgp_attr_print(&bgpa, tptr, alen)) 1565 return 0; 1566 tptr += alen; 1567 len -= alen; 1568 } 1569 break; 1570 1571 1572 default: 1573 TCHECK2(*pptr,len); 1574 printf("\n\t no Attribute %u decoder",attr->bgpa_type); /* we have no decoder for the attribute */ 1575 if (vflag <= 1) 1576 print_unknown_data(pptr,"\n\t ",len); 1577 break; 1578 } 1579 if (vflag > 1 && len) { /* omit zero length attributes*/ 1580 TCHECK2(*pptr,len); 1581 print_unknown_data(pptr,"\n\t ",len); 1582 } 1583 return 1; 1584 1585 trunc: 1586 return 0; 1587 } 1588 1589 static void 1590 bgp_open_print(const u_char *dat, int length) 1591 { 1592 struct bgp_open bgpo; 1593 struct bgp_opt bgpopt; 1594 const u_char *opt; 1595 int i,cap_type,cap_len,tcap_len,cap_offset; 1596 char tokbuf[TOKBUFSIZE]; 1597 char tokbuf2[TOKBUFSIZE]; 1598 1599 TCHECK2(dat[0], BGP_OPEN_SIZE); 1600 memcpy(&bgpo, dat, BGP_OPEN_SIZE); 1601 1602 printf("\n\t Version %d, ", bgpo.bgpo_version); 1603 printf("my AS %u, ", ntohs(bgpo.bgpo_myas)); 1604 printf("Holdtime %us, ", ntohs(bgpo.bgpo_holdtime)); 1605 printf("ID %s", getname((u_char *)&bgpo.bgpo_id)); 1606 printf("\n\t Optional parameters, length: %u", bgpo.bgpo_optlen); 1607 1608 /* some little sanity checking */ 1609 if (length < bgpo.bgpo_optlen+BGP_OPEN_SIZE) 1610 return; 1611 1612 /* ugly! */ 1613 opt = &((const struct bgp_open *)dat)->bgpo_optlen; 1614 opt++; 1615 1616 i = 0; 1617 while (i < bgpo.bgpo_optlen) { 1618 TCHECK2(opt[i], BGP_OPT_SIZE); 1619 memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE); 1620 if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) { 1621 printf("\n\t Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len); 1622 break; 1623 } 1624 1625 printf("\n\t Option %s (%u), length: %u", 1626 tok2strbuf(bgp_opt_values,"Unknown", 1627 bgpopt.bgpopt_type, 1628 tokbuf, sizeof(tokbuf)), 1629 bgpopt.bgpopt_type, 1630 bgpopt.bgpopt_len); 1631 1632 /* now lets decode the options we know*/ 1633 switch(bgpopt.bgpopt_type) { 1634 case BGP_OPT_CAP: 1635 cap_type=opt[i+BGP_OPT_SIZE]; 1636 cap_len=opt[i+BGP_OPT_SIZE+1]; 1637 tcap_len=cap_len; 1638 printf("\n\t %s (%u), length: %u", 1639 tok2strbuf(bgp_capcode_values, "Unknown", 1640 cap_type, tokbuf, sizeof(tokbuf)), 1641 cap_type, 1642 cap_len); 1643 switch(cap_type) { 1644 case BGP_CAPCODE_MP: 1645 printf("\n\t\tAFI %s (%u), SAFI %s (%u)", 1646 tok2strbuf(bgp_afi_values, "Unknown", 1647 EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2), 1648 tokbuf, sizeof(tokbuf)), 1649 EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2), 1650 tok2strbuf(bgp_safi_values, "Unknown", 1651 opt[i+BGP_OPT_SIZE+5], 1652 tokbuf, sizeof(tokbuf)), 1653 opt[i+BGP_OPT_SIZE+5]); 1654 break; 1655 case BGP_CAPCODE_RESTART: 1656 printf("\n\t\tRestart Flags: [%s], Restart Time %us", 1657 ((opt[i+BGP_OPT_SIZE+2])&0x80) ? "R" : "none", 1658 EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2)&0xfff); 1659 tcap_len-=2; 1660 cap_offset=4; 1661 while(tcap_len>=4) { 1662 printf("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", 1663 tok2strbuf(bgp_afi_values,"Unknown", 1664 EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset), 1665 tokbuf, sizeof(tokbuf)), 1666 EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset), 1667 tok2strbuf(bgp_safi_values,"Unknown", 1668 opt[i+BGP_OPT_SIZE+cap_offset+2], 1669 tokbuf2, sizeof(tokbuf2)), 1670 opt[i+BGP_OPT_SIZE+cap_offset+2], 1671 ((opt[i+BGP_OPT_SIZE+cap_offset+3])&0x80) ? "yes" : "no" ); 1672 tcap_len-=4; 1673 cap_offset+=4; 1674 } 1675 break; 1676 case BGP_CAPCODE_RR: 1677 case BGP_CAPCODE_RR_CISCO: 1678 break; 1679 default: 1680 TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); 1681 printf("\n\t\tno decoder for Capability %u", 1682 cap_type); 1683 if (vflag <= 1) 1684 print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len); 1685 break; 1686 } 1687 if (vflag > 1) { 1688 TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); 1689 print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len); 1690 } 1691 break; 1692 case BGP_OPT_AUTH: 1693 default: 1694 printf("\n\t no decoder for option %u", 1695 bgpopt.bgpopt_type); 1696 break; 1697 } 1698 1699 i += BGP_OPT_SIZE + bgpopt.bgpopt_len; 1700 } 1701 return; 1702 trunc: 1703 printf("[|BGP]"); 1704 } 1705 1706 static void 1707 bgp_update_print(const u_char *dat, int length) 1708 { 1709 struct bgp bgp; 1710 struct bgp_attr bgpa; 1711 const u_char *p; 1712 int len; 1713 int i; 1714 char tokbuf[TOKBUFSIZE]; 1715 1716 TCHECK2(dat[0], BGP_SIZE); 1717 memcpy(&bgp, dat, BGP_SIZE); 1718 p = dat + BGP_SIZE; /*XXX*/ 1719 1720 /* Unfeasible routes */ 1721 len = EXTRACT_16BITS(p); 1722 if (len) { 1723 /* 1724 * Without keeping state from the original NLRI message, 1725 * it's not possible to tell if this a v4 or v6 route, 1726 * so only try to decode it if we're not v6 enabled. 1727 */ 1728 #ifdef INET6 1729 printf("\n\t Withdrawn routes: %d bytes", len); 1730 #else 1731 char buf[MAXHOSTNAMELEN + 100]; 1732 int wpfx; 1733 1734 TCHECK2(p[2], len); 1735 i = 2; 1736 1737 printf("\n\t Withdrawn routes:"); 1738 1739 while(i < 2 + len) { 1740 wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); 1741 if (wpfx == -1) { 1742 printf("\n\t (illegal prefix length)"); 1743 break; 1744 } else if (wpfx == -2) 1745 goto trunc; 1746 else { 1747 i += wpfx; 1748 printf("\n\t %s", buf); 1749 } 1750 } 1751 #endif 1752 } 1753 p += 2 + len; 1754 1755 TCHECK2(p[0], 2); 1756 len = EXTRACT_16BITS(p); 1757 1758 if (len == 0 && length == BGP_UPDATE_MINSIZE) { 1759 printf("\n\t End-of-Rib Marker (empty NLRI)"); 1760 return; 1761 } 1762 1763 if (len) { 1764 /* do something more useful!*/ 1765 i = 2; 1766 while (i < 2 + len) { 1767 int alen, aoff; 1768 1769 TCHECK2(p[i], sizeof(bgpa)); 1770 memcpy(&bgpa, &p[i], sizeof(bgpa)); 1771 alen = bgp_attr_len(&bgpa); 1772 aoff = bgp_attr_off(&bgpa); 1773 1774 printf("\n\t %s (%u), length: %u", 1775 tok2strbuf(bgp_attr_values, "Unknown Attribute", 1776 bgpa.bgpa_type, 1777 tokbuf, sizeof(tokbuf)), 1778 bgpa.bgpa_type, 1779 alen); 1780 1781 if (bgpa.bgpa_flags) { 1782 printf(", Flags [%s%s%s%s", 1783 bgpa.bgpa_flags & 0x80 ? "O" : "", 1784 bgpa.bgpa_flags & 0x40 ? "T" : "", 1785 bgpa.bgpa_flags & 0x20 ? "P" : "", 1786 bgpa.bgpa_flags & 0x10 ? "E" : ""); 1787 if (bgpa.bgpa_flags & 0xf) 1788 printf("+%x", bgpa.bgpa_flags & 0xf); 1789 printf("]: "); 1790 } 1791 if (!bgp_attr_print(&bgpa, &p[i + aoff], alen)) 1792 goto trunc; 1793 i += aoff + alen; 1794 } 1795 } 1796 p += 2 + len; 1797 1798 if (dat + length > p) { 1799 printf("\n\t Updated routes:"); 1800 while (dat + length > p) { 1801 char buf[MAXHOSTNAMELEN + 100]; 1802 i = decode_prefix4(p, buf, sizeof(buf)); 1803 if (i == -1) { 1804 printf("\n\t (illegal prefix length)"); 1805 break; 1806 } else if (i == -2) 1807 goto trunc; 1808 else { 1809 printf("\n\t %s", buf); 1810 p += i; 1811 } 1812 } 1813 } 1814 return; 1815 trunc: 1816 printf("[|BGP]"); 1817 } 1818 1819 static void 1820 bgp_notification_print(const u_char *dat, int length) 1821 { 1822 struct bgp_notification bgpn; 1823 const u_char *tptr; 1824 char tokbuf[TOKBUFSIZE]; 1825 char tokbuf2[TOKBUFSIZE]; 1826 1827 TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); 1828 memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); 1829 1830 /* some little sanity checking */ 1831 if (length<BGP_NOTIFICATION_SIZE) 1832 return; 1833 1834 printf(", %s (%u)", 1835 tok2strbuf(bgp_notify_major_values, "Unknown Error", 1836 bgpn.bgpn_major, tokbuf, sizeof(tokbuf)), 1837 bgpn.bgpn_major); 1838 1839 switch (bgpn.bgpn_major) { 1840 1841 case BGP_NOTIFY_MAJOR_MSG: 1842 printf(", subcode %s (%u)", 1843 tok2strbuf(bgp_notify_minor_msg_values, "Unknown", 1844 bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), 1845 bgpn.bgpn_minor); 1846 break; 1847 case BGP_NOTIFY_MAJOR_OPEN: 1848 printf(", subcode %s (%u)", 1849 tok2strbuf(bgp_notify_minor_open_values, "Unknown", 1850 bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), 1851 bgpn.bgpn_minor); 1852 break; 1853 case BGP_NOTIFY_MAJOR_UPDATE: 1854 printf(", subcode %s (%u)", 1855 tok2strbuf(bgp_notify_minor_update_values, "Unknown", 1856 bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), 1857 bgpn.bgpn_minor); 1858 break; 1859 case BGP_NOTIFY_MAJOR_CAP: 1860 printf(" subcode %s (%u)", 1861 tok2strbuf(bgp_notify_minor_cap_values, "Unknown", 1862 bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), 1863 bgpn.bgpn_minor); 1864 case BGP_NOTIFY_MAJOR_CEASE: 1865 printf(", subcode %s (%u)", 1866 tok2strbuf(bgp_notify_minor_cease_values, "Unknown", 1867 bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)), 1868 bgpn.bgpn_minor); 1869 1870 /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes 1871 * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES 1872 */ 1873 if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) { 1874 tptr = dat + BGP_NOTIFICATION_SIZE; 1875 TCHECK2(*tptr, 7); 1876 printf(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", 1877 tok2strbuf(bgp_afi_values, "Unknown", 1878 EXTRACT_16BITS(tptr), tokbuf, sizeof(tokbuf)), 1879 EXTRACT_16BITS(tptr), 1880 tok2strbuf(bgp_safi_values, "Unknown", *(tptr+2), 1881 tokbuf2, sizeof(tokbuf)), 1882 *(tptr+2), 1883 EXTRACT_32BITS(tptr+3)); 1884 } 1885 break; 1886 default: 1887 break; 1888 } 1889 1890 return; 1891 trunc: 1892 printf("[|BGP]"); 1893 } 1894 1895 static void 1896 bgp_route_refresh_print(const u_char *pptr, int len) { 1897 1898 const struct bgp_route_refresh *bgp_route_refresh_header; 1899 char tokbuf[TOKBUFSIZE]; 1900 char tokbuf2[TOKBUFSIZE]; 1901 1902 TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE); 1903 1904 /* some little sanity checking */ 1905 if (len<BGP_ROUTE_REFRESH_SIZE) 1906 return; 1907 1908 bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr; 1909 1910 printf("\n\t AFI %s (%u), SAFI %s (%u)", 1911 tok2strbuf(bgp_afi_values,"Unknown", 1912 /* this stinks but the compiler pads the structure 1913 * weird */ 1914 EXTRACT_16BITS(&bgp_route_refresh_header->afi), 1915 tokbuf, sizeof(tokbuf)), 1916 EXTRACT_16BITS(&bgp_route_refresh_header->afi), 1917 tok2strbuf(bgp_safi_values,"Unknown", 1918 bgp_route_refresh_header->safi, 1919 tokbuf2, sizeof(tokbuf2)), 1920 bgp_route_refresh_header->safi); 1921 1922 if (vflag > 1) { 1923 TCHECK2(*pptr, len); 1924 print_unknown_data(pptr,"\n\t ", len); 1925 } 1926 1927 return; 1928 trunc: 1929 printf("[|BGP]"); 1930 } 1931 1932 static int 1933 bgp_header_print(const u_char *dat, int length) 1934 { 1935 struct bgp bgp; 1936 char tokbuf[TOKBUFSIZE]; 1937 1938 TCHECK2(dat[0], BGP_SIZE); 1939 memcpy(&bgp, dat, BGP_SIZE); 1940 printf("\n\t%s Message (%u), length: %u", 1941 tok2strbuf(bgp_msg_values, "Unknown", bgp.bgp_type, 1942 tokbuf, sizeof(tokbuf)), 1943 bgp.bgp_type, 1944 length); 1945 1946 switch (bgp.bgp_type) { 1947 case BGP_OPEN: 1948 bgp_open_print(dat, length); 1949 break; 1950 case BGP_UPDATE: 1951 bgp_update_print(dat, length); 1952 break; 1953 case BGP_NOTIFICATION: 1954 bgp_notification_print(dat, length); 1955 break; 1956 case BGP_KEEPALIVE: 1957 break; 1958 case BGP_ROUTE_REFRESH: 1959 bgp_route_refresh_print(dat, length); 1960 break; 1961 default: 1962 /* we have no decoder for the BGP message */ 1963 TCHECK2(*dat, length); 1964 printf("\n\t no Message %u decoder",bgp.bgp_type); 1965 print_unknown_data(dat,"\n\t ",length); 1966 break; 1967 } 1968 return 1; 1969 trunc: 1970 printf("[|BGP]"); 1971 return 0; 1972 } 1973 1974 void 1975 bgp_print(const u_char *dat, int length) 1976 { 1977 const u_char *p; 1978 const u_char *ep; 1979 const u_char *start; 1980 const u_char marker[] = { 1981 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1982 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1983 }; 1984 struct bgp bgp; 1985 u_int16_t hlen; 1986 char tokbuf[TOKBUFSIZE]; 1987 1988 ep = dat + length; 1989 if (snapend < dat + length) 1990 ep = snapend; 1991 1992 printf(": BGP, length: %u",length); 1993 1994 if (vflag < 1) /* lets be less chatty */ 1995 return; 1996 1997 p = dat; 1998 start = p; 1999 while (p < ep) { 2000 if (!TTEST2(p[0], 1)) 2001 break; 2002 if (p[0] != 0xff) { 2003 p++; 2004 continue; 2005 } 2006 2007 if (!TTEST2(p[0], sizeof(marker))) 2008 break; 2009 if (memcmp(p, marker, sizeof(marker)) != 0) { 2010 p++; 2011 continue; 2012 } 2013 2014 /* found BGP header */ 2015 TCHECK2(p[0], BGP_SIZE); /*XXX*/ 2016 memcpy(&bgp, p, BGP_SIZE); 2017 2018 if (start != p) 2019 printf(" [|BGP]"); 2020 2021 hlen = ntohs(bgp.bgp_len); 2022 if (hlen < BGP_SIZE) { 2023 printf("\n[|BGP Bogus header length %u < %u]", hlen, 2024 BGP_SIZE); 2025 break; 2026 } 2027 2028 if (TTEST2(p[0], hlen)) { 2029 if (!bgp_header_print(p, hlen)) 2030 return; 2031 p += hlen; 2032 start = p; 2033 } else { 2034 printf("\n[|BGP %s]", 2035 tok2strbuf(bgp_msg_values, 2036 "Unknown Message Type", 2037 bgp.bgp_type, 2038 tokbuf, sizeof(tokbuf))); 2039 break; 2040 } 2041 } 2042 2043 return; 2044 2045 trunc: 2046 printf(" [|BGP]"); 2047 } 2048