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