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#ifndef lint 27static const char rcsid[] _U_ = 28"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.135 2008-11-09 23:35:03 mcr Exp $ (LBL)"; 29#else 30__RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); 31#endif 32 33#ifdef HAVE_CONFIG_H 34#include "config.h" 35#endif 36 37#include <tcpdump-stdinc.h> 38 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42 43#include "interface.h" 44#include "addrtoname.h" 45#include "extract.h" 46 47#include "tcp.h" 48 49#include "ip.h" 50#ifdef INET6 51#include "ip6.h" 52#endif 53#include "ipproto.h" 54#include "rpc_auth.h" 55#include "rpc_msg.h" 56 57#include "nameser.h" 58 59#ifdef HAVE_LIBCRYPTO 60#include <CommonCrypto/CommonDigest.h> 61#include <signature.h> 62 63static int tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, 64 const u_char *data, int length, const u_char *rcvsig); 65#endif 66 67static void print_tcp_rst_data(register const u_char *sp, u_int length); 68 69#define MAX_RST_DATA_LEN 30 70 71 72struct tha { 73#ifndef INET6 74 struct in_addr src; 75 struct in_addr dst; 76#else 77 struct in6_addr src; 78 struct in6_addr dst; 79#endif /*INET6*/ 80 u_int port; 81}; 82 83struct tcp_seq_hash { 84 struct tcp_seq_hash *nxt; 85 struct tha addr; 86 tcp_seq seq; 87 tcp_seq ack; 88}; 89 90#define TSEQ_HASHSIZE 919 91 92/* These tcp optinos do not have the size octet */ 93#define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP) 94 95static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE]; 96 97struct tok tcp_flag_values[] = { 98 { TH_FIN, "F" }, 99 { TH_SYN, "S" }, 100 { TH_RST, "R" }, 101 { TH_PUSH, "P" }, 102 { TH_ACK, "." }, 103 { TH_URG, "U" }, 104 { TH_ECNECHO, "E" }, 105 { TH_CWR, "W" }, 106 { 0, NULL } 107}; 108 109struct tok tcp_option_values[] = { 110 { TCPOPT_EOL, "eol" }, 111 { TCPOPT_NOP, "nop" }, 112 { TCPOPT_MAXSEG, "mss" }, 113 { TCPOPT_WSCALE, "wscale" }, 114 { TCPOPT_SACKOK, "sackOK" }, 115 { TCPOPT_SACK, "sack" }, 116 { TCPOPT_ECHO, "echo" }, 117 { TCPOPT_ECHOREPLY, "echoreply" }, 118 { TCPOPT_TIMESTAMP, "TS" }, 119 { TCPOPT_CC, "cc" }, 120 { TCPOPT_CCNEW, "ccnew" }, 121 { TCPOPT_CCECHO, "" }, 122 { TCPOPT_SIGNATURE, "md5" }, 123 { TCPOPT_AUTH, "enhanced auth" }, 124 { TCPOPT_MPTCP, "mp" }, 125 { TCPOPT_UTO, "uto" }, 126 { 0, NULL } 127}; 128 129struct tok mptcp_subtypes[] = { 130 { TCPOPT_MPTCP_MP_CAPABLE, "capable" }, 131 { TCPOPT_MPTCP_MP_JOIN, "join" }, 132 { TCPOPT_MPTCP_DSS, "dss" }, 133 { TCPOPT_MPTCP_ADD_ADDR, "addaddr" }, 134 { TCPOPT_MPTCP_REMOVE_ADDR, "removeaddr" }, 135 { TCPOPT_MPTCP_MP_PRIO, "prio" }, 136 { TCPOPT_MPTCP_MP_FAIL, "fail" }, 137 { TCPOPT_MPTCP_MP_FASTCLOSE, "fastclose" }, 138 { 0, NULL } 139}; 140 141static int tcp_cksum(register const struct ip *ip, 142 register const struct tcphdr *tp, 143 register u_int len) 144{ 145 return (nextproto4_cksum(ip, (const u_int8_t *)tp, len, 146 IPPROTO_TCP)); 147} 148 149void 150tcp_print(register const u_char *bp, register u_int length, 151 register const u_char *bp2, int fragmented) 152{ 153 register const struct tcphdr *tp; 154 register const struct ip *ip; 155 register u_char flags; 156 register u_int hlen; 157 register char ch; 158 u_int16_t sport, dport, win, urp; 159 u_int32_t seq, ack, thseq, thack; 160 u_int utoval; 161 int threv; 162#ifdef INET6 163 register const struct ip6_hdr *ip6; 164#endif 165 166 tp = (struct tcphdr *)bp; 167 ip = (struct ip *)bp2; 168#ifdef INET6 169 if (IP_V(ip) == 6) 170 ip6 = (struct ip6_hdr *)bp2; 171 else 172 ip6 = NULL; 173#endif /*INET6*/ 174 ch = '\0'; 175 if (!TTEST(tp->th_dport)) { 176 (void)printf("%s > %s: [|tcp]", 177 ipaddr_string(&ip->ip_src), 178 ipaddr_string(&ip->ip_dst)); 179 return; 180 } 181 182 sport = EXTRACT_16BITS(&tp->th_sport); 183 dport = EXTRACT_16BITS(&tp->th_dport); 184 185 hlen = TH_OFF(tp) * 4; 186 187 /* 188 * If data present, header length valid, and NFS port used, 189 * assume NFS. 190 * Pass offset of data plus 4 bytes for RPC TCP msg length 191 * to NFS print routines. 192 */ 193 if (!qflag && hlen >= sizeof(*tp) && hlen <= length && 194 (length - hlen) >= 4) { 195 u_char *fraglenp; 196 u_int32_t fraglen; 197 register struct sunrpc_msg *rp; 198 enum sunrpc_msg_type direction; 199 200 fraglenp = (u_char *)tp + hlen; 201 if (TTEST2(*fraglenp, 4)) { 202 fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF; 203 if (fraglen > (length - hlen) - 4) 204 fraglen = (length - hlen) - 4; 205 rp = (struct sunrpc_msg *)(fraglenp + 4); 206 if (TTEST(rp->rm_direction)) { 207 direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); 208 if (dport == NFS_PORT && 209 direction == SUNRPC_CALL) { 210 nfsreq_print((u_char *)rp, fraglen, 211 (u_char *)ip); 212 return; 213 } 214 if (sport == NFS_PORT && 215 direction == SUNRPC_REPLY) { 216 nfsreply_print((u_char *)rp, fraglen, 217 (u_char *)ip); 218 return; 219 } 220 } 221 } 222 } 223#ifdef INET6 224 if (ip6) { 225 if (ip6->ip6_nxt == IPPROTO_TCP) { 226 (void)printf("%s.%s > %s.%s: ", 227 ip6addr_string(&ip6->ip6_src), 228 tcpport_string(sport), 229 ip6addr_string(&ip6->ip6_dst), 230 tcpport_string(dport)); 231 } else { 232 (void)printf("%s > %s: ", 233 tcpport_string(sport), tcpport_string(dport)); 234 } 235 } else 236#endif /*INET6*/ 237 { 238 if (ip->ip_p == IPPROTO_TCP) { 239 (void)printf("%s.%s > %s.%s: ", 240 ipaddr_string(&ip->ip_src), 241 tcpport_string(sport), 242 ipaddr_string(&ip->ip_dst), 243 tcpport_string(dport)); 244 } else { 245 (void)printf("%s > %s: ", 246 tcpport_string(sport), tcpport_string(dport)); 247 } 248 } 249 250 if (hlen < sizeof(*tp)) { 251 (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]", 252 length - hlen, hlen, (unsigned long)sizeof(*tp)); 253 return; 254 } 255 256 TCHECK(*tp); 257 258 seq = EXTRACT_32BITS(&tp->th_seq); 259 ack = EXTRACT_32BITS(&tp->th_ack); 260 win = EXTRACT_16BITS(&tp->th_win); 261 urp = EXTRACT_16BITS(&tp->th_urp); 262 263 if (qflag) { 264 (void)printf("tcp %d", length - hlen); 265 if (hlen > length) { 266 (void)printf(" [bad hdr length %u - too long, > %u]", 267 hlen, length); 268 } 269 return; 270 } 271 272 flags = tp->th_flags; 273 printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags)); 274 275 if (!Sflag && (flags & TH_ACK)) { 276 register struct tcp_seq_hash *th; 277 const void *src, *dst; 278 register int rev; 279 struct tha tha; 280 /* 281 * Find (or record) the initial sequence numbers for 282 * this conversation. (we pick an arbitrary 283 * collating order so there's only one entry for 284 * both directions). 285 */ 286#ifdef INET6 287 rev = 0; 288 if (ip6) { 289 src = &ip6->ip6_src; 290 dst = &ip6->ip6_dst; 291 if (sport > dport) 292 rev = 1; 293 else if (sport == dport) { 294 if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0) 295 rev = 1; 296 } 297 if (rev) { 298 memcpy(&tha.src, dst, sizeof ip6->ip6_dst); 299 memcpy(&tha.dst, src, sizeof ip6->ip6_src); 300 tha.port = dport << 16 | sport; 301 } else { 302 memcpy(&tha.dst, dst, sizeof ip6->ip6_dst); 303 memcpy(&tha.src, src, sizeof ip6->ip6_src); 304 tha.port = sport << 16 | dport; 305 } 306 } else { 307 /* 308 * Zero out the tha structure; the src and dst 309 * fields are big enough to hold an IPv6 310 * address, but we only have IPv4 addresses 311 * and thus must clear out the remaining 124 312 * bits. 313 * 314 * XXX - should we just clear those bytes after 315 * copying the IPv4 addresses, rather than 316 * zeroing out the entire structure and then 317 * overwriting some of the zeroes? 318 * 319 * XXX - this could fail if we see TCP packets 320 * with an IPv6 address with the lower 124 bits 321 * all zero and also see TCP packes with an 322 * IPv4 address with the same 32 bits as the 323 * upper 32 bits of the IPv6 address in question. 324 * Can that happen? Is it likely enough to be 325 * an issue? 326 */ 327 memset(&tha, 0, sizeof(tha)); 328 src = &ip->ip_src; 329 dst = &ip->ip_dst; 330 if (sport > dport) 331 rev = 1; 332 else if (sport == dport) { 333 if (memcmp(src, dst, sizeof ip->ip_dst) > 0) 334 rev = 1; 335 } 336 if (rev) { 337 memcpy(&tha.src, dst, sizeof ip->ip_dst); 338 memcpy(&tha.dst, src, sizeof ip->ip_src); 339 tha.port = dport << 16 | sport; 340 } else { 341 memcpy(&tha.dst, dst, sizeof ip->ip_dst); 342 memcpy(&tha.src, src, sizeof ip->ip_src); 343 tha.port = sport << 16 | dport; 344 } 345 } 346#else 347 rev = 0; 348 src = &ip->ip_src; 349 dst = &ip->ip_dst; 350 if (sport > dport) 351 rev = 1; 352 else if (sport == dport) { 353 if (memcmp(src, dst, sizeof ip->ip_dst) > 0) 354 rev = 1; 355 } 356 if (rev) { 357 memcpy(&tha.src, dst, sizeof ip->ip_dst); 358 memcpy(&tha.dst, src, sizeof ip->ip_src); 359 tha.port = dport << 16 | sport; 360 } else { 361 memcpy(&tha.dst, dst, sizeof ip->ip_dst); 362 memcpy(&tha.src, src, sizeof ip->ip_src); 363 tha.port = sport << 16 | dport; 364 } 365#endif 366 367 threv = rev; 368 for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; 369 th->nxt; th = th->nxt) 370 if (memcmp((char *)&tha, (char *)&th->addr, 371 sizeof(th->addr)) == 0) 372 break; 373 374 if (!th->nxt || (flags & TH_SYN)) { 375 /* didn't find it or new conversation */ 376 if (th->nxt == NULL) { 377 th->nxt = (struct tcp_seq_hash *) 378 calloc(1, sizeof(*th)); 379 if (th->nxt == NULL) 380 error("tcp_print: calloc"); 381 } 382 th->addr = tha; 383 if (rev) 384 th->ack = seq, th->seq = ack - 1; 385 else 386 th->seq = seq, th->ack = ack - 1; 387 } else { 388 if (rev) 389 seq -= th->ack, ack -= th->seq; 390 else 391 seq -= th->seq, ack -= th->ack; 392 } 393 394 thseq = th->seq; 395 thack = th->ack; 396 } else { 397 /*fool gcc*/ 398 thseq = thack = threv = 0; 399 } 400 if (hlen > length) { 401 (void)printf(" [bad hdr length %u - too long, > %u]", 402 hlen, length); 403 return; 404 } 405 406 if (vflag && !Kflag && !fragmented) { 407 /* Check the checksum, if possible. */ 408 u_int16_t sum, tcp_sum; 409 410 if (IP_V(ip) == 4) { 411 if (TTEST2(tp->th_sport, length)) { 412 sum = tcp_cksum(ip, tp, length); 413 tcp_sum = EXTRACT_16BITS(&tp->th_sum); 414 415 (void)printf(", cksum 0x%04x", tcp_sum); 416 if (sum != 0) 417 (void)printf(" (incorrect -> 0x%04x)", 418 in_cksum_shouldbe(tcp_sum, sum)); 419 else 420 (void)printf(" (correct)"); 421 } 422 } 423#ifdef INET6 424 else if (IP_V(ip) == 6 && ip6->ip6_plen) { 425 if (TTEST2(tp->th_sport, length)) { 426 sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP); 427 tcp_sum = EXTRACT_16BITS(&tp->th_sum); 428 429 (void)printf(", cksum 0x%04x", tcp_sum); 430 if (sum != 0) 431 (void)printf(" (incorrect -> 0x%04x)", 432 in_cksum_shouldbe(tcp_sum, sum)); 433 else 434 (void)printf(" (correct)"); 435 436 } 437 } 438#endif 439 } 440 441 length -= hlen; 442 if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) { 443 (void)printf(", seq %u", seq); 444 445 if (length > 0) { 446 (void)printf(":%u", seq + length); 447 } 448 } 449 450 if (flags & TH_ACK) { 451 (void)printf(", ack %u", ack); 452 } 453 454 (void)printf(", win %d", win); 455 456 if (flags & TH_URG) 457 (void)printf(", urg %d", urp); 458 /* 459 * Handle any options. 460 */ 461 if (hlen > sizeof(*tp)) { 462 register const u_char *cp; 463 register u_int i, opt, datalen; 464 register u_int len; 465 466 hlen -= sizeof(*tp); 467 cp = (const u_char *)tp + sizeof(*tp); 468 printf(", options ["); 469 while (hlen > 0) { 470 if (ch != '\0') 471 putchar(ch); 472 TCHECK(*cp); 473 opt = *cp++; 474 if (ZEROLENOPT(opt)) 475 len = 1; 476 else { 477 TCHECK(*cp); 478 len = *cp++; /* total including type, len */ 479 if (len < 2 || len > hlen) 480 goto bad; 481 --hlen; /* account for length byte */ 482 } 483 --hlen; /* account for type byte */ 484 datalen = 0; 485 486/* Bail if "l" bytes of data are not left or were not captured */ 487#define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); } 488 489 490 printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt)); 491 492 switch (opt) { 493 494 case TCPOPT_MAXSEG: 495 datalen = 2; 496 LENCHECK(datalen); 497 (void)printf(" %u", EXTRACT_16BITS(cp)); 498 break; 499 500 case TCPOPT_WSCALE: 501 datalen = 1; 502 LENCHECK(datalen); 503 (void)printf(" %u", *cp); 504 break; 505 506 case TCPOPT_SACK: 507 datalen = len - 2; 508 if (datalen % 8 != 0) { 509 (void)printf("malformed sack"); 510 } else { 511 u_int32_t s, e; 512 513 (void)printf(" %d ", datalen / 8); 514 for (i = 0; i < datalen; i += 8) { 515 LENCHECK(i + 4); 516 s = EXTRACT_32BITS(cp + i); 517 LENCHECK(i + 8); 518 e = EXTRACT_32BITS(cp + i + 4); 519 if (threv) { 520 s -= thseq; 521 e -= thseq; 522 } else { 523 s -= thack; 524 e -= thack; 525 } 526 (void)printf("{%u:%u}", s, e); 527 } 528 } 529 break; 530 531 case TCPOPT_CC: 532 case TCPOPT_CCNEW: 533 case TCPOPT_CCECHO: 534 case TCPOPT_ECHO: 535 case TCPOPT_ECHOREPLY: 536 537 /* 538 * those options share their semantics. 539 * fall through 540 */ 541 datalen = 4; 542 LENCHECK(datalen); 543 (void)printf(" %u", EXTRACT_32BITS(cp)); 544 break; 545 546 case TCPOPT_TIMESTAMP: 547 datalen = 8; 548 LENCHECK(datalen); 549 (void)printf(" val %u ecr %u", 550 EXTRACT_32BITS(cp), 551 EXTRACT_32BITS(cp + 4)); 552 break; 553 554 case TCPOPT_SIGNATURE: 555 datalen = TCP_SIGLEN; 556 LENCHECK(datalen); 557#ifdef HAVE_LIBCRYPTO 558 switch (tcp_verify_signature(ip, tp, 559 bp + TH_OFF(tp) * 4, length, cp)) { 560 561 case SIGNATURE_VALID: 562 (void)printf("valid"); 563 break; 564 565 case SIGNATURE_INVALID: 566 (void)printf("invalid"); 567 break; 568 569 case CANT_CHECK_SIGNATURE: 570 (void)printf("can't check - "); 571 for (i = 0; i < TCP_SIGLEN; ++i) 572 (void)printf("%02x", cp[i]); 573 break; 574 } 575#else 576 for (i = 0; i < TCP_SIGLEN; ++i) 577 (void)printf("%02x", cp[i]); 578#endif 579 break; 580 581 case TCPOPT_AUTH: 582 (void)printf("keyid %d", *cp++); 583 datalen = len - 3; 584 for (i = 0; i < datalen; ++i) { 585 LENCHECK(i); 586 (void)printf("%02x", cp[i]); 587 } 588 break; 589 590 591 case TCPOPT_EOL: 592 case TCPOPT_NOP: 593 case TCPOPT_SACKOK: 594 /* 595 * Nothing interesting. 596 * fall through 597 */ 598 break; 599 600 case TCPOPT_UTO: 601 datalen = 2; 602 LENCHECK(datalen); 603 utoval = EXTRACT_16BITS(cp); 604 (void)printf("0x%x", utoval); 605 if (utoval & 0x0001) 606 utoval = (utoval >> 1) * 60; 607 else 608 utoval >>= 1; 609 (void)printf(" %u", utoval); 610 break; 611 612 case TCPOPT_MPTCP: { 613 uint8_t subtype; 614 615 datalen = 1; 616 LENCHECK(datalen); 617 618 subtype = (*cp) >> 4; 619 620 printf(" %s ", tok2str(mptcp_subtypes, "Unknown MPTCP subtype %u", subtype)); 621 622 switch (subtype) { 623 case TCPOPT_MPTCP_MP_CAPABLE: { 624 uint8_t version = (*cp) & 0x0f; 625 uint8_t mpflags; 626 627 if (version != 0) { 628 printf(" version %u ", version); 629 for (i = 0; i < datalen; ++i) { 630 LENCHECK(i); 631 (void)printf("%02x", cp[i]); 632 } 633 break; 634 } 635 636 datalen += 1; 637 LENCHECK(datalen); 638 mpflags = cp[1]; 639 printf("%s%s%s%s%s%s%s%s%s", 640 (mpflags) ? "flags:" : "", 641 (mpflags & 0x80) ? "A" : "", 642 (mpflags & 0x40) ? "B" : "", 643 (mpflags & 0x20) ? "C" : "", 644 (mpflags & 0x10) ? "D" : "", 645 (mpflags & 0x08) ? "E" : "", 646 (mpflags & 0x04) ? "F" : "", 647 (mpflags & 0x02) ? "G" : "", 648 (mpflags & 0x01) ? "H" : ""); 649 650 if (len == 12 || len == 20) { 651 printf(" sndkey:"); 652 for (i = 0; i < 8; ++i) { 653 datalen++; 654 LENCHECK(datalen); 655 (void)printf("%02x", cp[2 + i]); 656 } 657 658 if (len == 20) { 659 printf(" rcvkey:"); 660 for (i = 0; i < 8; ++i) { 661 datalen++; 662 LENCHECK(datalen); 663 (void)printf("%02x", cp[10 + i]); 664 } 665 } 666 } else { 667 printf(" unknown:"); 668 datalen = len - 2; 669 for (i = 0; i < datalen; ++i) { 670 LENCHECK(i); 671 (void)printf("%02x", cp[i]); 672 } 673 } 674 675 break; 676 } 677 case TCPOPT_MPTCP_MP_JOIN: { 678 uint8_t mpflags = (*cp) & 0x0f; 679 680 /* Flags on SYN only */ 681 if (flags & TH_SYN) { 682 printf("%s%s%s%s%s", 683 (mpflags) ? "flags:" : "", 684 (mpflags & 0x08) ? "0" : "", 685 (mpflags & 0x04) ? "1" : "", 686 (mpflags & 0x02) ? "2" : "", 687 (mpflags & 0x01) ? "B" : ""); 688 } 689 /* Address ID on SYN only, otherwise ignored */ 690 datalen += 1; 691 LENCHECK(datalen); 692 if ((flags & TH_SYN)) 693 printf(" addrid:%0x", cp[1]); 694 695 if (flags == TH_SYN && len == 12) { 696 /* Initial SYN */ 697 printf(" rcvtok:"); 698 for (i = 0; i < 4; ++i) { 699 datalen++; 700 LENCHECK(datalen); 701 (void)printf("%02x", cp[2 + i]); 702 } 703 printf(" sndrand:"); 704 for (i = 0; i < 4; ++i) { 705 datalen++; 706 LENCHECK(datalen); 707 (void)printf("%02x", cp[6 + i]); 708 } 709 } else if ((flags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK) && len == 16) { 710 /* Responding SYN/ACK */ 711 printf(" sndhmac:"); 712 for (i = 0; i < 8; ++i) { 713 datalen++; 714 LENCHECK(datalen); 715 (void)printf("%02x", cp[2 + i]); 716 } 717 printf(" sndrand:"); 718 for (i = 0; i < 4; ++i) { 719 datalen++; 720 LENCHECK(datalen); 721 (void)printf("%02x", cp[8 + i]); 722 } 723 } else if ((flags & (TH_SYN | TH_ACK)) == TH_ACK && len == 24) { 724 /* Third ACK */ 725 printf(" sndhmac:"); 726 for (i = 0; i < 20; ++i) { 727 datalen++; 728 LENCHECK(i); 729 (void)printf("%02x", cp[2 + i]); 730 } 731 } else { 732 datalen = len - 2; 733 for (i = 0; i < datalen; ++i) { 734 LENCHECK(i); 735 (void)printf("%02x", cp[i]); 736 } 737 } 738 break; 739 } 740 case TCPOPT_MPTCP_DSS: { 741 uint8_t mpflags; 742 u_int ack_len = 0; 743 u_int dsn_len = 0; 744 u_int64_t dack; 745 u_int64_t dsn; 746 u_int32_t sfsn; 747 u_int16_t dlen; 748 u_int16_t csum; 749 750 datalen += 1; 751 LENCHECK(datalen); 752 mpflags = cp[1] & 0x1f; 753 754 printf("%s%s%s%s%s%s", 755 (mpflags) ? "flags:" : "", 756 (mpflags & 0x10) ? "F" : "", 757 (mpflags & 0x08) ? "m" : "", 758 (mpflags & 0x04) ? "M" : "", 759 (mpflags & 0x02) ? "a" : "", 760 (mpflags & 0x01) ? "A" : ""); 761 762 if ((mpflags & MPDSS_FLAG_A)) { 763 if ((mpflags & MPDSS_FLAG_a)) { 764 ack_len = 8; 765 datalen += ack_len; 766 LENCHECK(datalen); 767 dack = EXTRACT_64BITS(cp + 2); 768 } else { 769 ack_len = 4; 770 datalen += ack_len; 771 LENCHECK(datalen); 772 dack = EXTRACT_32BITS(cp + 2); 773 } 774 (void)printf(" dack: %" PRIu64, dack); 775 } 776 if ((mpflags & MPDSS_FLAG_M)) { 777 if ((mpflags & MPDSS_FLAG_m)) { 778 dsn_len = 8; 779 datalen += dsn_len; 780 LENCHECK(datalen); 781 dsn = EXTRACT_64BITS(cp + 2 + ack_len); 782 } else { 783 dsn_len = 4; 784 datalen += dsn_len; 785 LENCHECK(datalen); 786 dsn = EXTRACT_32BITS(cp + 2 + ack_len); 787 } 788 (void)printf(" dsn: %" PRIu64, dsn); 789 790 datalen += 4; 791 LENCHECK(datalen); 792 sfsn = EXTRACT_32BITS(cp + 2 + ack_len + dsn_len); 793 (void)printf(" sfsn: %" PRIu32, sfsn); 794 795 datalen += 2; 796 LENCHECK(datalen); 797 dlen = EXTRACT_16BITS(cp + 2 + ack_len + dsn_len + 4); 798 (void)printf(" dlen: %" PRIu16, dlen); 799 800 /* 801 * Use the length of the option to find out if 802 * the checksum is present 803 */ 804 if (datalen < len - 2) { 805 datalen += 2; 806 LENCHECK(datalen); 807 csum = EXTRACT_16BITS(cp + 2 + ack_len + dsn_len + 6); 808 (void)printf(" csum: %" PRIu16, csum); 809 } 810 } 811 break; 812 } 813 case TCPOPT_MPTCP_ADD_ADDR: { 814 uint8_t ipvers; 815 u_int addrlen = 0; 816 u_int16_t port; 817 818 ipvers = cp[1] & 0xf0; 819 printf(" vers:%u", ipvers); 820 821 datalen = 2; 822 LENCHECK(datalen); 823 printf(" addrid:%0x", cp[1]); 824 825 switch (ipvers) { 826 case 4: { 827 datalen = 6; 828 LENCHECK(datalen); 829 ipaddr_string(cp + 2); 830 break; 831 } 832 case 6: { 833 datalen = 18; 834 LENCHECK(datalen); 835#ifdef INET6 836 ip6addr_string(cp + 2); 837#endif 838 break; 839 } 840 default: 841 goto bad; 842 } 843 /* 844 * Use the length of the option to find out if 845 * the port is present 846 */ 847 if (datalen < len - 2) { 848 datalen += 2; 849 LENCHECK(datalen); 850 851 port = EXTRACT_16BITS(cp + 2 + addrlen); 852 853 printf(" port: %u", port); 854 } 855 break; 856 } 857 case TCPOPT_MPTCP_REMOVE_ADDR: 858 datalen = len - 2; 859 for (i = 0; i < datalen; ++i) { 860 LENCHECK(i); 861 (void)printf(" %u", cp[i]); 862 } 863 break; 864 865 case TCPOPT_MPTCP_MP_PRIO: { 866 uint8_t mpflags = (*cp) & 0x0f; 867 868 printf("flag %s", 869 (mpflags & 0x01) ? "B" : ""); 870 871 if (len == 4) { 872 datalen = 2; 873 LENCHECK(i); 874 printf(" addrid:%0x", cp[1]); 875 } 876 break; 877 } 878 case TCPOPT_MPTCP_MP_FAIL: 879 datalen = 10; 880 LENCHECK(datalen); 881 882 printf(" dsn:"); 883 for (i = 0; i < 8; ++i) { 884 (void)printf("%02x", cp[2 + i]); 885 } 886 break; 887 888 case TCPOPT_MPTCP_MP_FASTCLOSE: 889 datalen = 10; 890 LENCHECK(datalen); 891 892 printf(" rcvrkey:"); 893 for (i = 0; i < 8; ++i) { 894 (void)printf("%02x", cp[2 + i]); 895 } 896 break; 897 898 default: 899 datalen = len - 2; 900 for (i = 0; i < datalen; ++i) { 901 LENCHECK(i); 902 (void)printf("%02x", cp[i]); 903 } 904 break; 905 } 906 break; 907 } 908 909 default: 910 datalen = len - 2; 911 for (i = 0; i < datalen; ++i) { 912 LENCHECK(i); 913 (void)printf("%02x", cp[i]); 914 } 915 break; 916 } 917 918 /* Account for data printed */ 919 cp += datalen; 920 hlen -= datalen; 921 922 /* Check specification against observed length */ 923 ++datalen; /* option octet */ 924 if (!ZEROLENOPT(opt)) 925 ++datalen; /* size octet */ 926 if (datalen != len) 927 (void)printf("[len %d]", len); 928 ch = ','; 929 if (opt == TCPOPT_EOL) 930 break; 931 } 932 putchar(']'); 933 } 934 935 /* 936 * Print length field before crawling down the stack. 937 */ 938 printf(", length %u", length); 939 940 if (length <= 0) 941 return; 942 943 /* 944 * Decode payload if necessary. 945 */ 946 bp += TH_OFF(tp) * 4; 947 if ((flags & TH_RST) && vflag) { 948 print_tcp_rst_data(bp, length); 949 return; 950 } 951 952 if (sport == TELNET_PORT || dport == TELNET_PORT) { 953 if (!qflag && vflag) 954 telnet_print(bp, length); 955 } else if (sport == BGP_PORT || dport == BGP_PORT) 956 bgp_print(bp, length); 957 else if (sport == PPTP_PORT || dport == PPTP_PORT) 958 pptp_print(bp); 959#ifdef TCPDUMP_DO_SMB 960 else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT) 961 nbt_tcp_print(bp, length); 962 else if (sport == SMB_PORT || dport == SMB_PORT) 963 smb_tcp_print(bp, length); 964#endif 965 else if (sport == BEEP_PORT || dport == BEEP_PORT) 966 beep_print(bp, length); 967 else if (length > 2 && 968 (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT || 969 sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) { 970 /* 971 * TCP DNS query has 2byte length at the head. 972 * XXX packet could be unaligned, it can go strange 973 */ 974 ns_print(bp + 2, length - 2, 0); 975 } else if (sport == MSDP_PORT || dport == MSDP_PORT) { 976 msdp_print(bp, length); 977 } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) { 978 rpki_rtr_print(bp, length); 979 } 980 else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) { 981 ldp_print(bp, length); 982 } 983 984 return; 985 bad: 986 fputs("[bad opt]", stdout); 987 if (ch != '\0') 988 putchar('>'); 989 return; 990 trunc: 991 fputs("[|tcp]", stdout); 992 if (ch != '\0') 993 putchar('>'); 994} 995 996/* 997 * RFC1122 says the following on data in RST segments: 998 * 999 * 4.2.2.12 RST Segment: RFC-793 Section 3.4 1000 * 1001 * A TCP SHOULD allow a received RST segment to include data. 1002 * 1003 * DISCUSSION 1004 * It has been suggested that a RST segment could contain 1005 * ASCII text that encoded and explained the cause of the 1006 * RST. No standard has yet been established for such 1007 * data. 1008 * 1009 */ 1010 1011static void 1012print_tcp_rst_data(register const u_char *sp, u_int length) 1013{ 1014 int c; 1015 1016 if (TTEST2(*sp, length)) 1017 printf(" [RST"); 1018 else 1019 printf(" [!RST"); 1020 if (length > MAX_RST_DATA_LEN) { 1021 length = MAX_RST_DATA_LEN; /* can use -X for longer */ 1022 putchar('+'); /* indicate we truncate */ 1023 } 1024 putchar(' '); 1025 while (length-- && sp <= snapend) { 1026 c = *sp++; 1027 safeputchar(c); 1028 } 1029 putchar(']'); 1030} 1031 1032#ifdef HAVE_LIBCRYPTO 1033static int 1034tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, 1035 const u_char *data, int length, const u_char *rcvsig) 1036{ 1037 struct tcphdr tp1; 1038 u_char sig[TCP_SIGLEN]; 1039 char zero_proto = 0; 1040 CC_MD5_CTX ctx; 1041 u_int16_t savecsum, tlen; 1042#ifdef INET6 1043 struct ip6_hdr *ip6; 1044 u_int32_t len32; 1045 u_int8_t nxt; 1046#endif 1047 1048 if (data + length > snapend) { 1049 printf("snaplen too short, "); 1050 return (CANT_CHECK_SIGNATURE); 1051 } 1052 1053 tp1 = *tp; 1054 1055 if (sigsecret == NULL) { 1056 printf("shared secret not supplied with -M, "); 1057 return (CANT_CHECK_SIGNATURE); 1058 } 1059 1060 CC_MD5_Init(&ctx); 1061 /* 1062 * Step 1: Update MD5 hash with IP pseudo-header. 1063 */ 1064 if (IP_V(ip) == 4) { 1065 CC_MD5_Update(&ctx, (char *)&ip->ip_src, sizeof(ip->ip_src)); 1066 CC_MD5_Update(&ctx, (char *)&ip->ip_dst, sizeof(ip->ip_dst)); 1067 CC_MD5_Update(&ctx, (char *)&zero_proto, sizeof(zero_proto)); 1068 CC_MD5_Update(&ctx, (char *)&ip->ip_p, sizeof(ip->ip_p)); 1069 tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4; 1070 tlen = htons(tlen); 1071 CC_MD5_Update(&ctx, (char *)&tlen, sizeof(tlen)); 1072#ifdef INET6 1073 } else if (IP_V(ip) == 6) { 1074 ip6 = (struct ip6_hdr *)ip; 1075 CC_MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); 1076 CC_MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); 1077 len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen)); 1078 CC_MD5_Update(&ctx, (char *)&len32, sizeof(len32)); 1079 nxt = 0; 1080 CC_MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); 1081 CC_MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); 1082 CC_MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); 1083 nxt = IPPROTO_TCP; 1084 CC_MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); 1085#endif 1086 } else { 1087#ifdef INET6 1088 printf("IP version not 4 or 6, "); 1089#else 1090 printf("IP version not 4, "); 1091#endif 1092 return (CANT_CHECK_SIGNATURE); 1093 } 1094 1095 /* 1096 * Step 2: Update MD5 hash with TCP header, excluding options. 1097 * The TCP checksum must be set to zero. 1098 */ 1099 savecsum = tp1.th_sum; 1100 tp1.th_sum = 0; 1101 CC_MD5_Update(&ctx, (char *)&tp1, sizeof(struct tcphdr)); 1102 tp1.th_sum = savecsum; 1103 /* 1104 * Step 3: Update MD5 hash with TCP segment data, if present. 1105 */ 1106 if (length > 0) 1107 CC_MD5_Update(&ctx, data, length); 1108 /* 1109 * Step 4: Update MD5 hash with shared secret. 1110 */ 1111 CC_MD5_Update(&ctx, sigsecret, strlen(sigsecret)); 1112 CC_MD5_Final(sig, &ctx); 1113 1114 if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0) 1115 return (SIGNATURE_VALID); 1116 else 1117 return (SIGNATURE_INVALID); 1118} 1119#endif /* HAVE_LIBCRYPTO */ 1120 1121/* 1122 * Local Variables: 1123 * c-style: whitesmith 1124 * c-basic-offset: 8 1125 * End: 1126 */ 1127