📄 print-tcp.c
字号:
* both directions). */#ifdef INET6 memset(&tha, 0, sizeof(tha)); rev = 0; if (ip6) { if (sport > dport) { rev = 1; } else if (sport == dport) { int i; for (i = 0; i < 4; i++) { if (((u_int32_t *)(&ip6->ip6_src))[i] > ((u_int32_t *)(&ip6->ip6_dst))[i]) { rev = 1; break; } } } if (rev) { tha.src = ip6->ip6_dst; tha.dst = ip6->ip6_src; tha.port = dport << 16 | sport; } else { tha.dst = ip6->ip6_dst; tha.src = ip6->ip6_src; tha.port = sport << 16 | dport; } } else { if (sport > dport || (sport == dport && ip->ip_src.s_addr > ip->ip_dst.s_addr)) { rev = 1; } if (rev) { *(struct in_addr *)&tha.src = ip->ip_dst; *(struct in_addr *)&tha.dst = ip->ip_src; tha.port = dport << 16 | sport; } else { *(struct in_addr *)&tha.dst = ip->ip_dst; *(struct in_addr *)&tha.src = ip->ip_src; tha.port = sport << 16 | dport; } }#else if (sport < dport || (sport == dport && ip->ip_src.s_addr < ip->ip_dst.s_addr)) { tha.src = ip->ip_src, tha.dst = ip->ip_dst; tha.port = sport << 16 | dport; rev = 0; } else { tha.src = ip->ip_dst, tha.dst = ip->ip_src; tha.port = dport << 16 | sport; rev = 1; }#endif threv = rev; for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; th->nxt; th = th->nxt) if (!memcmp((char *)&tha, (char *)&th->addr, sizeof(th->addr))) break; if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash *) calloc(1, sizeof(*th)); if (th->nxt == NULL) error("tcp_print: calloc"); } th->addr = tha; if (rev) th->ack = seq, th->seq = ack - 1; else th->seq = seq, th->ack = ack - 1; } else { if (rev) seq -= th->ack, ack -= th->seq; else seq -= th->seq, ack -= th->ack; } thseq = th->seq; thack = th->ack; } else { /*fool gcc*/ thseq = thack = threv = 0; } if (hlen > length) { (void)printf(" [bad hdr length]"); return; } if (IP_V(ip) == 4 && vflag && !fragmented) { int sum; if (TTEST2(tp->th_sport, length)) { sum = tcp_cksum(ip, tp, length); if (sum != 0) (void)printf(" [bad tcp cksum %x!]", sum); else (void)printf(" [tcp sum ok]"); } }#ifdef INET6 if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !fragmented) { int sum; if (TTEST2(tp->th_sport, length)) { sum = tcp6_cksum(ip6, tp, length); if (sum != 0) (void)printf(" [bad tcp cksum %x!]", sum); else (void)printf(" [tcp sum ok]"); } }#endif length -= hlen; if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) (void)printf(" %u:%u(%d)", seq, seq + length, length); if (flags & TH_ACK) (void)printf(" ack %u", ack); (void)printf(" win %d", win); if (flags & TH_URG) (void)printf(" urg %d", urp); /* * Handle any options. */ if ((hlen -= sizeof(*tp)) > 0) { register const u_char *cp; register int i, opt, len, datalen; cp = (const u_char *)tp + sizeof(*tp); putchar(' '); ch = '<'; while (hlen > 0) { putchar(ch); TCHECK(*cp); opt = *cp++; if (ZEROLENOPT(opt)) len = 1; else { TCHECK(*cp); len = *cp++; /* total including type, len */ if (len < 2 || len > hlen) goto bad; --hlen; /* account for length byte */ } --hlen; /* account for type byte */ datalen = 0;/* Bail if "l" bytes of data are not left or were not captured */#define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); } switch (opt) { case TCPOPT_MAXSEG: (void)printf("mss"); datalen = 2; LENCHECK(datalen); (void)printf(" %u", EXTRACT_16BITS(cp)); break; case TCPOPT_EOL: (void)printf("eol"); break; case TCPOPT_NOP: (void)printf("nop"); break; case TCPOPT_WSCALE: (void)printf("wscale"); datalen = 1; LENCHECK(datalen); (void)printf(" %u", *cp); break; case TCPOPT_SACKOK: (void)printf("sackOK"); break; case TCPOPT_SACK: (void)printf("sack"); datalen = len - 2; if (datalen % 8 != 0) { (void)printf(" malformed sack "); } else { u_int32_t s, e; (void)printf(" sack %d ", datalen / 8); for (i = 0; i < datalen; i += 8) { LENCHECK(i + 4); s = EXTRACT_32BITS(cp + i); LENCHECK(i + 8); e = EXTRACT_32BITS(cp + i + 4); if (threv) { s -= thseq; e -= thseq; } else { s -= thack; e -= thack; } (void)printf("{%u:%u}", s, e); } (void)printf(" "); } break; case TCPOPT_ECHO: (void)printf("echo"); datalen = 4; LENCHECK(datalen); (void)printf(" %u", EXTRACT_32BITS(cp)); break; case TCPOPT_ECHOREPLY: (void)printf("echoreply"); datalen = 4; LENCHECK(datalen); (void)printf(" %u", EXTRACT_32BITS(cp)); break; case TCPOPT_TIMESTAMP: (void)printf("timestamp"); datalen = 8; LENCHECK(4); (void)printf(" %u", EXTRACT_32BITS(cp)); LENCHECK(datalen); (void)printf(" %u", EXTRACT_32BITS(cp + 4)); break; case TCPOPT_CC: (void)printf("cc"); datalen = 4; LENCHECK(datalen); (void)printf(" %u", EXTRACT_32BITS(cp)); break; case TCPOPT_CCNEW: (void)printf("ccnew"); datalen = 4; LENCHECK(datalen); (void)printf(" %u", EXTRACT_32BITS(cp)); break; case TCPOPT_CCECHO: (void)printf("ccecho"); datalen = 4; LENCHECK(datalen); (void)printf(" %u", EXTRACT_32BITS(cp)); break; default: (void)printf("opt-%d:", opt); datalen = len - 2; for (i = 0; i < datalen; ++i) { LENCHECK(i); (void)printf("%02x", cp[i]); } break; } /* Account for data printed */ cp += datalen; hlen -= datalen; /* Check specification against observed length */ ++datalen; /* option octet */ if (!ZEROLENOPT(opt)) ++datalen; /* size octet */ if (datalen != len) (void)printf("[len %d]", len); ch = ','; if (opt == TCPOPT_EOL) break; } putchar('>'); } if (length <= 0) return; /* * Decode payload if necessary. */ bp += TH_OFF(tp) * 4; if (flags & TH_RST) { if (vflag) print_tcp_rst_data(bp, length); } else { if (sport == TELNET_PORT || dport == TELNET_PORT) { if (!qflag && vflag) telnet_print(bp, length); } else if (sport == BGP_PORT || dport == BGP_PORT) bgp_print(bp, length); else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT) nbt_tcp_print(bp, length); else if (sport == BXXP_PORT || dport == BXXP_PORT) bxxp_print(bp, length); } return;bad: fputs("[bad opt]", stdout); if (ch != '\0') putchar('>'); return;trunc: fputs("[|tcp]", stdout); if (ch != '\0') putchar('>');}/* * RFC1122 says the following on data in RST segments: * * 4.2.2.12 RST Segment: RFC-793 Section 3.4 * * A TCP SHOULD allow a received RST segment to include data. * * DISCUSSION * It has been suggested that a RST segment could contain * ASCII text that encoded and explained the cause of the * RST. No standard has yet been established for such * data. * */static voidprint_tcp_rst_data(register const u_char *sp, u_int length){ int c; if (TTEST2(*sp, length)) printf(" [RST"); else printf(" [!RST"); if (length > MAX_RST_DATA_LEN) { length = MAX_RST_DATA_LEN; /* can use -X for longer */ putchar('+'); /* indicate we truncate */ } putchar(' '); while (length-- && sp <= snapend) { c = *sp++; if (isprint(c)) putchar(c); else putchar('.'); } putchar(']');}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -