]> The Tcpdump Group git mirrors - libpcap/commitdiff
Based on work from Florent Drouin, split the 32-bit link-layer type
authorguy <guy>
Sat, 29 Sep 2007 19:33:29 +0000 (19:33 +0000)
committerguy <guy>
Sat, 29 Sep 2007 19:33:29 +0000 (19:33 +0000)
field in a capture file into:

a 16-bit link-layer type field (it's 16 bits in pcap-NG, and
that'll probably be enough for the foreseeable future);

a 10-bit "class" field, indicating the group of link-layer type
values to which the link-layer type belongs - class 0 is for
regular DLT_ values, and class 0x224 grandfathers in the NetBSD
"raw address family" link-layer types;

a 6-bit "extension" field, storing information about the
capture, such an indication of whether the packets include an
FCS and, if so, how many bytes of FCS are present.

pcap-dag.c
pcap-int.h
pcap.c
pcap/bpf.h
pcap/pcap.h
savefile.c

index 477c632aa608766cbd1156be00286ea7d2ec1f67..86df4f68aaa698cce65530bd021fbe91a4eb4aa6 100644 (file)
@@ -17,7 +17,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-       "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.29 2007-06-22 06:32:06 guy Exp $ (LBL)";
+       "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.30 2007-09-29 19:33:29 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -644,24 +644,45 @@ dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebu
         */
        handle->md.dag_mem_bottom = 0;
        handle->md.dag_mem_top = 0;
-       handle->md.dag_fcs_bits = 32;
 
-       /* Query the card first for special cases. */
+       /*
+        * Find out how many FCS bits we should strip.
+        * First, query the card to see if it strips the FCS.
+        */
        daginf = dag_info(handle->fd);
-       if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code))
-       {
+       if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) {
                /* DAG 4.2S and 4.23S already strip the FCS.  Stripping the final word again truncates the packet. */
                handle->md.dag_fcs_bits = 0;
-       }
 
