tcpdump mailing list archives

Re: pcap-savefile(5) in libpcap-1.10


From: Guy Harris <gharris () sonic net>
Date: Fri, 10 May 2024 17:20:30 -0700

On May 10, 2024, at 1:39 PM, Denis Ovsienko <denis () ovsienko info> wrote:

I have been looking through commits and the 1.10.5 section of libpcap
change log, and the recent changes to the link-layer header type field
structure look like a potential place for things to go wrong.

Specifically, the new prose says:

             P  (1  bit):  A bit that, if set, indicates that the
             Frame Check Sequence (FCS) length value is present and,
             if  not  set,  indicates that the FCS value is not
             present.

...and:

             FCS  len  (4  bits): A 4-bit unsigned value giving the
             number of 16-bit (2-octet) words of FCS that are appended
             to each  packet, if the P bit is set; if the P bit is not
             set, and the FCS length is not indicated by the
             link-layer type value, the FCS length is unknown.   The
             valid  values of the FCS len field are between 0 and 15;
             Ethernet, for example, would have an FCS length value of
             2, corresponding to a 4-octet FCS.

This all began with this thread:

        https://seclists.org/tcpdump/2007/q1/83

from 2007-02.  This thread:

        https://seclists.org/tcpdump/2007/q1/94

continues it with a repost.  In

        https://seclists.org/tcpdump/2007/q1/97

I first proposed "repurpose the upper 16 bits":

Or perhaps the link type value in the file header should be interpreted as having bitfields, with the lower 16 bits 
being the link layer type, and an indication of whether there's an FCS present being somewhere in the upper 16 bits.

NetBSD already uses the upper 16 bits for its own purpose - if the upper 16 bits are 0x0224, the lower 16 bits are a 
NetBSD address family value. (Given that AF_INET6, for example, has at least 3 different values on various 
BSD-flavored OSes, 0x0224 should be treated as NetBSD-specific, with other values used for other OSes.)

We could, for example, use the uppermost nibble as an FCS length indication, with the bit below it being an 
indication of whether the FCS length is known or not. That doesn't touch any of the bits in 0x0224.

For all current DLT_ values, the bit would be clear, so the FCS length isn't known; that's the case for Ethernet, as 
not only is it not known whether any given DLT_EN10MB capture has FCSes in the packets or not (some do, some don't), 
it's not even known which *packets* in a capture that does have FCSes (packets sent by the machine doing the capture 
don't, but there's not a per-packet way of indicating that).I think it would be possible to make this work with 
pcap-NG as well.

This has the advantage that "what is the link-layer header?" and "do frames have FCSes?" are separate questions, 
answered in separate bitfields of the link type value.

I think NetBSD never did much with their extension; we never did, either.

Florent Drouin, the person who asked for the "MTP2 with an FCS" DLT_ sent a patch to implement that idea in

        https://seclists.org/tcpdump/2007/q1/101

The current pcap Editor's Draft:

        https://ietf-opsawg-wg.github.io/draft-ietf-opsawg-pcap/draft-ietf-opsawg-pcap.html#name-file-header

says:

        LinkType and additional information (32 bits):a 32-bit unsigned value that contains the link-layer type of 
packets in the file and may contain additional information.

        The LinkType and additional information field is in the form

                             1                   2                   3
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        |FCS len|R|P|     Reserved3     |        Link-layer type        |
        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        Figure 2: LinkType and additional information

        The field is shown as if it were in the byte order of the host reading or writing the file, with bit 0 being 
the most-significant bit of the field and bit 31 being the least-significant bit of the field.

        Link-layer type (16 bits): a 16-bit value indicating link-layer type for packets in the file; it is a value as 
defined in the PCAP LinkType list registry, as defined in [I-D.ietf-opsawg-pcaplinktype].

        Reserved3 (10 bits) :not used - MUST be set to zero by pcap writers, and MUST NOT be interpreted by pcap 
readers; a reader SHOULD treat a non-zero value as an error.

        P (1 bit): a bit that, if set, indicates that the Frame Check Sequence (FCS) length value is present and, if 
not set, indicates that the FCS value is not present.

        R (1 bit): not used - MUST be set to zero by pcap writers, and MUST NOT be interpreted by pcap readers; a 
reader SHOULD treat a non-zero value as an error.

        FCS len (4 bits): a 4-bit unsigned value indicating the number of 16-bit (2-octet) words of FCS that are 
appended to each packet, if the P bit is set; if the P bit is not set, and the FCS length is not indicated by the 
link-layer type value, the FCS length is unknown. The valid values of the FCS len field are between 0 and 15; Ethernet, 
for example, would have an FCS length value of 2, corresponding to a 4-octet FCS.


As far as I understand, this translates into the following 5-bit value
space (P-FCSlen):

0-0000: FCS length is unknown.
0-0001: 2-octet FCS is absent. <-- ???

        ...

This looks redundant, unless the case "FCS length is unknown" is not
the same as "FCS is absent".

They're not the same.

At least for Ethernet, whether packet capture provides an FCS for incoming packets depends on the driver, etc.

*Most* of the time, the FCS isn't present by default, but one of my earliest machines at Apple, a Power Mac, *did* 
provide the FCS, which was passed on to libpcap via the BPF capture mechanism.  That's why Wireshark has heuristics to 
try to guess whether an FCS is present; the guess is based on

        1) knowing how long the Ethernet payload was, based on the dissector for the next protocol indicating the 
length (based on the total packet length in protocols such as IPv4 and IPv6, based on the length field in protocols 
that have a length field rather than a Ethertype field, and on other mechanism for protocols such as ARP);

        2) knowing that a received packet may be padded out to 60 bytes without the FCS and thus 64 bytes with the FCS.

Linux can, with various ethtool ioctls, provide it or not, at least if the adapter supports it.

For Wi-Fi, the radiotap header has a flag to indicate the FCS presence.  There's no Ethernet metadata header, 
unfortunately; pcapng, at least, has fields to provide that on a per-packet basis.

So probably what "FCS length is unknown" means should be specified on a per-linktype-basis.  For Ethernet, it's "maybe 
present, maybe not, try a heuristic if you want, but assuming it's absent will probably work in most situations".

Also it is not clear why the presence and size of an FCS are not details of the LINKTYPE_ specification.

For PPP, the FCS length is negotiable to 0 (absent), 2 (default), or 4 bytes:

        https://datatracker.ietf.org/doc/html/rfc1570#section-2.1

pcapng allows per-packet FCS lengths, which allows indicating 1) "this frame doesn't have an FCS" (e.g., because it's 
an outgoing frame) or 2) "we negotiated a larger FCS".  In practice, perhaps having an "IDB update" block (or "this is 
an update to IDB n" option to an IDB) would have been the right way to handle PPP negotiation, and an "FCS not present" 
bit in the packet block flags option would have been the right way to handle outgoing frames or other frames that lack 
an FCS.

Also do link-level types exist that have FCS size not a multiple of 2 octets or
more than 30 octets?

There are some link-level types for "raw USB 2.0" rather than "USB message logging" that you get from 
Linux/FreeBSD/macOS/USBPcap/etc., which presumably, if they include token frames, have a 5-bit CRC for that frame.

Since the high 16 bits of this field come from a WIP document, it seems
likely the encoding will change before settling,

Possibly, but it's been around for a while, and Wireshark already interprets it in that fashion; it's not all that new.
_______________________________________________
tcpdump-workers mailing list -- tcpdump-workers () lists tcpdump org
To unsubscribe send an email to tcpdump-workers-leave () lists tcpdump org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s


Current thread: