Wireshark-users: Re: [Wireshark-users] filter application layer frames during capture kernel (SIP

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Wed, 24 Jan 2018 11:02:40 -0800
On Jan 24, 2018, at 10:27 AM, Manolis Katsidoniotis <manoska@xxxxxxxxx> wrote:

> Thus, I need to go in higher and filter more frames during capture so that I don't lose anything.
> 
> I'm not looking for complicated display filters functionality
> 
> But for example
> the first line of any sip INVITE is
> INVITE sip:bob@xxxxxxxxxx SIP/2.0
> thus I can filter the first 8 bytes of the SIP header and match them to a string == "INVITE"

As long as you're comparing bytes that are at an offset that can be calculated from values earlier in the packet, that can be implemented in a capture filter.

If, for example, you want to match bytes 0 through 6 in the TCP payload against 'I' 'N' 'V' 'I' 'T' 'E' ' ' ("INVITE " is 7 bytes long, not 8 bytes long), that can be done; see, for example, Jefferson Ogata's reply:

	http://seclists.org/tcpdump/2004/q4/95

in this thread:

	http://seclists.org/tcpdump/2004/q4/94

for an example of how that could be done.  The equivalent for matching "INVITE " in SIP would be

	tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x494e5649 and tcp[(((tcp[12:1] & 0xf0) >> 2) + 4):2] = 0x5445 and tcp[(((tcp[12:1] & 0xf0) >> 2) + 6):1] = 0x20

At some pointer I should probably add string comparison to the libpcap filtering engine, and perhaps also add the ability to directly refer to the TCP payload, so as to obviate the need to do the "(tcp[12:1] & 0xf0) >> 2" stuff in the filter.

If you're doing any form of filtering that would involve a loop, however, that's certainly not going to work for capture filters loaded into the kernel, as backwards jumps in BPF programs are not allowed.  This means that scanning through a packet looking for a string or pattern can't be done unless it can be done by a fully unrolled loop.

> But I don't see sip as an option in capture filters (I have checked both wireshark and linux:tcpdump)
> I can see  tcp port http  but no sip.

"See" where?

It might not be mentioned in an *example*, but if your /etc/services file has an entry like

	sip	5060/tcp	# SIP

then "tcp port sip" will be equivalent to "tcp port 5060", just as, given an entry like

	http	80/tcp	www www-http # World Wide Web HTTP

in /etc/services, "tcp port http" will be equivalent to "tcp port 80".

Note that this will *not* match alternate ports - port 8080 won't be matched by "tcp port http".