-       /* Then allow an environment variable to override. */
-       if ((s = getenv("ERF_FCS_BITS")) != NULL) {
-               if ((n = atoi(s)) == 0 || n == 16|| n == 32) {
-                       handle->md.dag_fcs_bits = n;
-               } else {
-                       snprintf(ebuf, PCAP_ERRBUF_SIZE,
-                               "pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
-                       goto failstop;
+               /* Note that no FCS will be supplied. */
+               handle->linktype_ext = LT_FCS_DATALINK_EXT(0);
+       } else {
+               /*
+                * Start out assuming it's 32 bits.
+                */
+               handle->md.dag_fcs_bits = 32;
+
+               /* Allow an environment variable to override. */
+               if ((s = getenv("ERF_FCS_BITS")) != NULL) {
+                       if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
+                               handle->md.dag_fcs_bits = n;
+                       } else {
+                               snprintf(ebuf, PCAP_ERRBUF_SIZE,
+                                       "pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
+                               goto failstop;
+                       }
+               }
+
+               /*
+                * Did the user request that they not be stripped?
+                */
+               if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) {
+                       /* Yes.  Note the number of bytes that will be
+                          supplied. */
+                       handle->linktype_ext = LT_FCS_DATALINK_EXT(handle->md.dag_fcs_bits/16);
+
+                       /* And don't strip them. */
+                       handle->md.dag_fcs_bits = 0;
                }
        }
 
index 7a8f3b6748a3f1a3602df2aadb1e3929bdce69a7..fe46316cd24275d5b7739c383a31991bb68e26ab 100644 (file)
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.84 2007-09-29 00:29:14 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.85 2007-09-29 19:33:29 guy Exp $ (LBL)
  */
 
 #ifndef pcap_int_h
@@ -166,7 +166,8 @@ struct pcap {
        int send_fd;
 #endif /* WIN32 */
        int snapshot;
-       int linktype;
+       int linktype;           /* Network linktype */
+       int linktype_ext;       /* Extended information stored in the linktype field of a file */
        int tzoff;              /* timezone offset */
        int offset;             /* offset for proper alignment */
 
diff --git a/pcap.c b/pcap.c
index 46bc34a026e360701cdd137d7643cc5a6572899d..a5879e5a1e8811d63a2ad4f4d75ff8f493de5305 100644 (file)
--- a/pcap.c
+++ b/pcap.c
@@ -33,7 +33,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.110 2007-09-19 02:40:34 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.111 2007-09-29 19:33:29 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -221,6 +221,12 @@ pcap_datalink(pcap_t *p)
        return (p->linktype);
 }
 
+int
+pcap_datalink_ext(pcap_t *p)
+{
+       return (p->linktype_ext);
+}
+
 int
 pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
 {
index 2a97cdf26f7acc9988c5e4354f9515f86a8b5f4d..05ec514aec24bc71344d444f3c46fb80d653b189 100644 (file)
@@ -37,7 +37,7 @@
  *
  *      @(#)bpf.h       7.1 (Berkeley) 5/7/91
  *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.17 2007-09-19 02:40:35 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.18 2007-09-29 19:33:29 guy Exp $ (LBL)
  */
 
 /*
@@ -742,6 +742,26 @@ struct bpf_version {
 #define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201
 
 
+/*
+ * DLT and savefile link type values are split into a class and
+ * a member of that class.  A class value of 0 indicates a regular
+ * DLT_/LINKTYPE_ value.
+ */
+#define DLT_CLASS(x)           ((x) & 0x03ff0000)
+
+/*
+ * NetBSD-specific generic "raw" link type.  The class value indicates
+ * that this is the generic raw type, and the lower 16 bits are the
+ * address family we're dealing with.  Those values are NetBSD-specific;
+ * do not assume that they correspond to AF_ values for your operating
+ * system.
+ */
+#define        DLT_CLASS_NETBSD_RAWAF  0x02240000
+#define        DLT_NETBSD_RAWAF(af)    (DLT_CLASS_NETBSD_RAWAF | (af))
+#define        DLT_NETBSD_RAWAF_AF(x)  ((x) & 0x0000ffff)
+#define        DLT_IS_NETBSD_RAWAF(x)  (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF)
+
+
 /*
  * The instruction encodings.
  */
index 066a2cb03d346e294e68756b42f2ae902e4df9ad..f3956bbc547d781ffbc588d40861beb83ad64eec 100644 (file)
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.2 2007-06-11 10:04:25 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.3 2007-09-29 19:33:29 guy Exp $ (LBL)
  */
 
 #ifndef lib_pcap_pcap_h
@@ -120,6 +120,16 @@ struct pcap_file_header {
        bpf_u_int32 linktype;   /* data link type (LINKTYPE_*) */
 };
 
+/*
+ * Macros for the value returned by pcap_datalink_ext().
+ * 
+ * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
+ * gives the FCS length of packets in the capture.
+ */
+#define LT_FCS_LENGTH_PRESENT(x)       ((x) & 0x04000000)
+#define LT_FCS_LENGTH(x)               (((x) & 0xF0000000) >> 28)
+#define LT_FCS_DATALINK_EXT(x)         (((x) & 0xF) << 28) | 0x04000000)
+
 typedef enum {
        PCAP_D_INOUT = 0,
        PCAP_D_IN,
@@ -245,6 +255,7 @@ int pcap_compile_nopcap(int, int, struct bpf_program *,
            const char *, int, bpf_u_int32);
 void   pcap_freecode(struct bpf_program *);
 int    pcap_datalink(pcap_t *);
+int    pcap_datalink_ext(pcap_t *);
 int    pcap_list_datalinks(pcap_t *, int **);
 int    pcap_set_datalink(pcap_t *, int);
 int    pcap_datalink_name_to_val(const char *);
index 06804f7fa4b4082855a9bfeeeb61f45c831d703e..d589a45e9642f0a62cc97b3b8a6aab3d2868e67a 100644 (file)
@@ -30,7 +30,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.166 2007-09-29 00:29:14 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.167 2007-09-29 19:33:29 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -834,6 +834,18 @@ static struct linktype_map {
        { -1,                   -1 }
 };
 
+/*
+ * Mechanism for storing information about a capture in the upper
+ * 6 bits of a linktype value in a capture file.
+ *
+ * LT_LINKTYPE_EXT(x) extracts the additional information.
+ *
+ * The rest of the bits are for a value describing the link-layer
+ * value.  LT_LINKTYPE(x) extracts that value.
+ */
+#define LT_LINKTYPE(x)         ((x) & 0x03FFFFFF)
+#define LT_LINKTYPE_EXT(x)     ((x) & 0xFC000000)
+
 static int
 dlt_to_linktype(int dlt)
 {
@@ -1064,7 +1076,8 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
        }
        p->tzoff = hdr.thiszone;
        p->snapshot = hdr.snaplen;
-       p->linktype = linktype_to_dlt(hdr.linktype);
+       p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
+       p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
        if (magic == KUZNETZOV_TCPDUMP_MAGIC && p->linktype == DLT_EN10MB) {
                /*
                 * This capture might have been done in raw mode or cooked
@@ -1479,6 +1492,7 @@ pcap_dump_open(pcap_t *p, const char *fname)
                    fname, linktype);
                return (NULL);
        }
+       linktype |= p->linktype_ext;
 
        if (fname[0] == '-' && fname[1] == '\0') {
                f = stdout;
@@ -1513,6 +1527,7 @@ pcap_dump_fopen(pcap_t *p, FILE *f)
                    linktype);
                return (NULL);
        }
+       linktype |= p->linktype_ext;
 
        return (pcap_setup_dump(p, linktype, f, "stream"));
 }