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