WinPcap編程【7】過濾串表達式的語法

wpcap的過濾器是以已聲明的謂詞語法爲基礎的。過濾器是一個ASCII字符串,它包含了一個過濾表達式。pcap_compile()把這個表達式編譯成內核級的包過濾器。

這個表達式會選擇那些數據包將會被堆存。如果表達式沒有給出,那麼,網絡上所有的包都會被內核過濾引擎所認可。不然,只有那些表達式爲'true'的包纔會被認可。

這個表達式包含了一個或多個原語。原語通常包含了id(名字或序列),這些id優先於限定詞。以下是三種不同的限定詞:

輸入(type)
指明瞭哪些東西是id所代表的。可能的輸入是hostnetport。比如:`host foo',`net 128.3',`port 20'。如果沒有輸入限定詞,就假定是host
方向(dir)
由id指明瞭一個特定的傳輸方向。可能的方向是srcdstsrc or dst。比如,'src foo','dst net 128.3',`src or dst port ftp-data'。如果沒有指定,就假定是src or dst。如果沒有鏈路層(比如,像slip這樣的點對點協議),那麼限定詞可以使用inboundoutbound,來指明一個方向。
協議(proto)
限定詞限制了所匹配的協議。可能的協議有:etherfdditripip6arprarpdecnettcpudp。比如:`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的首部,也應用在令牌環網絡首部。]

除了以上內容,還有一些特殊的限定詞和上面的形式不太一樣,它們是:gatewaybroadcastlessgreater和一些算術表達式。這些內容會在下面和大家介紹。

我們可以使用andornot將原語連接起來,來構造一個更復雜的過濾表達式。例如:`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表達式可以是iparprarpip6開頭,如下所示:
ip host host
等價於:
ether proto /ip and host host
如果host是一個多IP地址,那麼每一個地址都會被匹配。
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,但源地址和目的地址不同時爲hosthost必須能被機器的主機-IP地址(host-name-to-IP-address)機制找到(如主機名文件,DNS,NIS等),也能被主機-以太網地址(host-name-to-Ethernet-address)機制找到(如/etc/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地址是 net ,子網掩碼匹配 netmask 時爲true。可能需要 srcdst加以限制。注意,這個語法不能應用於IPv6。
net net/len
當IP地址是 net ,子網掩碼連續1的個數爲 len 時爲true。可能需要 srcdst加以限制。
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表達式可以以關鍵字tcpudp開頭,如下所示:
tcp src port port
只匹配源端口是 port 的tcp數據包。
less length
當數據包的長度小於等於length時爲true。即:
len <= length.
greater length
當數據包的長度大於等於length時爲true。即:
len >= length.
ip proto protocol
當數據包是IP數據包,並且它的協議類型爲protocol時爲true。protocol可以是一個數字,也可以是icmp, icmp6igmpigrppimahespvrrpudptcp中的一個。注意,tcpudpicmp是關鍵字,所以,它們要使用反斜槓(/)來轉義,就好比C-shell中的//。注意,這個原語不會去追蹤協議首部鏈。
ip6 proto protocol
當數據包是IPv6數據包,並且它的協議類型爲protocol時爲true。注意,這個原語不會去追蹤協議首部鏈。
ip6 protochain protocol
當數據包是IPv6數據包,並且,在它的協議首部鏈中,包含了protocol類型的協議首部時,爲true。例如:
ip6 protochain 6
能匹配所有的,擁有TCP協議首部的IPv6的數據包。在IPv6首部和TCP首部之間,可能包含認證首部,路由首部和跳數選項首部。由這個原語所生成的BPF(BSD Packet Filter,包過濾機制)碼是複雜的,而且不能被BPF優化器優化,所以,在某些程度上,它的速度比較慢。
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),stpnetbeui會檢查LLC首部的DSAP,atalk會檢查數據包是不是SNAP格式的,並且OUI是不是0x080007。Appletalk 同樣如此。
在以太網的例子中,tcpdump檢查大部分協議的以太網類型字段,isosapnetbeui除外,因爲它們會檢查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
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 ip6 proto p
p 是以上協議中的一個。
iso proto protocol
當數據包的協議類型爲protocol的OSI數據包時值爲true。Protocol可以是一個數字或以下名稱中的一個:clnpesisisis
clnp, esis, isis
縮寫是:
iso proto p
p 是以上協議中的一個。注意,tcpdump並不能完成這些協議的全部解析工作。
expr relop expr
若關係式如下:relop是 >, <, >=, <=, =, != 中的一個,並且expr是一個由正整常數(用標準C語言的語法表示),標準二進制運算符[ +, -, *, /, &, | ],運算符的長度,和指定數據包存取,則值爲true。要存取數據包內的數據,可以使用以下的語法:
proto [ expr : size ]
Protoether, 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的數據報。這個檢查隱含在tcpudp的下標操作中。例如,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的元字符,那麼用一個參數傳遞比較容易,最好把它括起來,多個參數在傳遞前,用空格連接起來。

發佈了49 篇原創文章 · 獲贊 5 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章