【系列文章】
《神探tcpdump第一招》-linux命令五分钟系列之三十五
《神探tcpdump第二招》-linux命令五分钟系列之三十六
《神探tcpdump第三招》-linux命令五分钟系列之三十七
《神探tcpdump第四招》-linux命令五分钟系列之三十八
《神探tcpdump第五招》-linux命令五分钟系列之三十九
《神探tcpdump第六招》-linux命令五分钟系列之四十
==
在上一招中,最后的3个例子比较复杂,大家可能会感觉云里雾里。我们现在回顾下这三个例子,然后今天的第七招就是教大家如何看懂他们!
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and not dst host qiyi.com' tcpdump 'ip[2:2] > 576' tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
==
在讲解前,需要你熟练掌握ETHER/IP/TCP/UDP等协议的包头定义格式,能够知道每一位的作用和含义。
有关ETHER的,可以参考《计算机网络协议包头赏析-以太网》;
有关IP的,可以参考《计算机网络协议包头赏析-IP》;
有关TCP的,可以参考《计算机网络协议包头赏析-TCP》;
有关UDP的,可以参考《计算机网络协议包头赏析-UDP》。
==
磨刀不误砍柴工,如果本系列的前六篇文章你都仔细看过了,同时,几种协议的包格式也都了然于心了,那我们就切入正题,介绍下过滤表达式的高级语法。
其实我们需要着重讲解的只有一种语法,即proto [ expr : size],只要掌握了这个语法格式,相信大家就能看懂上面的三个稀奇古怪的表达式了。
proto就是protocol的缩写,表示这里要指定的是某种协议的名称,比如ip、tcp、ether。其实proto这个位置,总共可以指定的协议类型有15个之多,包括:
ether – 链路层协议
fddi – 链路层协议
tr – 链路层协议
wlan – 链路层协议
ppp – 链路层协议
slip – 链路层协议
link – 链路层协议
ip
arp
rarp
tcp
udp
icmp
ip6
radio
expr用来指定数据报偏移量,表示从某个协议的数据报的第多少位开始提取内容,默认的起始位置是0;而size表示从偏移量的位置开始提取多少个字节,可以设置为1、2、4。
如果只设置了expr,而没有设置size,则默认提取1个字节。比如ip[2:2],就表示提取出第3、4个字节;而ip[0]则表示提取ip协议头的第一个字节。
在我们提取了特定内容之后,我们就需要设置我们的过滤条件了,我们可用的“比较操作符”包括:>,<,>=,<=,=,!=,总共有6个。
好,掌握了上面内容之后,我可以很负责任的告诉你,你已经掌握了tcpdump过滤表达式的最重要语法了。我们先来小试牛刀,看一个例题:
ip[0] & 0xf != 5
IP协议的第0-4位,表示IP版本号,可以是IPv4(值为0100)或者IPv6(0110);第5-8位表示首部长度,单位是“4字节”,如 果首部长度为默认的20字节的话,此值应为5,即”0101″。ip[0]则是取这两个域的合体。0xf中的0x表示十六进制,f是十六进制数,转换成8 位的二进制数是“0000 1111”。而5是一个十进制数,它转换成8位二进制数为”0000 0101″。
有了上面这些分析,大家应该可以很清楚的知道,这个语句中!=的左侧部分就是提取IP包首部长度域,如果首部长度不等于5,就满足过滤条件。言下之意也就是说,要求IP包的首部中含有可选字段。
大家可能已经有所体会,在写过滤表达式时,你需要把协议格式完全背在脑子里,才能把表达式写对。可这对大多数人来说,可能有些困难。为了让 tcpdump工具更人性化一些,有一些常用的偏移量,可以通过一些名称来代替,比如icmptype表示ICMP协议的类型域、icmpcode表示 ICMP的code域,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-ack, tcp-urg。
如果一个过滤表达式有多个过滤条件,那么就需要使用逻辑符了,其中,!或not都可以表示“否定”,&&与and都可以表示“与”,而||与or都可以表示“或”。
==
好了,大功告成,如果你真的仔细阅读并掌握了上面的内容,我相信你有能力自己来分析下面这三个语句,而且一定能明白它们的“言下之意”的!
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and not dst host qiyi.com' tcpdump 'ip[2:2] > 576' tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224'
谢谢!