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