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