- wpcap的過濾器是以已聲明的謂詞語法爲基礎的。過濾器是一個ASCII字符串,它包含了一個過濾表達式。pcap_compile()把這個表達式編譯成內核級的包過濾器。
這個表達式會選擇那些數據包將會被堆存。如果表達式沒有給出,那麼,網絡上所有的包都會被內核過濾引擎所認可。不然,只有那些表達式爲'true'的包纔會被認可。
這個表達式包含了一個或多個原語。原語通常包含了id(名字或序列),這些id優先於限定詞。以下是三種不同的限定詞:
- 輸入(type)
- 指明瞭哪些東西是id所代表的。可能的輸入是host,net和port。比如:`host foo',`net 128.3',`port 20'。如果沒有輸入限定詞,就假定是host
- 方向(dir)
- 由id指明瞭一個特定的傳輸方向。可能的方向是src,dst,src or dst。比如,'src foo','dst net 128.3',`src or dst port ftp-data'。如果沒有指定,就假定是src or dst。如果沒有鏈路層(比如,像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','port53'等價於'(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'。如果要簡化輸入,我們可以把已列出的id限定詞省略。比如:`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數據包的目標域(destination field)爲host時爲true,host既可以是地址,也可以是名字。
- src host host
- 當IPv4/v6數據包的源域(source field)爲host時爲true。
- host host
- 當IPv4/v6數據包的源域(source field)或目標域(destination field)爲host時爲true。以上任何一個host表達式可以是ip,arp,rarp或ip6開頭,如下所示:
-
ip host host
-
ether proto /ip and host host
-
- ether dst ehost
- 當以太網的目的地址爲ehost時爲true。ehost可以是一個來自/etc/ether的名字,也可以是一個數字代號(參見 ethers(3N)for numeric format)。
- ether src ehost
- 當以太網的源地址爲ehost時爲true。
- ether host ehost
- 當以太網的目的地址,或源地址爲ehost時爲true。
- gateway host
- 當host爲網關時爲true。即,以太網源地址或目的地址是host,但源地址和目的地址不同時爲host。host必須能被機器的主機-IP地址(host-name-to-IP-address)機制找到(如主機名文件,DNS,NIS等),也能被主機-以太網地址(host-name-to-Ethernet-address)機制找到(如/etc/ethers等)。例如:
-
ether host ehost and not host host
-
- 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地址是 net ,子網掩碼匹配 netmask 時爲true。可能需要 src 或 dst加以限制。注意,這個語法不能應用於IPv6。
- net net/len
- 當IP地址是 net ,子網掩碼連續1的個數爲 len 時爲true。可能需要 src 或 dst加以限制。
- dst port port
- 當數據包是ip/tcp, ip/udp, ip6/tcp 或 ip6/udp,並且目的端口號是port時爲true。port可以是數字,或是在/etc/services中被使用的名字。(參見 tcp(4P) and udp(4P))。如果使用名字,那麼端口號和協議都將被檢測。如果使用數字,或者一個不明確的名字,那麼只有端口號會被檢測。(比如:dst port 513將打印tcp/login數據流和udp/who數據流。port domain將打印tcp/domain的數據流和udp/domain的數據流)。
- src port port
- 當源端口號是 port時爲true。
- port port
- 當源端口號或目的端口號爲 port 時爲true。以上任何一個port表達式可以以關鍵字tcp或udp開頭,如下所示:
-
tcp src port port
-
- less length
- 當數據包的長度小於等於length時爲true。即:
-
len <= length.
-
- greater length
- 當數據包的長度大於等於length時爲true。即:
-
len >= length.
-
- ip proto protocol
- 當數據包是IP數據包,並且它的協議類型爲protocol時爲true。protocol可以是一個數字,也可以是icmp, icmp6,igmp,igrp,pim,ah,esp,vrrp,udp 或 tcp中的一個。注意,tcp,udp, icmp是關鍵字,所以,它們要使用反斜槓(/)來轉義,就好比C-shell中的//。注意,這個原語不會去追蹤協議首部鏈。
- ip6 proto protocol
- 當數據包是IPv6數據包,並且它的協議類型爲protocol時爲true。注意,這個原語不會去追蹤協議首部鏈。
- ip6 protochain protocol
- 當數據包是IPv6數據包,並且,在它的協議首部鏈中,包含了protocol類型的協議首部時,爲true。例如:
-
ip6 protochain 6
-
- ip protochain protocol
- 功能和 ip6 protochain protocol相同,只是這個應用於 IPv4。
- ether broadcast
- 當數據包是以太網廣播數據包時爲true。關鍵字ether是可選的。
- ip broadcast
- 當數據包是IP廣播數據包時爲true。它會檢查所有的廣播,包括地址全是0的和地址全是1的,然後,檢查子網掩碼。
- 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, aarp,decnet, sca, lat, mopdl, moprc,iso, stp, ipx, netbeui中的一個。注意,這些符號也都是關鍵字,所以,他們都需要用反斜槓(/)轉義。
- [在使用FDDI(比如'fddi protocol arp')和令牌環(比如'tr protocol arp')和其他大多數這種協議時,協議根據802.2邏輯鏈路控制(LLC)來識別,這些信息通常在FDDI或令牌環首部的開始。
- 當需要識別大多數協議的標識,比如FDDI或令牌環時, Tcpdump只檢查LLC報頭的ID數據域,它們以SNAP格式存儲,並且,組織單位識別碼(Organizational Unit Identifier(OUI))爲0x000000,以封裝以太網。它不會檢查這個包是不是SNAP格式的,並在0x000000單元有OUI。
- 然而,iso是個特例,它會檢查LLC首部的目的服務存取點DSAP(Destination Service Access Point)和源服務存取點SSAP(Source Service Access Point),stp和netbeui會檢查LLC首部的DSAP,atalk會檢查數據包是不是SNAP格式的,並且OUI是不是0x080007。Appletalk 同樣如此。
- 在以太網的例子中,tcpdump檢查大部分協議的以太網類型字段,iso,sap 和 netbeui除外,因爲它們會檢查802.3幀,然後檢查LLC首部,就像它對FDDI和令牌環那樣。atalk,它檢查以太網幀的Appletalk etype和SNAP格式的以太網幀,arrp,它在以太網幀中檢查Appletalk ARP etype,或是在OUI爲0x000000的802.2 SNAP幀中查找,還有ipx,他會在以太網幀中檢查IPX etype,在LLC首部檢查IPX DSAP,沒有用802.3封裝的LLC首部的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, aarp, decnet, iso, stp, ipx, netbeui
- 縮寫是:
-
ether proto p
-
- lat, moprc, mopdl
- 縮寫是:
-
ether proto p
-
- vlan [vlan_id]
- 當數據包是IEEE 802.1Q VLAN數據包時爲true。若[vlan_id]被指定,則僅當數據包爲指定的vlan_id,值才爲true。注意,在假設數據包爲VLAN數據包的前提下,表達式中的第一個關鍵字vlan會改變剩餘表達式的解碼偏移量。
- tcp, udp, icmp
- 縮寫是:
-
ip proto p or ip6 proto p
-
- iso proto protocol
- 當數據包的協議類型爲protocol的OSI數據包時值爲true。Protocol可以是一個數字或以下名稱中的一個:clnp,esis或isis。
- clnp, esis, isis
- 縮寫是:
-
iso proto p
-
- expr relop expr
- 若關係式如下:relop是 >, <, >=, <=, =, != 中的一個,並且expr是一個由正整常數(用標準C語言的語法表示),標準二進制運算符[ +, -, *, /, &, | ],運算符的長度,和指定數據包存取,則值爲true。要存取數據包內的數據,可以使用以下的語法:
proto [ expr : size ]
Proto 是 ether, fddi, tr, ip, arp, rarp, tcp, udp, icmp or 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 代碼域), and 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的元字符,那麼用一個參數傳遞比較容易,最好把它括起來,多個參數在傳遞前,用空格連接起來。