libpcap icon indicating copy to clipboard operation
libpcap copied to clipboard

expression rejects all packets for IPv6 upper-layer protocol

Open yiyuandao opened this issue 8 years ago • 20 comments

Hi,

I tried to run following command:

tcpdump -i em1 'ip6 and udp[10]&1 !=0' 

and got the following:

tcpdump: expression rejects all packets

I checked the document pcap-filter. and in the section 'expr relop expr':

Note that tcp, udp and other upper-layer protocol types only apply to IPv4, not IPv6 (this will be fixed in the future)

I wonder is there any plan to add this filter for IPv6?

Thanks.

yiyuandao avatar Aug 23 '17 03:08 yiyuandao

@yiyuandao wanted to follow up on your filtering question for IPv6; You could try using running your UDP filter wide open and then using grep to capture everything coming across as IP6.

tcpdump -i em1 udp and 'udp[10] & 1!=0' -vvv | grep -i 'IP6'

agnosticdev avatar Sep 25 '18 02:09 agnosticdev

This issue still exists (in tcp/udp). Is there a reason the syntax ought not to work? Since something like ip6 and tcp port 80 works fine.

If we do want syntax like ip6 and tcp[1] = 0x5 to work, do we want only tcp[1] = 0x5 to look for IPv6 in addition to IPv4? Or leave it as only IPv4? tcp port 80 Checks for both so there is a little inconsistency.

What is the desired behaviour? I was thinking of making a PR with these changes but I'm not sure what would be preferred.

KimiNewt avatar Aug 26 '19 11:08 KimiNewt

As the pcap-filter(7) man page explains it:

To access data inside the packet, use the following syntax: proto [ expr : size ] Note that tcp, udp and other upper-layer protocol types only apply to IPv4, not IPv6 (this will be fixed in the future).

infrastation avatar Nov 13 '21 12:11 infrastation

Closing as resolved (not a bug, but an improvement that remains to be made).

infrastation avatar Jan 04 '22 15:01 infrastation

Should this issue be left open to track it as an enhancement request?

bubbasnmp avatar Apr 07 '22 14:04 bubbasnmp

Alright, let's keep it reopened for a while longer.

infrastation avatar Jun 12 '22 17:06 infrastation

Is somebody working on this issue? What is to be implemented? If the compiler can generate instructions to find TCP port after IPv6 header, it should work for anything else inside the TCP header, shouldn't it?

jviki avatar Jan 31 '23 15:01 jviki

This is an old known problem, nobody is working on it now, as far as I am aware. Competent volunteers are welcome to contribute a solution. Ideally it would be best to discuss the solution in sufficient detail before spending time on the code.

infrastation avatar Jan 31 '23 16:01 infrastation

I agree. If it is not too complex, I believe I can provide some development capacity from my team. We would really like this thing to work, however, we have no experience with libpcap internals.

What can be some next step?

jviki avatar Feb 01 '23 09:02 jviki

That might turn out a deeper rabbit hole than it seems because this problem is not to extend an existing dual-stack mapping of another packet data accessor onto UDP, but to introduce dual-stack mapping of packet data accessors for the first time.

In any case, it should be helpful to study this and this documents, then you can have a look at scanner.l, grammar.y and gencode.c and try to think what a good solution would look like. After that it would be a good time to confirm your findings here or on the mailing list before committing into the implementation.

Hopefully that's good enough a starting point.

infrastation avatar Feb 01 '23 21:02 infrastation

The second link (https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf) gives me HTTP 404.

jviki avatar Feb 01 '23 21:02 jviki

I think the Wireshark web sites are being reworked. Down link reported on Discord.

bubbasnmp avatar Feb 01 '23 22:02 bubbasnmp

The keynote itself can still be found on YouTube though: https://www.youtube.com/watch?v=XHlqIqPvKw8

cjmaynard avatar Feb 01 '23 22:02 cjmaynard

A copy of the PDF is here.

infrastation avatar Feb 01 '23 22:02 infrastation

Thank you for raising this, www.tcpdump.org is now using the copy for the documentation reference.

infrastation avatar Feb 01 '23 22:02 infrastation

