I received a pcap file from someone containing kuznetzov's pcap format.
According to "upstream" libpcap[0] this format uses
struct pcap_sf_patched_pkthdr, which is:
struct pcap_sf_patched_pkthdr {
    struct pcap_timeval ts;     /* time stamp */
    bpf_u_int32 caplen;         /* length of portion present */
    bpf_u_int32 len;            /* length of this packet (off wire) */
    int         index;
    unsigned short protocol;
    unsigned char pkt_type;
};

So compared to a normal pkthdr this adds[1]:
- index: interface index
- protocol: ethernet packet type
- pkt_type: broadcast/multicast/etc. indication

I don't think this information is particularly useful per say, so why
not just skip the 8 bytes and continue business as usual?

No public header change and allows me read the dump.

OK?

martijn@

[0] https://www.tcpdump.org/
[1] https://wiki.wireshark.org/Development/LibpcapFileFormat#modified-pcap

Index: usr.sbin/tcpdump/privsep.h
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/privsep.h,v
retrieving revision 1.12
diff -u -p -r1.12 privsep.h
--- usr.sbin/tcpdump/privsep.h  18 Mar 2019 00:09:22 -0000      1.12
+++ usr.sbin/tcpdump/privsep.h  1 Dec 2022 19:53:47 -0000
@@ -19,8 +19,6 @@
 
 #include <pcap-int.h>
 
-#define TCPDUMP_MAGIC 0xa1b2c3d4
-
 enum cmd_types {
        PRIV_OPEN_BPF,          /* open a bpf descriptor */
        PRIV_OPEN_DUMP,         /* open dump file for reading */
Index: usr.sbin/tcpdump/privsep_pcap.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/privsep_pcap.c,v
retrieving revision 1.25
diff -u -p -r1.25 privsep_pcap.c
--- usr.sbin/tcpdump/privsep_pcap.c     28 Jun 2019 13:32:51 -0000      1.25
+++ usr.sbin/tcpdump/privsep_pcap.c     1 Dec 2022 19:53:47 -0000
@@ -334,6 +334,7 @@ priv_pcap_live(const char *dev, int slen
 static void
 swap_hdr(struct pcap_file_header *hp)
 {
+       hp->magic = swap32(hp->magic);
        hp->version_major = swap16(hp->version_major);
        hp->version_minor = swap16(hp->version_minor);
        hp->thiszone = swap32(hp->thiszone);
@@ -390,20 +391,25 @@ priv_pcap_offline(const char *fname, cha
                goto bad;
        }
 
-       if (hdr.magic != TCPDUMP_MAGIC) {
-               if (swap32(hdr.magic) != TCPDUMP_MAGIC) {
-                       snprintf(errbuf, PCAP_ERRBUF_SIZE,
-                           "bad dump file format");
-                       goto bad;
-               }
+       switch (hdr.magic) {
+       case TCPDUMP_MAGIC:
+       case TCPDUMP_MAGIC_KUZNETZOV:
+               break;
+       case swap32(TCPDUMP_MAGIC):
+       case swap32(TCPDUMP_MAGIC_KUZNETZOV):
                p->sf.swapped = 1;
                swap_hdr(&hdr);
+               break;
+       default:
+               snprintf(errbuf, PCAP_ERRBUF_SIZE, "bad dump file format");
+               goto bad;
        }
        if (hdr.version_major < PCAP_VERSION_MAJOR) {
                snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format");
                goto bad;
        }
 
+       p->sf.magic = hdr.magic;
        p->tzoff = hdr.thiszone;
        p->snapshot = hdr.snaplen;
        p->linktype = hdr.linktype;
Index: lib/libpcap/pcap-int.h
===================================================================
RCS file: /cvs/src/lib/libpcap/pcap-int.h,v
retrieving revision 1.14
diff -u -p -r1.14 pcap-int.h
--- lib/libpcap/pcap-int.h      5 Apr 2018 03:47:27 -0000       1.14
+++ lib/libpcap/pcap-int.h      1 Dec 2022 19:53:47 -0000
@@ -51,6 +51,9 @@ struct pcap_opt {
        int     immediate;      /* immediate mode - deliver packets as soon as 
they arrive */
 };
 
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+#define TCPDUMP_MAGIC_KUZNETZOV 0xa1b2cd34
+
 /*
  * Savefile
  */
@@ -59,6 +62,7 @@ struct pcap_sf {
        int swapped;
        int version_major;
        int version_minor;
+       uint32_t magic;
        u_char *base;
 };
 
Index: lib/libpcap/savefile.c
===================================================================
RCS file: /cvs/src/lib/libpcap/savefile.c,v
retrieving revision 1.17
diff -u -p -r1.17 savefile.c
--- lib/libpcap/savefile.c      27 May 2020 04:24:01 -0000      1.17
+++ lib/libpcap/savefile.c      1 Dec 2022 19:53:47 -0000
@@ -45,8 +45,6 @@
 
 #include "pcap-int.h"
 
-#define TCPDUMP_MAGIC 0xa1b2c3d4
-
 /*
  * We use the "receiver-makes-right" approach to byte order,
  * because time is at a premium when we are writing the file.
@@ -90,6 +88,7 @@ sf_write_header(FILE *fp, int linktype, 
 static void
 swap_hdr(struct pcap_file_header *hp)
 {
+       hp->magic = SWAPLONG(hp->magic);
        hp->version_major = SWAPSHORT(hp->version_major);
        hp->version_minor = SWAPSHORT(hp->version_minor);
        hp->thiszone = SWAPLONG(hp->thiszone);
@@ -145,19 +144,24 @@ pcap_fopen_offline(FILE *fp, char *errbu
                    pcap_strerror(errno));
                goto bad;
        }
-       if (hdr.magic != TCPDUMP_MAGIC) {
-               if (SWAPLONG(hdr.magic) != TCPDUMP_MAGIC) {
-                       snprintf(errbuf, PCAP_ERRBUF_SIZE,
-                           "bad dump file format");
-                       goto bad;
-               }
+       switch (hdr.magic) {
+       case TCPDUMP_MAGIC:
+       case TCPDUMP_MAGIC_KUZNETZOV:
+               break;
+       case swap32(TCPDUMP_MAGIC):
+       case swap32(TCPDUMP_MAGIC_KUZNETZOV):
                p->sf.swapped = 1;
                swap_hdr(&hdr);
+               break;
+       default:
+               snprintf(errbuf, PCAP_ERRBUF_SIZE, "bad dump file format");
+               goto bad;
        }
        if (hdr.version_major < PCAP_VERSION_MAJOR) {
                snprintf(errbuf, PCAP_ERRBUF_SIZE, "archaic file format");
                goto bad;
        }
+       p->sf.magic = hdr.magic;
        p->tzoff = hdr.thiszone;
        p->snapshot = hdr.snaplen;
        p->linktype = hdr.linktype;
@@ -217,6 +221,11 @@ sf_next_packet(pcap_t *p, struct pcap_pk
        if (fread((char *)hdr, sizeof(struct pcap_pkthdr), 1, fp) != 1) {
                /* probably an EOF, though could be a truncated packet */
                return (1);
+       }
+       if (p->sf.magic == TCPDUMP_MAGIC_KUZNETZOV) {
+               /* The kuznetzov header doesn't contain anything interesting */
+               if (fseek(fp, 8, SEEK_CUR) == -1)
+                       return (1);
        }
 
        if (p->sf.swapped) {

Reply via email to