1 /* $OpenBSD: print-bgp.c,v 1.25 2017/08/30 09:23:00 otto Exp $ */ 2 3 /* 4 * Copyright (C) 1999 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/time.h> 33 #include <sys/types.h> 34 #include <sys/socket.h> 35 36 #include <netinet/in.h> 37 38 #include <errno.h> 39 #include <stdio.h> 40 #include <string.h> 41 #include <netdb.h> 42 #include <limits.h> 43 44 #include "interface.h" 45 #include "addrtoname.h" 46 #include "extract.h" 47 #include "afnum.h" 48 49 struct bgp { 50 u_int8_t bgp_marker[16]; 51 u_int16_t bgp_len; 52 u_int8_t bgp_type; 53 }; 54 #define BGP_SIZE 19 /* unaligned */ 55 56 #define BGP_OPEN 1 57 #define BGP_UPDATE 2 58 #define BGP_NOTIFICATION 3 59 #define BGP_KEEPALIVE 4 60 #define BGP_ROUTE_REFRESH 5 61 62 struct bgp_open { 63 u_int8_t bgpo_marker[16]; 64 u_int16_t bgpo_len; 65 u_int8_t bgpo_type; 66 u_int8_t bgpo_version; 67 u_int16_t bgpo_myas; 68 u_int16_t bgpo_holdtime; 69 u_int32_t bgpo_id; 70 u_int8_t bgpo_optlen; 71 /* options should follow */ 72 }; 73 #define BGP_OPEN_SIZE 29 /* unaligned */ 74 75 struct bgp_opt { 76 u_int8_t bgpopt_type; 77 u_int8_t bgpopt_len; 78 /* variable length */ 79 }; 80 #define BGP_OPT_CAP 2 81 #define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ 82 83 #define BGP_UPDATE_MINSIZE 23 84 85 struct bgp_notification { 86 u_int8_t bgpn_marker[16]; 87 u_int16_t bgpn_len; 88 u_int8_t bgpn_type; 89 u_int8_t bgpn_major; 90 u_int8_t bgpn_minor; 91 /* data should follow */ 92 }; 93 #define BGP_NOTIFICATION_SIZE 21 /* unaligned */ 94 95 struct bgp_route_refresh { 96 u_int8_t bgp_marker[16]; 97 u_int16_t len; 98 u_int8_t type; 99 u_int8_t afi[2]; /* unaligned; should be u_int16_t */ 100 u_int8_t res; 101 u_int8_t safi; 102 }; 103 #define BGP_ROUTE_REFRESH_SIZE 23 104 105 struct bgp_attr { 106 u_int8_t bgpa_flags; 107 u_int8_t bgpa_type; 108 union { 109 u_int8_t len; 110 u_int16_t elen; 111 } bgpa_len; 112 #define bgp_attr_len(p) \ 113 (((p)->bgpa_flags & 0x10) ? \ 114 ntohs((p)->bgpa_len.elen) : (p)->bgpa_len.len) 115 #define bgp_attr_off(p) \ 116 (((p)->bgpa_flags & 0x10) ? 4 : 3) 117 }; 118 119 #define BGPTYPE_ORIGIN 1 120 #define BGPTYPE_AS_PATH 2 121 #define BGPTYPE_NEXT_HOP 3 122 #define BGPTYPE_MULTI_EXIT_DISC 4 123 #define BGPTYPE_LOCAL_PREF 5 124 #define BGPTYPE_ATOMIC_AGGREGATE 6 125 #define BGPTYPE_AGGREGATOR 7 126 #define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ 127 #define BGPTYPE_ORIGINATOR_ID 9 /* RFC1998 */ 128 #define BGPTYPE_CLUSTER_LIST 10 /* RFC1998 */ 129 #define BGPTYPE_DPA 11 /* draft-ietf-idr-bgp-dpa */ 130 #define BGPTYPE_ADVERTISERS 12 /* RFC1863 */ 131 #define BGPTYPE_RCID_PATH 13 /* RFC1863 */ 132 #define BGPTYPE_MP_REACH_NLRI 14 /* RFC2283 */ 133 #define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2283 */ 134 #define BGPTYPE_EXTD_COMMUNITIES 16 /* RFC4360 */ 135 #define BGPTYPE_AS4_PATH 17 /* RFC4893 */ 136 #define BGPTYPE_AGGREGATOR4 18 /* RFC4893 */ 137 #define BGPTYPE_LARGE_COMMUNITIES 32 /* draft-ietf-idr-large-community */ 138 139 #define BGP_AS_SET 1 140 #define BGP_AS_SEQUENCE 2 141 #define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */ 142 #define BGP_CONFED_AS_SET 4 /* draft-ietf-idr-rfc3065bis-01 */ 143 144 static struct tok bgp_as_path_segment_open_values[] = { 145 { BGP_AS_SET, " {" }, 146 { BGP_AS_SEQUENCE, " " }, 147 { BGP_CONFED_AS_SEQUENCE, " (" }, 148 { BGP_CONFED_AS_SET, " ({" }, 149 { 0, NULL}, 150 }; 151 152 static struct tok bgp_as_path_segment_close_values[] = { 153 { BGP_AS_SET, "}" }, 154 { BGP_AS_SEQUENCE, "" }, 155 { BGP_CONFED_AS_SEQUENCE, ")" }, 156 { BGP_CONFED_AS_SET, "})" }, 157 { 0, NULL}, 158 }; 159 160 #define BGP_MP_NLRI_MINSIZE 3 161 162 static const char *bgptype[] = { 163 NULL, "OPEN", "UPDATE", "NOTIFICATION", "KEEPALIVE", "ROUTE-REFRESH", 164 }; 165 #define bgp_type(x) num_or_str(bgptype, sizeof(bgptype)/sizeof(bgptype[0]), (x)) 166 167 static const char *bgpopt_type[] = { 168 NULL, "Authentication Information", "Capabilities Advertisement", 169 }; 170 #define bgp_opttype(x) \ 171 num_or_str(bgpopt_type, sizeof(bgpopt_type)/sizeof(bgpopt_type[0]), (x)) 172 173 #define BGP_CAPCODE_MP 1 174 #define BGP_CAPCODE_REFRESH 2 175 #define BGP_CAPCODE_RESTART 64 /* draft-ietf-idr-restart-05 */ 176 #define BGP_CAPCODE_AS4 65 /* RFC4893 */ 177 178 static const char *bgp_capcode[] = { 179 NULL, "MULTI_PROTOCOL", "ROUTE_REFRESH", 180 /* 3: RFC5291 */ "OUTBOUND_ROUTE_FILTERING", 181 /* 4: RFC3107 */ "MULTIPLE_ROUTES", 182 /* 5: RFC5549 */ "EXTENDED_NEXTHOP_ENCODING", 183 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187 /* 64: RFC4724 */ "GRACEFUL_RESTART", 188 /* 65: RFC4893 */ "AS4", 0, 189 /* 67: [Chen] */ "DYNAMIC_CAPABILITY", 190 /* 68: [Appanna] */ "MULTISESSION", 191 /* 69: [draft-ietf-idr-add-paths] */ "ADD-PATH", 192 }; 193 194 #define bgp_capcode(x) \ 195 num_or_str(bgp_capcode, sizeof(bgp_capcode)/sizeof(bgp_capcode[0]), (x)) 196 197 #define BGP_NOTIFY_MAJOR_CEASE 6 198 static const char *bgpnotify_major[] = { 199 NULL, "Message Header Error", 200 "OPEN Message Error", "UPDATE Message Error", 201 "Hold Timer Expired", "Finite State Machine Error", 202 "Cease", "Capability Message Error", 203 }; 204 #define bgp_notify_major(x) \ 205 num_or_str(bgpnotify_major, \ 206 sizeof(bgpnotify_major)/sizeof(bgpnotify_major[0]), (x)) 207 208 static const char *bgpnotify_minor_msg[] = { 209 NULL, "Connection Not Synchronized", 210 "Bad Message Length", "Bad Message Type", 211 }; 212 213 static const char *bgpnotify_minor_open[] = { 214 NULL, "Unsupported Version Number", 215 "Bad Peer AS", "Bad BGP Identifier", 216 "Unsupported Optional Parameter", "Authentication Failure", 217 "Unacceptable Hold Time", "Unsupported Capability", 218 }; 219 220 static const char *bgpnotify_minor_update[] = { 221 NULL, "Malformed Attribute List", 222 "Unrecognized Well-known Attribute", "Missing Well-known Attribute", 223 "Attribute Flags Error", "Attribute Length Error", 224 "Invalid ORIGIN Attribute", "AS Routing Loop", 225 "Invalid NEXT_HOP Attribute", "Optional Attribute Error", 226 "Invalid Network Field", "Malformed AS_PATH", 227 }; 228 229 static const char *bgpnotify_minor_holdtime[] = { 230 NULL, 231 }; 232 233 /* RFC 6608 */ 234 static const char *bgpnotify_minor_fsm[] = { 235 "Unspecified Error", "In OpenSent State", "In OpenConfirm State", 236 "In Established State", 237 }; 238 239 /* RFC 4486 */ 240 #define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1 241 /* RFC 8203 */ 242 #define BGP_NOTIFY_MINOR_CEASE_SHUT 2 243 #define BGP_NOTIFY_MINOR_CEASE_RESET 4 244 #define BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN 128 245 static const char *bgpnotify_minor_cease[] = { 246 NULL, "Maximum Number of Prefixes Reached", "Administrative Shutdown", 247 "Peer De-configured", "Administrative Reset", "Connection Rejected", 248 "Other Configuration Change", "Connection Collision Resolution", 249 "Out of Resources", 250 }; 251 252 /* RFC 7313 */ 253 static const char *bgpnotify_minor_err[] = { 254 NULL, "Invalid Message Length", 255 }; 256 257 static const char **bgpnotify_minor[] = { 258 NULL, bgpnotify_minor_msg, bgpnotify_minor_open, bgpnotify_minor_update, 259 bgpnotify_minor_holdtime, bgpnotify_minor_fsm, bgpnotify_minor_cease, 260 bgpnotify_minor_err, 261 }; 262 static const int bgpnotify_minor_siz[] = { 263 0, 264 sizeof(bgpnotify_minor_msg)/sizeof(bgpnotify_minor_msg[0]), 265 sizeof(bgpnotify_minor_open)/sizeof(bgpnotify_minor_open[0]), 266 sizeof(bgpnotify_minor_update)/sizeof(bgpnotify_minor_update[0]), 267 sizeof(bgpnotify_minor_holdtime)/sizeof(bgpnotify_minor_holdtime[0]), 268 sizeof(bgpnotify_minor_fsm)/sizeof(bgpnotify_minor_fsm[0]), 269 sizeof(bgpnotify_minor_cease)/sizeof(bgpnotify_minor_cease[0]), 270 sizeof(bgpnotify_minor_err)/sizeof(bgpnotify_minor_err[0]), 271 }; 272 273 static const char *bgpattr_origin[] = { 274 "IGP", "EGP", "INCOMPLETE", 275 }; 276 #define bgp_attr_origin(x) \ 277 num_or_str(bgpattr_origin, \ 278 sizeof(bgpattr_origin)/sizeof(bgpattr_origin[0]), (x)) 279 280 static const char *bgpattr_type[] = { 281 NULL, "ORIGIN", "AS_PATH", "NEXT_HOP", 282 "MULTI_EXIT_DISC", "LOCAL_PREF", "ATOMIC_AGGREGATE", "AGGREGATOR", 283 "COMMUNITIES", "ORIGINATOR_ID", "CLUSTER_LIST", "DPA", 284 "ADVERTISERS", "RCID_PATH", "MP_REACH_NLRI", "MP_UNREACH_NLRI", 285 "EXTD_COMMUNITIES", "AS4_PATH", "AGGREGATOR4", NULL, NULL, NULL, 286 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 287 "LARGE_COMMUNITIES", 288 }; 289 #define bgp_attr_type(x) \ 290 num_or_str(bgpattr_type, \ 291 sizeof(bgpattr_type)/sizeof(bgpattr_type[0]), (x)) 292 293 /* Subsequent address family identifier, RFC2283 section 7 */ 294 static const char *bgpattr_nlri_safi[] = { 295 "Reserved", "Unicast", "Multicast", "Unicast+Multicast", 296 "labeled Unicast", /* MPLS BGP RFC3107 */ 297 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 299 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301 /* 64-66: MPLS BGP RFC3107 */ 302 "Tunnel", "VPLS", "MDT", 303 }; 304 #define bgp_attr_nlri_safi(x) \ 305 num_or_str(bgpattr_nlri_safi, \ 306 sizeof(bgpattr_nlri_safi)/sizeof(bgpattr_nlri_safi[0]), (x)) 307 308 /* well-known community */ 309 #define BGP_COMMUNITY_NO_EXPORT 0xffffff01 310 #define BGP_COMMUNITY_NO_ADVERT 0xffffff02 311 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 312 #define BGP_COMMUNITY_NO_PEER 0xffffff04 313 314 static const char *afnumber[] = AFNUM_NAME_STR; 315 #define af_name(x) \ 316 (((x) == 65535) ? afnumber[0] : \ 317 num_or_str(afnumber, \ 318 sizeof(afnumber)/sizeof(afnumber[0]), (x))) 319 320 321 static const char * 322 num_or_str(const char **table, size_t siz, int value) 323 { 324 static char buf[20]; 325 if (value < 0 || siz <= value || table[value] == NULL) { 326 snprintf(buf, sizeof(buf), "#%d", value); 327 return buf; 328 } else 329 return table[value]; 330 } 331 332 static const char * 333 bgp_notify_minor(int major, int minor) 334 { 335 static const char **table; 336 int siz; 337 static char buf[20]; 338 const char *p; 339 340 if (0 <= major 341 && major < sizeof(bgpnotify_minor)/sizeof(bgpnotify_minor[0]) 342 && bgpnotify_minor[major]) { 343 table = bgpnotify_minor[major]; 344 siz = bgpnotify_minor_siz[major]; 345 if (0 <= minor && minor < siz && table[minor]) 346 p = table[minor]; 347 else 348 p = NULL; 349 } else 350 p = NULL; 351 if (p == NULL) { 352 snprintf(buf, sizeof(buf), "#%d", minor); 353 return buf; 354 } else 355 return p; 356 } 357 358 static int 359 decode_prefix4(const u_char *pd, char *buf, u_int buflen) 360 { 361 struct in_addr addr; 362 u_int plen; 363 int n; 364 365 TCHECK(pd[0]); 366 plen = pd[0]; /* 367 * prefix length is in bits; packet only contains 368 * enough bytes of address to contain this many bits 369 */ 370 plen = pd[0]; 371 if (32 < plen) 372 return -1; 373 memset(&addr, 0, sizeof(addr)); 374 TCHECK2(pd[1], (plen + 7) / 8); 375 memcpy(&addr, &pd[1], (plen + 7) / 8); 376 if (plen % 8) { 377 ((u_char *)&addr)[(plen + 7) / 8 - 1] &= 378 ((0xff00 >> (plen % 8)) & 0xff); 379 } 380 n = snprintf(buf, buflen, "%s/%u", getname((u_char *)&addr), plen); 381 if (n == -1 || n >= buflen) 382 return -1; 383 384 return 1 + (plen + 7) / 8; 385 386 trunc: 387 return -2; 388 } 389 390 #ifdef INET6 391 static int 392 decode_prefix6(const u_char *pd, char *buf, u_int buflen) 393 { 394 struct in6_addr addr; 395 u_int plen; 396 int n; 397 398 TCHECK(pd[0]); 399 plen = pd[0]; 400 if (128 < plen) 401 return -1; 402 403 memset(&addr, 0, sizeof(addr)); 404 TCHECK2(pd[1], (plen + 7) / 8); 405 memcpy(&addr, &pd[1], (plen + 7) / 8); 406 if (plen % 8) { 407 addr.s6_addr[(plen + 7) / 8 - 1] &= 408 ((0xff00 >> (plen % 8)) & 0xff); 409 } 410 411 n = snprintf(buf, buflen, "%s/%u", getname6((u_char *)&addr), plen); 412 if (n == -1 || n >= buflen) 413 return -1; 414 415 return 1 + (plen + 7) / 8; 416 417 trunc: 418 return -2; 419 } 420 #endif 421 422 static int 423 bgp_attr_print(const struct bgp_attr *attr, const u_char *dat, int len) 424 { 425 int i; 426 u_int16_t af; 427 u_int8_t safi, snpa; 428 int advance; 429 int tlen, asn_bytes; 430 const u_char *p; 431 char buf[HOST_NAME_MAX+1 + 100]; 432 433 p = dat; 434 tlen = len; 435 asn_bytes = 0; 436 437 switch (attr->bgpa_type) { 438 case BGPTYPE_ORIGIN: 439 if (len != 1) 440 printf(" invalid len"); 441 else { 442 TCHECK(p[0]); 443 printf(" %s", bgp_attr_origin(p[0])); 444 } 445 break; 446 case BGPTYPE_AS4_PATH: 447 asn_bytes = 4; 448 /* FALLTHROUGH */ 449 case BGPTYPE_AS_PATH: 450 /* 451 * 2-byte speakers will receive AS4_PATH as well AS_PATH (2-byte). 452 * 4-byte speakers will only receive AS_PATH but it will be 4-byte. 453 * To identify which is the case, compare the length of the path 454 * segment value in bytes, with the path segment length from the 455 * message (counted in # of AS) 456 */ 457 458 if (len % 2) { 459 printf(" invalid len"); 460 break; 461 } 462 if (!len) { 463 /* valid: local originated routes to IBGP peers */ 464 printf(" empty"); 465 break; 466 } 467 while (p < dat + len) { 468 TCHECK2(p[0], 2); 469 if (asn_bytes == 0) { 470 if (p[1] == 0) { 471 /* invalid: segment contains one or more AS */ 472 printf(" malformed"); 473 break; 474 } 475 asn_bytes = (len-2)/p[1]; 476 } 477 printf("%s", 478 tok2str(bgp_as_path_segment_open_values, 479 "?", p[0])); 480 for (i = 0; i < p[1] * asn_bytes; i += asn_bytes) { 481 TCHECK2(p[2 + i], asn_bytes); 482 printf("%s", i == 0 ? "" : " "); 483 if (asn_bytes == 2 || EXTRACT_16BITS(&p[2 + i])) 484 printf("%u%s", 485 EXTRACT_16BITS(&p[2 + i]), 486 asn_bytes == 4 ? "." : ""); 487 if (asn_bytes == 4) 488 printf("%u", 489 EXTRACT_16BITS(&p[2 + i + 2])); 490 } 491 printf("%s", 492 tok2str(bgp_as_path_segment_close_values, 493 "?", p[0])); 494 p += 2 + p[1] * asn_bytes; 495 } 496 break; 497 case BGPTYPE_NEXT_HOP: 498 if (len != 4) 499 printf(" invalid len"); 500 else { 501 TCHECK2(p[0], 4); 502 printf(" %s", getname(p)); 503 } 504 break; 505 case BGPTYPE_MULTI_EXIT_DISC: 506 case BGPTYPE_LOCAL_PREF: 507 if (len != 4) 508 printf(" invalid len"); 509 else { 510 TCHECK2(p[0], 4); 511 printf(" %u", EXTRACT_32BITS(p)); 512 } 513 break; 514 case BGPTYPE_ATOMIC_AGGREGATE: 515 if (len != 0) 516 printf(" invalid len"); 517 break; 518 case BGPTYPE_AGGREGATOR4: 519 case BGPTYPE_AGGREGATOR: 520 /* 521 * like AS_PATH/AS4_PATH, AGGREGATOR can contain 522 * either 2-byte or 4-byte ASN, and AGGREGATOR4 523 * always contains 4-byte ASN. 524 */ 525 if (len != 6 && len != 8) { 526 printf(" invalid len"); 527 break; 528 } 529 TCHECK2(p[0], len); 530 printf(" AS #"); 531 if (len == 6 || EXTRACT_16BITS(p)) 532 printf("%u%s", EXTRACT_16BITS(p), len == 8 ? "." : ""); 533 if (len == 8) 534 printf("%u", EXTRACT_16BITS(p+2)); 535 printf(", origin %s", getname(p+len-4)); 536 break; 537 case BGPTYPE_COMMUNITIES: 538 if (len % 4) { 539 printf(" invalid len"); 540 break; 541 } 542 while (tlen>0) { 543 u_int32_t comm; 544 TCHECK2(p[0], 4); 545 comm = EXTRACT_32BITS(p); 546 switch (comm) { 547 case BGP_COMMUNITY_NO_EXPORT: 548 printf(" NO_EXPORT"); 549 break; 550 case BGP_COMMUNITY_NO_ADVERT: 551 printf(" NO_ADVERTISE"); 552 break; 553 case BGP_COMMUNITY_NO_EXPORT_SUBCONFED: 554 printf(" NO_EXPORT_SUBCONFED"); 555 break; 556 case BGP_COMMUNITY_NO_PEER: 557 printf(" NO_PEER"); 558 break; 559 default: 560 printf(" %d:%d", 561 (comm >> 16) & 0xffff, comm & 0xffff); 562 break; 563 } 564 tlen -= 4; 565 p += 4; 566 } 567 break; 568 case BGPTYPE_LARGE_COMMUNITIES: 569 if (len == 0 || len % 12) { 570 printf(" invalid len"); 571 break; 572 } 573 while (tlen>0) { 574 TCHECK2(p[0], 12); 575 printf(" %u:%u:%u", 576 EXTRACT_32BITS(p), 577 EXTRACT_32BITS(p + 4), 578 EXTRACT_32BITS(p + 8)); 579 tlen -= 12; 580 p += 12; 581 } 582 break; 583 case BGPTYPE_ORIGINATOR_ID: 584 if (len != 4) { 585 printf(" invalid len"); 586 break; 587 } 588 TCHECK2(p[0], 4); 589 printf("%s",getname(p)); 590 break; 591 case BGPTYPE_CLUSTER_LIST: 592 if (len % 4) { 593 printf(" invalid len"); 594 break; 595 } 596 while (tlen>0) { 597 TCHECK2(p[0], 4); 598 printf(" %s%s", 599 getname(p), 600 (tlen>4) ? ", " : ""); 601 tlen -=4; 602 p +=4; 603 } 604 break; 605 case BGPTYPE_MP_REACH_NLRI: 606 TCHECK2(p[0], BGP_MP_NLRI_MINSIZE); 607 af = EXTRACT_16BITS(p); 608 safi = p[2]; 609 if (safi >= 128) 610 printf(" %s vendor specific %u,", af_name(af), safi); 611 else { 612 printf(" %s %s,", af_name(af), 613 bgp_attr_nlri_safi(safi)); 614 } 615 p += 3; 616 617 if (af == AFNUM_INET) 618 ; 619 #ifdef INET6 620 else if (af == AFNUM_INET6) 621 ; 622 #endif 623 else 624 break; 625 626 TCHECK(p[0]); 627 tlen = p[0]; 628 if (tlen) { 629 printf(" nexthop"); 630 i = 0; 631 while (i < tlen) { 632 switch (af) { 633 case AFNUM_INET: 634 TCHECK2(p[1+i], sizeof(struct in_addr)); 635 printf(" %s", getname(p + 1 + i)); 636 i += sizeof(struct in_addr); 637 break; 638 #ifdef INET6 639 case AFNUM_INET6: 640 TCHECK2(p[1+i], sizeof(struct in6_addr)); 641 printf(" %s", getname6(p + 1 + i)); 642 i += sizeof(struct in6_addr); 643 break; 644 #endif 645 default: 646 printf(" (unknown af)"); 647 i = tlen; /*exit loop*/ 648 break; 649 } 650 } 651 printf(","); 652 } 653 p += 1 + tlen; 654 655 TCHECK(p[0]); 656 snpa = p[0]; 657 p++; 658 if (snpa) { 659 printf(" %u snpa", snpa); 660 for (/*nothing*/; snpa > 0; snpa--) { 661 TCHECK(p[0]); 662 printf("(%d bytes)", p[0]); 663 p += p[0] + 1; 664 } 665 printf(","); 666 } 667 668 printf(" NLRI"); 669 while (len - (p - dat) > 0) { 670 switch (af) { 671 case AFNUM_INET: 672 advance = decode_prefix4(p, buf, sizeof(buf)); 673 break; 674 #ifdef INET6 675 case AFNUM_INET6: 676 advance = decode_prefix6(p, buf, sizeof(buf)); 677 break; 678 #endif 679 default: 680 printf(" (unknown af)"); 681 advance = 0; 682 p = dat + len; 683 break; 684 } 685 686 if (advance <= 0) 687 break; 688 689 printf(" %s", buf); 690 p += advance; 691 } 692 693 break; 694 695 case BGPTYPE_MP_UNREACH_NLRI: 696 TCHECK2(p[0], BGP_MP_NLRI_MINSIZE); 697 af = EXTRACT_16BITS(p); 698 safi = p[2]; 699 if (safi >= 128) 700 printf(" %s vendor specific %u,", af_name(af), safi); 701 else { 702 printf(" %s %s,", af_name(af), 703 bgp_attr_nlri_safi(safi)); 704 } 705 p += 3; 706 707 printf(" Withdraw"); 708 while (len - (p - dat) > 0) { 709 switch (af) { 710 case AFNUM_INET: 711 advance = decode_prefix4(p, buf, sizeof(buf)); 712 break; 713 #ifdef INET6 714 case AFNUM_INET6: 715 advance = decode_prefix6(p, buf, sizeof(buf)); 716 break; 717 #endif 718 default: 719 printf(" (unknown af)"); 720 advance = 0; 721 p = dat + len; 722 break; 723 } 724 725 if (advance <= 0) 726 break; 727 728 printf(" %s", buf); 729 p += advance; 730 } 731 break; 732 default: 733 break; 734 } 735 return 1; 736 737 trunc: 738 return 0; 739 } 740 741 static void 742 bgp_open_capa_print(const u_char *opt, int length) 743 { 744 int i,cap_type,cap_len,tcap_len,cap_offset; 745 746 i = 0; 747 while (i < length) { 748 TCHECK2(opt[i], 2); 749 750 cap_type=opt[i]; 751 cap_len=opt[i+1]; 752 printf("%sCAP %s", i == 0 ? "(" : " ", /* ) */ 753 bgp_capcode(cap_type)); 754 755 /* can we print the capability? */ 756 TCHECK2(opt[i+2],cap_len); 757 i += 2; 758 759 switch(cap_type) { 760 case BGP_CAPCODE_MP: 761 if (cap_len != 4) { 762 printf(" BAD ENCODING"); 763 break; 764 } 765 printf(" [%s %s]", 766 af_name(EXTRACT_16BITS(opt+i)), 767 bgp_attr_nlri_safi(opt[i+3])); 768 break; 769 case BGP_CAPCODE_REFRESH: 770 if (cap_len != 0) { 771 printf(" BAD ENCODING"); 772 break; 773 } 774 break; 775 case BGP_CAPCODE_RESTART: 776 if (cap_len < 2 || (cap_len - 2) % 4) { 777 printf(" BAD ENCODING"); 778 break; 779 } 780 printf(" [%s], Time %us", 781 ((opt[i])&0x80) ? "R" : "none", 782 EXTRACT_16BITS(opt+i)&0xfff); 783 tcap_len=cap_len - 2; 784 cap_offset=2; 785 while(tcap_len>=4) { 786 printf(" (%s %s)%s", 787 af_name(EXTRACT_16BITS(opt+i+cap_offset)), 788 bgp_attr_nlri_safi(opt[i+cap_offset+2]), 789 ((opt[i+cap_offset+3])&0x80) ? 790 " forwarding state preserved" : "" ); 791 tcap_len-=4; 792 cap_offset+=4; 793 } 794 break; 795 case BGP_CAPCODE_AS4: 796 if (cap_len != 4) { 797 printf(" BAD ENCODING"); 798 break; 799 } 800 printf(" #"); 801 if (EXTRACT_16BITS(opt+i)) 802 printf("%u.", 803 EXTRACT_16BITS(opt+i)); 804 printf("%u", 805 EXTRACT_16BITS(opt+i+2)); 806 break; 807 default: 808 printf(" len %d", cap_len); 809 break; 810 } 811 i += cap_len; 812 if (i + cap_len < length) 813 printf(","); 814 } 815 /* ( */ 816 printf(")"); 817 return; 818 trunc: 819 printf("[|BGP]"); 820 } 821 822 static void 823 bgp_open_print(const u_char *dat, int length) 824 { 825 struct bgp_open bgpo; 826 struct bgp_opt bgpopt; 827 const u_char *opt; 828 int i; 829 830 TCHECK2(dat[0], BGP_OPEN_SIZE); 831 memcpy(&bgpo, dat, BGP_OPEN_SIZE); 832 833 printf(": Version %d,", bgpo.bgpo_version); 834 printf(" AS #%u,", ntohs(bgpo.bgpo_myas)); 835 printf(" Holdtime %u,", ntohs(bgpo.bgpo_holdtime)); 836 printf(" ID %s,", getname((u_char *)&bgpo.bgpo_id)); 837 printf(" Option length %u", bgpo.bgpo_optlen); 838 839 /* sanity checking */ 840 if ((length < bgpo.bgpo_optlen+BGP_OPEN_SIZE) || (!bgpo.bgpo_optlen)) 841 return; 842 843 /* ugly! */ 844 opt = &((const struct bgp_open *)dat)->bgpo_optlen; 845 opt++; 846 847 i = 0; 848 while (i < bgpo.bgpo_optlen) { 849 TCHECK2(opt[i], BGP_OPT_SIZE); 850 memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE); 851 if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) { 852 printf(" [|opt %d %d]", bgpopt.bgpopt_len, bgpopt.bgpopt_type); 853 break; 854 } 855 856 if (i == 0) 857 printf(" ("); /* ) */ 858 else 859 printf(" "); 860 861 switch(bgpopt.bgpopt_type) { 862 case BGP_OPT_CAP: 863 bgp_open_capa_print(opt + i + BGP_OPT_SIZE, 864 bgpopt.bgpopt_len); 865 break; 866 default: 867 printf(" (option %s, len=%u)", 868 bgp_opttype(bgpopt.bgpopt_type), 869 bgpopt.bgpopt_len); 870 break; 871 } 872 873 i += BGP_OPT_SIZE + bgpopt.bgpopt_len; 874 } 875 /* ( */ 876 printf(")"); 877 return; 878 trunc: 879 printf("[|BGP]"); 880 } 881 882 static void 883 bgp_update_print(const u_char *dat, int length) 884 { 885 struct bgp bgp; 886 struct bgp_attr bgpa; 887 const u_char *p; 888 int len; 889 int i; 890 int newline; 891 892 TCHECK2(dat[0], BGP_SIZE); 893 memcpy(&bgp, dat, BGP_SIZE); 894 p = dat + BGP_SIZE; /*XXX*/ 895 printf(":"); 896 897 /* Unfeasible routes */ 898 len = EXTRACT_16BITS(p); 899 if (len) { 900 /* 901 * Without keeping state from the original NLRI message, 902 * it's not possible to tell if this a v4 or v6 route, 903 * so only try to decode it if we're not v6 enabled. 904 */ 905 #ifdef INET6 906 printf(" (Withdrawn routes: %d bytes)", len); 907 #else 908 char buf[HOST_NAME_MAX+1 + 100]; 909 int wpfx; 910 911 TCHECK2(p[2], len); 912 i = 2; 913 914 printf(" (Withdrawn routes:"); 915 916 while(i < 2 + len) { 917 wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); 918 if (wpfx == -1) { 919 printf(" (illegal prefix length)"); 920 break; 921 } else if (wpfx == -2) 922 goto trunc; 923 i += wpfx; 924 printf(" %s", buf); 925 } 926 printf(")"); 927 #endif 928 } 929 p += 2 + len; 930 931 TCHECK2(p[0], 2); 932 len = EXTRACT_16BITS(p); 933 934 if (len == 0 && length == BGP_UPDATE_MINSIZE) { 935 printf(" End-of-Rib Marker (empty NLRI)"); 936 return; 937 } 938 939 if (len) { 940 /* do something more useful!*/ 941 i = 2; 942 printf(" (Path attributes:"); /* ) */ 943 newline = 0; 944 while (i < 2 + len) { 945 int alen, aoff; 946 947 TCHECK2(p[i], sizeof(bgpa)); 948 memcpy(&bgpa, &p[i], sizeof(bgpa)); 949 alen = bgp_attr_len(&bgpa); 950 aoff = bgp_attr_off(&bgpa); 951 952 if (vflag && newline) 953 printf("\n\t\t"); 954 else 955 printf(" "); 956 printf("("); /* ) */ 957 printf("%s", bgp_attr_type(bgpa.bgpa_type)); 958 if (bgpa.bgpa_flags) { 959 printf("[%s%s%s%s", 960 bgpa.bgpa_flags & 0x80 ? "O" : "", 961 bgpa.bgpa_flags & 0x40 ? "T" : "", 962 bgpa.bgpa_flags & 0x20 ? "P" : "", 963 bgpa.bgpa_flags & 0x10 ? "E" : ""); 964 if (bgpa.bgpa_flags & 0xf) 965 printf("+%x", bgpa.bgpa_flags & 0xf); 966 printf("]"); 967 } 968 969 if (!bgp_attr_print(&bgpa, &p[i + aoff], alen)) 970 goto trunc; 971 newline = 1; 972 973 /* ( */ 974 printf(")"); 975 976 i += aoff + alen; 977 } 978 979 /* ( */ 980 printf(")"); 981 } 982 p += 2 + len; 983 984 if (len && dat + length > p) 985 printf("\n\t\t"); 986 if (dat + length > p) { 987 printf("(NLRI:"); /* ) */ 988 while (dat + length > p) { 989 char buf[HOST_NAME_MAX+1 + 100]; 990 i = decode_prefix4(p, buf, sizeof(buf)); 991 if (i == -1) { 992 printf(" (illegal prefix length)"); 993 break; 994 } else if (i == -2) 995 goto trunc; 996 printf(" %s", buf); 997 p += i; 998 } 999 1000 /* ( */ 1001 printf(")"); 1002 } 1003 return; 1004 trunc: 1005 printf("[|BGP]"); 1006 } 1007 1008 static void 1009 bgp_notification_print(const u_char *dat, int length) 1010 { 1011 struct bgp_notification bgpn; 1012 u_int16_t af; 1013 u_int8_t safi; 1014 const u_char *p; 1015 uint8_t shutdown_comm_length; 1016 char shutstring[BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN + 1]; 1017 1018 TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); 1019 memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); 1020 1021 /* sanity checking */ 1022 if (length<BGP_NOTIFICATION_SIZE) 1023 return; 1024 1025 printf(": error %s,", bgp_notify_major(bgpn.bgpn_major)); 1026 printf(" subcode %s", 1027 bgp_notify_minor(bgpn.bgpn_major, bgpn.bgpn_minor)); 1028 1029 if (bgpn.bgpn_major == BGP_NOTIFY_MAJOR_CEASE) { 1030 /* 1031 * RFC 4486: optional maxprefix subtype of 7 bytes 1032 * may contain AFI, SAFI and MAXPREFIXES 1033 */ 1034 if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && 1035 length >= BGP_NOTIFICATION_SIZE + 7) { 1036 1037 p = dat + BGP_NOTIFICATION_SIZE; 1038 TCHECK2(*p, 7); 1039 1040 af = EXTRACT_16BITS(p); 1041 safi = p[2]; 1042 printf(" %s %s,", af_name(af), 1043 bgp_attr_nlri_safi(safi)); 1044 1045 printf(" Max Prefixes: %u", EXTRACT_32BITS(p+3)); 1046 } 1047 1048 /* 1049 * RFC 8203 describes a method to send a message intended 1050 * for human consumption regarding the Administrative 1051 * Shutdown or Reset event. This is called the "Shutdown 1052 * Communication". The communication is UTF-8 encoded 1053 * and may be no longer than 128 bytes. 1054 */ 1055 if ((bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_SHUT || 1056 bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_RESET) && 1057 (length >= BGP_NOTIFICATION_SIZE + 1)) { 1058 p = dat + BGP_NOTIFICATION_SIZE; 1059 TCHECK2(*p, 1); 1060 shutdown_comm_length = *(p); 1061 1062 /* sanity checking */ 1063 if (shutdown_comm_length == 0) 1064 return; 1065 if (shutdown_comm_length > 1066 BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN) 1067 return; 1068 if (length < (shutdown_comm_length + 1 + BGP_NOTIFICATION_SIZE)) 1069 return; 1070 TCHECK2(*(p+1), shutdown_comm_length); 1071 1072 /* a proper shutdown communication */ 1073 printf(", Shutdown Communication [len %u]: \"", 1074 shutdown_comm_length); 1075 memset(shutstring, 0, BGP_NOTIFY_MINOR_CEASE_ADMIN_SHUTDOWN_LEN + 1); 1076 memcpy(shutstring, p+1, shutdown_comm_length); 1077 safeputs(shutstring); 1078 printf("\""); 1079 } 1080 } 1081 1082 return; 1083 1084 trunc: 1085 printf("[|BGP]"); 1086 } 1087 1088 static void 1089 bgp_route_refresh_print(const u_char *dat, int length) 1090 { 1091 const struct bgp_route_refresh *bgp_route_refresh_header; 1092 1093 TCHECK2(dat[0], BGP_ROUTE_REFRESH_SIZE); 1094 1095 /* sanity checking */ 1096 if (length<BGP_ROUTE_REFRESH_SIZE) 1097 return; 1098 1099 bgp_route_refresh_header = (const struct bgp_route_refresh *)dat; 1100 1101 printf(" (%s %s)", 1102 af_name(EXTRACT_16BITS(&bgp_route_refresh_header->afi)), 1103 bgp_attr_nlri_safi(bgp_route_refresh_header->safi)); 1104 1105 return; 1106 trunc: 1107 printf("[|BGP]"); 1108 } 1109 1110 static int 1111 bgp_header_print(const u_char *dat, int length) 1112 { 1113 struct bgp bgp; 1114 1115 TCHECK2(dat[0], BGP_SIZE); 1116 memcpy(&bgp, dat, BGP_SIZE); 1117 printf("(%s", bgp_type(bgp.bgp_type)); /* ) */ 1118 1119 switch (bgp.bgp_type) { 1120 case BGP_OPEN: 1121 bgp_open_print(dat, length); 1122 break; 1123 case BGP_UPDATE: 1124 bgp_update_print(dat, length); 1125 break; 1126 case BGP_NOTIFICATION: 1127 bgp_notification_print(dat, length); 1128 break; 1129 case BGP_KEEPALIVE: 1130 break; 1131 case BGP_ROUTE_REFRESH: 1132 bgp_route_refresh_print(dat, length); 1133 default: 1134 TCHECK2(*dat, length); 1135 break; 1136 } 1137 1138 /* ( */ 1139 printf(")"); 1140 return 1; 1141 trunc: 1142 printf("[|BGP]"); 1143 return 0; 1144 } 1145 1146 void 1147 bgp_print(const u_char *dat, int length) 1148 { 1149 const u_char *p; 1150 const u_char *ep; 1151 const u_char *start; 1152 const u_char marker[] = { 1153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1154 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1155 }; 1156 struct bgp bgp; 1157 u_int16_t hlen; 1158 int newline; 1159 1160 ep = dat + length; 1161 if (snapend < dat + length) 1162 ep = snapend; 1163 1164 printf(": BGP"); 1165 1166 p = dat; 1167 newline = 0; 1168 start = p; 1169 while (p < ep) { 1170 if (!TTEST2(p[0], 1)) 1171 break; 1172 if (p[0] != 0xff) { 1173 p++; 1174 continue; 1175 } 1176 1177 if (!TTEST2(p[0], sizeof(marker))) 1178 break; 1179 if (memcmp(p, marker, sizeof(marker)) != 0) { 1180 p++; 1181 continue; 1182 } 1183 1184 /* found BGP header */ 1185 TCHECK2(p[0], BGP_SIZE); /*XXX*/ 1186 memcpy(&bgp, p, BGP_SIZE); 1187 1188 if (start != p) 1189 printf(" [|BGP]"); 1190 1191 hlen = ntohs(bgp.bgp_len); 1192 if (vflag && newline) 1193 printf("\n\t"); 1194 else 1195 printf(" "); 1196 if (hlen < BGP_SIZE) { 1197 printf("\n[|BGP Bogus header length %u < %u]", 1198 hlen, BGP_SIZE); 1199 break; 1200 } 1201 if (TTEST2(p[0], hlen)) { 1202 if (!bgp_header_print(p, hlen)) 1203 return; 1204 newline = 1; 1205 p += hlen; 1206 start = p; 1207 } else { 1208 printf("[|BGP %s]", bgp_type(bgp.bgp_type)); 1209 break; 1210 } 1211 } 1212 1213 return; 1214 1215 trunc: 1216 printf(" [|BGP]"); 1217 } 1218