1 /* $OpenBSD: print-tcp.c,v 1.31 2014/08/14 12:44:44 mpi 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 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #include <sys/param.h> 25 #include <sys/time.h> 26 #include <sys/socket.h> 27 28 #include <netinet/in.h> 29 #include <netinet/ip.h> 30 #include <netinet/ip_var.h> 31 #include <netinet/tcp.h> 32 #include <net/if.h> 33 #include <net/pfvar.h> 34 35 #include <rpc/rpc.h> 36 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <unistd.h> 41 42 #ifdef INET6 43 #include <netinet/ip6.h> 44 #endif 45 46 #include "interface.h" 47 #include "addrtoname.h" 48 #include "extract.h" 49 50 #include "nfs.h" 51 52 static void print_tcp_rst_data(register const u_char *sp, u_int length); 53 54 #define MAX_RST_DATA_LEN 30 55 56 /* Compatibility */ 57 #ifndef TCPOPT_WSCALE 58 #define TCPOPT_WSCALE 3 /* window scale factor (rfc1072) */ 59 #endif 60 #ifndef TCPOPT_SACKOK 61 #define TCPOPT_SACKOK 4 /* selective ack ok (rfc2018) */ 62 #endif 63 #ifndef TCPOPT_SACK 64 #define TCPOPT_SACK 5 /* selective ack (rfc2018) */ 65 #endif 66 #ifndef TCPOLEN_SACK 67 #define TCPOLEN_SACK 8 /* length of a SACK block */ 68 #endif 69 #ifndef TCPOPT_ECHO 70 #define TCPOPT_ECHO 6 /* echo (rfc1072) */ 71 #endif 72 #ifndef TCPOPT_ECHOREPLY 73 #define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */ 74 #endif 75 #ifndef TCPOPT_TIMESTAMP 76 #define TCPOPT_TIMESTAMP 8 /* timestamps (rfc1323) */ 77 #endif 78 #ifndef TCPOPT_CC 79 #define TCPOPT_CC 11 /* T/TCP CC options (rfc1644) */ 80 #endif 81 #ifndef TCPOPT_CCNEW 82 #define TCPOPT_CCNEW 12 /* T/TCP CC options (rfc1644) */ 83 #endif 84 #ifndef TCPOPT_CCECHO 85 #define TCPOPT_CCECHO 13 /* T/TCP CC options (rfc1644) */ 86 #endif 87 88 /* Definitions required for ECN 89 for use if the OS running tcpdump does not have ECN */ 90 #ifndef TH_ECNECHO 91 #define TH_ECNECHO 0x40 /* ECN Echo in tcp header */ 92 #endif 93 #ifndef TH_CWR 94 #define TH_CWR 0x80 /* ECN Cwnd Reduced in tcp header*/ 95 #endif 96 97 struct tha { 98 #ifndef INET6 99 struct in_addr src; 100 struct in_addr dst; 101 #else 102 struct in6_addr src; 103 struct in6_addr dst; 104 #endif /*INET6*/ 105 u_int port; 106 }; 107 108 struct tcp_seq_hash { 109 struct tcp_seq_hash *nxt; 110 struct tha addr; 111 tcp_seq seq; 112 tcp_seq ack; 113 }; 114 115 #define TSEQ_HASHSIZE 919 116 117 /* These tcp optinos do not have the size octet */ 118 #define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP) 119 120 static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE]; 121 122 #ifndef BGP_PORT 123 #define BGP_PORT 179 124 #endif 125 #define NETBIOS_SSN_PORT 139 126 127 static int tcp_cksum(const struct ip *ip, const struct tcphdr *tp, int len) 128 { 129 union phu { 130 struct phdr { 131 u_int32_t src; 132 u_int32_t dst; 133 u_char mbz; 134 u_char proto; 135 u_int16_t len; 136 } ph; 137 u_int16_t pa[6]; 138 } phu; 139 const u_int16_t *sp; 140 u_int32_t sum; 141 142 /* pseudo-header.. */ 143 phu.ph.len = htons((u_int16_t)len); 144 phu.ph.mbz = 0; 145 phu.ph.proto = IPPROTO_TCP; 146 memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); 147 memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); 148 149 sp = &phu.pa[0]; 150 sum = sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]; 151 152 return in_cksum((u_short *)tp, len, sum); 153 } 154 155 #ifdef INET6 156 static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp, 157 u_int len) 158 { 159 union { 160 struct { 161 struct in6_addr ph_src; 162 struct in6_addr ph_dst; 163 u_int32_t ph_len; 164 u_int8_t ph_zero[3]; 165 u_int8_t ph_nxt; 166 } ph; 167 u_int16_t pa[20]; 168 } phu; 169 size_t i; 170 u_int32_t sum = 0; 171 172 /* pseudo-header */ 173 memset(&phu, 0, sizeof(phu)); 174 phu.ph.ph_src = ip6->ip6_src; 175 phu.ph.ph_dst = ip6->ip6_dst; 176 phu.ph.ph_len = htonl(len); 177 phu.ph.ph_nxt = IPPROTO_TCP; 178 179 for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) 180 sum += phu.pa[i]; 181 182 return in_cksum((u_short *)tp, len, sum); 183 } 184 #endif 185 186 187 void 188 tcp_print(register const u_char *bp, register u_int length, 189 register const u_char *bp2) 190 { 191 register const struct tcphdr *tp; 192 register const struct ip *ip; 193 register u_char flags; 194 register int hlen; 195 register char ch; 196 register struct tcp_seq_hash *th = NULL; 197 register int rev = 0; 198 u_int16_t sport, dport, win, urp; 199 tcp_seq seq, ack; 200 #ifdef INET6 201 register const struct ip6_hdr *ip6; 202 #endif 203 204 tp = (struct tcphdr *)bp; 205 switch (((struct ip *)bp2)->ip_v) { 206 case 4: 207 ip = (struct ip *)bp2; 208 #ifdef INET6 209 ip6 = NULL; 210 #endif 211 break; 212 #ifdef INET6 213 case 6: 214 ip = NULL; 215 ip6 = (struct ip6_hdr *)bp2; 216 break; 217 #endif 218 default: 219 (void)printf("invalid ip version"); 220 return; 221 } 222 223 ch = '\0'; 224 if (length < sizeof(*tp)) { 225 (void)printf("truncated-tcp %d", length); 226 return; 227 } 228 229 if (!TTEST(tp->th_dport)) { 230 #ifdef INET6 231 if (ip6) { 232 (void)printf("%s > %s: [|tcp]", 233 ip6addr_string(&ip6->ip6_src), 234 ip6addr_string(&ip6->ip6_dst)); 235 } else 236 #endif /*INET6*/ 237 { 238 (void)printf("%s > %s: [|tcp]", 239 ipaddr_string(&ip->ip_src), 240 ipaddr_string(&ip->ip_dst)); 241 } 242 return; 243 } 244 245 sport = ntohs(tp->th_sport); 246 dport = ntohs(tp->th_dport); 247 248 #ifdef INET6 249 if (ip6) { 250 if (ip6->ip6_nxt == IPPROTO_TCP) { 251 (void)printf("%s.%s > %s.%s: ", 252 ip6addr_string(&ip6->ip6_src), 253 tcpport_string(sport), 254 ip6addr_string(&ip6->ip6_dst), 255 tcpport_string(dport)); 256 } else { 257 (void)printf("%s > %s: ", 258 tcpport_string(sport), tcpport_string(dport)); 259 } 260 } else 261 #endif /*INET6*/ 262 { 263 if (ip->ip_p == IPPROTO_TCP) { 264 (void)printf("%s.%s > %s.%s: ", 265 ipaddr_string(&ip->ip_src), 266 tcpport_string(sport), 267 ipaddr_string(&ip->ip_dst), 268 tcpport_string(dport)); 269 } else { 270 (void)printf("%s > %s: ", 271 tcpport_string(sport), tcpport_string(dport)); 272 } 273 } 274 275 if (!qflag && TTEST(tp->th_seq) && !TTEST(tp->th_ack)) 276 (void)printf("%u ", ntohl(tp->th_seq)); 277 278 TCHECK(*tp); 279 seq = ntohl(tp->th_seq); 280 ack = ntohl(tp->th_ack); 281 win = ntohs(tp->th_win); 282 urp = ntohs(tp->th_urp); 283 hlen = tp->th_off * 4; 284 285 if (qflag) { 286 (void)printf("tcp %d", length - tp->th_off * 4); 287 return; 288 } else if (packettype != PT_TCP) { 289 290 /* 291 * If data present and NFS port used, assume NFS. 292 * Pass offset of data plus 4 bytes for RPC TCP msg length 293 * to NFS print routines. 294 */ 295 u_int len = length - hlen; 296 if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend && 297 dport == NFS_PORT) { 298 nfsreq_print((u_char *)tp + hlen + 4, len, bp2); 299 return; 300 } else if ((u_char *)tp + 4 + 301 sizeof(struct rpc_msg) <= snapend && sport == NFS_PORT) { 302 nfsreply_print((u_char *)tp + hlen + 4, len, bp2); 303 return; 304 } 305 } 306 if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH| 307 TH_ECNECHO|TH_CWR)) { 308 if (flags & TH_SYN) 309 putchar('S'); 310 if (flags & TH_FIN) 311 putchar('F'); 312 if (flags & TH_RST) 313 putchar('R'); 314 if (flags & TH_PUSH) 315 putchar('P'); 316 if (flags & TH_CWR) 317 putchar('W'); /* congestion _W_indow reduced (ECN) */ 318 if (flags & TH_ECNECHO) 319 putchar('E'); /* ecn _E_cho sent (ECN) */ 320 } else 321 putchar('.'); 322 323 if (!Sflag && (flags & TH_ACK)) { 324 struct tha tha; 325 /* 326 * Find (or record) the initial sequence numbers for 327 * this conversation. (we pick an arbitrary 328 * collating order so there's only one entry for 329 * both directions). 330 */ 331 #ifdef INET6 332 bzero(&tha, sizeof(tha)); 333 rev = 0; 334 if (ip6) { 335 if (sport > dport) { 336 rev = 1; 337 } else if (sport == dport) { 338 int i; 339 340 for (i = 0; i < 4; i++) { 341 if (((u_int32_t *)(&ip6->ip6_src))[i] > 342 ((u_int32_t *)(&ip6->ip6_dst))[i]) { 343 rev = 1; 344 break; 345 } 346 } 347 } 348 if (rev) { 349 tha.src = ip6->ip6_dst; 350 tha.dst = ip6->ip6_src; 351 tha.port = dport << 16 | sport; 352 } else { 353 tha.dst = ip6->ip6_dst; 354 tha.src = ip6->ip6_src; 355 tha.port = sport << 16 | dport; 356 } 357 } else { 358 if (sport > dport || 359 (sport == dport && 360 ip->ip_src.s_addr > ip->ip_dst.s_addr)) { 361 rev = 1; 362 } 363 if (rev) { 364 *(struct in_addr *)&tha.src = ip->ip_dst; 365 *(struct in_addr *)&tha.dst = ip->ip_src; 366 tha.port = dport << 16 | sport; 367 } else { 368 *(struct in_addr *)&tha.dst = ip->ip_dst; 369 *(struct in_addr *)&tha.src = ip->ip_src; 370 tha.port = sport << 16 | dport; 371 } 372 } 373 #else 374 if (sport < dport || 375 (sport == dport && 376 ip->ip_src.s_addr < ip->ip_dst.s_addr)) { 377 tha.src = ip->ip_src, tha.dst = ip->ip_dst; 378 tha.port = sport << 16 | dport; 379 rev = 0; 380 } else { 381 tha.src = ip->ip_dst, tha.dst = ip->ip_src; 382 tha.port = dport << 16 | sport; 383 rev = 1; 384 } 385 #endif 386 387 for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; 388 th->nxt; th = th->nxt) 389 if (!memcmp((char *)&tha, (char *)&th->addr, 390 sizeof(th->addr))) 391 break; 392 393 if (!th->nxt || flags & TH_SYN) { 394 /* didn't find it or new conversation */ 395 if (th->nxt == NULL) { 396 th->nxt = (struct tcp_seq_hash *) 397 calloc(1, sizeof(*th)); 398 if (th->nxt == NULL) 399 error("tcp_print: calloc"); 400 } 401 th->addr = tha; 402 if (rev) 403 th->ack = seq, th->seq = ack - 1; 404 else 405 th->seq = seq, th->ack = ack - 1; 406 } else { 407 if (rev) 408 seq -= th->ack, ack -= th->seq; 409 else 410 seq -= th->seq, ack -= th->ack; 411 } 412 } 413 hlen = tp->th_off * 4; 414 if (hlen > length) { 415 (void)printf(" [bad hdr length]"); 416 return; 417 } 418 419 if (ip && ip->ip_v == 4 && vflag) { 420 if (TTEST2(tp->th_sport, length)) { 421 u_int16_t sum, tcp_sum; 422 sum = tcp_cksum(ip, tp, length); 423 if (sum != 0) { 424 tcp_sum = EXTRACT_16BITS(&tp->th_sum); 425 (void)printf(" [bad tcp cksum %x! -> %x]", tcp_sum, 426 in_cksum_shouldbe(tcp_sum, sum)); 427 } else 428 (void)printf(" [tcp sum ok]"); 429 } 430 } 431 #ifdef INET6 432 if (ip6 && ip6->ip6_plen && vflag) { 433 if (TTEST2(tp->th_sport, length)) { 434 u_int16_t sum, tcp_sum; 435 sum = tcp6_cksum(ip6, tp, length); 436 if (sum != 0) { 437 tcp_sum = EXTRACT_16BITS(&tp->th_sum); 438 (void)printf(" [bad tcp cksum %x! -> %x]", tcp_sum, 439 in_cksum_shouldbe(tcp_sum, sum)); 440 } else 441 (void)printf(" [tcp sum ok]"); 442 } 443 } 444 #endif 445 446 /* OS Fingerprint */ 447 if (oflag && (flags & (TH_SYN|TH_ACK)) == TH_SYN) { 448 struct pf_osfp_enlist *head = NULL; 449 struct pf_osfp_entry *fp; 450 unsigned long left; 451 left = (unsigned long)(snapend - (const u_char *)tp); 452 453 if (left >= hlen) 454 head = pf_osfp_fingerprint_hdr(ip, ip6, tp); 455 if (head) { 456 int prev = 0; 457 printf(" (src OS:"); 458 SLIST_FOREACH(fp, head, fp_entry) { 459 if (fp->fp_enflags & PF_OSFP_EXPANDED) 460 continue; 461 if (prev) 462 printf(","); 463 printf(" %s", fp->fp_class_nm); 464 if (fp->fp_version_nm[0]) 465 printf(" %s", fp->fp_version_nm); 466 if (fp->fp_subtype_nm[0]) 467 printf(" %s", fp->fp_subtype_nm); 468 prev = 1; 469 } 470 printf(")"); 471 } else { 472 if (left < hlen) 473 printf(" (src OS: short-pkt)"); 474 else 475 printf(" (src OS: unknown)"); 476 } 477 } 478 479 length -= hlen; 480 if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) 481 (void)printf(" %lu:%lu(%d)", (long) seq, (long) (seq + length), 482 length); 483 if (flags & TH_ACK) 484 (void)printf(" ack %u", ack); 485 486 (void)printf(" win %d", win); 487 488 if (flags & TH_URG) 489 (void)printf(" urg %d", urp); 490 /* 491 * Handle any options. 492 */ 493 if ((hlen -= sizeof(*tp)) > 0) { 494 register const u_char *cp; 495 register int i, opt, len, datalen; 496 497 cp = (const u_char *)tp + sizeof(*tp); 498 putchar(' '); 499 ch = '<'; 500 while (hlen > 0) { 501 putchar(ch); 502 TCHECK(*cp); 503 opt = *cp++; 504 if (ZEROLENOPT(opt)) 505 len = 1; 506 else { 507 TCHECK(*cp); 508 len = *cp++; /* total including type, len */ 509 if (len < 2 || len > hlen) 510 goto bad; 511 --hlen; /* account for length byte */ 512 } 513 --hlen; /* account for type byte */ 514 datalen = 0; 515 516 /* Bail if "l" bytes of data are not left or were not captured */ 517 #define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); } 518 519 switch (opt) { 520 521 case TCPOPT_MAXSEG: 522 (void)printf("mss"); 523 datalen = 2; 524 LENCHECK(datalen); 525 (void)printf(" %u", EXTRACT_16BITS(cp)); 526 527 break; 528 529 case TCPOPT_EOL: 530 (void)printf("eol"); 531 break; 532 533 case TCPOPT_NOP: 534 (void)printf("nop"); 535 break; 536 537 case TCPOPT_WSCALE: 538 (void)printf("wscale"); 539 datalen = 1; 540 LENCHECK(datalen); 541 (void)printf(" %u", *cp); 542 break; 543 544 case TCPOPT_SACKOK: 545 (void)printf("sackOK"); 546 if (len != 2) 547 (void)printf("[len %d]", len); 548 break; 549 550 case TCPOPT_SACK: 551 { 552 u_long s, e; 553 554 datalen = len - 2; 555 if ((datalen % TCPOLEN_SACK) != 0 || 556 !(flags & TH_ACK)) { 557 (void)printf("malformed sack "); 558 (void)printf("[len %d] ", datalen); 559 break; 560 } 561 printf("sack %d ", datalen/TCPOLEN_SACK); 562 for (i = 0; i < datalen; i += TCPOLEN_SACK) { 563 LENCHECK (i + TCPOLEN_SACK); 564 s = EXTRACT_32BITS(cp + i); 565 e = EXTRACT_32BITS(cp + i + 4); 566 if (!Sflag) { 567 if (rev) { 568 s -= th->seq; 569 e -= th->seq; 570 } else { 571 s -= th->ack; 572 e -= th->ack; 573 } 574 } 575 (void) printf("{%lu:%lu} ", s, e); 576 } 577 break; 578 } 579 case TCPOPT_ECHO: 580 (void)printf("echo"); 581 datalen = 4; 582 LENCHECK(datalen); 583 (void)printf(" %u", EXTRACT_32BITS(cp)); 584 break; 585 586 case TCPOPT_ECHOREPLY: 587 (void)printf("echoreply"); 588 datalen = 4; 589 LENCHECK(datalen); 590 (void)printf(" %u", EXTRACT_32BITS(cp)); 591 break; 592 593 case TCPOPT_TIMESTAMP: 594 (void)printf("timestamp"); 595 datalen = 8; 596 LENCHECK(4); 597 (void)printf(" %u", EXTRACT_32BITS(cp)); 598 LENCHECK(datalen); 599 (void)printf(" %u", EXTRACT_32BITS(cp + 4)); 600 break; 601 602 case TCPOPT_CC: 603 (void)printf("cc"); 604 datalen = 4; 605 LENCHECK(datalen); 606 (void)printf(" %u", EXTRACT_32BITS(cp)); 607 break; 608 609 case TCPOPT_CCNEW: 610 (void)printf("ccnew"); 611 datalen = 4; 612 LENCHECK(datalen); 613 (void)printf(" %u", EXTRACT_32BITS(cp)); 614 break; 615 616 case TCPOPT_CCECHO: 617 (void)printf("ccecho"); 618 datalen = 4; 619 LENCHECK(datalen); 620 (void)printf(" %u", EXTRACT_32BITS(cp)); 621 break; 622 623 case TCPOPT_SIGNATURE: 624 (void)printf("tcpmd5:"); 625 datalen = len - 2; 626 for (i = 0; i < datalen; ++i) { 627 LENCHECK(i+1); 628 (void)printf("%02x", cp[i]); 629 } 630 break; 631 632 default: 633 (void)printf("opt-%d:", opt); 634 datalen = len - 2; 635 for (i = 0; i < datalen; ++i) { 636 LENCHECK(i+1); 637 (void)printf("%02x", cp[i]); 638 } 639 break; 640 } 641 642 /* Account for data printed */ 643 cp += datalen; 644 hlen -= datalen; 645 646 /* Check specification against observed length */ 647 ++datalen; /* option octet */ 648 if (!ZEROLENOPT(opt)) 649 ++datalen; /* size octet */ 650 if (datalen != len) 651 (void)printf("[len %d]", len); 652 ch = ','; 653 if (opt == TCPOPT_EOL) 654 break; 655 } 656 putchar('>'); 657 } 658 659 if (length <= 0) 660 return; 661 662 /* 663 * Decode payload if necessary. 664 */ 665 bp += (tp->th_off * 4); 666 if (flags & TH_RST) { 667 if (vflag) 668 print_tcp_rst_data(bp, length); 669 } else { 670 if (sport == BGP_PORT || dport == BGP_PORT) 671 bgp_print(bp, length); 672 #if 0 673 else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT) 674 nbt_tcp_print(bp, length); 675 #endif 676 } 677 return; 678 bad: 679 fputs("[bad opt]", stdout); 680 if (ch != '\0') 681 putchar('>'); 682 return; 683 trunc: 684 fputs("[|tcp]", stdout); 685 if (ch != '\0') 686 putchar('>'); 687 } 688 689 690 /* 691 * RFC1122 says the following on data in RST segments: 692 * 693 * 4.2.2.12 RST Segment: RFC-793 Section 3.4 694 * 695 * A TCP SHOULD allow a received RST segment to include data. 696 * 697 * DISCUSSION 698 * It has been suggested that a RST segment could contain 699 * ASCII text that encoded and explained the cause of the 700 * RST. No standard has yet been established for such 701 * data. 702 * 703 */ 704 705 static void 706 print_tcp_rst_data(register const u_char *sp, u_int length) 707 { 708 int c; 709 710 if (TTEST2(*sp, length)) 711 printf(" [RST"); 712 else 713 printf(" [!RST"); 714 if (length > MAX_RST_DATA_LEN) { 715 length = MAX_RST_DATA_LEN; /* can use -X for longer */ 716 putchar('+'); /* indicate we truncate */ 717 } 718 putchar(' '); 719 while (length-- && sp < snapend) { 720 c = *sp++; 721 safeputchar(c); 722 } 723 putchar(']'); 724 } 725