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