1 /* $OpenBSD: print-tcp.c,v 1.32 2015/01/16 06:40:21 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 = (struct tcp_seq_hash *) 396 calloc(1, sizeof(*th)); 397 if (th->nxt == NULL) 398 error("tcp_print: calloc"); 399 } 400 th->addr = tha; 401 if (rev) 402 th->ack = seq, th->seq = ack - 1; 403 else 404 th->seq = seq, th->ack = ack - 1; 405 } else { 406 if (rev) 407 seq -= th->ack, ack -= th->seq; 408 else 409 seq -= th->seq, ack -= th->ack; 410 } 411 } 412 hlen = tp->th_off * 4; 413 if (hlen > length) { 414 (void)printf(" [bad hdr length]"); 415 return; 416 } 417 418 if (ip && ip->ip_v == 4 && vflag) { 419 if (TTEST2(tp->th_sport, length)) { 420 u_int16_t sum, tcp_sum; 421 sum = tcp_cksum(ip, tp, length); 422 if (sum != 0) { 423 tcp_sum = EXTRACT_16BITS(&tp->th_sum); 424 (void)printf(" [bad tcp cksum %x! -> %x]", tcp_sum, 425 in_cksum_shouldbe(tcp_sum, sum)); 426 } else 427 (void)printf(" [tcp sum ok]"); 428 } 429 } 430 #ifdef INET6 431 if (ip6 && ip6->ip6_plen && vflag) { 432 if (TTEST2(tp->th_sport, length)) { 433 u_int16_t sum, tcp_sum; 434 sum = tcp6_cksum(ip6, tp, length); 435 if (sum != 0) { 436 tcp_sum = EXTRACT_16BITS(&tp->th_sum); 437 (void)printf(" [bad tcp cksum %x! -> %x]", tcp_sum, 438 in_cksum_shouldbe(tcp_sum, sum)); 439 } else 440 (void)printf(" [tcp sum ok]"); 441 } 442 } 443 #endif 444 445 /* OS Fingerprint */ 446 if (oflag && (flags & (TH_SYN|TH_ACK)) == TH_SYN) { 447 struct pf_osfp_enlist *head = NULL; 448 struct pf_osfp_entry *fp; 449 unsigned long left; 450 left = (unsigned long)(snapend - (const u_char *)tp); 451 452 if (left >= hlen) 453 head = pf_osfp_fingerprint_hdr(ip, ip6, tp); 454 if (head) { 455 int prev = 0; 456 printf(" (src OS:"); 457 SLIST_FOREACH(fp, head, fp_entry) { 458 if (fp->fp_enflags & PF_OSFP_EXPANDED) 459 continue; 460 if (prev) 461 printf(","); 462 printf(" %s", fp->fp_class_nm); 463 if (fp->fp_version_nm[0]) 464 printf(" %s", fp->fp_version_nm); 465 if (fp->fp_subtype_nm[0]) 466 printf(" %s", fp->fp_subtype_nm); 467 prev = 1; 468 } 469 printf(")"); 470 } else { 471 if (left < hlen) 472 printf(" (src OS: short-pkt)"); 473 else 474 printf(" (src OS: unknown)"); 475 } 476 } 477 478 length -= hlen; 479 if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) 480 (void)printf(" %lu:%lu(%d)", (long) seq, (long) (seq + length), 481 length); 482 if (flags & TH_ACK) 483 (void)printf(" ack %u", ack); 484 485 (void)printf(" win %d", win); 486 487 if (flags & TH_URG) 488 (void)printf(" urg %d", urp); 489 /* 490 * Handle any options. 491 */ 492 if ((hlen -= sizeof(*tp)) > 0) { 493 register const u_char *cp; 494 register int i, opt, len, datalen; 495 496 cp = (const u_char *)tp + sizeof(*tp); 497 putchar(' '); 498 ch = '<'; 499 while (hlen > 0) { 500 putchar(ch); 501 TCHECK(*cp); 502 opt = *cp++; 503 if (ZEROLENOPT(opt)) 504 len = 1; 505 else { 506 TCHECK(*cp); 507 len = *cp++; /* total including type, len */ 508 if (len < 2 || len > hlen) 509 goto bad; 510 --hlen; /* account for length byte */ 511 } 512 --hlen; /* account for type byte */ 513 datalen = 0; 514 515 /* Bail if "l" bytes of data are not left or were not captured */ 516 #define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); } 517 518 switch (opt) { 519 520 case TCPOPT_MAXSEG: 521 (void)printf("mss"); 522 datalen = 2; 523 LENCHECK(datalen); 524 (void)printf(" %u", EXTRACT_16BITS(cp)); 525 526 break; 527 528 case TCPOPT_EOL: 529 (void)printf("eol"); 530 break; 531 532 case TCPOPT_NOP: 533 (void)printf("nop"); 534 break; 535 536 case TCPOPT_WSCALE: 537 (void)printf("wscale"); 538 datalen = 1; 539 LENCHECK(datalen); 540 (void)printf(" %u", *cp); 541 break; 542 543 case TCPOPT_SACKOK: 544 (void)printf("sackOK"); 545 if (len != 2) 546 (void)printf("[len %d]", len); 547 break; 548 549 case TCPOPT_SACK: 550 { 551 u_long s, e; 552 553 datalen = len - 2; 554 if ((datalen % TCPOLEN_SACK) != 0 || 555 !(flags & TH_ACK)) { 556 (void)printf("malformed sack "); 557 (void)printf("[len %d] ", datalen); 558 break; 559 } 560 printf("sack %d ", datalen/TCPOLEN_SACK); 561 for (i = 0; i < datalen; i += TCPOLEN_SACK) { 562 LENCHECK (i + TCPOLEN_SACK); 563 s = EXTRACT_32BITS(cp + i); 564 e = EXTRACT_32BITS(cp + i + 4); 565 if (!Sflag) { 566 if (rev) { 567 s -= th->seq; 568 e -= th->seq; 569 } else { 570 s -= th->ack; 571 e -= th->ack; 572 } 573 } 574 (void) printf("{%lu:%lu} ", s, e); 575 } 576 break; 577 } 578 case TCPOPT_ECHO: 579 (void)printf("echo"); 580 datalen = 4; 581 LENCHECK(datalen); 582 (void)printf(" %u", EXTRACT_32BITS(cp)); 583 break; 584 585 case TCPOPT_ECHOREPLY: 586 (void)printf("echoreply"); 587 datalen = 4; 588 LENCHECK(datalen); 589 (void)printf(" %u", EXTRACT_32BITS(cp)); 590 break; 591 592 case TCPOPT_TIMESTAMP: 593 (void)printf("timestamp"); 594 datalen = 8; 595 LENCHECK(4); 596 (void)printf(" %u", EXTRACT_32BITS(cp)); 597 LENCHECK(datalen); 598 (void)printf(" %u", EXTRACT_32BITS(cp + 4)); 599 break; 600 601 case TCPOPT_CC: 602 (void)printf("cc"); 603 datalen = 4; 604 LENCHECK(datalen); 605 (void)printf(" %u", EXTRACT_32BITS(cp)); 606 break; 607 608 case TCPOPT_CCNEW: 609 (void)printf("ccnew"); 610 datalen = 4; 611 LENCHECK(datalen); 612 (void)printf(" %u", EXTRACT_32BITS(cp)); 613 break; 614 615 case TCPOPT_CCECHO: 616 (void)printf("ccecho"); 617 datalen = 4; 618 LENCHECK(datalen); 619 (void)printf(" %u", EXTRACT_32BITS(cp)); 620 break; 621 622 case TCPOPT_SIGNATURE: 623 (void)printf("tcpmd5:"); 624 datalen = len - 2; 625 for (i = 0; i < datalen; ++i) { 626 LENCHECK(i+1); 627 (void)printf("%02x", cp[i]); 628 } 629 break; 630 631 default: 632 (void)printf("opt-%d:", opt); 633 datalen = len - 2; 634 for (i = 0; i < datalen; ++i) { 635 LENCHECK(i+1); 636 (void)printf("%02x", cp[i]); 637 } 638 break; 639 } 640 641 /* Account for data printed */ 642 cp += datalen; 643 hlen -= datalen; 644 645 /* Check specification against observed length */ 646 ++datalen; /* option octet */ 647 if (!ZEROLENOPT(opt)) 648 ++datalen; /* size octet */ 649 if (datalen != len) 650 (void)printf("[len %d]", len); 651 ch = ','; 652 if (opt == TCPOPT_EOL) 653 break; 654 } 655 putchar('>'); 656 } 657 658 if (length <= 0) 659 return; 660 661 /* 662 * Decode payload if necessary. 663 */ 664 bp += (tp->th_off * 4); 665 if (flags & TH_RST) { 666 if (vflag) 667 print_tcp_rst_data(bp, length); 668 } else { 669 if (sport == BGP_PORT || dport == BGP_PORT) 670 bgp_print(bp, length); 671 #if 0 672 else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT) 673 nbt_tcp_print(bp, length); 674 #endif 675 } 676 return; 677 bad: 678 fputs("[bad opt]", stdout); 679 if (ch != '\0') 680 putchar('>'); 681 return; 682 trunc: 683 fputs("[|tcp]", stdout); 684 if (ch != '\0') 685 putchar('>'); 686 } 687 688 689 /* 690 * RFC1122 says the following on data in RST segments: 691 * 692 * 4.2.2.12 RST Segment: RFC-793 Section 3.4 693 * 694 * A TCP SHOULD allow a received RST segment to include data. 695 * 696 * DISCUSSION 697 * It has been suggested that a RST segment could contain 698 * ASCII text that encoded and explained the cause of the 699 * RST. No standard has yet been established for such 700 * data. 701 * 702 */ 703 704 static void 705 print_tcp_rst_data(register const u_char *sp, u_int length) 706 { 707 int c; 708 709 if (TTEST2(*sp, length)) 710 printf(" [RST"); 711 else 712 printf(" [!RST"); 713 if (length > MAX_RST_DATA_LEN) { 714 length = MAX_RST_DATA_LEN; /* can use -X for longer */ 715 putchar('+'); /* indicate we truncate */ 716 } 717 putchar(' '); 718 while (length-- && sp < snapend) { 719 c = *sp++; 720 safeputchar(c); 721 } 722 putchar(']'); 723 } 724