重读TCP
TCP 的数据流
TCP的数据流大致可以分为两类,交互数据流与成块的数据流。交互数据流就是发送控制命令的数据流,比如relogin,telnet,ftp命令等等;成块数据流是用来发送数据的包,网络上大部分的TCP包都是这种包。
很明显,TCP在传输这两种类型的包时的效率是不一样的,因此为了提高TCP的传输效率,应该对这两种类型的包采用不同的算法。
总之,TCP的传输原则是尽量减少小分组传输的数量。
TCP的交互式数据流
Ø 经受时延的确认技术
TCP的交互式数据流通常使用“经过时延的确认”技术。通常Server在接收到从Client发送过来的数据时,并不马上发送ACK,而是等一小段时间,看看本机是否有数据要反馈给Client,如果有,就将数据包含在此ACK包中,以前发送给Client。一般情况下这个时延为200ms。需要注意的时这个200ms的定时器时相对于内核的时钟滴答的,也就是jeffs的。加入一个数据分组到达后,此定时器已经pass了100ms,那么再过100ms ACK才会被发送,如果在这100ms内有数据要反馈,则在100ms后ACK会和数据一起发送。
Ø Nagle算法分析。
Nagle算法主要用来预防小分组的产生。在广域网上,大量TCP小分组极有可能造成网络的拥塞。
Nagle时针对每一个TCP连接的。它要求一个TCP连接上最多只能有一个未被确认的小分组。在改分组的确认到达之前不能发送其他小分组。TCP会搜集这些小的分组,然后在之前小分组的确认到达后将刚才搜集的小分组合并发送出去。
有时候我们必须要关闭Nagle算法,特别是在一些对时延要求较高的交互式操作环境中,所有的小分组必须尽快发送出去。
我们可以通过编程取消Nagle算法,利用TCP_NODELAY选项来关闭Nagle算法。
TCP成块数据流
和TCP成块数据流相关的东西有很多,比如流量控制,紧急数据传输,数据窗口大小调整等等。
Ø 正常数据流
TCP通常不会对每个到达的数据分段进行确认操作,通常一个ACK报文可以确认多个成块数据段报文,通常情况下是两个成块数据报文段需要一个ACK报文确认。通常是由下面的原有造成的:当收到一个报文后,此TCP连接被标识未一个未完成的时延确认,当再次收到一个数据报文后,此连接有两个未确认的报文段,TCP马上发送一个ACK,当第三个数据报文到达后,第四个报文到达前,通常此TCP连接已经经过了200ms延时,因此一个ACK被发送,这样的循环周而复始,从而出现了一个ACK确认两个数据报文的情况。当然,ACK的产生很大程度上和其接收数据报文段的时间紧密相关,也就是和Client段发送数据的频率相关,和网络拥塞程度相关,和Client与Server两端的处理能力相关,总是是一个多因素决定的结果。
Ø TCP的滑动窗口协议
TCP使用滑动窗口协议来进行流量控制。特别需要注意的是,滑动窗口是一个抽象的概念,它是针对每一个TCP连接的,而且是有方向的,一个TCP连接应该有两个滑动窗口,每个数据传输方向上有一个,而不是针对连接的每一端的。
窗口左边沿向右边滑动叫做窗口合拢,表示发送方发送了数据或者接收到了确认;窗口右边沿向右边滑动叫做窗口的张开,表示数据已经被用户空间进程接收并且释放了缓存;窗口左边沿向左移动则表明此ACK是重复ACK,应该丢弃;窗口右边沿向左移动叫做窗口收缩,一般不会有人这样做。
当左边沿和右边沿重合的时候表明窗口大小是0,此时发送方不应该在发送数据了,因为接收方的接收缓冲区已满,用户进程还没以接收。当用户进程接收完成后,接收方应该发送一个ACK,表明此时的接收窗口已经恢复,此ACK的序号同前一个win为0的ACK相同。
同样,在实现中,发送方不必发送一个全窗口的数据,但是它当然可以这样做。ACK总是将窗口向右边滑动,窗口的大小可以减小,接收方在发送ACK之前不必等待窗口被填满(即变为0),很多实现是收到两个数据报文段后立刻发送ACK。
Ø TCP窗口大小的调整
TCP窗口的大小通常由接收端来确认,也就是在TCP建立连接的第二个SYN+ACK报文的Win字段来确认。
当然,程序可以随时改变这个窗口(缓存)的大小。默认的窗口大小是4096字节,但是对于文件传输来说这并不是一个理想的数字,如果程序的主要目的是传输文件,那么最好将这个缓存设置到最大,但是这样可能会造成发送端连续发送多个数据报文段后,接收方才反馈一个ACK的情况,当然,这也没有什么不可以的,只要不超时,就不算错。
Ø TCP的PUSH包
PUSH是TCP报头中的一个标志位,发送方在发送数据的时候可以设置这个标志位。该标志通知接收方将接收到的数据全部提交给接收进程。这里所说的数据包括与此PUSH包一起传输的数据以及之前就为该进程传输过来的数据。
当Server端收到这些数据后,它需要立刻将这些数据提交给应用层进程,而不再等待是否还有额外的数据到达。
那么应该合适设置PUSH标志呢?实际上现在的TCP协议栈基本上都可以自行处理这个问题,而不是交给应用层处理。如果待发送的数据会清空发送缓存,那么栈就会自动为此包设置PUSH标志,源于BSD的栈一般都会这么做,而且,BSD TCP STACK也从来不会将收到的数据推迟提交给应用程序,因此,在BSD TCP STACK中,PUSH位是被忽略的,因为根本就没有用。
Ø TCP的慢启动(拥塞窗口)
TCP在局域网环境中的效率是很高的,但是到了广域网的环境中情况就不同了,在发送方和接收方之间可能存在多个Router以及一些速率比较慢的链路,而且一些中继路由器必须缓存分组,还可能分片,所以在广域网的环境中,TCP的效率可能出现问题。
为了解决这个问题,现在的TCP栈都支持“慢启动”算法,即拥塞窗口控制算法。该算法通过观察到新分组进入网络的速率与另一端返回ACK的速率相同而工作。其实,拥塞窗口是发送方使用的一种流量控制算法。
慢启动为TCP的发送方增加了一个拥塞窗口,当连接建立时,拥塞窗口被初始化为一个报文段大小,每收到一个ACK,拥塞窗口就会增加一个报文段,发送方取拥塞窗口与通过窗口的最小值作为发送的上限。
Ø TCP成块数据吞吐量
TCP窗口大小,窗口流量控制,慢启动对TCP的成块数据传输综合作用,可能对TCP的数据传输有意想不到的影响。
RTT(Round-Trip Time):往返时间。是指一个报文段从发出去到收到此报文段的ACK所经历的时间。通常一个报文段的RTT与传播时延和发送时延两个因素相关。
在发送的过程中有可能发生这样的情况,即TCP两端的传输“管道”被填满,即整个管道上都有数据在跑,此时不管拥塞窗口和通告窗口是多少,管道上都不能在容纳更多的数据了。此时每当接收方从网络上移去一个报文段,发送方就发送一个,但是管道上的ACK总是固定的,这种情况就是连接的理想稳定状态。
一般情况下带宽*时延就是一条线路的容量,因此吧RTT减小可以增加一条线路的容量,注意RTT加大的意思时传输时间减小!
当 数据由一个大的管道向一个小的管道传输时,就有可能发生拥塞,例如,当若干输入流到达一个路由器,而此路由器的输出带宽小于这些输入流的带宽总和时,就会 发生拥塞。这种情况普遍见于局域网与广域网的接口处。如果发送方处于局域网,而且不使用慢启动,使用局域网的带宽尽快的发送报文,那么返回的ACK之间的间隔与最慢的广域网链路一致。而且,由于路由器转发包速度慢,所以路由器就有可能主动丢失分组包。
Ø TCP的紧急方式
TCP提供了一种“紧急方式”的数据传输方式,TCP的一端可以告诉另一端有些具有某种方式的紧急数据被放在了普通的数据流中,接收方可以自行选择处理。紧急方式客厅通过设置TCP的URG标识位与紧急指针的偏移量来设置。这个紧急指针指向紧急数据的最后一个字节(也有可能是最后一个字节的下一个字节)。
现在有许多实现将紧急方式叫做“带外数据”,其实这是不正确的。
目前紧急指针被用来禁止停止FTP的数据传输。不过总的来说,用的不多。
对于数据传输来说,如果用紧急数据来传输大量数据,这种方法显然是不可取的,再建立一个TCP连接不是更简单有效吗?
WinDump使用提示
基本用法:
windump [ -aBdDeflnNOpqRStvxX ] [ -c count ] [ -F file ] [
-i interface ] [ -m module ] [ -r file ] [ -s snaplen ] [ -T type ] [
-w file ] [ -E algo:secret ] [ expression ]
主要参数有选项和表达式两类。下面说明几个必要的选项和表达式:
-i 指定要监听的网络接口,可以使用windump -D 列出当前系统中所有的网络设备接口,不指定的话是设备列表中找得的第一个。例如:
./WinDump.exe -D
1."Device"NPF_GenericNdisWanAdapter (Generic NdisWan adapter)
2."Device"NPF_{6AA36CF4-E4FD-49BF-93E5-DC29AB8A3AA5} (SiS NIC SISNIC (Microsoft' s Packet Scheduler) )
则
./WinDump.exe
./WinDump.exe -i 1
./WinDump.exe -i ""Device""NPF_GenericNdisWanAdapter
都是监听第一个网络接口设备Generic NdisWan adapter。
./WinDump.exe -i 2
./WinDump.exe -i ""Device""NPF_{6AA36CF4-E4FD-49BF-93E5-DC29AB8A3AA5}
都是监听第二个网络接口设备SiS NIC SISNIC (Microsoft' s Packet Scheduler)。
如果不指定表达式,所有通过指定接口的packet都输出,否则只把表达式expression为真的输出。
最基本的表达式是这样的:
[proto] [dir] [type] [id]
proto 协议,可以是ether, fddi, tr, ip, ip6, arp, rarp, decnet, tcp , udp中任一个或它们的表达式组合,如果不指定,所有和后面的type一致的都考虑在内。
dir packet传输的方向,可以是src, dst中的任一个或它们的表达式组合。不指定的话,相当于src or dst 。
type 指定后面的id是网络地址、主机地址还是端口号,可以是host, net ,port中任一个,如果不指定,默认为host。
id 就是希望监听的网络或主机或端口地址。
一个覆盖所有元素的表达式如下:
ether src host 00:11:D8:6A:33:22
./WinDump.exe -i 2 ether src host 00:11:D8:6A:33:22
监听所有从本地网卡向外发的packet,其中00:11:D8:6A:33:22是本地网卡的mac地址。
./WinDump.exe -i 2 udp dst port 135
监听所有发给本地135 udp端口的packet。
更复杂的表达式是以上基本的表达式的逻辑组合,可用于组合的关键字有and, or, not,同时构成基本表达式的四类运算都是可选,不是必须的,比如:“host foo and not port ftp and not port ftp-data”,其中foo代表主机名,其他都是关键字。
此外,有gateway, broadcast , multicast , mask , protochain , proto , less , greater 四个关键字和一些算术表达式、逻辑符合等。
gateway foo 其中,foo是主机名,如果某个packet以foo为gateway,表达式为真,也就是该packet的ether源或目的地址是foo,而ip源和目的地址都不是foo。
broadcast,multicast 跟在ether或者ip、ip6后面表示某个packet是广播包、多播包,比如“ether broadcast”,“ip multicast”。
mask 和net一起说明网络地址,例如“net 192.168.0 mask 255.255.255.0”。
protochain 跟在ip、ip6后面说明更上层的协议字,比如“ip protochain 6”。
proto
跟在ether或者ip、ip6后面表示更上层的协议,跟在“ether proto”之后的可以是ip, ip6, arp, rarp,
atalk, aarp, decnet, sca, lat, mopdl, moprc, iso,跟在“ip proto”或“ip6
proto”之后的可以是icmp, icmp6, igmp, igrp, pim, ah, esp, udp,
tcp,注意对于有些本身就是关键字的要加“"”转义,比如“ether proto "ip”。
其他表达式是这样的格式:
expr relop expr
其中,relop 可以是 >, <, >=, <=, =, !=, 中任一个,expr是由C语言规范描述的整数常量、二进制运算符(+, -, *, /, &, |)、len(取长度的关键字)、包数据构成,包数据这样访问:
proto
[ offset : size ] proto是ether, fddi, tr, ip, arp, rarp, tcp, udp, icmp
,
ip6中任一个,表示要取的数据是该协议头范围内的,相对于PDU开始处的偏移由offset指定,size可选、说明要取数据的字节数,可以是1~4,
默认是1。例如,
“ether[0] & 1 != 0”匹配所有multicast数据包,因为01:00:5e:00:00:00到 01:00:5e:7f:ff:ff都是多播地址。
“ip[0] & 0xf != 5”匹配所有带选项的ip包,根据ip协议,“ip[0] & 0xf”取到的是IP协议头长度,而不带选项的ip协议头长度刚好是5。
“ip[6:2] & 0x1fff = 0”,“ip[6:2] & 0x1fff”取到该ip包的Fragment Offset,所以匹配所有不分段的ip包或所有分段ip包中的第一段。
其它操作法有!(相当于not )、&&(相当于and )、||(相当于or)。
使用举例:
./WinDump.exe -i 2 not arp and ether host not 02:01:00:00:00:00
抓取所有非arp协议、且源或目的主机的ether地址都不是02:01:00:00:00:00的packet。
windump.exe -i 2 -w cap ether host 00:11:D8:6A:33:22
抓取所有源或目的主机的ether地址是00:11:D8:6A:33:22(本地网卡的mac地址)的packet,但不知道屏幕上输出,而是把所有抓获的raw packet写入文件cap中。
windump.exe -r cap
读取刚才的输出文件cap,对抓获的所有packet进行解析输出。
经粗略分析,windump输出的raw packet文件格式如下:
文件头24个字节:“D4 C3 B2 A1 02 00 04 00 00 00 00 00 00 00 00 00 60 00 00 00 01 00 00 00 ”,具体含义不明确。
接下来是所有raw packet连续存放的数据,对于每个raw packet依次有:
8个字节的timestamp(时间戳)
ether frame header(7 bytes Preamble,1 byte SOF,6 bytes DA, 6 bytes SA,2bytes length/type)
ether frame payload(更上层协议PDU)
windump.exe -r cap 只是在屏幕上依次输出每个packet对应的时间戳、ether frame payload 中PDU协议类型,再是与该协议相关的简单信息。
windump.exe -r cap -x 除了输出基本的信息之外,还把ether frame payload以十六进制输出。
WinDump手册
命令格式
windump [ -aBdDeflnNOpqRStvxX ] [ -c count ] [ -F file ] [ -i interface ] [ -m module ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -E algo:secret ] [ expression ]
描述 Tcpdump 输出网卡数据包中匹配布尔表达式的数据包头。
SunOS 系统下使用nit或bpf:要运行tcpdump,你必须有对dev/nit或/dev/bpf*的权利。Solaris系统下使用dlpi:你必须有对网络假设置的权利。HP-UX系统下使用dlpi:你应该以超级用户ROOT或安装SETUID到ROOT下。IRIX下使用SNOOP:你应该以超级用户ROOT或安装SETUID到ROOT下。
LINUX下:你应该以超级用户ROOT或安装SETUID到ROOT下。
在系统Ultrix和Digital UNIX:
命令参数
-a 将网络和广播地址转化为名称
-c 接收指定数据包后退出
-d 接收人可读的包匹配编译代码到标准输出,然后停止
-dd 以C程序分段方式捕获包匹配代码
-ddd 以十进制数据形式捕获包匹配代码
-e 在每个捕获行打印链路层头标
-E algo:secret为解密IPSE ESP包使用算法。
算法可以是des-cbc, 3des-cbc, blowfish-cbc, rc3-cbc, cast128-cbc, 或none。
默认值是desc-cbc。只有当TCPDUMP编译时使用激活加密选项时,才可以解密数据包。
Secret是ESP密匙是ASCII码。当前还不能认为一定是二进制值。该选项是以RFC2406ESP为假设,而不是RFC1827 ESP。只用于调试,不鼓励用真正的密码作为选项。当你在PS或其他场合,把IPSEC密码写在命令行上时,会被他人看到。
-f 不用符号而用数字方式输出外部英特网地址 -F 使用文件作为过滤表达式的输入。命令行的其他部分会被忽略。
-i 在接口上监听。如果没有指定,TCPDUMP将搜索系统接口列表中最小,被配置激活的接口(LOOPBACK接口除外)。可用最先匹配替换这种关系。在 WINDOWS中接口可以是网卡的名称,或是网卡的号码(-D参数可显示该号码)。内核为2。2或其后的LINUX系统,参数“ANY”可以获取所有接口的数据。应注意的是在混乱模式下不能使用“ANY”参数。
-l 标准输出行缓存。如果你想在捕获数据时查看的话,这个参数很有用。
例如:“tcpdump -l │ tee dat” or “tcpdump -l > dat & tail -f dat”.” n 不要将地址(如主机地址,端口号)转换为名称 -N 不要打印主机名称的域名限定。如:如果你使用该参数,TCPDUMP会输出“NIC”而不是“NIC。DDN。MIL”。
-m 从文件模块中载入SMI MIB 模块定义。这个选项可以为TCPDUMP载入多个MIB模块
-O 不要运行包匹配代码优化器。只有在你怀疑优化器有问题时可以使用这个参数。
-p 不要让接口处于“混乱”模式。注意接口可能由于其他原因处于“混乱”模式;因此“-p”不能用作以太网络主机或广播的缩写。
-q 快速(安静?)输出。打印较少的协议信息,因此输出行更短。
-r 从文件中读取包(与参数据-W一起使用)。如果文件是“-”就使用标准输入。
-s 不使用默认的68个字节,更改从每个包中获取数据的字节数量( SunOS系统实际最小为96)。对于IP,ICMP,TCP和UDP包68个字节已足够,但是对命名服务和NFS包,他们的协议会被截断(见下面)。包被截断是因为在使用参数“[│proto]”输出时指定受限制的快照,proto是被截断协议层的名称。注意如果使用大的快照会增加处理包的时间,并且明显地减少包的缓存数量。也许会导致包的丢失。你应该将snaplen 设置成你感兴趣协议的最小数。当snaplen 为0时接收整个包。
-T 根据表达式将选中的数据包表达成指定的类型。当前已有的类型有CNFP(Cisco的网络流量协议),rpc(远端程序调用),rtp(实时程序协议), rtcp(实时程序控制协议),snmp(简单网络管理协议),vat(可视单频工具),和wb(分布式白板)。 -R 假设ESP/AH包遵守旧的说明(RFC1825到RFC1829)。如果该参数被指定,TCPDUMP不打输出域。因为在ESP/AH说明中没有协议版本,TCPDUMP就无法推断出其版本号。 -S 输出绝对TCP序列号,而不是相对号。
-t 每个捕获行不要显示时间戳。 -tt 每个捕获行显示非格式化的时间时间戳。
-v 详细输出。例如,显示生存时间TTL,标识符,总长度和IP数据包的选项。也进行额外的包完整性较验,如验证IP和ICMP的头标较验值。
-vv 更为详细的输出。例如,显示NFS中继包中的其他域。
-vvv 很详细的输出。如,完全输出TELNET SB… SE选项。带-X参数的TELNET,打印并以十六进制输出。
-w 不对原始数据包解析打印而是转到文件中去。以后可用-r选项打印。当文件名为“-”表示标准输出。 -x 以十六进制(去除链路层头标)输出每个数据包。输出整个包的小部分或snaplen 个字节。
-X 输出十六进制同时,输出ASCII码。如果-x也被设置,数据包会以十六制/ASCII码显示。这对于分析新协议非常方便。如果-x也没有设置,一些数据包的部分会以十六制/ASCII码显示。 Win32特殊扩展
-B 以千字节为单位设置驱动缓存。默认缓存为1M(即1000)。如果在获取数据包时有数据丢失,建议使用该参数增大核心缓存大小,因为驱动缓存大小对数据捕获性能有很大影响。
-D 显示系统上可用的网卡列表。该参数将返回每块网卡的号码,名称和描述。
用户可以输入“WinDump –i 网卡名称”或“WinDump –i 网卡号码”。如果机器有多块网卡,不带参数的WINDUMP命令会从系统的第一块可用网卡开始。表达式选择哪些包被捕获。如果没有指定表达式,会捕获所有在网络中的数据包。否则只获捕表达式为真的数据包。表达式由一个或多个原语组成。原语通常由一个 ID(名称或号码)前面加一个或多个限定词组成。有三种不同的限定词。类型限定词指出id,名称或号码属于哪种类型。可能的类型包括:host,net和port。如’host foo’, `net 128.3′, `port 20′. 如果没有指定类型,假设为host。 方向 限定词指出特定的传输方向,是从id传来还是传到id。可能方向是src, dst, src or dst 和 src and dst。例如`src foo’, `dst net 128.3′, `src or dst port ftp-data’。如果没有方向限定词将指定src or dst。对于‘空’链路层(像SLIP这样的点到点协议),可以用inbound和outbound 限定词指明需要的方向。协议限定词限定匹配某类特定的协议。可能的协议有:ether, fddi, tr, ip, ip6, arp, rarp, decnet, tcp和udp。如`ether src foo’, `arp net 128.3′, `tcp port 21′。如没指定协议,则假设匹配所有协议。如`src foo’ 指 `(ip or arp or rarp) src foo’ (但后面的表达式不合法法)(except the latter is not legal syntax), `net bar’ 指 `(ip or arp or rarp) net bar’ 和 `port 53′ 指 `(tcp or udp) port 53′。 `fddi’ 实际上是’ether’的别名;解析器会认为两者都是指“指定接口中使用的数据链路层”FDDI头标包括类似以太网的源和目的地址,经常包含类似以太网的包类型,所以你可像对以太网字段一样过滤FDDI域。FDDI头标也包括其他域,但你不能在表达式中直接使用他们。同样’tr’也是’ether’的别名;前一段FDDI头标的情况也适用于令牌环网头标。除了以上所讲的,还有一些特殊的原语关键字不使用这种方式:gateway, broadcast, less, greater 和算术表达式,都描述如下: 通过使用and, or和 not 结合原语,构成更复杂的过滤表达式。如`host foo and not port ftp and not port ftp-data’。为了减少输入,可以忽略相同的限定词列表。如`tcp dst port ftp or ftp-data or domain’ 实际等同于 `tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain’.
-------------
WinPcap过滤表达式语法
注:该文档从tcpdump的主页上获得,在www.tcpdump.org能够找到它的原始版本。
Wpcap过滤器基于已公开的断言语法。一个过滤器是一串包括过滤表达式的ASCII字符串。Pcap_compile()接受表达式并利用一个程序将之转化为核心层的包过滤器。
表达式选择将要接受的数据包。若未给出表达式,网络上的所有数据包将被核心层的过滤驱动所接受。否则,只有满足表达式为”ture”的数据包会被接受。
表达式可以包括一个或多个原子式。原子式通常由一个带前置限定词的id(名称或数字)所组成。有三种不同的前置限定词:
Type 限定词指定名称或数字所指向的类别。可能的类别有host、net和port。例如:’host foo’、’net 128.3’、’port 20’。若未指定类别限定词,默认为host。
Dir 限定词指定一个到和/或从id的特定的传输方向。可能的方向有src、dst、src or dst和src and dst。例如:’src foo’、’dst net 128.3’、’src or dst port ftp-data’。若没有该限定词,默认为src or dst。对于’null’链路层(例如像slip这种点对点的协议)inbound和outbound这两上限定词能够指定想要的方向。
Proto 限定词限定一个特殊的协议。可能的协议有:ether、fddi、tr、ip、ip6、arp、rarp、decnet、tcp和udp。例如:’ether src foo’、’arp net 128.3’、’tcp port 21’。若没有协议限定词,则默认为所有与类别相一致的协议。例如:’src foo’的意思是’(ip or arp or rarp) src foo’(除非后面的语法不合法),’net bar’的意思是’(ip or arp or rarp) net bar’,’port 53’的意思’(tcp or udp) port 53’。
[‘fddi’实际上是’ether’的一个别名;解析器将它们的意思处理为“在指定网络接口下使用数据链路层。”FDDI首部包括类以太网的源和目的地址,并且通常包括类以太网的包类型,因此你能够像对以太网一样在这些部分对FDDI进行过滤。FDDI首部还包括其他部分,但你无法在过滤表达式中精确命名它们。
类似的,’tr’是’ether’的一个别名;之前对FDDI首部的解释也适用于令牌环网的首部。]
做为对以上的补充,还有一些特殊的‘原子式’的关键字并不遵循这种模式:gateway、broadcast、less、greater和算术表达式。所有这些将在后面讲到。
更复杂的过滤表达式由and、or和not将原子式组合而成。例如:’host foo and not port ftp and not port ftp-data’。简略起见,样同的限定试列表可以省略。例如:’tcp dst port ftp or ftp-data or domain’与’tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'完全一样。
合法的原子式有:
dst host host
如果IPv4/v6数据包的目的地址是host则表达式值为true,host可以是IP地址或主机名。
src host host
如果IPv4/v6数据包的源地址是host则表达式值为true。
host host
如果IPv4/v6数据包的源或目的地址是host则表达式值为true。以上的任一主机表达式都能够用关键字如ip、arp、rarp或ip6预先指定,就像以下所示:
Ip host host
等价于:
Ether proto "ip and host host
如果host是多个IP地址,每个地址都会被做匹配检查。
ether dst ehost
若以太网目的地址是ehost则值为true。ehost可以是/etc/ethers中的一个名称或一个数字(请见ethers(3N)的数字格式)。
ether src ehost
若以太网源地址是ehost则值为true。
ether host ehost
若以太网源或目的地址是ehost则值为true。
gateway host
若数据包以host为网关则值为true。例如:以太网的源或目的地址是host但无论是IP地址的源还是目的地址都不是host。Host必须是一个名称并且能够在机器的host-name-to-IP-address机制(如主机名文件、DNS、NIS)和host-name-to-Ethernet-address机制(如/ect/ethers)中找到。(一个等价的表达式是:
ether host ehost and not host host
它能够使用名称或数字表示host / ehost。)目前来说,这种语法无法在能够运行IPv6的结构下工作。
dst net net
若IPv4/v6的目的地址的网络号是net,则值为true。Net可以是/etc/networks中的一个名称或是一个网络号(详细内容请见networks(4))。
src net net
若IPv4/v6的源地址的网络号是net,则值为true。
net net
若IPv4/v6的源地址或目的地址的网络号是net,则值为true。
net net mask netmask
若IP地址根据指定的子网掩码netmask能与net匹配。可以用限定词src或dst限定。注意:这个语法在IPv6中是不合法的。
net net/len
若IPv4/v6地址根据指定的子网掩码长度能与net匹配。可以用限定词src或dst限定。
dst port port
若数据包是ip/tcp、ip/udp、ip6/tcp或ip6/udp并且目的端口为port,则值为true。端口可以是一个数字或一个在/etc/services(详见tcp(4P)和udp(4P))中的名称。若使用名称,则端口和协议都将被指定。若使用数字或不明确的名称,则只有端口地址被指定(例如:dst port 513将显示tcp/login和udp/who的数据流,port domain将显示tcp/domain和udp/domain的数据流)。
src port port
若数据包的源端口的值是port,则值为true。
port port
若数据包的源或目的端口地址的值是port,则值为true。以上所有关于端口的表达式都可以用关键字,tcp或udp,预先指定,如:
tcp src port port
仅当tcp的数据包的源端口地址为port的时才匹配。
less length
若数据包的长度小于等于length,则值为true。这相当于:
len <= length。
greater length
若数据包的长度大于等于length,则值为true。这相当于:
len >= length。
ip proto protocol
若数据包是协议类型为protocol的IP数据包(详见ip(4P))。Protocol可以是一个数字或一个名称:icmp、icmp6、igmp、igrp、pim、ah、esp、vrrp、udp或tcp。注意标识符tcp、udp、和icmp同时又是关键字并且必需经过反斜线(")过滤(在C-shell中是"")。注意这个原子式不对协议首部进行分析。(这段话理解不太清楚,原文如下:Note that the identifiers tcp, udp, and icmp are also keywords and must be escaped via backslash ("), which is "" in the C-shell. Note that this primitive does not chase the protocol header chain.)
ip6 proto protocol
若数据包是协议类型为protocol的IPv6数据包。注意这个原子式不对协议首部进行分析。
ip6 protochain protocol
若数据包是IPv6数据包,并且在它的协议首部串中包括类型为protocol的协议首部,则值为ture。例如:
ip6 protochain 6
与任何在协议首部串中包括TCP协议首部的IPv6数据包匹配。数据包可能包括,例如:在IPv6首部和TCP首部之间包括authentication首部,routing首部或hop-by-hop option首部。由该原子式发送的BPF编码是很复杂的并且在tcpdump中不能被BPF编码优化器所优化,因此它可能有点慢。
ip protochain protocol
等价于ip6 protochain protocol,但是它用于IPv4。
ether broadcast
若数据包是以太网广播数据包,则值为true。关键字ether是可选的。
ip broadcast
若数据包是IP广播数据包,则值为true。它会检察所有全一和全零的广播协定并查寻本地子网掩码。
ether multicast
若数据包是以太网多播数据包,则值为true。Ether关键字是可选的。这是‘ether[0] & 1 != 0’的简写。
ip multicast
若数据包是IP多播数据包,则值为true。
ip6 multicast
若数据包是IPv6多播数据包,则值为true。
ether proto protocol
若数据包是protocol类型的以太协议,则值为true。Protocol可以是一个数字或以下中的一个名称:ip、ip6、arp、rarp、atalk、decnet、sca、lat、mopdl、moprc、iso、stp、ipx或netbeui。注意这些标识符同时也是关键字并且必须用反斜线(")过滤。
[在FDDI(如‘fddi protocol arp’)和令牌环(如‘tr protocol arp’)的例子中,对于大多数的协议来说,协议证明来自802.2的逻辑链接控制(LLC)首部,LLC通常在首部分层中处于FDDI或令牌环的顶层。
当过滤FDDI或令牌环网络的大部分协议时,对于压缩以太网tcpdump只检查在所谓的SNAP格式的组织单元标识符(OUI)值为0x000000的LLC首部的协议的ID字段;它并不检查数据包是否在SNAP格式下拥有OUI值为0x000000。例外的是iso,它检查的是LLC首部的DSAP(Destination Service Access Point)和SSAP(Source Service Access Point)字段;stp和netbeui检查LLC首部的DSAP;还有atalk检查拥有OUI为0x080007的SNAP格式数据包和Appletalk etype(这个怎么译)。
在以太网的例子中,tcpdump检查大部分协议的以太网类型字段;例外的是iso、sap和netbeui,对于这些它检查802.3的帧,然后像它对FDDI和令牌环网做的那样检查LLC首部;atalk,它检查以太网帧中的Appletalk etype并且同时像在FDDI和令牌环网中那样检查SNAP格式的数据包;aarp,它在以太网帧或OUI值为0x000000的802.2 SNAP帧中检查Appletalk ARP etype;还有ipx,它检查以太网帧中的IPX etype,LLC首部的IPX DSAP,没有LLC首部封装的802.3的IPX和SNAP帧中的IPX etype。]
decnet src host
若DECNET的源地址是host,则值为true,它可能是一个格式为‘10.123’的地址或一个DECNET的主机名称。[DECNET主机名称支持只有在配置成运行DECNET的Ultrix系统中可用。]
decnet dst host
若DECNET目的地址为host,则值为true。
decnet host host
若DECNET的源或目的地址为host,则值为true。
ip、ip6、arp、rarp、atalk、decnet、iso、stp、ipx、netbeui
缩写为:
ether proto p
P是以上协议中的一个。
lat、moprc、mopdl
缩写为:
ether proto p
p是以上协议中的一个。注意tcpdump目前还不知道如何解析这些协议。
vlan [vlan_id]
若数据包是IEEE 802.1Q VLAN数据包,则值为true。若[vlan_id]被指定,则仅当数据包为指定的vlan_id,值才为true。注意在表达式中遇到的第一个关键字vlan在假设数据包为VLAN数据包的前提下改变了剩下的表达式的解码偏移量。
tcp、udp、icmp
缩写为:
ip proto p or io6 proto p
p是以上协议中的一个。
iso proto protocol
若数据包是协议类型为protocol的OSI数据包,则值为true。Protocol可以是一个数字或以下名称中的一个:clnp、esis或isis。
clnp、esis、isis
缩写为:
iso proto p
p是以上协议中的一个。注意tcpdump在解析这些协议时所做的工作并不完全。
expr relop expr
若关系式如下:relop是 >、<、>=、<=、=、!= 中的一个,并且expr是一个由正整常数(用标准C的语法表达)、标准二进制操作[+、-、*、/、&、| ]和指定数据包存取,则值为true。要存取数据包内的数据,可以使用以下的语法:
proto [ expr : size ]
proto 是ether、fddi、tr、ip、arp、rarp、tcp、udp、icmp或ip6同的一个,并且用索引操场作指定协议层。注意tcp、udp和其他上层协议类型仅应用于IPv4,而不能应用于IPv6(这在将来将会改进)。相对于指定的协议层,字节偏移量是由expr给出。Size是可选的,它指定感兴趣的字段的字节数;它可以是1、2或4,默认为1。由len指定的长度操作会给出数据包的长度。
例如:‘ether[0] & 1 != 0’捕获所有多播的数据流。表达式‘ip[0] & 0xf != 5’捕获所有选中的IP数据包。表达式‘ip[6:2] & 0x1fff = 0’仅捕获不分片的数据和分片数据的第0片数据。这些检查将暗中的应用于tcp和udp的索引操作。例如:tcp[0]总是意味着TCP首部的第一个字节,而决不会意味着一个中间片段的第一个字节。
某些偏移量和字段值可能是用名称来表达而不是数值。以下的协议首部字段偏移量可用:icmptype (ICMP类型字段)、icmpcode (ICMP代码字段)和tcpflags (TCP标识字段)。
以下的ICMP类型字段值可用:icmp-echoreply、icmp-unreach、icmp-sourcequench、icmp-redirect、icmp-echo、icmp-routeradvert、icmp-routersolicit、icmp-timxceed、icmp-paramprob、icmp-tstamp、icmp-tstampreply、icmp-ireq、icmp-ireqreply、icmp-maskreq、icmp-maskreply。
以下的TCP标识字段值可用:tcp-fin、tcp-syn、tcp-rst、tcp-push、tcp-push、tcp-ack、tcp-urg。
原子式可以使用以下操作进行组合:
一个加上括号的原子式和操作的组(圆括号专用于Shell因此必须过滤掉)。
否(‘!’或‘not’)。
与(‘&&’或‘and’)。
或(‘||’或‘or’)。
否具有最高的优先级。与和或具有相同的优先级且是左连接的。注意外在的and记号不是并列的,而是要求串联的。
如果一个标识符给出时没有关联关键字,则假设为最近使用过的关键字。例如:
not host vs and ace
是以下表达式的简写:
not host vs and host ace
不要与以下的表达式混淆了:
not ( host vs or ace )
表达式参数可以以单个参数的形式也可以以多个参数的形式传给tcpdump。一般的,若表达式包括Shell metacharacters,传送单个引用参数更为容易。多个参数在解析前可用空格联接起来。
-------
WinDump
最强有力和最广泛使用的Unix命令列工具-Windows端口事实上相当普遍。我用过各种Windows版本搜索工具,例如grep。其中最有用的就是tcpdump-为进一步分析记录、报告网络传输中数据包页眉的一种工具。Cace Technologies的工作人员已经编译一Windows端口程序命名为WinDump,它具有基于Unix系列的所有特征。方便你编译自定义界面,该程序所有的源代码也包括在内。
网络流量的倾销有许多可能的应用。我已经用其判断恶性软件是否已经安装到已给的机器上,就是通过观察无任何程序运行的计算机中数据包是否播散(它也可以识别页眉信息和目的地)。除登记所有可用的流量外,该程序仅记录、报告页眉中有某些匹配信息的信息包――如果你已经知道你在找什么并仅仅要这些,那么这个工具很有用。
安装和基本用途
WinDump分两部分。第一部分是WinPcap一系列网络记录驱动,是WinDump用来获得计算机中信息包到网络界面的信息。第二部分是程序本身,windump,在安装WinPcap library后从命令列中调用。
当你运行windump时你第一个想要使用的选项是-D,它会列出目前系统中所有可使用的网络界面。默认情况下程序听从第一可用界面,但是在Windows中,它是典型的软件拨号配置器,不是实体网络配置器。-D的结果通常如下:
1."Device"NPF_GenericDialupAdapter (Generic dialup adapter)
2."Device"NPF_{707E0236-BEE4-4097-93B1-56DEC35564AA} (Intel DC21140 PCI Fast Ethernet Adapter (Microsoft's Packet Scheduler) )
要使用专门的配置器,用-i命令和配置器号运行程序。例如,如果你想使用上述Ethernet配置器,用windump -i 2。这要比通过GUID向配置器提交简单得多,但是要注意如果新硬件或软件配置器增加,那么配置器号不是保持固定不变的。
Windump具有通过详细标准过滤已记录数据的能力――详细的网络协议,主机或端口――通常在命令列中有详细说明。其中的语法相当复杂。在程序文件中有详细解释,这有一些例子:
windump -i 2 port 80
通过端口80从界面#2记录所有流量
windump -i 2 host im-chat.com
记录所有从the host im-chat.com.或来或到界面#2的流量
windump -i 1 net 127
这些参数也可以自由组合。
输出记录
默认情况下,程序的输出记录存在控制台。除非,你使用程序仅仅是为了观察网络流量,你都想用-w<filename> 命令将结果记录到文件。默认情况下,程序用这个名字记录已存在的文件,所以注意不要用这种方式擦掉已记录的数据!
如果你打算在程序运行时查看输出文件,用-U选项。它使得程序将每一已接收信息包写到输出文件中。默认情况下,程序为数据保留1MB的缓存空间。
默认情况下,windump只记录每个信息包的标题,不是full payload。-s 0选项使程序为每个信息包堆积整个raw payload。如果你和-A选项一起用,你可以以ASCII格式记录结果。例如,用这种方式记录网页,服务器会提供可读形式,不会以gzip/deflate形式发送记录。
另一个有用的选项, -C <filesize>,将数据记录到multiple files,每一个文件的长度都不多过<filesize>。每一个连续文件是递增编码的。<filesize>是以MB校对;如果你用-C 5,每一个文件的长度都将是5,000,000字节。
当你停止程序(通过点击Ctrl-Break)时,程序向控制台提交一份报告列出所记录、阻止、丢弃(由于缺少缓存空间)的信息包数。如果程序开始丢弃信息包,你可以向记录缓冲器增加分配空间,通过-B <size>命令,其中<size>是分配的千字节数。默认缓存大小是1MB。
高端性能
WinDump一个更强有力的用途就是它能通过IPsec将已加密的网络数据流解密。这不是简单的操作,她要求你有IPsec加密的ESP密匙,同时将tcpdump应用软件与密码使用法选项结合才能解密(一些本文以外的内容)。
如果你想将有滤镜参数的外部文件列入清单,你可以用-F <filename>选项。注意这会使程序忽略命令列中提供的任何滤镜参数。
最后,如果你想使程序阅读、过滤之前已标记的数据而不是网络适配器上的现时数据,使用-r <filename>选项。
----------------
利用WinDump来探测HTTP网页数据包
54powerman
54powerman@163.com
http://blog.csdn.net/54powerman
windump是一个开源软件,可以进行各种协议的网络数据包探测,是一个不错的免费、开源Net Sniffer软件,当前最新版本是3.9.5,官方下载网址:http://www.winpcap.org/windump/install/。
详细的帮助文件官方网址是:http://www.winpcap.org/windump/docs/manual.htm
常用的参数:
-w write的缩写,写入文件,供后期分析。
-D 打印系统可用的网络接口列表。
-i[n] interface的缩写,选择要监测的网络接口。
host 指定要监测的主机,可以是域名或IP地址。
port 指定要监测的端口。
src/dst source/Destination的缩写,该参数配合host和port参数一起使用,指定要监测的主机或端口为源/终点的数据包。
-s size的缩写,指定抓取的每个数据包的大小,缺省是68,如果该值太小,可能会丢失数据。如果设置为0,则表示捕获整个包。
-t 不显示时间。
-tttt 以缺省ISO格式显示时间。
tcp, udp, icmp 指定使用的协议
使用范例:
监测某个网站的访问数据包,如mail.163.com:
1 运行命令行
windump -i2 -w pc.dump -s 0 host mail.163.com
2 用浏览器访问mail.163.com的某个网页。
3 用Ultraedit或其他16进制编辑器打开pc.dump文件,你就可以看到你对网页操作的“Request->Response”数据包了。
如果你只对服务器返回的消息感兴趣,如下修改上面的命令:
windump -i2 -w pc.dump -s 0 src host mail.163.com
反之:
windump -i2 -w pc.dump -s 0 dst host mail.163.com
windump的确是个不可多得的优秀Sniffer软件,值得收藏使用。
------------------
工具名称:Windump
运行平台:Windows/Unix
软件类别:免费软件
网址:http://winpcap.polito.it/install/default.htm
Windump是Windows环境下一款经典的网络协议分析软件,其Unix版本名称为Tcpdump。它可以捕捉网络上两台电脑之间所有的数据包,供网络管理员/入侵分析员做进一步流量分析和入侵检测。在这种监视状态下,任何两台电脑之间都没有秘密可言,(当然加密的数据不在讨论范畴之内,而且,对数据包分析的结果依赖于你的TCP/IP知识和经验)。在W.Richard Stevens的大作《TCP/IP详解》卷一中,通篇采用Tcpdump捕捉的数据包来向读者讲解TCP/IP;而当年美国最出色的电脑安全专家在追捕世界头号黑客米特尼克时,也使用了Tcpdump,Tcpdump/Windump的价值由此可见一斑。
该软件是免费软件,命令行下面使用,需要WinPcap驱动,该驱动可以在http://winpcap.polito.it/install/default.htm下载。
打开一个命令提示符,运行windump后出现:
D:"tools>windump
windump: listening on "Device"NPF_{3B4C19BE-6A7E-4A20-9518-F7CA659886F3}
这表示windump正在监听我的网卡,网卡的设备名称是:
"Device"NPF_{3B4C19BE-6A7E-4A20-9518-F7CA659886F3}
如果你看见屏幕上显示出这个信息,说明你的winpcap驱动已经正常安装,否则请下载并安装正确的驱动。Windump的参数很多,运行windump -h可以看到:
Usage: windump [-aAdDeflnNOpqRStuvxX] [-B size] [-c count] [ -C file_size ] [ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -E algo:secret ] [ expression ]
下面结合TCP的三步握手来介绍Windump的使用:
D:"tools>windump -n
windump: listening on "Device"NPF_{3B4C19BE-6A7E-4A20-9518-F7CA659886F3}
09:32:30.977290 IP 192.168.0.226.3295 > 192.168.0.10.80: S 912144276:912144276(0) win 64240 <mss 1460,nop,nop,sackOK> (DF)//第一行
09:32:30.978165 IP 192.168.0.10.80 > 192.168.0.226.3295: S 2733950406:2733950406(0) ack 912144277 win 8760 <nop,nop,sackOK,mss 1460> (DF)//第二行
09:32:30.978191 IP 192.168.0.226.3295 > 192.168.0.10.80: . ack 1 win 64240 (DF)//第三行
先看第一行。其中09:32:30.977290表示时间;192.168.0.226为源IP地址,端口3295,其实就是我自己的那台电脑;192.168.0.10是目的地址,端口80,我们可以判断这是连接在远程主机的WEB服务上面;S 912144276:912144276(0)表示我的电脑主动发起了一个SYN请求,这是第一步握手,912144276是请求端的初始序列号;win 64240 表示发端通告的窗口大小;mss 1460表示由发端指明的最大报文段长度。这一行所表示的含义是IP地址为192.168.0.226的电脑向IP地址为61.133.136.34的电脑发起一个TCP的连接请求。
接下来我们看第二行,时间不说了;源IP地址为192.168.0.10,而目的IP地址变为192.168.0.226;后面是S 2733950406:2733950406(0) ack 912144277,这是第二步握手,2733950406是服务器端所给的初始序列号,ack 912144277是确认序号,是对第一行中客户端发起请求的初始序列号加1。该行表示服务器端接受客户端发起的TCP连接请求,并发出自己的初始序列号。
再看第三行,这是三步握手的最后一步,客户端发送ack 1,表示三步握手已经正常结束,下面就可以传送数据了。
在这个例子里面,我们使用了-n的参数,表示源地址和目的地址不采用主机名的形式显示而采用IP地址的形式。
只有深入了解TCP/IP才有可能成为一个合格的网络管理员。Windump的参数很多,功能也非常强大,以上所介绍的仅仅是它冰山的一角,希望有更多的网络管理员能关注协议分析,只有这样,我们才能在日常的网络管理和应急时期的入侵分析中立于不败之地。