Handle ETH_P_CANFD as well as ETH_P_CAN.
[metze/wireshark/wip.git] / wiretap / pcap-common.c
index cfd090c60de18a1acf4a49fb7de6db7ef1038914..27e3fd687f5939d88ef4185d9817db80ef55d103 100644 (file)
@@ -1,8 +1,6 @@
 /* pcap-common.c
  * Code common to libpcap and pcap-NG file formats
  *
- * $Id$
- *
  * Wiretap Library
  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
  *
 #include "pcap-common.h"
 
 /*
- * Map link-layer types (LINKTYPE_ values) to Wiretap encapsulations.
- */
-/*
+ * Map link-layer header types (LINKTYPE_ values) to Wiretap encapsulations.
+ *
  * Either LBL NRG wasn't an adequate central registry (e.g., because of
  * the slow rate of releases from them), or nobody bothered using them
  * as a central registry, as many different groups have patched libpcap
  * (and BPF, on the BSDs) to add new encapsulation types, and have ended
  * up using the same DLT_ values for different encapsulation types.
  *
- * For those numerical encapsulation type values that everybody uses for
- * the same encapsulation type (which inclues those that some platforms
- * specify different DLT_ names for but don't appear to use), we map
- * those values to the appropriate Wiretap values.
+ * The Tcpdump Group now maintains the list of link-layer header types;
+ * they introduced a separate namespace of LINKTYPE_ values for the
+ * values to be used in capture files, and have libpcap map between
+ * those values in capture file headers and the DLT_ values that the
+ * pcap_datalink() and pcap_open_dead() APIs use.  See
+ * http://www.tcpdump.org/linktypes.html for a list of LINKTYPE_ values.
+ *
+ * In most cases, the corresponding LINKTYPE_ and DLT_ values are the
+ * same.  In the cases where the same link-layer header type was given
+ * different values in different OSes, a new LINKTYPE_ value was defined,
+ * different from all of the existing DLT_ values.
  *
- * For those numerical encapsulation type values that different libpcap
- * variants use for different encapsulation types, we check what
- * <pcap.h> defined to determine how to interpret them, so that we
- * interpret them the way the libpcap with which we're building
+ * This table maps LINKTYPE_ values to the corresponding Wiretap
+ * encapsulation.  For cases where multiple DLT_ values were in use,
+ * it also checks what <pcap.h> defineds to determine how to interpret
+ * them, so that if a file was written by a version of libpcap prior
+ * to the introduction of the LINKTYPE_ values, and has a DLT_ value
+ * from the OS on which it was written rather than a LINKTYPE_ value
+ * as its linktype value in the file header, we map the numerical
+ * DLT_ value, as interpreted by the libpcap with which we're building
  * Wireshark/Wiretap interprets them (which, if it doesn't support
  * them at all, means we don't support them either - any capture files
  * using them are foreign, and we don't hazard a guess as to which
  * platform they came from; we could, I guess, choose the most likely
- * platform).
+ * platform), to the corresponding Wiretap encapsulation.
  *
  * Note: if you need a new encapsulation type for libpcap files, do
  * *N*O*T* use *ANY* of the values listed here!  I.e., do *NOT*
  * leave the existing entries alone.
  *
  * Instead, send mail to tcpdump-workers@lists.tcpdump.org, asking for
- * a new DLT_ value, and specifying the purpose of the new value.  When
- * you get the new DLT_ value, use that numerical value in the "dlt_value"
- * field of "pcap_to_wtap_map[]".
+ * a new LINKTYPE_/DLT_ value, and specifying the purpose of the new
+ * value.  When you get the new LINKTYPE_/DLT_ value, use that numerical
+ * value in the "linktype_value" field of "pcap_to_wtap_map[]".
  */
 
 static const struct {
-       int     dlt_value;
+       int     linktype_value;
        int     wtap_encap_value;
 } pcap_to_wtap_map[] = {
        /*
         * These are the values that are almost certainly the same
         * in all libpcaps (I've yet to find one where the values
         * in question are used for some purpose other than the
-        * one below, but...), and that Wiretap and Wireshark
-        * currently support.
+        * one below, but...), and thus assigned as LINKTYPE_ values,
+        * and that Wiretap and Wireshark currently support.
         */
        { 0,            WTAP_ENCAP_NULL },      /* null encapsulation */
        { 1,            WTAP_ENCAP_ETHERNET },
@@ -174,7 +182,9 @@ static const struct {
         * These are the values that libpcap 0.5 and later use in
         * capture file headers, in an attempt to work around the
         * confusion decried above, and that Wiretap and Wireshark
-        * currently support.
+        * currently support.  I.e., they're the LINKTYPE_ values
+        * for RFC 1483 ATM and "raw IP", respectively, not the
+        * DLT_ values for them on all platforms.
         */
        { 100,          WTAP_ENCAP_ATM_RFC1483 },
        { 101,          WTAP_ENCAP_RAW_IP },
@@ -196,7 +206,7 @@ static const struct {
        { 105,          WTAP_ENCAP_IEEE_802_11 }, /* IEEE 802.11 */
        { 106,          WTAP_ENCAP_LINUX_ATM_CLIP },
        { 107,          WTAP_ENCAP_FRELAY },    /* Frame Relay */
-       { 108,          WTAP_ENCAP_NULL },      /* OpenBSD loopback */
+       { 108,          WTAP_ENCAP_LOOP },      /* OpenBSD loopback */
        { 109,          WTAP_ENCAP_ENC },       /* OpenBSD IPSEC enc */
 #if 0
        { 110,          WTAP_ENCAP_LANE_802_3 },/* ATM LANE 802.3 */
@@ -207,10 +217,10 @@ static const struct {
        /*
         * Linux "cooked mode" captures, used by the current CVS version
         * of libpcap
-         * OR
-         * it could be a packet in Cisco's ERSPAN encapsulation which uses
-         * this number as well (why can't people stick to protocols when it
-         * comes to allocating/using DLT types).
+        * OR
+        * it could be a packet in Cisco's ERSPAN encapsulation which uses
+        * this number as well (why can't people stick to protocols when it
+        * comes to allocating/using DLT types).
         */
        { 113,          WTAP_ENCAP_SLL },       /* Linux cooked capture */
 
@@ -289,17 +299,16 @@ static const struct {
        /* Ethernet PPPoE frames captured on a service PIC */
        { 167,          WTAP_ENCAP_JUNIPER_PPPOE },
 
-        /*
+       /*
         * 168 is reserved for more Juniper private-chassis-
         * internal meta-information.
         */
 
        { 169,          WTAP_ENCAP_GPRS_LLC },
 
-       /*
-        * 170 and 171 are reserved for ITU-T G.7041/Y.1303 Generic
-        * Framing Procedure.
-        */
+       /* ITU-T G.7041/Y.1303 Generic Framing Procedure. */
+       { 170,          WTAP_ENCAP_GFP_T },
+       { 171,          WTAP_ENCAP_GFP_F },
 
        /* Registered by Gcom, Inc. */
        { 172,          WTAP_ENCAP_GCOM_TIE1 },
@@ -307,7 +316,7 @@ static const struct {
 
        { 177,          WTAP_ENCAP_LINUX_LAPD },
 
-    /* Ethernet frames prepended with meta-information */
+       /* Ethernet frames prepended with meta-information */
        { 178,          WTAP_ENCAP_JUNIPER_ETHER },
        /* PPP frames prepended with meta-information */
        { 179,          WTAP_ENCAP_JUNIPER_PPP },
@@ -317,16 +326,18 @@ static const struct {
        { 181,          WTAP_ENCAP_JUNIPER_CHDLC },
        /* VOIP Frames prepended with meta-information */
        { 183,          WTAP_ENCAP_JUNIPER_VP },
-       /* raw USB packets */
-       { 186,          WTAP_ENCAP_USB },
+       /* Virtual Network Frames prepended with meta-information */
+       { 184,          WTAP_ENCAP_JUNIPER_VN },
+       /* USB packets from FreeBSD's USB BPF tap */
+       { 186,          WTAP_ENCAP_USB_FREEBSD },
        /* Bluetooth HCI UART transport (part H:4) frames, like hcidump */
-       { 187,          WTAP_ENCAP_BLUETOOTH_H4 },
+       { 187,          WTAP_ENCAP_BLUETOOTH_H4 },
        /* IEEE 802.16 MAC Common Part Sublayer */
        { 188,          WTAP_ENCAP_IEEE802_16_MAC_CPS },
        /* USB packets with Linux-specified header */
-       { 189,          WTAP_ENCAP_USB_LINUX },
+       { 189,          WTAP_ENCAP_USB_LINUX },
        /* CAN 2.0b frame */
-       { 190,          WTAP_ENCAP_CAN20B },
+       { 190,          WTAP_ENCAP_CAN20B },
        /* Per-Packet Information header */
        { 192,          WTAP_ENCAP_PPI },
        /* IEEE 802.15.4 Wireless PAN */
@@ -338,29 +349,29 @@ static const struct {
        /* IPMB */
        { 199,          WTAP_ENCAP_IPMB },
        /* Bluetooth HCI UART transport (part H:4) frames, like hcidump */
-       { 201,          WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR },
+       { 201,          WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR },
        /* AX.25 packet with a 1-byte KISS header */
        { 202,          WTAP_ENCAP_AX25_KISS },
        /* LAPD frame */
-       { 203,          WTAP_ENCAP_LAPD },
+       { 203,          WTAP_ENCAP_LAPD },
        /* PPP with pseudoheader */
        { 204,          WTAP_ENCAP_PPP_WITH_PHDR },
        /* IPMB/I2C */
        { 209,          WTAP_ENCAP_I2C },
        /* FlexRay frame */
-       { 210,          WTAP_ENCAP_FLEXRAY },
+       { 210,          WTAP_ENCAP_FLEXRAY },
        /* MOST frame */
-       { 211,          WTAP_ENCAP_MOST },
+       { 211,          WTAP_ENCAP_MOST },
        /* LIN frame */
-       { 212,          WTAP_ENCAP_LIN },
+       { 212,          WTAP_ENCAP_LIN },
        /* X2E Xoraya serial frame */
-       { 213,          WTAP_ENCAP_X2E_SERIAL },
+       { 213,          WTAP_ENCAP_X2E_SERIAL },
        /* X2E Xoraya frame */
-       { 214,          WTAP_ENCAP_X2E_XORAYA },
+       { 214,          WTAP_ENCAP_X2E_XORAYA },
        /* IEEE 802.15.4 Wireless PAN non-ASK PHY */
        { 215,          WTAP_ENCAP_IEEE802_15_4_NONASK_PHY },
        /* USB packets with padded Linux-specified header */
-       { 220,          WTAP_ENCAP_USB_LINUX_MMAPPED },
+       { 220,          WTAP_ENCAP_USB_LINUX_MMAPPED },
        /* Fibre Channel FC-2 frame */
        { 224,          WTAP_ENCAP_FIBRE_CHANNEL_FC2 },
        /* Fibre Channel FC-2 frame with Delimiter */
@@ -381,6 +392,8 @@ static const struct {
        { 235,          WTAP_ENCAP_DVBCI },
        /* MUX27010 */
        { 236,          WTAP_ENCAP_MUX27010 },
+       /* STANAG 5066 - DTS(Data Transfer Sublayer) PDU */
+       { 237,          WTAP_ENCAP_STANAG_5066_D_PDU },
        /* NFLOG */
        { 239,          WTAP_ENCAP_NFLOG },
        /* netANALYZER pseudo-header followed by Ethernet with CRC */
@@ -388,7 +401,7 @@ static const struct {
        /* netANALYZER pseudo-header in transparent mode */
        { 241,          WTAP_ENCAP_NETANALYZER_TRANSPARENT },
        /* IP-over-Infiniband, as specified by RFC 4391 section 6 */
-       { 242,          WTAP_ENCAP_IP_OVER_IB },
+       { 242,          WTAP_ENCAP_IP_OVER_IB_PCAP },
        /* ISO/IEC 13818-1 MPEG2-TS packets */
        { 243,          WTAP_ENCAP_MPEG_2_TS },
        /* NFC LLCP */
@@ -399,6 +412,30 @@ static const struct {
        { 249,          WTAP_ENCAP_USBPCAP},
        /* RTAC SERIAL */
        { 250,          WTAP_ENCAP_RTAC_SERIAL},
+       /* Bluetooth Low Energy Link Layer */
+       { 251,          WTAP_ENCAP_BLUETOOTH_LE_LL},
+       /* Wireshark Upper PDU export */
+       { 252,          WTAP_ENCAP_WIRESHARK_UPPER_PDU},
+       /* Netlink Protocol (nlmon devices) */
+       { 253,          WTAP_ENCAP_NETLINK },
+       /* Bluetooth Linux Monitor */
+       { 254,          WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR },
+       /* Bluetooth BR/EDR Baseband RF captures */
+       { 255,          WTAP_ENCAP_BLUETOOTH_BREDR_BB },
+       /* Bluetooth Low Energy Link Layer RF captures */
+       { 256,          WTAP_ENCAP_BLUETOOTH_LE_LL_WITH_PHDR },
+
+       /* Apple PKTAP */
+       { 258,          WTAP_ENCAP_PKTAP },
+
+       /* Ethernet Passive Optical Network */
+       { 259,          WTAP_ENCAP_EPON },
+
+       /* IPMI Trace Data Collection */
+       { 260,          WTAP_ENCAP_IPMI_TRACE },
+
+       /* ISO14443 contactless smartcard standards */
+       { 264,          WTAP_ENCAP_ISO14443 },
 
        /*
         * To repeat:
@@ -411,42 +448,30 @@ static const struct {
         * Instead, send mail to tcpdump-workers@lists.tcpdump.org, asking
         * for a new DLT_ value, and specifying the purpose of the new value.
         * When you get the new DLT_ value, use that numerical value in
-        * the "dlt_value" field of "pcap_to_wtap_map[]".
+        * the "linktype_value" field of "pcap_to_wtap_map[]".
         */
 
        /*
         * The following are entries for libpcap type values that have
-        * different meanings on different OSes.
+        * different meanings on different OSes.  I.e., these are DLT_
+        * values that are different on different OSes, and that have
+        * a separate LINKTYPE_ value assigned to them.
         *
-        * We put these *after* the entries for the platform-independent
-        * libpcap type values for those Wiretap encapsulation types, so
-        * that Wireshark chooses the platform-independent libpcap type
-        * value for those encapsulatioin types, not the platform-dependent
-        * one.
+        * We put these *after* the entries for the LINKTYPE_ values for
+        * those Wiretap encapsulation types, so that, when writing a
+        * pcap or pcap-ng file, Wireshark writes the LINKTYPE_ value,
+        * not the OS's DLT_ value, as the file's link-layer header type
+        * for pcap or the interface's link-layer header type.
         */
 
        /*
         * 11 is DLT_ATM_RFC1483 on most platforms; the only libpcaps I've
         * seen that define anything other than DLT_ATM_RFC1483 as 11 are
-        * the BSD/OS one, which defines DLT_FR as 11, and libpcap 0.5,
-        * which define it as 100, mapping the kernel's value to 100, in
-        * an attempt to hide the different values used on different
+        * the BSD/OS one, which defines DLT_FR as 11.  We handle it as
+        * Frame Relay on BSD/OS and LLC-encapsulated ATM on all other
         * platforms.
-        *
-        * If this is a platform where DLT_FR is defined as 11, we
-        * don't handle 11 at all; otherwise, we handle it as
-        * DLT_ATM_RFC1483 (this means we'd misinterpret Frame Relay
-        * captures from BSD/OS if running on platforms other than BSD/OS,
-        * but
-        *
-        *      1) we don't yet support DLT_FR
-        *
-        * and
-        *
-        *      2) nothing short of a heuristic would let us interpret
-        *         them correctly).
         */
-#if defined(DLT_FR) && (DLT_FR == 11)
+#if defined(__bsdi__) /* BSD/OS */
        { 11,           WTAP_ENCAP_FRELAY },
 #else
        { 11,           WTAP_ENCAP_ATM_RFC1483 },
@@ -460,13 +485,13 @@ static const struct {
         * (it's just like DLT_NULL, only with the AF_ value in network
         * rather than host byte order - Wireshark figures out the
         * byte order from the data, so we don't care what byte order
-        * it's in), so if DLT_LOOP is defined as 12, interpret 12
-        * as WTAP_ENCAP_NULL, otherwise, unless DLT_C_HDLC is defined
-        * as 12, interpret it as WTAP_ENCAP_RAW_IP.
+        * it's in), so, on OpenBSD, interpret 12 as WTAP_ENCAP_LOOP,
+        * otherwise, if we're not on BSD/OS, interpret it as
+        * WTAP_ENCAP_RAW_IP.
         */
-#if defined(DLT_LOOP) && (DLT_LOOP == 12)
-       { 12,           WTAP_ENCAP_NULL },
-#elif defined(DLT_C_HDLC) && (DLT_C_HDLC == 12)
+#if defined(__OpenBSD__)
+       { 12,           WTAP_ENCAP_LOOP },
+#elif defined(__bsdi__) /* BSD/OS */
        /*
         * Put entry for Cisco HDLC here.
         * XXX - is this just WTAP_ENCAP_CHDLC, i.e. does the frame
@@ -497,7 +522,7 @@ static const struct {
         * treate 13 as WTAP_ENCAP_ATM_RFC1483, but, on all other
         * systems, we can read OpenBSD DLT_ENC captures.
         */
-#if defined(DLT_ATM_RFC1483) && (DLT_ATM_RFC1483 == 13)
+#if defined(__bsdi__) /* BSD/OS */
        { 13,           WTAP_ENCAP_ATM_RFC1483 },
 #else
        { 13,           WTAP_ENCAP_ENC },
@@ -546,21 +571,24 @@ static const struct {
         *      DLT_I4L_IP with the ISDN4Linux patches for libpcap
         *      (and on SuSE 6.3).
         */
-#if defined(DLT_CIP) && (DLT_CIP == 16)
-       { 16,           WTAP_ENCAP_LINUX_ATM_CLIP },
-#endif
-#if defined(DLT_HDLC) && (DLT_HDLC == 16)
+#if defined(__NetBSD__)
        { 16,           WTAP_ENCAP_CHDLC },
+#elif !defined(__bsdi__)
+       /*
+        * If you care about the two different Linux interpretations
+        * of 16, fix it yourself.
+        */
+       { 16,           WTAP_ENCAP_LINUX_ATM_CLIP },
 #endif
 
        /*
         * 17 is DLT_LANE8023 in SuSE 6.3 libpcap; we don't currently
         * handle it.
         * It is also used as the PF (Packet Filter) logging format beginning
-        * with OpenBSD 3.0; we use 17 for PF logs unless DLT_LANE8023 is
-        * defined with the value 17.
+        * with OpenBSD 3.0; we use 17 for PF logs on OpenBSD and don't
+        * use it otherwise.
         */
-#if !defined(DLT_LANE8023) || (DLT_LANE8023 != 17)
+#if defined(__OpenBSD__)
        { 17,           WTAP_ENCAP_OLD_PFLOG },
 #endif
 
@@ -592,7 +620,7 @@ static const struct {
         * Instead, send mail to tcpdump-workers@lists.tcpdump.org, asking
         * for a new DLT_ value, and specifying the purpose of the new value.
         * When you get the new DLT_ value, use that numerical value in
-        * the "dlt_value" field of "pcap_to_wtap_map[]".
+        * the "linktype_value" field of "pcap_to_wtap_map[]".
         */
 };
 #define NUM_PCAP_ENCAPS (sizeof pcap_to_wtap_map / sizeof pcap_to_wtap_map[0])
@@ -603,7 +631,7 @@ wtap_pcap_encap_to_wtap_encap(int encap)
        unsigned int i;
 
        for (i = 0; i < NUM_PCAP_ENCAPS; i++) {
-               if (pcap_to_wtap_map[i].dlt_value == encap)
+               if (pcap_to_wtap_map[i].linktype_value == encap)
                        return pcap_to_wtap_map[i].wtap_encap_value;
        }
        return WTAP_ENCAP_UNKNOWN;
@@ -618,7 +646,6 @@ wtap_wtap_encap_to_pcap_encap(int encap)
 
        case WTAP_ENCAP_FDDI:
        case WTAP_ENCAP_FDDI_BITSWAPPED:
-       case WTAP_ENCAP_NETTL_FDDI:
                /*
                 * Special-case WTAP_ENCAP_FDDI and
                 * WTAP_ENCAP_FDDI_BITSWAPPED; both of them get mapped
@@ -626,12 +653,25 @@ wtap_wtap_encap_to_pcap_encap(int encap)
                 * order in the FDDI MAC addresses is wrong; so it goes
                 * - libpcap format doesn't record the byte order,
                 * so that's not fixable).
+                *
+                * The pcap_to_wtap_map[] table will only have an
+                * entry for one of the above, which is why we have
+                * to special-case them.
+                */
+               return 10;      /* that's DLT_FDDI */
+
+       case WTAP_ENCAP_NETTL_FDDI:
+               /*
+                * This will discard the nettl information, as that's
+                * in the pseudo-header.
+                *
+                * XXX - what about Ethernet and Token Ring?
                 */
                return 10;      /* that's DLT_FDDI */
 
        case WTAP_ENCAP_FRELAY_WITH_PHDR:
                /*
-                * Do the same with Frame Relay.
+                * This will discard the pseudo-header information.
                 */
                return 107;
 
@@ -639,45 +679,36 @@ wtap_wtap_encap_to_pcap_encap(int encap)
                /*
                 * Map this to DLT_IEEE802_11, for now, even though
                 * that means the radio information will be lost.
-                * Once tcpdump support for the BSD radiotap header
-                * is sufficiently widespread, we should probably
-                * use that, instead - although we should probably
-                * ultimately just have WTAP_ENCAP_IEEE_802_11
-                * as the only Wiretap encapsulation for 802.11,
-                * and have the pseudo-header include a radiotap-style
-                * list of attributes.  If we do that, though, we
-                * should probably bypass the regular Wiretap code
-                * when writing out packets during a capture, and just
-                * do the equivalent of a libpcap write (unfortunately,
-                * libpcap doesn't have an "open dump by file descriptor"
-                * function, so we can't just use "pcap_dump()"), so
-                * that we don't spend cycles mapping from libpcap to
-                * Wiretap and then back to libpcap.  (There are other
-                * reasons to do that, e.g. to handle AIX libpcap better.)
+                * We should try to map those values to radiotap
+                * values and write this out as a radiotap file,
+                * if possible.
                 */
                return 105;
        }
 
        for (i = 0; i < NUM_PCAP_ENCAPS; i++) {
                if (pcap_to_wtap_map[i].wtap_encap_value == encap)
-                       return pcap_to_wtap_map[i].dlt_value;
+                       return pcap_to_wtap_map[i].linktype_value;
        }
        return -1;
 }
 
 gboolean
-wtap_encap_requires_phdr(int encap) {
-       if (
-               (encap == WTAP_ENCAP_ATM_PDUS) ||
-               (encap == WTAP_ENCAP_IRDA) ||
-               (encap == WTAP_ENCAP_MTP2_WITH_PHDR) ||
-               (encap == WTAP_ENCAP_LINUX_LAPD) ||
-               (encap == WTAP_ENCAP_SITA) ||
-               (encap == WTAP_ENCAP_ERF) ||
-               (encap == WTAP_ENCAP_I2C) ||
-               (encap == WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR) ||
-               (encap == WTAP_ENCAP_PPP_WITH_PHDR)
-       ) {
+wtap_encap_requires_phdr(int wtap_encap)
+{
+       switch (wtap_encap) {
+
+       case WTAP_ENCAP_ATM_PDUS:
+       case WTAP_ENCAP_IRDA:
+       case WTAP_ENCAP_MTP2_WITH_PHDR:
+       case WTAP_ENCAP_LINUX_LAPD:
+       case WTAP_ENCAP_SITA:
+       case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
+       case WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR:
+       case WTAP_ENCAP_NFC_LLCP:
+       case WTAP_ENCAP_PPP_WITH_PHDR:
+       case WTAP_ENCAP_ERF:
+       case WTAP_ENCAP_I2C:
                return TRUE;
        }
        return FALSE;
@@ -713,6 +744,18 @@ wtap_encap_requires_phdr(int encap) {
  */
 #define NOKIA_LEN      4       /* length of the header */
 
+/*
+ * The fake link-layer header of Linux cooked packets.
+ */
+#define LINUX_SLL_PROTOCOL_OFFSET      14      /* protocol */
+#define LINUX_SLL_LEN                  16      /* length of the header */
+
+/*
+ * The protocols we have to check for.
+ */
+#define LINUX_SLL_P_CAN                        0x000C  /* Controller Area Network */
+#define LINUX_SLL_P_CANFD              0x000D  /* Controller Area Network flexible data rate */
+
 /*
  * The fake link-layer header of IrDA packets as introduced by Jean Tourrilhes
  * to libpcap.
@@ -765,8 +808,8 @@ wtap_encap_requires_phdr(int encap) {
  * I2C link-layer on-disk format
  */
 struct i2c_file_hdr {
-    guint8 bus;
-    guint8 flags[4];
+       guint8 bus;
+       guint8 flags[4];
 };
 
 static gboolean
@@ -774,21 +817,14 @@ pcap_read_sunatm_pseudoheader(FILE_T fh,
     union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
        guint8  atm_phdr[SUNATM_LEN];
-       int     bytes_read;
        guint8  vpi;
        guint16 vci;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(atm_phdr, SUNATM_LEN, fh);
-       if (bytes_read != SUNATM_LEN) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, atm_phdr, SUNATM_LEN, err, err_info))
                return FALSE;
-       }
 
        vpi = atm_phdr[SUNATM_VPI];
-       vci = pntohs(&atm_phdr[SUNATM_VCI]);
+       vci = pntoh16(&atm_phdr[SUNATM_VCI]);
 
        switch (atm_phdr[SUNATM_FLAGS] & 0x0F) {
 
@@ -862,21 +898,14 @@ pcap_read_nokiaatm_pseudoheader(FILE_T fh,
     union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
        guint8  atm_phdr[NOKIAATM_LEN];
-       int     bytes_read;
        guint8  vpi;
        guint16 vci;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(atm_phdr, NOKIAATM_LEN, fh);
-       if (bytes_read != NOKIAATM_LEN) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, atm_phdr, NOKIAATM_LEN, err, err_info))
                return FALSE;
-       }
 
        vpi = atm_phdr[NOKIAATM_VPI];
-       vci = pntohs(&atm_phdr[NOKIAATM_VCI]);
+       vci = pntoh16(&atm_phdr[NOKIAATM_VCI]);
 
        pseudo_header->atm.vpi = vpi;
        pseudo_header->atm.vci = vci;
@@ -897,9 +926,7 @@ pcap_read_nokia_pseudoheader(FILE_T fh,
     union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
        guint8  phdr[NOKIA_LEN];
-       int     bytes_read;
 
-       errno = WTAP_ERR_CANT_READ;
 
        /* backtrack to read the 4 mysterious bytes that aren't considered
        * part of the packet size
@@ -912,13 +939,8 @@ pcap_read_nokia_pseudoheader(FILE_T fh,
                return FALSE;
        }
 
-       bytes_read = file_read(phdr, NOKIA_LEN, fh);
-       if (bytes_read != NOKIA_LEN) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, phdr, NOKIA_LEN, err, err_info))
                return FALSE;
-       }
 
        memcpy(pseudo_header->nokia.stuff, phdr, NOKIA_LEN);
 
@@ -930,25 +952,18 @@ pcap_read_irda_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
     int *err, gchar **err_info)
 {
        guint8  irda_phdr[IRDA_SLL_LEN];
-       int     bytes_read;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(irda_phdr, IRDA_SLL_LEN, fh);
-       if (bytes_read != IRDA_SLL_LEN) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, irda_phdr, IRDA_SLL_LEN, err, err_info))
                return FALSE;
-       }
 
-       if (pntohs(&irda_phdr[IRDA_SLL_PROTOCOL_OFFSET]) != 0x0017) {
+       if (pntoh16(&irda_phdr[IRDA_SLL_PROTOCOL_OFFSET]) != 0x0017) {
                *err = WTAP_ERR_BAD_FILE;
                if (err_info != NULL)
                        *err_info = g_strdup("libpcap: IrDA capture has a packet with an invalid sll_protocol field");
                return FALSE;
        }
 
-       pseudo_header->irda.pkttype = pntohs(&irda_phdr[IRDA_SLL_PKTTYPE_OFFSET]);
+       pseudo_header->irda.pkttype = pntoh16(&irda_phdr[IRDA_SLL_PKTTYPE_OFFSET]);
 
        return TRUE;
 }
@@ -957,20 +972,13 @@ static gboolean
 pcap_read_mtp2_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
        guint8 mtp2_hdr[MTP2_HDR_LEN];
-       int    bytes_read;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(mtp2_hdr, MTP2_HDR_LEN, fh);
-       if (bytes_read != MTP2_HDR_LEN) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, mtp2_hdr, MTP2_HDR_LEN, err, err_info))
                return FALSE;
-       }
 
        pseudo_header->mtp2.sent         = mtp2_hdr[MTP2_SENT_OFFSET];
        pseudo_header->mtp2.annex_a_used = mtp2_hdr[MTP2_ANNEX_A_USED_OFFSET];
-       pseudo_header->mtp2.link_number  = pntohs(&mtp2_hdr[MTP2_LINK_NUMBER_OFFSET]);
+       pseudo_header->mtp2.link_number  = pntoh16(&mtp2_hdr[MTP2_LINK_NUMBER_OFFSET]);
 
        return TRUE;
 }
@@ -980,25 +988,18 @@ pcap_read_lapd_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
     int *err, gchar **err_info)
 {
        guint8  lapd_phdr[LAPD_SLL_LEN];
-       int     bytes_read;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(lapd_phdr, LAPD_SLL_LEN, fh);
-       if (bytes_read != LAPD_SLL_LEN) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, lapd_phdr, LAPD_SLL_LEN, err, err_info))
                return FALSE;
-       }
 
-       if (pntohs(&lapd_phdr[LAPD_SLL_PROTOCOL_OFFSET]) != ETH_P_LAPD) {
+       if (pntoh16(&lapd_phdr[LAPD_SLL_PROTOCOL_OFFSET]) != ETH_P_LAPD) {
                *err = WTAP_ERR_BAD_FILE;
                if (err_info != NULL)
                        *err_info = g_strdup("libpcap: LAPD capture has a packet with an invalid sll_protocol field");
                return FALSE;
        }
 
-       pseudo_header->lapd.pkttype = pntohs(&lapd_phdr[LAPD_SLL_PKTTYPE_OFFSET]);
+       pseudo_header->lapd.pkttype = pntoh16(&lapd_phdr[LAPD_SLL_PKTTYPE_OFFSET]);
        pseudo_header->lapd.we_network = !!lapd_phdr[LAPD_SLL_ADDR_OFFSET+0];
 
        return TRUE;
@@ -1008,16 +1009,9 @@ static gboolean
 pcap_read_sita_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
        guint8  sita_phdr[SITA_HDR_LEN];
-       int     bytes_read;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(sita_phdr, SITA_HDR_LEN, fh);
-       if (bytes_read != SITA_HDR_LEN) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, sita_phdr, SITA_HDR_LEN, err, err_info))
                return FALSE;
-       }
 
        pseudo_header->sita.sita_flags   = sita_phdr[SITA_FLAGS_OFFSET];
        pseudo_header->sita.sita_signals = sita_phdr[SITA_SIGNALS_OFFSET];
@@ -1078,8 +1072,8 @@ pcap_read_sita_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
  * This structure is 8 bytes long.
  */
 struct iso_rec {
-    gint32 error_count;
-    gint32 numdesc;
+       gint32 error_count;
+       gint32 numdesc;
 };
 
 /*
@@ -1090,53 +1084,53 @@ struct iso_rec {
  * The values are in *host* byte order.
  */
 struct linux_usb_phdr {
-    guint64 id;             /* urb id, to link submission and completion events */
-    guint8 event_type;      /* Submit ('S'), Completed ('C'), Error ('E') */
-    guint8 transfer_type;   /* ISO (0), Intr, Control, Bulk (3) */
-    guint8 endpoint_number; /* Endpoint number (0-15) and transfer direction */
-    guint8 device_address;  /* 0-127 */
-    guint16 bus_id;
-    gint8 setup_flag;       /* 0, if the urb setup header is meaningful */
-    gint8 data_flag;        /* 0, if urb data is present */
-    gint64 ts_sec;
-    gint32 ts_usec;
-    gint32 status;
-    guint32 urb_len;        /* whole len of urb this event refers to */
-    guint32 data_len;       /* amount of urb data really present in this event */
-
-    /*
-     * Packet-type-dependent data.
-     * USB setup information of setup_flag is true.
-     * Otherwise, some isochronous transfer information.
-     */
-    union {
-        guint8 data[8];
-        struct iso_rec iso;
-    } s;
-
-    /*
-     * This data is provided by Linux 2.6.31 and later kernels.
-     *
-     * For WTAP_ENCAP_USB_LINUX, it's not in the pseudo-header, so
-     * the pseudo-header is always 48 bytes long, including the
-     * packet-type-dependent data.
-     *
-     * For WTAP_ENCAP_USB_LINUX_MMAPPED, the pseudo-header is always
-     * 64 bytes long, with the packet-type-dependent data preceding
-     * these last 16 bytes.  In pre-2.6.31 kernels, it's zero padding;
-     * in 2.6.31 and later, it's the following data.
-     */
-    gint32 interval;    /* only for Interrupt and Isochronous events */
-    gint32 start_frame; /* for Isochronous */
-    guint32 xfer_flags; /* copy of URB's transfer_flags */
-    guint32 ndesc;      /* actual number of isochronous descriptors */
+       guint64 id;             /* urb id, to link submission and completion events */
+       guint8 event_type;      /* Submit ('S'), Completed ('C'), Error ('E') */
+       guint8 transfer_type;   /* ISO (0), Intr, Control, Bulk (3) */
+       guint8 endpoint_number; /* Endpoint number (0-15) and transfer direction */
+       guint8 device_address;  /* 0-127 */
+       guint16 bus_id;
+       gint8 setup_flag;       /* 0, if the urb setup header is meaningful */
+       gint8 data_flag;        /* 0, if urb data is present */
+       gint64 ts_sec;
+       gint32 ts_usec;
+       gint32 status;
+       guint32 urb_len;        /* whole len of urb this event refers to */
+       guint32 data_len;       /* amount of urb data really present in this event */
+
+       /*
+        * Packet-type-dependent data.
+        * USB setup information of setup_flag is true.
+        * Otherwise, some isochronous transfer information.
+        */
+       union {
+               guint8 data[8];
+               struct iso_rec iso;
+       } s;
+
+       /*
+        * This data is provided by Linux 2.6.31 and later kernels.
+        *
+        * For WTAP_ENCAP_USB_LINUX, it's not in the pseudo-header, so
+        * the pseudo-header is always 48 bytes long, including the
+        * packet-type-dependent data.
+        *
+        * For WTAP_ENCAP_USB_LINUX_MMAPPED, the pseudo-header is always
+        * 64 bytes long, with the packet-type-dependent data preceding
+        * these last 16 bytes.  In pre-2.6.31 kernels, it's zero padding;
+        * in 2.6.31 and later, it's the following data.
+        */
+       gint32 interval;    /* only for Interrupt and Isochronous events */
+       gint32 start_frame; /* for Isochronous */
+       guint32 xfer_flags; /* copy of URB's transfer_flags */
+       guint32 ndesc;      /* actual number of isochronous descriptors */
 };
 
 struct linux_usb_isodesc {
-    gint32 iso_status;
-    guint32 iso_off;
-    guint32 iso_len;
-    guint32 _pad;
+       gint32 iso_status;
+       guint32 iso_off;
+       guint32 iso_len;
+       guint32 _pad;
 };
 
 /*
@@ -1147,14 +1141,13 @@ struct linux_usb_isodesc {
  * This structure is 8 bytes long.
  */
 struct usb_device_setup_hdr {
-    gint8 bmRequestType;
-    guint8 bRequest;
-    guint16 wValue;
-    guint16 wIndex;
-    guint16 wLength;
+       gint8 bmRequestType;
+       guint8 bRequest;
+       guint16 wValue;
+       guint16 wIndex;
+       guint16 wLength;
 };
 
-
 /*
  * Offset of the *end* of a field within a particular structure.
  */
@@ -1162,215 +1155,355 @@ struct usb_device_setup_hdr {
        (((char *)(void *)(fieldp)) - ((char *)(void *)(basep)) + \
            sizeof(*fieldp))
 
+/*
+ * Is that offset within the bounds of the packet?
+ */
+#define WITHIN_PACKET(basep, fieldp) \
+       (packet_size >= END_OFFSETOF((basep), (fieldp)))
+
+#define CHECK_AND_SWAP16(fieldp) \
+       { \
+               if (!WITHIN_PACKET(usb_phdr, fieldp)) \
+                       return; \
+               PBSWAP16((guint8 *)fieldp); \
+       }
+
+#define CHECK_AND_SWAP32(fieldp) \
+       { \
+               if (!WITHIN_PACKET(usb_phdr, fieldp)) \
+                       return; \
+               PBSWAP32((guint8 *)fieldp); \
+       }
+
+#define CHECK_AND_SWAP64(fieldp) \
+       { \
+               if (!WITHIN_PACKET(usb_phdr, fieldp)) \
+                       return; \
+               PBSWAP64((guint8 *)fieldp); \
+       }
+
+struct can_socketcan_hdr {
+       guint32 can_id;                 /* CAN ID and flags */
+       guint8 payload_length;          /* Frame payload length */
+       guint8 padding;
+       guint8 reserved1;
+       guint8 reserved2;
+};
+
 static void
-pcap_process_linux_usb_pseudoheader(guint packet_size, gboolean byte_swapped,
-    gboolean header_len_64_bytes, guint8 *pd)
+pcap_byteswap_linux_sll_pseudoheader(struct wtap_pkthdr *phdr, guint8 *pd)
 {
-       struct linux_usb_phdr *phdr;
+       guint packet_size;
+       guint16 protocol;
+       struct can_socketcan_hdr *can_socketcan_phdr;
+
+       /*
+        * Minimum of captured and actual length (just in case the
+        * actual length < the captured length, which Should Never
+        * Happen).
+        */
+       packet_size = phdr->caplen;
+       if (packet_size > phdr->len)
+               packet_size = phdr->len;
+
+       if (packet_size < LINUX_SLL_LEN) {
+               /* Not enough data to have the protocol */
+               return;
+       }
+
+       protocol = pntoh16(&pd[LINUX_SLL_PROTOCOL_OFFSET]);
+       if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD) {
+               /* Not a CAN packet; nothing to fix */
+               return;
+       }
+
+       /*
+        * Greasy hack, but we never directly dereference any of
+        * the fields in *can_socketcan_phdr, we just get offsets
+        * of and addresses of its members and byte-swap it with a
+        * byte-at-a-time macro, so it's alignment-safe.
+        */
+       can_socketcan_phdr = (struct can_socketcan_hdr *)(void *)(pd + LINUX_SLL_LEN);
+
+       if (packet_size < LINUX_SLL_LEN + sizeof(can_socketcan_phdr->can_id)) {
+               /* Not enough data to have the full CAN ID */
+               return;
+       }
+
+       PBSWAP32((guint8 *)&can_socketcan_phdr->can_id);
+}
+
+static void
+pcap_byteswap_linux_usb_pseudoheader(struct wtap_pkthdr *phdr, guint8 *pd,
+    gboolean header_len_64_bytes)
+{
+       guint packet_size;
+       struct linux_usb_phdr *usb_phdr;
        struct linux_usb_isodesc *pisodesc;
        gint32 iso_numdesc, i;
 
-       if (byte_swapped) {
+       /*
+        * Minimum of captured and actual length (just in case the
+        * actual length < the captured length, which Should Never
+        * Happen).
+        */
+       packet_size = phdr->caplen;
+       if (packet_size > phdr->len)
+               packet_size = phdr->len;
+
+       /*
+        * Greasy hack, but we never directly dereference any of
+        * the fields in *usb_phdr, we just get offsets of and
+        * addresses of its members and byte-swap it with a
+        * byte-at-a-time macro, so it's alignment-safe.
+        */
+       usb_phdr = (struct linux_usb_phdr *)(void *)pd;
+
+       CHECK_AND_SWAP64(&usb_phdr->id);
+       CHECK_AND_SWAP16(&usb_phdr->bus_id);
+       CHECK_AND_SWAP64(&usb_phdr->ts_sec);
+       CHECK_AND_SWAP32(&usb_phdr->ts_usec);
+       CHECK_AND_SWAP32(&usb_phdr->status);
+       CHECK_AND_SWAP32(&usb_phdr->urb_len);
+       CHECK_AND_SWAP32(&usb_phdr->data_len);
+
+       if (usb_phdr->transfer_type == URB_ISOCHRONOUS) {
+               CHECK_AND_SWAP32(&usb_phdr->s.iso.error_count);
+               CHECK_AND_SWAP32(&usb_phdr->s.iso.numdesc);
+       }
+
+       if (header_len_64_bytes) {
                /*
-                * Greasy hack, but we never directly direference any of
-                * the fields in *phdr, we just get offsets of and
-                * addresses of its members, so it's safe.
+                * This is either the "version 1" header, with
+                * 16 bytes of additional fields at the end, or
+                * a "version 0" header from a memory-mapped
+                * capture, with 16 bytes of zeroed-out padding
+                * at the end.  Byte swap them as if this were
+                * a "version 1" header.
+                *
+                * Yes, the first argument to END_OFFSETOF() should
+                * be usb_phdr, not usb_phdr_ext; we want the offset of
+                * the additional fields from the beginning of
+                * the packet.
                 */
-               phdr = (struct linux_usb_phdr *)(void *)pd;
+               CHECK_AND_SWAP32(&usb_phdr->interval);
+               CHECK_AND_SWAP32(&usb_phdr->start_frame);
+               CHECK_AND_SWAP32(&usb_phdr->xfer_flags);
+               CHECK_AND_SWAP32(&usb_phdr->ndesc);
+       }
 
-               if (packet_size < END_OFFSETOF(phdr, &phdr->id))
-                       return;
-               PBSWAP64((guint8 *)&phdr->id);
-               if (packet_size < END_OFFSETOF(phdr, &phdr->bus_id))
-                       return;
-               PBSWAP16((guint8 *)&phdr->bus_id);
-               if (packet_size < END_OFFSETOF(phdr, &phdr->ts_sec))
-                       return;
-               PBSWAP64((guint8 *)&phdr->ts_sec);
-               if (packet_size < END_OFFSETOF(phdr, &phdr->ts_usec))
-                       return;
-               PBSWAP32((guint8 *)&phdr->ts_usec);
-               if (packet_size < END_OFFSETOF(phdr, &phdr->status))
-                       return;
-               PBSWAP32((guint8 *)&phdr->status);
-               if (packet_size < END_OFFSETOF(phdr, &phdr->urb_len))
-                       return;
-               PBSWAP32((guint8 *)&phdr->urb_len);
-               if (packet_size < END_OFFSETOF(phdr, &phdr->data_len))
-                       return;
-               PBSWAP32((guint8 *)&phdr->data_len);
+       if (usb_phdr->transfer_type == URB_ISOCHRONOUS) {
+               /* swap the values in struct linux_usb_isodesc */
 
-               if (phdr->transfer_type == URB_ISOCHRONOUS) {
-                       if (packet_size < END_OFFSETOF(phdr, &phdr->s.iso.error_count))
-                               return;
-                       PBSWAP32((guint8 *)&phdr->s.iso.error_count);
+               /*
+                * See previous "Greasy hack" comment.
+                */
+               if (header_len_64_bytes) {
+                       pisodesc = (struct linux_usb_isodesc*)(void *)(pd + 64);
+               } else {
+                       pisodesc = (struct linux_usb_isodesc*)(void *)(pd + 48);
+               }
+               iso_numdesc = usb_phdr->s.iso.numdesc;
+               for (i = 0; i < iso_numdesc; i++) {
+                       CHECK_AND_SWAP32(&pisodesc->iso_status);
+                       CHECK_AND_SWAP32(&pisodesc->iso_off);
+                       CHECK_AND_SWAP32(&pisodesc->iso_len);
+                       CHECK_AND_SWAP32(&pisodesc->_pad);
+
+                       pisodesc++;
+               }
+       }
+}
 
-                       if (packet_size < END_OFFSETOF(phdr, &phdr->s.iso.numdesc))
-                               return;
-                       PBSWAP32((guint8 *)&phdr->s.iso.numdesc);
+struct nflog_hdr {
+       guint8 nflog_family;            /* address family */
+       guint8 nflog_version;           /* version */
+       guint16 nflog_rid;              /* resource ID */
+};
 
-               }
+struct nflog_tlv {
+       guint16 tlv_length;             /* tlv length */
+       guint16 tlv_type;               /* tlv type */
+       /* value follows this */
+};
 
-               if (header_len_64_bytes) {
-                       /*
-                        * This is either the "version 1" header, with
-                        * 16 bytes of additional fields at the end, or
-                        * a "version 0" header from a memory-mapped
-                        * capture, with 16 bytes of zeroed-out padding
-                        * at the end.  Byte swap them as if this were
-                        * a "version 1" header.
-                        *
-                        * Yes, the first argument to END_OFFSETOF() should
-                        * be phdr, not phdr_ext; we want the offset of
-                        * the additional fields from the beginning of
-                        * the packet.
-                        */
-                       if (packet_size < END_OFFSETOF(phdr, &phdr->interval))
-                               return;
-                       PBSWAP32((guint8 *)&phdr->interval);
-                       if (packet_size < END_OFFSETOF(phdr, &phdr->start_frame))
-                               return;
-                       PBSWAP32((guint8 *)&phdr->start_frame);
-                       if (packet_size < END_OFFSETOF(phdr, &phdr->xfer_flags))
-                               return;
-                       PBSWAP32((guint8 *)&phdr->xfer_flags);
-                       if (packet_size < END_OFFSETOF(phdr, &phdr->ndesc))
-                               return;
-                       PBSWAP32((guint8 *)&phdr->ndesc);
-               }
+static void
+pcap_byteswap_nflog_pseudoheader(struct wtap_pkthdr *phdr, guint8 *pd)
+{
+       guint packet_size;
+       guint8 *p;
+       struct nflog_hdr *nfhdr;
+       struct nflog_tlv *tlv;
+       guint size;
 
-               if (phdr->transfer_type == URB_ISOCHRONOUS) {
-                       /* swap the values in struct linux_usb_isodesc */
+       /*
+        * Minimum of captured and actual length (just in case the
+        * actual length < the captured length, which Should Never
+        * Happen).
+        */
+       packet_size = phdr->caplen;
+       if (packet_size > phdr->len)
+               packet_size = phdr->len;
 
-                       /*
-                        * See previous "Greasy hack" comment.
-                        */
-                       if (header_len_64_bytes) {
-                               pisodesc = (struct linux_usb_isodesc*)(void *)(pd + 64);
-                       } else {
-                               pisodesc = (struct linux_usb_isodesc*)(void *)(pd + 48);
-                       }
-                       iso_numdesc = phdr->s.iso.numdesc;
-                       for (i = 0; i < iso_numdesc; i++) {
-                               /* always check if we have enough data from the
-                                * beginnig of the packet (phdr)
-                                */
-                               if (packet_size < END_OFFSETOF(phdr, &pisodesc->iso_status))
-                                       return;
-                               PBSWAP32((guint8 *)&pisodesc->iso_status);
-                               if (packet_size < END_OFFSETOF(phdr, &pisodesc->iso_off))
-                                       return;
-                               PBSWAP32((guint8 *)&pisodesc->iso_off);
-                               if (packet_size < END_OFFSETOF(phdr, &pisodesc->iso_len))
-                                       return;
-                               PBSWAP32((guint8 *)&pisodesc->iso_len);
-                               if (packet_size < END_OFFSETOF(phdr, &pisodesc->_pad))
-                                       return;
-                               PBSWAP32((guint8 *)&pisodesc->_pad);
-
-                               pisodesc++;
-                       }
+       if (packet_size < sizeof(struct nflog_hdr)) {
+               /* Not enough data to have any TLVs. */
+               return;
+       }
+
+       p = pd;
+       nfhdr = (struct nflog_hdr *)pd;
+       if (nfhdr->nflog_version != 0) {
+               /* Unknown NFLOG version */
+               return;
+       }
+
+       packet_size -= (guint)sizeof(struct nflog_hdr);
+       p += sizeof(struct nflog_hdr);
+
+       while (packet_size >= sizeof(struct nflog_tlv)) {
+               tlv = (struct nflog_tlv *) p;
+
+               /* Swap the type and length. */
+               PBSWAP16((guint8 *)&tlv->tlv_type);
+               PBSWAP16((guint8 *)&tlv->tlv_length);
+
+               /* Get the length of the TLV. */
+               size = tlv->tlv_length;
+               if (size % 4 != 0)
+                       size += 4 - size % 4;
+
+               /* Is the TLV's length less than the minimum? */
+               if (size < sizeof(struct nflog_tlv)) {
+                       /* Yes. Give up now. */
+                       return;
                }
+
+               /* Do we have enough data for the full TLV? */
+               if (packet_size < size) {
+                       /* No. */
+                       return;
+               }
+
+               /* Skip over the TLV. */
+               packet_size -= size;
+               p += size;
        }
 }
 
+/*
+ * Pseudo-header at the beginning of DLT_BLUETOOTH_HCI_H4_WITH_PHDR frames.
+ * Values in network byte order.
+ */
+struct libpcap_bt_phdr {
+       guint32 direction;     /* Bit 0 hold the frame direction. */
+};
+
+#define LIBPCAP_BT_PHDR_SENT    0
+#define LIBPCAP_BT_PHDR_RECV    1
+
 static gboolean
 pcap_read_bt_pseudoheader(FILE_T fh,
     union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
-       int     bytes_read;
        struct libpcap_bt_phdr phdr;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(&phdr,
-           sizeof (struct libpcap_bt_phdr), fh);
-       if (bytes_read != sizeof (struct libpcap_bt_phdr)) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, &phdr, sizeof (struct libpcap_bt_phdr),
+           err, err_info))
                return FALSE;
-       }
        pseudo_header->p2p.sent = ((g_ntohl(phdr.direction) & LIBPCAP_BT_PHDR_RECV) == 0)? TRUE: FALSE;
        return TRUE;
 }
 
+/*
+ * Pseudo-header at the beginning of DLT_BLUETOOTH_LINUX_MONITOR frames.
+ * Values in network byte order.
+ */
+struct libpcap_bt_monitor_phdr {
+       guint16 adapter_id;
+       guint16 opcode;
+};
+
+static gboolean
+pcap_read_bt_monitor_pseudoheader(FILE_T fh,
+    union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
+{
+       struct libpcap_bt_monitor_phdr phdr;
+
+       if (!wtap_read_bytes(fh, &phdr, sizeof (struct libpcap_bt_monitor_phdr),
+           err, err_info))
+               return FALSE;
+
+       pseudo_header->btmon.adapter_id = g_ntohs(phdr.adapter_id);
+       pseudo_header->btmon.opcode = g_ntohs(phdr.opcode);
+       return TRUE;
+}
+
 static gboolean
 pcap_read_llcp_pseudoheader(FILE_T fh,
     union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
-       int bytes_read;
        guint8 phdr[LLCP_HEADER_LEN];
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(phdr, LLCP_HEADER_LEN, fh);
-       if (bytes_read != LLCP_HEADER_LEN) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, phdr, LLCP_HEADER_LEN, err, err_info))
                return FALSE;
-       }
        pseudo_header->llcp.adapter = phdr[LLCP_ADAPTER_OFFSET];
        pseudo_header->llcp.flags = phdr[LLCP_FLAGS_OFFSET];
        return TRUE;
 }
 
+/*
+ * Pseudo-header at the beginning of DLT_PPP_WITH_DIR frames.
+ */
+struct libpcap_ppp_phdr {
+       guint8 direction;
+};
+
+#define LIBPCAP_PPP_PHDR_RECV    0
+#define LIBPCAP_PPP_PHDR_SENT    1
+
 static gboolean
 pcap_read_ppp_pseudoheader(FILE_T fh,
     union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
-       int     bytes_read;
        struct libpcap_ppp_phdr phdr;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(&phdr,
-           sizeof (struct libpcap_ppp_phdr), fh);
-       if (bytes_read != sizeof (struct libpcap_ppp_phdr)) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, &phdr, sizeof (struct libpcap_ppp_phdr),
+           err, err_info))
                return FALSE;
-       }
        pseudo_header->p2p.sent = (phdr.direction == LIBPCAP_PPP_PHDR_SENT) ? TRUE: FALSE;
        return TRUE;
 }
 
 static gboolean
 pcap_read_erf_pseudoheader(FILE_T fh, struct wtap_pkthdr *whdr,
-                             union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
+                          union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
-  guint8 erf_hdr[sizeof(struct erf_phdr)];
-  int    bytes_read;
-
-  errno = WTAP_ERR_CANT_READ;
-  bytes_read = file_read(erf_hdr, sizeof(struct erf_phdr), fh);
-  if (bytes_read != sizeof(struct erf_phdr)) {
-    *err = file_error(fh, err_info);
-    if (*err == 0)
-      *err = WTAP_ERR_SHORT_READ;
-    return FALSE;
-  }
-  pseudo_header->erf.phdr.ts = pletohll(&erf_hdr[0]); /* timestamp */
-  pseudo_header->erf.phdr.type =  erf_hdr[8];
-  pseudo_header->erf.phdr.flags = erf_hdr[9];
-  pseudo_header->erf.phdr.rlen = pntohs(&erf_hdr[10]);
-  pseudo_header->erf.phdr.lctr = pntohs(&erf_hdr[12]);
-  pseudo_header->erf.phdr.wlen = pntohs(&erf_hdr[14]);
-
-  /* The high 32 bits of the timestamp contain the integer number of seconds
-   * while the lower 32 bits contain the binary fraction of the second.
-   * This allows an ultimate resolution of 1/(2^32) seconds, or approximately 233 picoseconds */
-  if (whdr) {
-    guint64 ts = pseudo_header->erf.phdr.ts;
-    whdr->ts.secs = (guint32) (ts >> 32);
-    ts = ((ts & 0xffffffff) * 1000 * 1000 * 1000);
-    ts += (ts & 0x80000000) << 1; /* rounding */
-    whdr->ts.nsecs = ((guint32) (ts >> 32));
-    if ( whdr->ts.nsecs >= 1000000000) {
-      whdr->ts.nsecs -= 1000000000;
-      whdr->ts.secs += 1;
-    }
-  }
-  return TRUE;
+       guint8 erf_hdr[sizeof(struct erf_phdr)];
+
+       if (!wtap_read_bytes(fh, erf_hdr, sizeof(struct erf_phdr), err, err_info))
+               return FALSE;
+       pseudo_header->erf.phdr.ts = pletoh64(&erf_hdr[0]); /* timestamp */
+       pseudo_header->erf.phdr.type =  erf_hdr[8];
+       pseudo_header->erf.phdr.flags = erf_hdr[9];
+       pseudo_header->erf.phdr.rlen = pntoh16(&erf_hdr[10]);
+       pseudo_header->erf.phdr.lctr = pntoh16(&erf_hdr[12]);
+       pseudo_header->erf.phdr.wlen = pntoh16(&erf_hdr[14]);
+
+       /* The high 32 bits of the timestamp contain the integer number of seconds
+        * while the lower 32 bits contain the binary fraction of the second.
+        * This allows an ultimate resolution of 1/(2^32) seconds, or approximately 233 picoseconds */
+       if (whdr) {
+               guint64 ts = pseudo_header->erf.phdr.ts;
+               whdr->ts.secs = (guint32) (ts >> 32);
+               ts = ((ts & 0xffffffff) * 1000 * 1000 * 1000);
+               ts += (ts & 0x80000000) << 1; /* rounding */
+               whdr->ts.nsecs = ((guint32) (ts >> 32));
+               if ( whdr->ts.nsecs >= 1000000000) {
+                       whdr->ts.nsecs -= 1000000000;
+                       whdr->ts.secs += 1;
+               }
+       }
+       return TRUE;
 }
 
 /*
@@ -1379,33 +1512,26 @@ pcap_read_erf_pseudoheader(FILE_T fh, struct wtap_pkthdr *whdr,
  */
 static gboolean
 pcap_read_erf_exheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
-                          int *err, gchar **err_info, guint * psize)
+                      int *err, gchar **err_info, guint * psize)
 {
-  int bytes_read = 0;
-  guint8 erf_exhdr[8];
-  guint64 erf_exhdr_sw;
-  int i = 0, max = sizeof(pseudo_header->erf.ehdr_list)/sizeof(struct erf_ehdr);
-  guint8 type;
-  *psize = 0;
-  if (pseudo_header->erf.phdr.type & 0x80){
-    do{
-      errno = WTAP_ERR_CANT_READ;
-      bytes_read = file_read(erf_exhdr, 8, fh);
-      if (bytes_read != 8 ) {
-       *err = file_error(fh, err_info);
-       if (*err == 0)
-         *err = WTAP_ERR_SHORT_READ;
-       return FALSE;
-      }
-      type = erf_exhdr[0];
-      erf_exhdr_sw = pntohll(erf_exhdr);
-      if (i < max)
-       memcpy(&pseudo_header->erf.ehdr_list[i].ehdr, &erf_exhdr_sw, sizeof(erf_exhdr_sw));
-      *psize += 8;
-      i++;
-    } while (type & 0x80);
-  }
-  return TRUE;
+       guint8 erf_exhdr[8];
+       guint64 erf_exhdr_sw;
+       int i = 0, max = sizeof(pseudo_header->erf.ehdr_list)/sizeof(struct erf_ehdr);
+       guint8 type;
+       *psize = 0;
+       if (pseudo_header->erf.phdr.type & 0x80){
+               do{
+                       if (!wtap_read_bytes(fh, erf_exhdr, 8, err, err_info))
+                               return FALSE;
+                       type = erf_exhdr[0];
+                       erf_exhdr_sw = pntoh64(erf_exhdr);
+                       if (i < max)
+                               memcpy(&pseudo_header->erf.ehdr_list[i].ehdr, &erf_exhdr_sw, sizeof(erf_exhdr_sw));
+                       *psize += 8;
+                       i++;
+               } while (type & 0x80);
+       }
+       return TRUE;
 }
 
 /*
@@ -1414,72 +1540,60 @@ pcap_read_erf_exheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
  */
 static gboolean
 pcap_read_erf_subheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
-                          int *err, gchar **err_info, guint * psize)
+                       int *err, gchar **err_info, guint * psize)
 {
-  guint8 erf_subhdr[sizeof(union erf_subhdr)];
-  int    bytes_read;
-
-  *psize=0;
-  switch(pseudo_header->erf.phdr.type & 0x7F) {
-  case ERF_TYPE_MC_HDLC:
-  case ERF_TYPE_MC_RAW:
-  case ERF_TYPE_MC_ATM:
-  case ERF_TYPE_MC_RAW_CHANNEL:
-  case ERF_TYPE_MC_AAL5:
-  case ERF_TYPE_MC_AAL2:
-  case ERF_TYPE_COLOR_MC_HDLC_POS:
-    /* Extract the Multi Channel header to include it in the pseudo header part */
-    errno = WTAP_ERR_CANT_READ;
-    bytes_read = file_read(erf_subhdr, sizeof(erf_mc_header_t), fh);
-    if (bytes_read != sizeof(erf_mc_header_t) ) {
-      *err = file_error(fh, err_info);
-      if (*err == 0)
-       *err = WTAP_ERR_SHORT_READ;
-      return FALSE;
-    }
-    pseudo_header->erf.subhdr.mc_hdr = pntohl(&erf_subhdr[0]);
-    *psize = sizeof(erf_mc_header_t);
-    break;
-  case ERF_TYPE_ETH:
-  case ERF_TYPE_COLOR_ETH:
-  case ERF_TYPE_DSM_COLOR_ETH:
-    /* Extract the Ethernet additional header to include it in the pseudo header part */
-    errno = WTAP_ERR_CANT_READ;
-    bytes_read = file_read(erf_subhdr, sizeof(erf_eth_header_t), fh);
-    if (bytes_read != sizeof(erf_eth_header_t) ) {
-      *err = file_error(fh, err_info);
-      if (*err == 0)
-       *err = WTAP_ERR_SHORT_READ;
-      return FALSE;
-    }
-    pseudo_header->erf.subhdr.eth_hdr = pntohs(&erf_subhdr[0]);
-    *psize = sizeof(erf_eth_header_t);
-    break;
-  default:
-    /* No optional pseudo header for this ERF type */
-    break;
-  }
-  return TRUE;
+       guint8 erf_subhdr[sizeof(union erf_subhdr)];
+
+       *psize=0;
+       switch(pseudo_header->erf.phdr.type & 0x7F) {
+       case ERF_TYPE_MC_HDLC:
+       case ERF_TYPE_MC_RAW:
+       case ERF_TYPE_MC_ATM:
+       case ERF_TYPE_MC_RAW_CHANNEL:
+       case ERF_TYPE_MC_AAL5:
+       case ERF_TYPE_MC_AAL2:
+       case ERF_TYPE_COLOR_MC_HDLC_POS:
+               /* Extract the Multi Channel header to include it in the pseudo header part */
+               if (!wtap_read_bytes(fh, erf_subhdr, sizeof(erf_mc_header_t), err, err_info))
+                       return FALSE;
+               pseudo_header->erf.subhdr.mc_hdr = pntoh32(&erf_subhdr[0]);
+               *psize = sizeof(erf_mc_header_t);
+               break;
+       case ERF_TYPE_AAL2:
+               /* Extract the AAL2 header to include it in the pseudo header part */
+               if (!wtap_read_bytes(fh, erf_subhdr, sizeof(erf_aal2_header_t), err, err_info))
+                       return FALSE;
+               pseudo_header->erf.subhdr.aal2_hdr = pntoh32(&erf_subhdr[0]);
+               *psize = sizeof(erf_aal2_header_t);
+               break;
+       case ERF_TYPE_ETH:
+       case ERF_TYPE_COLOR_ETH:
+       case ERF_TYPE_DSM_COLOR_ETH:
+       case ERF_TYPE_COLOR_HASH_ETH:
+               /* Extract the Ethernet additional header to include it in the pseudo header part */
+               if (!wtap_read_bytes(fh, erf_subhdr, sizeof(erf_eth_header_t), err, err_info))
+                       return FALSE;
+               memcpy(&pseudo_header->erf.subhdr.eth_hdr, erf_subhdr, sizeof pseudo_header->erf.subhdr.eth_hdr);
+               *psize = sizeof(erf_eth_header_t);
+               break;
+       default:
+               /* No optional pseudo header for this ERF type */
+               break;
+       }
+       return TRUE;
 }
 
 static gboolean
 pcap_read_i2c_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
 {
        struct i2c_file_hdr i2c_hdr;
-       int    bytes_read;
 
-       errno = WTAP_ERR_CANT_READ;
-       bytes_read = file_read(&i2c_hdr, sizeof (i2c_hdr), fh);
-       if (bytes_read != sizeof (i2c_hdr)) {
-               *err = file_error(fh, err_info);
-               if (*err == 0)
-                       *err = WTAP_ERR_SHORT_READ;
+       if (!wtap_read_bytes(fh, &i2c_hdr, sizeof (i2c_hdr), err, err_info))
                return FALSE;
-       }
 
        pseudo_header->i2c.is_event = i2c_hdr.bus & 0x80 ? 1 : 0;
        pseudo_header->i2c.bus = i2c_hdr.bus & 0x7f;
-       pseudo_header->i2c.flags = pntohl(&i2c_hdr.flags);
+       pseudo_header->i2c.flags = pntoh32(&i2c_hdr.flags);
 
        return TRUE;
 }
@@ -1495,7 +1609,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
        switch (wtap_encap) {
 
        case WTAP_ENCAP_ATM_PDUS:
-               if (file_type == WTAP_FILE_PCAP_NOKIA) {
+               if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA) {
                        /*
                         * Nokia IPSO ATM.
                         */
@@ -1537,7 +1651,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
                break;
 
        case WTAP_ENCAP_ETHERNET:
-               if (file_type == WTAP_FILE_PCAP_NOKIA) {
+               if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA) {
                        /*
                         * Nokia IPSO.  Psuedo header has already been read, but it's not considered
                         * part of the packet size, so reread it to store the data for later (when saving)
@@ -1557,15 +1671,17 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
        case WTAP_ENCAP_IEEE_802_11_RADIOTAP:
        case WTAP_ENCAP_IEEE_802_11_AVS:
                /*
-                * We don't know whether there's an FCS in this frame or not.
-                * XXX - are there any OSes where the capture mechanism
-                * supplies an FCS?
+                * We don't know whether there's an FCS in this frame or not,
+                * at least in pcap files.  For radiotap, that's indicated in
+                * the radiotap header.
+                *
+                * XXX - in pcap-ng, there *could* be a packet option
+                * indicating the FCS length.
                 */
+               memset(&phdr->pseudo_header.ieee_802_11, 0, sizeof(phdr->pseudo_header.ieee_802_11));
                phdr->pseudo_header.ieee_802_11.fcs_len = -1;
                phdr->pseudo_header.ieee_802_11.decrypted = FALSE;
-               phdr->pseudo_header.ieee_802_11.channel = 0;
-               phdr->pseudo_header.ieee_802_11.data_rate = 0;
-               phdr->pseudo_header.ieee_802_11.signal_level = 0;
+               phdr->pseudo_header.ieee_802_11.datapad = FALSE;
                break;
 
        case WTAP_ENCAP_IRDA:
@@ -1664,10 +1780,29 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
                phdr_len = (int)sizeof (struct libpcap_bt_phdr);
                break;
 
+       case WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR:
+               if (check_packet_size &&
+                   packet_size < sizeof (struct libpcap_bt_monitor_phdr)) {
+                       /*
+                        * Uh-oh, the packet isn't big enough to even
+                        * have a pseudo-header.
+                        */
+                       *err = WTAP_ERR_BAD_FILE;
+                       *err_info = g_strdup_printf("pcap: libpcap bluetooth monitor file has a %u-byte packet, too small to have even a pseudo-header",
+                           packet_size);
+                       return -1;
+               }
+               if (!pcap_read_bt_monitor_pseudoheader(fh,
+                   &phdr->pseudo_header, err, err_info))
+                       return -1;      /* Read error */
+
+               phdr_len = (int)sizeof (struct libpcap_bt_monitor_phdr);
+               break;
+
        case WTAP_ENCAP_NFC_LLCP:
                if (check_packet_size && packet_size < LLCP_HEADER_LEN) {
                        *err = WTAP_ERR_BAD_FILE;
-                       *err_info = g_strdup_printf("pcap: libpcap llcp file too short");
+                       *err_info = g_strdup("pcap: libpcap llcp file too short");
                        return -1;
                }
                if (!pcap_read_llcp_pseudoheader(fh, &phdr->pseudo_header, err, err_info))
@@ -1768,20 +1903,19 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
 
 void
 pcap_read_post_process(int file_type, int wtap_encap,
-    union wtap_pseudo_header *pseudo_header,
-    guint8 *pd, guint packet_size, gboolean bytes_swapped, int fcs_len)
+    struct wtap_pkthdr *phdr, guint8 *pd, gboolean bytes_swapped, int fcs_len)
 {
        switch (wtap_encap) {
 
        case WTAP_ENCAP_ATM_PDUS:
-               if (file_type == WTAP_FILE_PCAP_NOKIA) {
+               if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA) {
                        /*
                         * Nokia IPSO ATM.
                         *
                         * Guess the traffic type based on the packet
                         * contents.
                         */
-                       atm_guess_traffic_type(pd, packet_size, pseudo_header);
+                       atm_guess_traffic_type(phdr, pd);
                } else {
                        /*
                         * SunATM.
@@ -1790,24 +1924,28 @@ pcap_read_post_process(int file_type, int wtap_encap,
                         * type of LANE traffic it is based on the packet
                         * contents.
                         */
-                       if (pseudo_header->atm.type == TRAF_LANE)
-                               atm_guess_lane_type(pd, packet_size,
-                                   pseudo_header);
+                       if (phdr->pseudo_header.atm.type == TRAF_LANE)
+                               atm_guess_lane_type(phdr, pd);
                }
                break;
 
        case WTAP_ENCAP_ETHERNET:
-               pseudo_header->eth.fcs_len = fcs_len;
+               phdr->pseudo_header.eth.fcs_len = fcs_len;
+               break;
+
+       case WTAP_ENCAP_SLL:
+               if (bytes_swapped)
+                       pcap_byteswap_linux_sll_pseudoheader(phdr, pd);
                break;
 
        case WTAP_ENCAP_USB_LINUX:
-               pcap_process_linux_usb_pseudoheader(packet_size,
-                   bytes_swapped, FALSE, pd);
+               if (bytes_swapped)
+                       pcap_byteswap_linux_usb_pseudoheader(phdr, pd, FALSE);
                break;
 
        case WTAP_ENCAP_USB_LINUX_MMAPPED:
-               pcap_process_linux_usb_pseudoheader(packet_size,
-                   bytes_swapped, TRUE, pd);
+               if (bytes_swapped)
+                       pcap_byteswap_linux_usb_pseudoheader(phdr, pd, TRUE);
                break;
 
        case WTAP_ENCAP_NETANALYZER:
@@ -1816,7 +1954,22 @@ pcap_read_post_process(int file_type, int wtap_encap,
                 * dissector calls the "Ethernet with FCS"
                 * dissector, but we might as well set it.
                 */
-               pseudo_header->eth.fcs_len = 4;
+               phdr->pseudo_header.eth.fcs_len = 4;
+               break;
+
+       case WTAP_ENCAP_NFLOG:
+               if (bytes_swapped)
+                       pcap_byteswap_nflog_pseudoheader(phdr, pd);
+               break;
+
+       case WTAP_ENCAP_ERF:
+               /*
+                * Update packet size to account for ERF padding and snapping.
+                * Captured length is minimum of wlen and previously calculated
+                * caplen (which would have included padding but not phdr).
+                */
+               phdr->len = phdr->pseudo_header.erf.phdr.wlen;
+               phdr->caplen = MIN(phdr->len, phdr->caplen);
                break;
 
        default:
@@ -1864,10 +2017,14 @@ pcap_get_phdr_size(int encap, const union wtap_pseudo_header *pseudo_header)
                case ERF_TYPE_COLOR_MC_HDLC_POS:
                        hdrsize += (int)sizeof(struct erf_mc_hdr);
                        break;
+               case ERF_TYPE_AAL2:
+                       hdrsize += (int)sizeof(struct erf_aal2_hdr);
+                       break;
 
                case ERF_TYPE_ETH:
                case ERF_TYPE_COLOR_ETH:
                case ERF_TYPE_DSM_COLOR_ETH:
+               case ERF_TYPE_COLOR_HASH_ETH:
                        hdrsize += (int)sizeof(struct erf_eth_hdr);
                        break;
 
@@ -1904,6 +2061,10 @@ pcap_get_phdr_size(int encap, const union wtap_pseudo_header *pseudo_header)
                hdrsize = (int)sizeof (struct libpcap_ppp_phdr);
                break;
 
+       case WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR:
+               hdrsize = (int)sizeof (struct libpcap_bt_monitor_phdr);
+       break;
+
        default:
                hdrsize = 0;
                break;
@@ -1922,10 +2083,13 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
        guint8 mtp2_hdr[MTP2_HDR_LEN];
        guint8 sita_hdr[SITA_HDR_LEN];
        guint8 erf_hdr[ sizeof(struct erf_mc_phdr)];
+       guint8 erf_subhdr[sizeof(union erf_subhdr)];
        struct i2c_file_hdr i2c_hdr;
        struct libpcap_bt_phdr bt_hdr;
+       struct libpcap_bt_monitor_phdr bt_monitor_hdr;
        struct libpcap_ppp_phdr ppp_hdr;
        size_t size;
+       size_t subhdr_size = 0;
 
        switch (encap) {
 
@@ -2034,7 +2198,17 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
                phtolell(&erf_hdr[0], pseudo_header->erf.phdr.ts);
                erf_hdr[8] = pseudo_header->erf.phdr.type;
                erf_hdr[9] = pseudo_header->erf.phdr.flags;
-               phtons(&erf_hdr[10], pseudo_header->erf.phdr.rlen);
+
+               /*
+                * Recalculate rlen as padding (and maybe extension headers)
+                * have been stripped from caplen.
+                *
+                * XXX: Since we don't have phdr->caplen here, assume caplen was
+                * calculated correctly and recalculate from wlen.
+                */
+               phtons(&erf_hdr[10],
+                       MIN(pseudo_header->erf.phdr.rlen, pseudo_header->erf.phdr.wlen + pcap_get_phdr_size(WTAP_ENCAP_ERF, pseudo_header)));
+
                phtons(&erf_hdr[12], pseudo_header->erf.phdr.lctr);
                phtons(&erf_hdr[14], pseudo_header->erf.phdr.wlen);
                size = sizeof(struct erf_phdr);
@@ -2047,14 +2221,19 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
                case ERF_TYPE_MC_AAL5:
                case ERF_TYPE_MC_AAL2:
                case ERF_TYPE_COLOR_MC_HDLC_POS:
-                       phtonl(&erf_hdr[16], pseudo_header->erf.subhdr.mc_hdr);
-                       size += (int)sizeof(struct erf_mc_hdr);
+                       phtonl(&erf_subhdr[0], pseudo_header->erf.subhdr.mc_hdr);
+                       subhdr_size += (int)sizeof(struct erf_mc_hdr);
+                       break;
+               case ERF_TYPE_AAL2:
+                       phtonl(&erf_subhdr[0], pseudo_header->erf.subhdr.aal2_hdr);
+                       subhdr_size += (int)sizeof(struct erf_aal2_hdr);
                        break;
                case ERF_TYPE_ETH:
                case ERF_TYPE_COLOR_ETH:
                case ERF_TYPE_DSM_COLOR_ETH:
-                       phtons(&erf_hdr[16], pseudo_header->erf.subhdr.eth_hdr);
-                       size += (int)sizeof(struct erf_eth_hdr);
+               case ERF_TYPE_COLOR_HASH_ETH:
+                       memcpy(&erf_subhdr[0], &pseudo_header->erf.subhdr.eth_hdr, sizeof pseudo_header->erf.subhdr.eth_hdr);
+                       subhdr_size += (int)sizeof(struct erf_eth_hdr);
                        break;
                default:
                        break;
@@ -2074,12 +2253,23 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
                        do {
                                phtonll(erf_exhdr, pseudo_header->erf.ehdr_list[i].ehdr);
                                type = erf_exhdr[0];
+                               /* Clear more extension headers bit if > 8 */
+                               if(i == max-1)
+                                       erf_exhdr[0] = erf_exhdr[0] & 0x7F;
+
                                if (!wtap_dump_file_write(wdh, erf_exhdr, 8, err))
                                        return FALSE;
                                wdh->bytes_dumped += 8;
                                i++;
                        } while (type & 0x80 && i < max);
                }
+
+               /*
+                * Now write out the subheader.
+                */
+               if(!wtap_dump_file_write(wdh, erf_subhdr, subhdr_size, err))
+                       return FALSE;
+               wdh->bytes_dumped += subhdr_size;
                break;
 
        case WTAP_ENCAP_I2C:
@@ -2102,6 +2292,15 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
                wdh->bytes_dumped += sizeof bt_hdr;
                break;
 
+       case WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR:
+               bt_monitor_hdr.adapter_id = GUINT16_TO_BE(pseudo_header->btmon.adapter_id);
+               bt_monitor_hdr.opcode = GUINT16_TO_BE(pseudo_header->btmon.opcode);
+
+               if (!wtap_dump_file_write(wdh, &bt_monitor_hdr, sizeof bt_monitor_hdr, err))
+                       return FALSE;
+               wdh->bytes_dumped += sizeof bt_monitor_hdr;
+               break;
+
        case WTAP_ENCAP_PPP_WITH_PHDR:
                ppp_hdr.direction = (pseudo_header->p2p.sent ? LIBPCAP_PPP_PHDR_SENT : LIBPCAP_PPP_PHDR_RECV);
                if (!wtap_dump_file_write(wdh, &ppp_hdr, sizeof ppp_hdr, err))
@@ -2111,3 +2310,16 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
        }
        return TRUE;
 }
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */