Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libpcap doesn't adjust for eth priority tag when filtering for other fields? #1256

Open
rscheff opened this issue Oct 12, 2023 · 3 comments
Open
Labels
BPF related VLAN Tagged frames requiring different filtering to match

Comments

@rscheff
Copy link

rscheff commented Oct 12, 2023

While working on some improvements with the freebsd iscsi initiator - which offers among other things the capability to set the
IP DSCP and Eth PCP specifically, I found that

tcpdump version 4.99.4
libpcap version 1.10.4

tcpdump -i en0 host <host>

would only capture relevant packets, when no vlan tag was present; when the PCP is set, and a packet is sent with the special vlan id 0
in the vlan header (on a non-tagged interface, if that plays a role), the filter would not capture the packet.

I suspect that "untagged" but prioritized Ethernet traffic (signified by the presence of a vlan tag header, but the vlan ID equals 0) is
not special cased in the BPF code.

Capturing with tcpdump -i en0 vlan would capture the frames.

So the capture point does provide the relevant packets, it's just not matched properly...

Shouldn't a filter for "host " capture both tagged and untagged traffic? (and tread vlan 0 not different from vlans 1..4094 or even 4095)?

Wireshark, filtered to the relevant host, captures/shows the Priority Tagged Frame just fine:

Ethernet II, Src: 36:ba:38:20:b2:9a (36:ba:38:20:b2:9a), Dst: Netgear_18:04:ed (e4:f4:c6:18:04:ed)
    Destination: Netgear_18:04:ed (e4:f4:c6:18:04:ed)
    Source: 36:ba:38:20:b2:9a (36:ba:38:20:b2:9a)
    Type: 802.1Q Virtual LAN (0x8100)
802.1Q Virtual LAN, PRI: 5, DEI: 0, ID: 0
    101. .... .... .... = Priority: Voice, < 10ms latency and jitter (5)
    ...0 .... .... .... = DEI: Ineligible
    .... 0000 0000 0000 = ID: 0
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 192.168.233.233, Dst: 192.168.136.2
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0xa0 (DSCP: CS5, ECN: Not-ECT)
        1010 00.. = Differentiated Services Codepoint: Class Selector 5 (40)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 60
    Identification: 0x0000 (0)
    010. .... = Flags: 0x2, Don't fragment
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 64
    Protocol: TCP (6)
    Header Checksum: 0x46df [validation disabled]
    [Header checksum status: Unverified]
    Source Address: 192.168.233.233
    Destination Address: 192.168.136.2
Transmission Control Protocol, Src Port: 40232, Dst Port: 3260, Seq: 0, Len: 0
    Source Port: 40232
    Destination Port: 3260
    [Stream index: 1]
    [Conversation completeness: Incomplete, SYN_SENT (1)]
    [TCP Segment Len: 0]
    Sequence Number: 0    (relative sequence number)
    Sequence Number (raw): 3616783108
    [Next Sequence Number: 1    (relative sequence number)]
    Acknowledgment Number: 0
    Acknowledgment number (raw): 0
    1010 .... = Header Length: 40 bytes (10)
    Flags: 0x0c2 (SYN, ECE, CWR)
    Window: 65535
    [Calculated window size: 65535]
    Checksum: 0x06f0 [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    Options: (20 bytes), Maximum segment size, No-Operation (NOP), Window scale, SACK permitted, Timestamps
        TCP Option - Maximum segment size: 1460 bytes
        TCP Option - No-Operation (NOP)
        TCP Option - Window scale: 6 (multiply by 64)
        TCP Option - SACK permitted
        TCP Option - Timestamps
@rscheff rscheff changed the title tcpdump doesn't capture Eth PCP frame (vlan tag with vlan id 0) tcpdump doesn't adjust for eth priority tag when filtering for other fields? Oct 12, 2023
@guyharris guyharris transferred this issue from the-tcpdump-group/tcpdump Jan 21, 2024
@guyharris
Copy link
Member

Shouldn't a filter for "host " capture both tagged and untagged traffic?

That would be ideal, but it means more complicated BPF code, which also means more complicated compiler code, so it's not easy to do. (And it would be even more complicated if it had to handle an arbitrary number of tags, given that it would involve looping BPF code), but, fortunately, that probably wouldn't be necessary.)

@guyharris guyharris changed the title tcpdump doesn't adjust for eth priority tag when filtering for other fields? libpcap doesn't adjust for eth priority tag when filtering for other fields? Jan 21, 2024
@guyharris guyharris added VLAN Tagged frames requiring different filtering to match BPF related labels Jan 21, 2024
@rscheff
Copy link
Author

rscheff commented Jan 21, 2024

I think storing the "stack pointer" (what offset into a packet the BPF references relative to) and restoring it when writing hierarchical filter code would already go a long way.

Currently, every mention of "vlan" seems to shift this offset to the right by 2 bytes, but even if enclosed in brackets, the previous offset is not restored.

From memory, something like

"host1 or (vlan 10 and host2) or (vlan 20 and host3)"

will match host1 only on untagged traffic (maybe also in a Q-tagged, but IIRC the vlan token stops that internal extended match), host2 with one Q tag, and host3 only with 2 successive Q-tags, and every instance of "vlan" shifts the offset right by 2...

Not 100% sure though, but there was definitly something amiss with the "vlan" token and the handling of the offset beyond the current scope of the expression.

@infrastation
Copy link
Member

With regard to the original problem, there is a certain sense behind the current implementation: in the packet above the EtherType is 802.1Q, not IPv4 or IPv6, and the 802.1Q header is present, as far as the stack of headers goes. The VLAN ID equals 0, which indeed demands particular semantics in processing of the packet, but not at the encoding level, where BPF operates. Wireshark seems to define its "host" filter to chase certain headers, but BPF does not (not with the current syntax, anyway). So if you consider the expected behaviour and the observed behaviour, it may make more sense, separately in Wireshark filters and separately in BPF.

That said, the current expected behaviour of vlan is indeed not what users tend to expect, which is FAQ 13 (one of the bug reports linked from there discusses potential way to improve this).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BPF related VLAN Tagged frames requiring different filtering to match
Development

No branches or pull requests

3 participants