>Synopsis:      Allow libpcap to read files with some additional link-layer 
>type values
>Category:      library
>Environment:
        System      : OpenBSD 7.3
        Details     : OpenBSD 7.3 (GENERIC.MP) #1125: Sat Mar 25 10:36:29 MDT 
2023
                         
dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP

        Architecture: OpenBSD.amd64
        Machine     : amd64
>Description:
        Some DLT_s have values on one operating system that collide with
        values for different DLT_s on other operating systems.

        If those DLT_ values are used in pcap files as the link-layer
        header type, that means that the packets in captures with that
        link-layer type will be interpreted incorrectly on other
        operating systems.

        To resolve this, a different set of values for use as link-layer
        header types in files, the LINKTYPE_ values, was created:

                https://www.tcpdump.org/linktypes.html

        Most LINKTYPE_ values are numerically equal to the corresponding
        DLT_ values, so code that reads pcap files and that uses DLT_
        values in its APIs can just pass the link-layer type value on to
        the caller as a DLT_ value.

        However, for the LINKTYPE_ values that are not equal to the
        corresponding DLT_ value on some platform, because that
        platform's value collides with the value for a different DLT_ on
        another platform or platforms, the LINKTYPE_ value must be
        mapped to the corresponding DLT_ value before being provided to
        the caller.

        OpenBSD's libpcap does not do that, so captures for certain
        link-layer types will, if written using the LINKTYPE_ value, not
        be readable by programs using libpcap, such as tcpdump.
>How-To-Repeat:
        Build tcpdump.org's version of libpcap from the tip of the main
        branch, and then use that to build tcpdump.org's version of
        tcpdump.

        Capture on the loopback device with that version of tcpdump,
        saving the packets to a file using -w.

        Attempt to read that file with the tcpdump that comes with
        OpenBSD.
>Fix:
        Make this change to libpcap's savefile.c:

Index: savefile.c
===================================================================
RCS file: /cvs/src/lib/libpcap/savefile.c,v
retrieving revision 1.17
diff -u -r1.17 savefile.c
--- savefile.c  27 May 2020 04:24:01 -0000      1.17
+++ savefile.c  2 Aug 2023 05:36:57 -0000
@@ -160,7 +160,65 @@
        }
        p->tzoff = hdr.thiszone;
        p->snapshot = hdr.snaplen;
-       p->linktype = hdr.linktype;
+       /*
+        * Handle some LINKTYPE_ values in pcap headers that aren't
+        * the same as the corresponding OpenBSD DLT_ values.
+        *
+        * Those LINKTYPE_ values were assigned for DLT_s whose
+        * numerical values differ between platforms, so that
+        * the link-layer type value in pcap file headers can
+        * be platform-independent.  This means that code reading
+        * a pcap file doesn't have to know on which platform a
+        * file was written in order to read it correctly.
+        *
+        * See
+        *
+        *     https://www.tcpdump.org/linktypes.html
+        *
+        * for the current list of LINKTYPE_ values and the corresponding
+        * DLT_ values.
+        */
+       switch (hdr.linktype) {
+
+       case 100:
+               /* LINKTYPE_ATM_RFC1483 */
+               p->linktype = DLT_ATM_RFC1483;
+               break;
+
+       case 101:
+               /* LINKTYPE_RAW */
+               p->linktype = DLT_RAW;
+               break;
+
+       case 102:
+               /* LINKTYPE_SLIP_BSDOS */
+               p->linktype = DLT_SLIP_BSDOS;
+               break;
+
+       case 103:
+               /* LINKTYPE_PPP_BSDOS */
+               p->linktype = DLT_PPP_BSDOS;
+               break;
+
+       case 108:
+               /* LINKTYPE_LOOP */
+               p->linktype = DLT_LOOP;
+               break;
+
+       case 109:
+               /* LINKTYPE_ENC */
+               p->linktype = DLT_ENC;
+               break;
+
+       case 256:
+               /* LINKTYPE_PFSYNC */
+               p->linktype = DLT_PFSYNC;
+               break;
+
+       default:
+               p->linktype = hdr.linktype;
+               break;
+       }
        p->sf.rfile = fp;
        p->bufsize = hdr.snaplen;
 


Reply via email to