A possible work-around until a more robust solution is available: ip6 and (ip6[6] = 17) and ((ip6[40 + 8 + 2] & 1) != 0). Of course this only works if there are no IPv6 extension headers present, and I didn't combine the offsets intentionally so it's more obvious that we're skipping the standard 40 bytes of the IPv6 header, the 8 bytes of the UDP header and 2 additional bytes.

cjmaynard avatar Feb 01 '23 23:02 cjmaynard

I think the Wireshark web sites are being reworked.

They are indeed being reworked, and a recent change inadvertently broke some links. https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf should be working again.

geraldcombs avatar Feb 01 '23 23:02 geraldcombs

I did a quick research about the topic and performed some very basic experiments.

Here is bytecode for IPv4/TCP with dst port 80...

$ tcpdump -d 'ip and tcp dst port 80'
Warning: assuming Ethernet
(000) ldh      [12]
(001) jeq      #0x800           jt 2	jf 10
(002) ldb      [23]
(003) jeq      #0x6             jt 4	jf 10
(004) ldh      [20]
(005) jset     #0x1fff          jt 10	jf 6
(006) ldxb     4*([14]&0xf)
(007) ldh      [x + 16]                              ; loading dst port
(008) jeq      #0x50            jt 9	jf 10        ; testing for TCP dst port 80
(009) ret      #262144
(010) ret      #0

Bytecode for IPv4/TCP flags (currently same result as with tcp[tcpflags] & 2 != 0):

$ tcpdump -d 'ip and tcp[tcpflags] & 2 != 0'
Warning: assuming Ethernet
(000) ldh      [12]
(001) jeq      #0x800           jt 2	jf 10
(002) ldb      [23]
(003) jeq      #0x6             jt 4	jf 10
(004) ldh      [20]
(005) jset     #0x1fff          jt 10	jf 6
(006) ldxb     4*([14]&0xf)
(007) ldb      [x + 27]                              ; loading TCP flags
(008) jset     #0x2             jt 9	jf 10        ; testing for TCP flags SYN
(009) ret      #262144
(010) ret      #0

Here is bytecode for IPv6/TCP with dst port 80... It ignores IPv6 extension headers.

$ tcpdump -d 'ip6 and tcp dst port 80'
Warning: assuming Ethernet
(000) ldh      [12]
(001) jeq      #0x86dd          jt 2	jf 7
(002) ldb      [20]
(003) jeq      #0x6             jt 4	jf 7
(004) ldh      [56]                                 ; loading dst port
(005) jeq      #0x50            jt 6	jf 7        ; testing for TCP dst port 80
(006) ret      #262144
(007) ret      #0

And for IPv6/TCP flags, it something like fails:

$ tcpdump -d 'ip6 and tcp[tcpflags] & 2 != 0'
Warning: assuming Ethernet
tcpdump: expression rejects all packets

I do not see any reason why the last expression would not give something like this:

(000) ldh      [12]
(001) jeq      #0x86dd          jt 2	jf 7
(002) ldb      [20]
(003) jeq      #0x6             jt 4	jf 7
(004) ldh      [69]                                 ; loading TCP flags
(005) jset     #0x2             jt 6	jf 7        ; testing for TCP flags SYN
(006) ret      #262144
(007) ret      #0

And expression tcp[tcpflags] & 2 != 0 should take advantage of such improvement as well and consider both IPv4 and IPv6. I think, generating such code would be the goal of this issue. I believe that the logic to be updated is in this switch case: https://github.com/the-tcpdump-group/libpcap/blob/master/gencode.c#L7483.

After that, the much more difficult part would be to parse IPv6 extension headers... But I consider it to be another story.

jviki avatar Feb 03 '23 12:02 jviki

Loading of ports is regardless of L3 layer is done via gen_load_a(), the IPv6 case is here https://github.com/the-tcpdump-group/libpcap/blob/master/gencode.c#L1865. Thus, I assume that this logic can be somehow refactored/merged or something.

jviki avatar Feb 03 '23 12:02 jviki

When you study the bytecode, it helps to remember that by default you see the optimized version. You could use BPF Exam to get a slightly better view of what comes out of gencode.c and what how it changes in optimize.c.

infrastation avatar Feb 03 '23 20:02 infrastation