mostly we can use netfilter related tools' exsisted proto rules to meet our requirements.
but sometimes we may want something special but related tools may not provide the easiest way or different tools needs itsown method.
just one example, we'd like to collect GRE protocol packets.
<1>packet filter for capture(d)
--for live capture using tcpdump or filter captured packets
for live capture using tcpdump(wireshark or else), seems no existed proto support,
you may have to check the exact packets bytes to learn its data struct characturistict,
with checking one captured packets by the wireshark, its protocol is like
the value is at the 10th octs in the ip packet, so you can use below:
tcpdump -i any -nn -Z root 'ip[9]==0x2f'
notice: the field index start from 0, just like C array.
<2>what about iptables?
we can have similar way
iptables -m u32 --u32 "3&0x0000FF00=0x2f" -j LOG --log-prefix "PROTO-GRE"
the usage is
iptables -m u32 --u32 "Start&Mask=Range", the range is like "min:max" or an exact value.
notice: remember that the mask match length is 4 bytes(u32) long and the bytes order in the packets is like [1][2][3][4]
we can also another way
iptables -m string --string "/" --algo bm --from 9 --to 10 -j LOG --log-prefix "PROTO-GRE"
the string value is just the value of ASCII.
notice: not printable values seems not easy to use by this way.
some more details references you may intrested:
http://www.tcpdump.org/manpages/pcap-filter.7.html
http://linux.die.net/man/8/iptables
http://www.watters.ws/mediawiki/index.php/Drop_packets_in_iptables_with_string_matching
http://www.stearns.org/doc/iptables-u32.current.html