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