vlan
変だ。
pcap-filter の man ページを引用するには:
vlan [vlan_id]
True if the packet is an IEEE 802.1Q VLAN packet. If [vlan_id]
is specified, only true if the packet has the specified vlan_id.
Note that the first vlan keyword encountered in expression
changes the decoding offsets for the remainder of expression on
the assumption that the packet is a VLAN packet. The vlan
[vlan_id] expression may be used more than once, to filter on
VLAN hierarchies. Each use of that expression increments the
filter offsets by 4.
For example:
vlan 100 && vlan 200
filters on VLAN 200 encapsulated within VLAN 100, and
vlan && vlan 300 && ip
filters IPv4 protocols encapsulated in VLAN 300 encapsulated
within any higher order VLAN.
「式で検出された最初のvlanキーワードは、パケットが VLAN パケットであると仮定して、式の残りの部分のデコード オフセットを変更することに注意してください。」ここで重要です。
これは、および他のフィルタの順序がvlan
重要であることを意味します。
そう:
(protocol_filter と vlan_filter) を渡すと、パケットは表示されません
これは、パケットがVLAN パケットではないという前提に基づいて「protocol_filter」が評価されるためです。そのフィルターを通過するものはすべて VLAN パケットではないため、「vlan_filter」は失敗します。
しかし、exp を (vlan_filter と protocol_filter) と交換すると、パケット フィルタリングが機能します。
これは、「vlan_filter」が VLAN パケットをチェックし、その後のすべてのテストの実行方法を変更して、パケットがVLAN パケットであると想定するためです。「protocol_filter」は、パケットがVLAN パケットであるという仮定に基づいて評価されます。
「not」プロトコルを含む vlan を含めると、プロトコル フィルターが適用されたパケットが取得されます。例: (((vlan 20)) and (not (udp port 3800)) and ((not (tcp)) and (not (udp port) 53)) および (not (icmp)) および (not (ip6)) および (not (udp ポート 5353))))
そのフィルターは VLAN パケットのみに一致し、パケットが VLAN 20 用である場合、パケットが VLAN パケットであるという仮定の下で他のすべてのチェックを行います。たとえば、イーサネット ヘッダーを含むパケットをキャプチャしている場合、 IPv4 または IPv6 をチェックしている場合、他のチェックでは、12 ではなく 16 のオフセットでイーサネット タイプが調べられます。
プロトコルに vlan を含めない場合、bpf が (not (udp port 3800)) and ((not (tcp)) and (not (udp port 53)) and ( の場合、tcp、icmp、ip6 などを含むすべてのパケットを取得します。 not (icmp)) および (not (ip6)) および (not (udp ポート 5353))))
これは少し紛らわしいですが、libpcap のバグであると主張することもできます。
「udp ポート 3800」は最初に「これは IPv4 か IPv6 か」をチェックします。イーサネットでは、イーサネット タイプ/長さフィールドの値が IPv6 の場合は 0x0800 であるか、IPv6 の場合は 0x86dd であるかをチェックします。それが IPv4 に一致する場合、IPv4 プロトコル フィールドをチェックして、それが UDP であるかどうかを確認します。IPv6 に一致する場合は、IPv6 の次のヘッダー フィールドをチェックして、UDP であるかどうかを確認します。UDP の場合は、送信元と宛先のポート番号をチェックして、いずれかが 3800 かどうかを確認します。一致する場合、パケットは一致し、そうでない場合は一致しません。
「not (udp port 3800)」は同じチェックを行いますが、いずれかのテストが一致しない場合、パケットは一致し、いずれかが一致する場合、パケットは一致しません。
VLAN パケットのイーサネット タイプ/長さフィールドには 0x8100 が含まれているため、IPv4 と IPv6 のチェックは一致しません。したがって、「not」フィルターは一致します。
ここでのバグは、ポート 3800との間の UDP パケットがIPv4 または IPv6 パケットであることです。VLAN 上にある場合、イーサネット上では、パケットの先頭から 12 のオフセットで 0x0800 または 0x86dd を持つことはありません。0x8100 があります。
(((not vlan)) および (not (udp ポート 3800)) および ((not (tcp)) および (not (udp ポート 53)) および (not (icmp)) および (not (ip6)) および (not (udp ポート 5353)))) ip6、tcp などを含むすべてのパケットを取得します
これは libpcap のもう 1 つのバグです。イーサネット上で「vlan」を使用すると、後続のすべてのテストで VLAN ヘッダーの後のイーサネット タイプ フィールドが参照されるため、「not vlan」も同様です。しかし、「not vlan」の場合は間違っています。一致する場合、パケットはVLAN パケットではないため、VLAN ヘッダーはありません!
(((not vlan)) and (not (udp port 3800)) and (((tcp)) or ((udp port 53)) or ((icmp)) or ((ip6)) or ((udp port 5353) ))) 単一のパケットすら取得しない
同じ問題。
libpcap/WinPcap のバグを修正するのは簡単ではないかもしれませんが、時間があれば調べてみます。