1 /* NetBSD: print-tcp.c,v 1.9 2007/07/26 18:15:12 plunky Exp */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Copyright (c) 1999-2004 The tcpdump.org project 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that: (1) source code distributions 11 * retain the above copyright notice and this paragraph in its entirety, (2) 12 * distributions including binary code include the above copyright notice and 13 * this paragraph in its entirety in the documentation or other materials 14 * provided with the distribution, and (3) all advertising materials mentioning 15 * features or use of this software display the following acknowledgement: 16 * ``This product includes software developed by the University of California, 17 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 18 * the University nor the names of its contributors may be used to endorse 19 * or promote products derived from this software without specific prior 20 * written permission. 21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 22 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 24 */ 25 26 /* \summary: TCP printer */ 27 28 #include <sys/cdefs.h> 29 #ifndef lint 30 __RCSID("$NetBSD: print-tcp.c,v 1.12 2024/09/02 16:15:33 christos Exp $"); 31 #endif 32 33 #include <config.h> 34 35 #include "netdissect-stdinc.h" 36 37 #include <stdlib.h> 38 #include <string.h> 39 40 #include "netdissect.h" 41 #include "addrtoname.h" 42 #include "extract.h" 43 44 #include "diag-control.h" 45 46 #include "tcp.h" 47 48 #include "ip.h" 49 #include "ip6.h" 50 #include "ipproto.h" 51 #include "rpc_auth.h" 52 #include "rpc_msg.h" 53 54 #ifdef HAVE_LIBCRYPTO 55 #include <openssl/md5.h> 56 #include "signature.h" 57 58 static int tcp_verify_signature(netdissect_options *ndo, 59 const struct ip *ip, const struct tcphdr *tp, 60 const u_char *data, u_int length, const u_char *rcvsig); 61 #endif 62 63 static void print_tcp_rst_data(netdissect_options *, const u_char *sp, u_int length); 64 static void print_tcp_fastopen_option(netdissect_options *ndo, const u_char *cp, 65 u_int datalen, int exp); 66 67 #define MAX_RST_DATA_LEN 30 68 69 70 struct tha { 71 nd_ipv4 src; 72 nd_ipv4 dst; 73 u_int port; 74 }; 75 76 struct tcp_seq_hash { 77 struct tcp_seq_hash *nxt; 78 struct tha addr; 79 uint32_t seq; 80 uint32_t ack; 81 }; 82 83 struct tha6 { 84 nd_ipv6 src; 85 nd_ipv6 dst; 86 u_int port; 87 }; 88 89 struct tcp_seq_hash6 { 90 struct tcp_seq_hash6 *nxt; 91 struct tha6 addr; 92 uint32_t seq; 93 uint32_t ack; 94 }; 95 96 #define TSEQ_HASHSIZE 919 97 98 /* These tcp options do not have the size octet */ 99 #define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP) 100 101 static struct tcp_seq_hash tcp_seq_hash4[TSEQ_HASHSIZE]; 102 static struct tcp_seq_hash6 tcp_seq_hash6[TSEQ_HASHSIZE]; 103 104 static const struct tok tcp_flag_values[] = { 105 { TH_FIN, "F" }, 106 { TH_SYN, "S" }, 107 { TH_RST, "R" }, 108 { TH_PUSH, "P" }, 109 { TH_ACK, "." }, 110 { TH_URG, "U" }, 111 { TH_ECNECHO, "E" }, 112 { TH_CWR, "W" }, 113 { 0, NULL } 114 }; 115 116 static const struct tok tcp_option_values[] = { 117 { TCPOPT_EOL, "eol" }, 118 { TCPOPT_NOP, "nop" }, 119 { TCPOPT_MAXSEG, "mss" }, 120 { TCPOPT_WSCALE, "wscale" }, 121 { TCPOPT_SACKOK, "sackOK" }, 122 { TCPOPT_SACK, "sack" }, 123 { TCPOPT_ECHO, "echo" }, 124 { TCPOPT_ECHOREPLY, "echoreply" }, 125 { TCPOPT_TIMESTAMP, "TS" }, 126 { TCPOPT_CC, "cc" }, 127 { TCPOPT_CCNEW, "ccnew" }, 128 { TCPOPT_CCECHO, "ccecho" }, 129 { TCPOPT_SIGNATURE, "md5" }, 130 { TCPOPT_SCPS, "scps" }, 131 { TCPOPT_UTO, "uto" }, 132 { TCPOPT_TCPAO, "tcp-ao" }, 133 { TCPOPT_MPTCP, "mptcp" }, 134 { TCPOPT_FASTOPEN, "tfo" }, 135 { TCPOPT_EXPERIMENT2, "exp" }, 136 { 0, NULL } 137 }; 138 139 static uint16_t 140 tcp_cksum(netdissect_options *ndo, 141 const struct ip *ip, 142 const struct tcphdr *tp, 143 u_int len) 144 { 145 return nextproto4_cksum(ndo, ip, (const uint8_t *)tp, len, len, 146 IPPROTO_TCP); 147 } 148 149 static uint16_t 150 tcp6_cksum(netdissect_options *ndo, 151 const struct ip6_hdr *ip6, 152 const struct tcphdr *tp, 153 u_int len) 154 { 155 return nextproto6_cksum(ndo, ip6, (const uint8_t *)tp, len, len, 156 IPPROTO_TCP); 157 } 158 159 UNALIGNED_OK 160 void 161 tcp_print(netdissect_options *ndo, 162 const u_char *bp, u_int length, 163 const u_char *bp2, int fragmented) 164 { 165 const struct tcphdr *tp; 166 const struct ip *ip; 167 u_char flags; 168 u_int hlen; 169 char ch; 170 uint16_t sport, dport, win, urp; 171 uint32_t seq, ack, thseq, thack; 172 u_int utoval; 173 uint16_t magic; 174 int rev; 175 const struct ip6_hdr *ip6; 176 u_int header_len; /* Header length in bytes */ 177 178 ndo->ndo_protocol = "tcp"; 179 tp = (const struct tcphdr *)bp; 180 ip = (const struct ip *)bp2; 181 if (IP_V(ip) == 6) 182 ip6 = (const struct ip6_hdr *)bp2; 183 else 184 ip6 = NULL; 185 ch = '\0'; 186 if (!ND_TTEST_2(tp->th_dport)) { 187 if (ip6) { 188 ND_PRINT("%s > %s:", 189 GET_IP6ADDR_STRING(ip6->ip6_src), 190 GET_IP6ADDR_STRING(ip6->ip6_dst)); 191 } else { 192 ND_PRINT("%s > %s:", 193 GET_IPADDR_STRING(ip->ip_src), 194 GET_IPADDR_STRING(ip->ip_dst)); 195 } 196 nd_print_trunc(ndo); 197 return; 198 } 199 200 sport = GET_BE_U_2(tp->th_sport); 201 dport = GET_BE_U_2(tp->th_dport); 202 203 if (ip6) { 204 if (GET_U_1(ip6->ip6_nxt) == IPPROTO_TCP) { 205 ND_PRINT("%s.%s > %s.%s: ", 206 GET_IP6ADDR_STRING(ip6->ip6_src), 207 tcpport_string(ndo, sport), 208 GET_IP6ADDR_STRING(ip6->ip6_dst), 209 tcpport_string(ndo, dport)); 210 } else { 211 ND_PRINT("%s > %s: ", 212 tcpport_string(ndo, sport), tcpport_string(ndo, dport)); 213 } 214 } else { 215 if (GET_U_1(ip->ip_p) == IPPROTO_TCP) { 216 ND_PRINT("%s.%s > %s.%s: ", 217 GET_IPADDR_STRING(ip->ip_src), 218 tcpport_string(ndo, sport), 219 GET_IPADDR_STRING(ip->ip_dst), 220 tcpport_string(ndo, dport)); 221 } else { 222 ND_PRINT("%s > %s: ", 223 tcpport_string(ndo, sport), tcpport_string(ndo, dport)); 224 } 225 } 226 227 ND_TCHECK_SIZE(tp); 228 229 hlen = TH_OFF(tp) * 4; 230 231 if (hlen < sizeof(*tp)) { 232 ND_PRINT(" tcp %u [bad hdr length %u - too short, < %zu]", 233 length - hlen, hlen, sizeof(*tp)); 234 return; 235 } 236 237 seq = GET_BE_U_4(tp->th_seq); 238 ack = GET_BE_U_4(tp->th_ack); 239 win = GET_BE_U_2(tp->th_win); 240 urp = GET_BE_U_2(tp->th_urp); 241 242 if (ndo->ndo_qflag) { 243 ND_PRINT("tcp %u", length - hlen); 244 if (hlen > length) { 245 ND_PRINT(" [bad hdr length %u - too long, > %u]", 246 hlen, length); 247 } 248 return; 249 } 250 251 flags = GET_U_1(tp->th_flags); 252 ND_PRINT("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags)); 253 254 if (!ndo->ndo_Sflag && (flags & TH_ACK)) { 255 /* 256 * Find (or record) the initial sequence numbers for 257 * this conversation. (we pick an arbitrary 258 * collating order so there's only one entry for 259 * both directions). 260 */ 261 rev = 0; 262 if (ip6) { 263 struct tcp_seq_hash6 *th; 264 struct tcp_seq_hash6 *tcp_seq_hash; 265 const void *src, *dst; 266 struct tha6 tha; 267 268 tcp_seq_hash = tcp_seq_hash6; 269 src = (const void *)ip6->ip6_src; 270 dst = (const void *)ip6->ip6_dst; 271 if (sport > dport) 272 rev = 1; 273 else if (sport == dport) { 274 if (UNALIGNED_MEMCMP(src, dst, sizeof(ip6->ip6_dst)) > 0) 275 rev = 1; 276 } 277 if (rev) { 278 UNALIGNED_MEMCPY(&tha.src, dst, sizeof(ip6->ip6_dst)); 279 UNALIGNED_MEMCPY(&tha.dst, src, sizeof(ip6->ip6_src)); 280 tha.port = ((u_int)dport) << 16 | sport; 281 } else { 282 UNALIGNED_MEMCPY(&tha.dst, dst, sizeof(ip6->ip6_dst)); 283 UNALIGNED_MEMCPY(&tha.src, src, sizeof(ip6->ip6_src)); 284 tha.port = ((u_int)sport) << 16 | dport; 285 } 286 287 for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; 288 th->nxt; th = th->nxt) 289 if (memcmp((char *)&tha, (char *)&th->addr, 290 sizeof(th->addr)) == 0) 291 break; 292 293 if (!th->nxt || (flags & TH_SYN)) { 294 /* didn't find it or new conversation */ 295 /* calloc() return used by the 'tcp_seq_hash6' 296 hash table: do not free() */ 297 if (th->nxt == NULL) { 298 th->nxt = (struct tcp_seq_hash6 *) 299 calloc(1, sizeof(*th)); 300 if (th->nxt == NULL) 301 (*ndo->ndo_error)(ndo, 302 S_ERR_ND_MEM_ALLOC, 303 "%s: calloc", __func__); 304 } 305 th->addr = tha; 306 if (rev) 307 th->ack = seq, th->seq = ack - 1; 308 else 309 th->seq = seq, th->ack = ack - 1; 310 } else { 311 if (rev) 312 seq -= th->ack, ack -= th->seq; 313 else 314 seq -= th->seq, ack -= th->ack; 315 } 316 317 thseq = th->seq; 318 thack = th->ack; 319 } else { 320 struct tcp_seq_hash *th; 321 struct tcp_seq_hash *tcp_seq_hash; 322 struct tha tha; 323 324 tcp_seq_hash = tcp_seq_hash4; 325 if (sport > dport) 326 rev = 1; 327 else if (sport == dport) { 328 if (UNALIGNED_MEMCMP(ip->ip_src, ip->ip_dst, sizeof(ip->ip_dst)) > 0) 329 rev = 1; 330 } 331 if (rev) { 332 UNALIGNED_MEMCPY(&tha.src, ip->ip_dst, 333 sizeof(ip->ip_dst)); 334 UNALIGNED_MEMCPY(&tha.dst, ip->ip_src, 335 sizeof(ip->ip_src)); 336 tha.port = ((u_int)dport) << 16 | sport; 337 } else { 338 UNALIGNED_MEMCPY(&tha.dst, ip->ip_dst, 339 sizeof(ip->ip_dst)); 340 UNALIGNED_MEMCPY(&tha.src, ip->ip_src, 341 sizeof(ip->ip_src)); 342 tha.port = ((u_int)sport) << 16 | dport; 343 } 344 345 for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; 346 th->nxt; th = th->nxt) 347 if (memcmp((char *)&tha, (char *)&th->addr, 348 sizeof(th->addr)) == 0) 349 break; 350 351 if (!th->nxt || (flags & TH_SYN)) { 352 /* didn't find it or new conversation */ 353 /* calloc() return used by the 'tcp_seq_hash4' 354 hash table: do not free() */ 355 if (th->nxt == NULL) { 356 th->nxt = (struct tcp_seq_hash *) 357 calloc(1, sizeof(*th)); 358 if (th->nxt == NULL) 359 (*ndo->ndo_error)(ndo, 360 S_ERR_ND_MEM_ALLOC, 361 "%s: calloc", __func__); 362 } 363 th->addr = tha; 364 if (rev) 365 th->ack = seq, th->seq = ack - 1; 366 else 367 th->seq = seq, th->ack = ack - 1; 368 } else { 369 if (rev) 370 seq -= th->ack, ack -= th->seq; 371 else 372 seq -= th->seq, ack -= th->ack; 373 } 374 375 thseq = th->seq; 376 thack = th->ack; 377 } 378 } else { 379 /*fool gcc*/ 380 thseq = thack = rev = 0; 381 } 382 if (hlen > length) { 383 ND_PRINT(" [bad hdr length %u - too long, > %u]", 384 hlen, length); 385 return; 386 } 387 388 if (ndo->ndo_vflag && !ndo->ndo_Kflag && !fragmented) { 389 /* Check the checksum, if possible. */ 390 uint16_t sum, tcp_sum; 391 392 if (IP_V(ip) == 4) { 393 if (ND_TTEST_LEN(tp->th_sport, length)) { 394 sum = tcp_cksum(ndo, ip, tp, length); 395 tcp_sum = GET_BE_U_2(tp->th_sum); 396 397 ND_PRINT(", cksum 0x%04x", tcp_sum); 398 if (sum != 0) 399 ND_PRINT(" (incorrect -> 0x%04x)", 400 in_cksum_shouldbe(tcp_sum, sum)); 401 else 402 ND_PRINT(" (correct)"); 403 } 404 } else if (IP_V(ip) == 6) { 405 if (ND_TTEST_LEN(tp->th_sport, length)) { 406 sum = tcp6_cksum(ndo, ip6, tp, length); 407 tcp_sum = GET_BE_U_2(tp->th_sum); 408 409 ND_PRINT(", cksum 0x%04x", tcp_sum); 410 if (sum != 0) 411 ND_PRINT(" (incorrect -> 0x%04x)", 412 in_cksum_shouldbe(tcp_sum, sum)); 413 else 414 ND_PRINT(" (correct)"); 415 416 } 417 } 418 } 419 420 length -= hlen; 421 if (ndo->ndo_vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) { 422 ND_PRINT(", seq %u", seq); 423 424 if (length > 0) { 425 ND_PRINT(":%u", seq + length); 426 } 427 } 428 429 if (flags & TH_ACK) { 430 ND_PRINT(", ack %u", ack); 431 } 432 433 ND_PRINT(", win %u", win); 434 435 if (flags & TH_URG) 436 ND_PRINT(", urg %u", urp); 437 /* 438 * Handle any options. 439 */ 440 if (hlen > sizeof(*tp)) { 441 const u_char *cp; 442 u_int i, opt, datalen; 443 u_int len; 444 445 hlen -= sizeof(*tp); 446 cp = (const u_char *)tp + sizeof(*tp); 447 ND_PRINT(", options ["); 448 while (hlen > 0) { 449 if (ch != '\0') 450 ND_PRINT("%c", ch); 451 opt = GET_U_1(cp); 452 cp++; 453 if (ZEROLENOPT(opt)) 454 len = 1; 455 else { 456 len = GET_U_1(cp); 457 cp++; /* total including type, len */ 458 if (len < 2 || len > hlen) 459 goto bad; 460 --hlen; /* account for length byte */ 461 } 462 --hlen; /* account for type byte */ 463 datalen = 0; 464 465 /* Bail if "l" bytes of data are not left or were not captured */ 466 #define LENCHECK(l) { if ((l) > hlen) goto bad; ND_TCHECK_LEN(cp, l); } 467 468 469 ND_PRINT("%s", tok2str(tcp_option_values, "unknown-%u", opt)); 470 471 switch (opt) { 472 473 case TCPOPT_MAXSEG: 474 datalen = 2; 475 LENCHECK(datalen); 476 ND_PRINT(" %u", GET_BE_U_2(cp)); 477 break; 478 479 case TCPOPT_WSCALE: 480 datalen = 1; 481 LENCHECK(datalen); 482 ND_PRINT(" %u", GET_U_1(cp)); 483 break; 484 485 case TCPOPT_SACK: 486 datalen = len - 2; 487 if (datalen % 8 != 0) { 488 ND_PRINT(" invalid sack"); 489 } else { 490 uint32_t s, e; 491 492 ND_PRINT(" %u ", datalen / 8); 493 for (i = 0; i < datalen; i += 8) { 494 LENCHECK(i + 4); 495 s = GET_BE_U_4(cp + i); 496 LENCHECK(i + 8); 497 e = GET_BE_U_4(cp + i + 4); 498 if (rev) { 499 s -= thseq; 500 e -= thseq; 501 } else { 502 s -= thack; 503 e -= thack; 504 } 505 ND_PRINT("{%u:%u}", s, e); 506 } 507 } 508 break; 509 510 case TCPOPT_CC: 511 case TCPOPT_CCNEW: 512 case TCPOPT_CCECHO: 513 case TCPOPT_ECHO: 514 case TCPOPT_ECHOREPLY: 515 516 /* 517 * those options share their semantics. 518 * fall through 519 */ 520 datalen = 4; 521 LENCHECK(datalen); 522 ND_PRINT(" %u", GET_BE_U_4(cp)); 523 break; 524 525 case TCPOPT_TIMESTAMP: 526 datalen = 8; 527 LENCHECK(datalen); 528 ND_PRINT(" val %u ecr %u", 529 GET_BE_U_4(cp), 530 GET_BE_U_4(cp + 4)); 531 break; 532 533 case TCPOPT_SIGNATURE: 534 datalen = TCP_SIGLEN; 535 LENCHECK(datalen); 536 ND_PRINT(" "); 537 #ifdef HAVE_LIBCRYPTO 538 switch (tcp_verify_signature(ndo, ip, tp, 539 bp + TH_OFF(tp) * 4, length, cp)) { 540 541 case SIGNATURE_VALID: 542 ND_PRINT("valid"); 543 break; 544 545 case SIGNATURE_INVALID: 546 nd_print_invalid(ndo); 547 break; 548 549 case CANT_CHECK_SIGNATURE: 550 ND_PRINT("can't check - "); 551 for (i = 0; i < TCP_SIGLEN; ++i) 552 ND_PRINT("%02x", 553 GET_U_1(cp + i)); 554 break; 555 } 556 #else 557 for (i = 0; i < TCP_SIGLEN; ++i) 558 ND_PRINT("%02x", GET_U_1(cp + i)); 559 #endif 560 break; 561 562 case TCPOPT_SCPS: 563 datalen = 2; 564 LENCHECK(datalen); 565 ND_PRINT(" cap %02x id %u", GET_U_1(cp), 566 GET_U_1(cp + 1)); 567 break; 568 569 case TCPOPT_TCPAO: 570 datalen = len - 2; 571 /* RFC 5925 Section 2.2: 572 * "The Length value MUST be greater than or equal to 4." 573 * (This includes the Kind and Length fields already processed 574 * at this point.) 575 */ 576 if (datalen < 2) { 577 nd_print_invalid(ndo); 578 } else { 579 LENCHECK(1); 580 ND_PRINT(" keyid %u", GET_U_1(cp)); 581 LENCHECK(2); 582 ND_PRINT(" rnextkeyid %u", 583 GET_U_1(cp + 1)); 584 if (datalen > 2) { 585 ND_PRINT(" mac 0x"); 586 for (i = 2; i < datalen; i++) { 587 LENCHECK(i + 1); 588 ND_PRINT("%02x", 589 GET_U_1(cp + i)); 590 } 591 } 592 } 593 break; 594 595 case TCPOPT_EOL: 596 case TCPOPT_NOP: 597 case TCPOPT_SACKOK: 598 /* 599 * Nothing interesting. 600 * fall through 601 */ 602 break; 603 604 case TCPOPT_UTO: 605 datalen = 2; 606 LENCHECK(datalen); 607 utoval = GET_BE_U_2(cp); 608 ND_PRINT(" 0x%x", utoval); 609 if (utoval & 0x0001) 610 utoval = (utoval >> 1) * 60; 611 else 612 utoval >>= 1; 613 ND_PRINT(" %u", utoval); 614 break; 615 616 case TCPOPT_MPTCP: 617 { 618 const u_char *snapend_save; 619 int ret; 620 621 datalen = len - 2; 622 LENCHECK(datalen); 623 /* Update the snapend to the end of the option 624 * before calling mptcp_print(). Some options 625 * (MPTCP or others) may be present after a 626 * MPTCP option. This prevents that, in 627 * mptcp_print(), the remaining length < the 628 * remaining caplen. 629 */ 630 snapend_save = ndo->ndo_snapend; 631 ndo->ndo_snapend = ND_MIN(cp - 2 + len, 632 ndo->ndo_snapend); 633 ret = mptcp_print(ndo, cp - 2, len, flags); 634 ndo->ndo_snapend = snapend_save; 635 if (!ret) 636 goto bad; 637 break; 638 } 639 640 case TCPOPT_FASTOPEN: 641 datalen = len - 2; 642 LENCHECK(datalen); 643 ND_PRINT(" "); 644 print_tcp_fastopen_option(ndo, cp, datalen, FALSE); 645 break; 646 647 case TCPOPT_EXPERIMENT2: 648 datalen = len - 2; 649 LENCHECK(datalen); 650 if (datalen < 2) 651 goto bad; 652 /* RFC6994 */ 653 magic = GET_BE_U_2(cp); 654 ND_PRINT("-"); 655 656 switch(magic) { 657 658 case 0xf989: /* TCP Fast Open RFC 7413 */ 659 print_tcp_fastopen_option(ndo, cp + 2, datalen - 2, TRUE); 660 break; 661 662 default: 663 /* Unknown magic number */ 664 ND_PRINT("%04x", magic); 665 break; 666 } 667 break; 668 669 default: 670 datalen = len - 2; 671 if (datalen) 672 ND_PRINT(" 0x"); 673 for (i = 0; i < datalen; ++i) { 674 LENCHECK(i + 1); 675 ND_PRINT("%02x", GET_U_1(cp + i)); 676 } 677 break; 678 } 679 680 /* Account for data printed */ 681 cp += datalen; 682 hlen -= datalen; 683 684 /* Check specification against observed length */ 685 ++datalen; /* option octet */ 686 if (!ZEROLENOPT(opt)) 687 ++datalen; /* size octet */ 688 if (datalen != len) 689 ND_PRINT("[len %u]", len); 690 ch = ','; 691 if (opt == TCPOPT_EOL) 692 break; 693 } 694 ND_PRINT("]"); 695 } 696 697 /* 698 * Print length field before crawling down the stack. 699 */ 700 ND_PRINT(", length %u", length); 701 702 if (length == 0) 703 return; 704 705 /* 706 * Decode payload if necessary. 707 */ 708 header_len = TH_OFF(tp) * 4; 709 /* 710 * Do a bounds check before decoding the payload. 711 * At least the header data is required. 712 */ 713 if (!ND_TTEST_LEN(bp, header_len)) { 714 ND_PRINT(" [remaining caplen(%u) < header length(%u)]", 715 ND_BYTES_AVAILABLE_AFTER(bp), header_len); 716 nd_trunc_longjmp(ndo); 717 } 718 bp += header_len; 719 if ((flags & TH_RST) && ndo->ndo_vflag) { 720 print_tcp_rst_data(ndo, bp, length); 721 return; 722 } 723 724 if (ndo->ndo_packettype) { 725 switch (ndo->ndo_packettype) { 726 case PT_ZMTP1: 727 zmtp1_print(ndo, bp, length); 728 break; 729 case PT_RESP: 730 resp_print(ndo, bp, length); 731 break; 732 case PT_DOMAIN: 733 /* over_tcp: TRUE, is_mdns: FALSE */ 734 domain_print(ndo, bp, length, TRUE, FALSE); 735 break; 736 } 737 return; 738 } 739 740 if (IS_SRC_OR_DST_PORT(FTP_PORT)) { 741 ND_PRINT(": "); 742 ftp_print(ndo, bp, length); 743 } else if (IS_SRC_OR_DST_PORT(SSH_PORT)) { 744 ssh_print(ndo, bp, length); 745 } else if (IS_SRC_OR_DST_PORT(TELNET_PORT)) { 746 telnet_print(ndo, bp, length); 747 } else if (IS_SRC_OR_DST_PORT(SMTP_PORT)) { 748 ND_PRINT(": "); 749 smtp_print(ndo, bp, length); 750 } else if (IS_SRC_OR_DST_PORT(WHOIS_PORT)) { 751 ND_PRINT(": "); 752 whois_print(ndo, bp, length); 753 } else if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT)) { 754 /* over_tcp: TRUE, is_mdns: FALSE */ 755 domain_print(ndo, bp, length, TRUE, FALSE); 756 } else if (IS_SRC_OR_DST_PORT(HTTP_PORT)) { 757 ND_PRINT(": "); 758 http_print(ndo, bp, length); 759 #ifdef ENABLE_SMB 760 } else if (IS_SRC_OR_DST_PORT(NETBIOS_SSN_PORT)) { 761 nbt_tcp_print(ndo, bp, length); 762 #endif 763 } else if (IS_SRC_OR_DST_PORT(BGP_PORT)) { 764 bgp_print(ndo, bp, length); 765 } else if (IS_SRC_OR_DST_PORT(RPKI_RTR_PORT)) { 766 rpki_rtr_print(ndo, bp, length); 767 #ifdef ENABLE_SMB 768 } else if (IS_SRC_OR_DST_PORT(SMB_PORT)) { 769 smb_tcp_print(ndo, bp, length); 770 #endif 771 } else if (IS_SRC_OR_DST_PORT(RTSP_PORT)) { 772 ND_PRINT(": "); 773 rtsp_print(ndo, bp, length); 774 } else if (IS_SRC_OR_DST_PORT(MSDP_PORT)) { 775 msdp_print(ndo, bp, length); 776 } else if (IS_SRC_OR_DST_PORT(LDP_PORT)) { 777 ldp_print(ndo, bp, length); 778 } else if (IS_SRC_OR_DST_PORT(PPTP_PORT)) 779 pptp_print(ndo, bp); 780 else if (IS_SRC_OR_DST_PORT(REDIS_PORT)) 781 resp_print(ndo, bp, length); 782 else if (IS_SRC_OR_DST_PORT(BEEP_PORT)) 783 beep_print(ndo, bp, length); 784 else if (IS_SRC_OR_DST_PORT(OPENFLOW_PORT_OLD) || IS_SRC_OR_DST_PORT(OPENFLOW_PORT_IANA)) { 785 openflow_print(ndo, bp, length); 786 } else if (IS_SRC_OR_DST_PORT(HTTP_PORT_ALT)) { 787 ND_PRINT(": "); 788 http_print(ndo, bp, length); 789 } else if (IS_SRC_OR_DST_PORT(RTSP_PORT_ALT)) { 790 ND_PRINT(": "); 791 rtsp_print(ndo, bp, length); 792 } else if ((IS_SRC_OR_DST_PORT(NFS_PORT)) && 793 length >= 4 && ND_TTEST_4(bp)) { 794 /* 795 * If data present, header length valid, and NFS port used, 796 * assume NFS. 797 * Pass offset of data plus 4 bytes for RPC TCP msg length 798 * to NFS print routines. 799 */ 800 uint32_t fraglen; 801 const struct sunrpc_msg *rp; 802 enum sunrpc_msg_type direction; 803 804 fraglen = GET_BE_U_4(bp) & 0x7FFFFFFF; 805 if (fraglen > (length) - 4) 806 fraglen = (length) - 4; 807 rp = (const struct sunrpc_msg *)(bp + 4); 808 if (ND_TTEST_4(rp->rm_direction)) { 809 direction = (enum sunrpc_msg_type) GET_BE_U_4(rp->rm_direction); 810 if (dport == NFS_PORT && direction == SUNRPC_CALL) { 811 ND_PRINT(": NFS request xid %u ", 812 GET_BE_U_4(rp->rm_xid)); 813 nfsreq_noaddr_print(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); 814 return; 815 } 816 if (sport == NFS_PORT && direction == SUNRPC_REPLY) { 817 ND_PRINT(": NFS reply xid %u ", 818 GET_BE_U_4(rp->rm_xid)); 819 nfsreply_noaddr_print(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); 820 return; 821 } 822 } 823 } 824 825 return; 826 bad: 827 ND_PRINT("[bad opt]"); 828 if (ch != '\0') 829 ND_PRINT("]"); 830 return; 831 trunc: 832 nd_print_trunc(ndo); 833 if (ch != '\0') 834 ND_PRINT(">"); 835 } 836 837 /* 838 * RFC1122 says the following on data in RST segments: 839 * 840 * 4.2.2.12 RST Segment: RFC-793 Section 3.4 841 * 842 * A TCP SHOULD allow a received RST segment to include data. 843 * 844 * DISCUSSION 845 * It has been suggested that a RST segment could contain 846 * ASCII text that encoded and explained the cause of the 847 * RST. No standard has yet been established for such 848 * data. 849 * 850 */ 851 852 static void 853 print_tcp_rst_data(netdissect_options *ndo, 854 const u_char *sp, u_int length) 855 { 856 u_char c; 857 858 ND_PRINT(ND_TTEST_LEN(sp, length) ? " [RST" : " [!RST"); 859 if (length > MAX_RST_DATA_LEN) { 860 length = MAX_RST_DATA_LEN; /* can use -X for longer */ 861 ND_PRINT("+"); /* indicate we truncate */ 862 } 863 ND_PRINT(" "); 864 while (length && sp < ndo->ndo_snapend) { 865 c = GET_U_1(sp); 866 sp++; 867 fn_print_char(ndo, c); 868 length--; 869 } 870 ND_PRINT("]"); 871 } 872 873 static void 874 print_tcp_fastopen_option(netdissect_options *ndo, const u_char *cp, 875 u_int datalen, int exp) 876 { 877 u_int i; 878 879 if (exp) 880 ND_PRINT("tfo"); 881 882 if (datalen == 0) { 883 /* Fast Open Cookie Request */ 884 ND_PRINT(" cookiereq"); 885 } else { 886 /* Fast Open Cookie */ 887 if (datalen % 2 != 0 || datalen < 4 || datalen > 16) { 888 nd_print_invalid(ndo); 889 } else { 890 ND_PRINT(" cookie "); 891 for (i = 0; i < datalen; ++i) 892 ND_PRINT("%02x", GET_U_1(cp + i)); 893 } 894 } 895 } 896 897 #ifdef HAVE_LIBCRYPTO 898 DIAG_OFF_DEPRECATION 899 static int 900 tcp_verify_signature(netdissect_options *ndo, 901 const struct ip *ip, const struct tcphdr *tp, 902 const u_char *data, u_int length, const u_char *rcvsig) 903 { 904 struct tcphdr tp1; 905 u_char sig[TCP_SIGLEN]; 906 char zero_proto = 0; 907 MD5_CTX ctx; 908 uint16_t savecsum, tlen; 909 const struct ip6_hdr *ip6; 910 uint32_t len32; 911 uint8_t nxt; 912 913 if (data + length > ndo->ndo_snapend) { 914 ND_PRINT("snaplen too short, "); 915 return (CANT_CHECK_SIGNATURE); 916 } 917 918 tp1 = *tp; 919 920 if (ndo->ndo_sigsecret == NULL) { 921 ND_PRINT("shared secret not supplied with -M, "); 922 return (CANT_CHECK_SIGNATURE); 923 } 924 925 MD5_Init(&ctx); 926 /* 927 * Step 1: Update MD5 hash with IP pseudo-header. 928 */ 929 if (IP_V(ip) == 4) { 930 MD5_Update(&ctx, (const char *)&ip->ip_src, sizeof(ip->ip_src)); 931 MD5_Update(&ctx, (const char *)&ip->ip_dst, sizeof(ip->ip_dst)); 932 MD5_Update(&ctx, (const char *)&zero_proto, sizeof(zero_proto)); 933 MD5_Update(&ctx, (const char *)&ip->ip_p, sizeof(ip->ip_p)); 934 tlen = GET_BE_U_2(ip->ip_len) - IP_HL(ip) * 4; 935 tlen = htons(tlen); 936 MD5_Update(&ctx, (const char *)&tlen, sizeof(tlen)); 937 } else if (IP_V(ip) == 6) { 938 ip6 = (const struct ip6_hdr *)ip; 939 MD5_Update(&ctx, (const char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); 940 MD5_Update(&ctx, (const char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); 941 len32 = htonl(GET_BE_U_2(ip6->ip6_plen)); 942 MD5_Update(&ctx, (const char *)&len32, sizeof(len32)); 943 nxt = 0; 944 MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); 945 MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); 946 MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); 947 nxt = IPPROTO_TCP; 948 MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); 949 } else { 950 ND_PRINT("IP version not 4 or 6, "); 951 return (CANT_CHECK_SIGNATURE); 952 } 953 954 /* 955 * Step 2: Update MD5 hash with TCP header, excluding options. 956 * The TCP checksum must be set to zero. 957 */ 958 memcpy(&savecsum, tp1.th_sum, sizeof(savecsum)); 959 memset(tp1.th_sum, 0, sizeof(tp1.th_sum)); 960 MD5_Update(&ctx, (const char *)&tp1, sizeof(struct tcphdr)); 961 memcpy(tp1.th_sum, &savecsum, sizeof(tp1.th_sum)); 962 /* 963 * Step 3: Update MD5 hash with TCP segment data, if present. 964 */ 965 if (length > 0) 966 MD5_Update(&ctx, data, length); 967 /* 968 * Step 4: Update MD5 hash with shared secret. 969 */ 970 MD5_Update(&ctx, ndo->ndo_sigsecret, strlen(ndo->ndo_sigsecret)); 971 MD5_Final(sig, &ctx); 972 973 if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0) 974 return (SIGNATURE_VALID); 975 else 976 return (SIGNATURE_INVALID); 977 } 978 DIAG_ON_DEPRECATION 979 #endif /* HAVE_LIBCRYPTO */ 980