Open ralequi opened 2 years ago
That's an interesting question. The packet with a convenience pcap savefile header prepended is base64-encoded below:
1MOyoQIABAAAAAAAAAAAAP//AAABAAAACgoKCgsLCwuSAAAAkgAAAHyRaZvTbRDvSV+x5wgARQAA
hAAAAAD9L6X9auOctWrjpNEAAGVYyv7K/sr+ysrKysrKgQAAaQgARSAAWqHFQAB5BncCwKgDYMCo
ZAXCJw09ScrrFrcsPjBQGAP98WYAABcDAwAtAAAAAAABwitH+mXW6zxy5EyHy0qGf4fHn5073/aT
PyBIW7b822ExA5VBPCj4
Using Wireshark ([Protocols in frame: eth:ethertype:ip:gre:eth:ethertype:vlan:ethertype:ip:tcp:tls]
), it is easy to notice that both ip proto gre
and ip protochain gre
match the packet, but ether host ca:ca:ca:ca:ca:ca
does not (which is expected). Also ip protochain \tcp
does not match the packet, which indicates that ip protochain
does not chase the protocol header stack (which would be understandably difficult or impossible using BPF) and consequently would not be able to advance the packet data offset for the ether host
predicate by an unknown amount.
Please note that protochain P
is a shorthand for ip protochain P or ip6 protochain P
, so more than a half of the BPF code above is no-op on this packet. However, even the IPv4-only version visualized using BPF Exam does not immediately remind me of anything particular. I agree that it would be useful to reconstruct the meaning of ip protochain
and to update the man page with more specifics. The add 0
instruction likely indicates that the code has some space for improvement.
Thanks for your quick reply @infrastation .
It's bad to hear that you cannot "chain" protocols (such as VXLAN/GRE, which is common on a SDN/ERSPAN in today's monitoring). Correct me if I have misunderstood you.
By reading the "BPF assembly", I don't think it may be too hard to "chain" protocols. It should be as "easy" as keep any loads as ldxb
where x
is the offset
of whatever you have been parsed. By adding some context using something like parenthesis it would be possible to do something like:
host <erspan source> && (chain GRE && vlan && host <interesting IP>)
or even simpler for most SDN env:
chain VXLAN && host <interesting IP>
I mean, vlan
keyword actually "moves" (not very clean in my opinion) the packet pointer from that point, so I don't find any strong reason to avoid adding more keywords that moves the packet pointer.
I'm not familiar with the libpcap insights and probably this suggestion might not be quick/simply to implement. But if someone thinks about it, they would be quick realize this functionality is more and more required as long as encapsulating traffic is more and more popular everywhere.
Thanks for your support.
The BPF does the filtering, and anything is possible with the right BPF compiled in. Decoding is a different kettle of fish, and that's done in the tcpdump code, not in the libpcap code.
Thanks for your reply @mcr,
But that's exactly what I'm proposing: using BPF to filter tunneled headers. If you wanna use a network probe with ERSPAN or a simple local-mirror under a VXLAN-SDN, is a common thing to want to filter the "real" communication instead of (just) the transport one.
From my point of view, chaining protocols is a must in order to use BPF efficiently in the new SDN era. (I don't like SDN btw, but it is what it is)
Hardcoding ether[n]==CA && ether[n+1]==CA && ...
is not an usable way of filtering MACs... (or ips, or whatever... specially with non-constant size protocols in the middle)
The add #0
statement is an intentional no-op in gencode.c:gen_protochain()
; from the function code it seems that in IPv4 case it would skip an AH header and do something else that I do not understand yet.
I'm trying to use BPF in order to filter eth/vlan/ip/tcp headers that are behind a GRE encapsulation protocol.
Consider this example packet:
If we try something "simple", that only checks for the
CA:CA:CA:CA:CA:CA
ethernet address, let's say:(protochain GRE && ether host CA:CA:CA:CA:CA:CA)
We'll get the following code:
This code, unless I'm missing something, will only execute in this order:
Unless I have missunderstood the behaviour of
protochain
, it should "virtually move" the packet pointer behind the GRE header, so we can filter there.I'm really confused and everything I found on the internet says that filter
(protochain GRE && ether host CA:CA:CA:CA:CA:CA)
should work.This have been deeply tested on
Fedora 37
and replicated onUbuntu 22
libpcap: 1.10.1
Dumpcap (Wireshark) 3.6.8 (Git commit d25900c51508)
Any help would be welcomed. Thank you in advance.