📄 print-tcp.c
字号:
/* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lintstatic const char rcsid[] = "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.81 2000/12/23 20:55:22 guy Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifndef WIN32
#include <sys/param.h>#include <sys/time.h>#include <rpc/rpc.h>#include <netinet/in.h>#else
#include <winsock2.h>
#include "bittypes.h"
#include "IP6_misc.h"
#include <time.h>
#include <rpc/rpc_cut.h>
#endif /* WIN32 */
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include "interface.h"#include "addrtoname.h"#include "extract.h"#include "tcp.h"#include "ip.h"#ifdef INET6#ifndef WIN32
#include "ip6.h"#endif /* WIN32 */
#endifstatic void print_tcp_rst_data(register const u_char *sp, u_int length);#define MAX_RST_DATA_LEN 30/* Compatibility */#ifndef TCPOPT_WSCALE#define TCPOPT_WSCALE 3 /* window scale factor (rfc1072) */#endif#ifndef TCPOPT_SACKOK#define TCPOPT_SACKOK 4 /* selective ack ok (rfc1072) */#endif#ifndef TCPOPT_SACK#define TCPOPT_SACK 5 /* selective ack (rfc1072) */#endif#ifndef TCPOPT_ECHO#define TCPOPT_ECHO 6 /* echo (rfc1072) */#endif#ifndef TCPOPT_ECHOREPLY#define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */#endif#ifndef TCPOPT_TIMESTAMP#define TCPOPT_TIMESTAMP 8 /* timestamps (rfc1323) */#endif#ifndef TCPOPT_CC#define TCPOPT_CC 11 /* T/TCP CC options (rfc1644) */#endif#ifndef TCPOPT_CCNEW#define TCPOPT_CCNEW 12 /* T/TCP CC options (rfc1644) */#endif#ifndef TCPOPT_CCECHO#define TCPOPT_CCECHO 13 /* T/TCP CC options (rfc1644) */#endif/* * Definitions required for ECN * for use if the OS running tcpdump does not have ECN */#ifndef TH_ECNECHO#define TH_ECNECHO 0x40 /* ECN Echo in tcp header */#endif#ifndef TH_CWR#define TH_CWR 0x80 /* ECN Cwnd Reduced in tcp header*/#endifstruct tha {#ifndef INET6 struct in_addr src; struct in_addr dst;#else struct in6_addr src; struct in6_addr dst;#endif /*INET6*/ u_int port;};struct tcp_seq_hash { struct tcp_seq_hash *nxt; struct tha addr; tcp_seq seq; tcp_seq ack;};#define TSEQ_HASHSIZE 919/* These tcp optinos do not have the size octet */#define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP)static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];#ifndef TELNET_PORT#define TELNET_PORT 23#endif#ifndef BGP_PORT#define BGP_PORT 179#endif#define NETBIOS_SSN_PORT 139#define BXXP_PORT 10288#ifndef NFS_PORT#define NFS_PORT 2049#endifstatic int tcp_cksum(register const struct ip *ip, register const struct tcphdr *tp, register int len){ int i, tlen; union phu { struct phdr { u_int32_t src; u_int32_t dst; u_char mbz; u_char proto; u_int16_t len; } ph; u_int16_t pa[6]; } phu; register const u_int16_t *sp; u_int32_t sum; tlen = ntohs(ip->ip_len) - ((const char *)tp-(const char*)ip); /* pseudo-header.. */ phu.ph.len = htons(tlen); phu.ph.mbz = 0; phu.ph.proto = IPPROTO_TCP; memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); sp = &phu.pa[0]; sum = sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]; sp = (const u_int16_t *)tp; for (i=0; i<(tlen&~1); i+= 2) sum += *sp++; if (tlen & 1) { sum += htons( (*(const u_int8_t *)sp) << 8); } while (sum > 0xffff) sum = (sum & 0xffff) + (sum >> 16); sum = ~sum & 0xffff; return (sum);}#ifdef INET6static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp, int len){ int i, tlen; register const u_int16_t *sp; u_int32_t sum; union { struct { struct in6_addr ph_src; struct in6_addr ph_dst; u_int32_t ph_len; u_int8_t ph_zero[3]; u_int8_t ph_nxt; } ph; u_int16_t pa[20]; } phu; tlen = ntohs(ip6->ip6_plen) + sizeof(struct ip6_hdr) - ((const char *)tp - (const char*)ip6); /* pseudo-header */ memset(&phu, 0, sizeof(phu)); phu.ph.ph_src = ip6->ip6_src; phu.ph.ph_dst = ip6->ip6_dst; phu.ph.ph_len = htonl(tlen); phu.ph.ph_nxt = IPPROTO_TCP; sum = 0; for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) sum += phu.pa[i]; sp = (const u_int16_t *)tp; for (i = 0; i < (tlen & ~1); i += 2) sum += *sp++; if (tlen & 1) sum += htons((*(const u_int8_t *)sp) << 8); while (sum > 0xffff) sum = (sum & 0xffff) + (sum >> 16); sum = ~sum & 0xffff; return (sum);}#endifvoidtcp_print(register const u_char *bp, register u_int length, register const u_char *bp2, int fragmented){ register const struct tcphdr *tp; register const struct ip *ip; register u_char flags; register int hlen; register char ch; u_int16_t sport, dport, win, urp; u_int32_t seq, ack, thseq, thack; int threv;#ifdef INET6 register const struct ip6_hdr *ip6;#endif tp = (struct tcphdr *)bp; ip = (struct ip *)bp2;#ifdef INET6 if (IP_V(ip) == 6) ip6 = (struct ip6_hdr *)bp2; else ip6 = NULL;#endif /*INET6*/ ch = '\0'; if (!TTEST(tp->th_dport)) { (void)printf("%s > %s: [|tcp]", ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst)); return; } sport = ntohs(tp->th_sport); dport = ntohs(tp->th_dport); hlen = TH_OFF(tp) * 4; /* * If data present and NFS port used, assume NFS. * Pass offset of data plus 4 bytes for RPC TCP msg length * to NFS print routines. */ if (!qflag) { if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend && dport == NFS_PORT) { nfsreq_print((u_char *)tp + hlen + 4, length-hlen, (u_char *)ip); return; } else if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend && sport == NFS_PORT) { nfsreply_print((u_char *)tp + hlen + 4,length-hlen, (u_char *)ip); return; } }#ifdef INET6 if (ip6) { if (ip6->ip6_nxt == IPPROTO_TCP) { (void)printf("%s.%s > %s.%s: ", ip6addr_string(&ip6->ip6_src), tcpport_string(sport), ip6addr_string(&ip6->ip6_dst), tcpport_string(dport)); } else { (void)printf("%s > %s: ", tcpport_string(sport), tcpport_string(dport)); } } else#endif /*INET6*/ { if (ip->ip_p == IPPROTO_TCP) { (void)printf("%s.%s > %s.%s: ", ipaddr_string(&ip->ip_src), tcpport_string(sport), ipaddr_string(&ip->ip_dst), tcpport_string(dport)); } else { (void)printf("%s > %s: ", tcpport_string(sport), tcpport_string(dport)); } } TCHECK(*tp); seq = (u_int32_t)ntohl(tp->th_seq); ack = (u_int32_t)ntohl(tp->th_ack); win = ntohs(tp->th_win); urp = ntohs(tp->th_urp); if (qflag) { (void)printf("tcp %d", length - TH_OFF(tp) * 4); return; } if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH| TH_ECNECHO|TH_CWR)) { if (flags & TH_SYN) putchar('S'); if (flags & TH_FIN) putchar('F'); if (flags & TH_RST) putchar('R'); if (flags & TH_PUSH) putchar('P'); if (flags & TH_CWR) putchar('W'); /* congestion _W_indow reduced (ECN) */ if (flags & TH_ECNECHO) putchar('E'); /* ecn _E_cho sent (ECN) */ } else putchar('.'); if (!Sflag && (flags & TH_ACK)) { register struct tcp_seq_hash *th; register int rev; struct tha tha; /* * Find (or record) the initial sequence numbers for * this conversation. (we pick an arbitrary * collating order so there's only one entry for
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -