]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Use nd_ types, add host-endian extract routines, clean up signed vs. unsigned.
authorGuy Harris <[email protected]>
Thu, 11 Jan 2018 19:10:21 +0000 (11:10 -0800)
committerGuy Harris <[email protected]>
Thu, 11 Jan 2018 19:10:21 +0000 (11:10 -0800)
We now define the structures for Linux USB headers in print-usb.c, so it
doesn't need to include <pcap/usb.h>; don't check for it.

config.h.in
configure
configure.ac
extract.h
netdissect.h
print-usb.c
print.c

index e5ae27c39bd19a600e014b28fa215e562320dce4..e0351163e6e8661ff01df8ff2f8577d35977c718 100644 (file)
 /* Define to 1 if you have the `pcap_set_tstamp_type' function. */
 #undef HAVE_PCAP_SET_TSTAMP_TYPE
 
-/* Define to 1 if you have the <pcap/usb.h> header file. */
-#undef HAVE_PCAP_USB_H
-
 /* define if libpcap has pcap_version */
 #undef HAVE_PCAP_VERSION
 
index 72955936178b431215ad042e346b12ae5299bde3..0c0939133c68f77ac3dea81b0a6b6fe86d10001d 100755 (executable)
--- a/configure
+++ b/configure
@@ -6671,19 +6671,6 @@ fi
 
 done
 
-for ac_header in pcap/usb.h
-do :
-  ac_fn_c_check_header_compile "$LINENO" "pcap/usb.h" "ac_cv_header_pcap_usb_h" "#include \"netdissect-stdinc.h\"
-"
-if test "x$ac_cv_header_pcap_usb_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_PCAP_USB_H 1
-_ACEOF
-
-fi
-
-done
-
 CPPFLAGS="$savedcppflags"
 
 if test -n "$ac_tool_prefix"; then
index 485ac1f9c825944d9c766dce2962a7229f508f7c..81ec675c88f6c1a40433853dd016c10b2e88bf5b 100644 (file)
@@ -835,7 +835,6 @@ savedcppflags="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS $V_INCLS"
 AC_CHECK_HEADERS(pcap/bluetooth.h,,,[#include "netdissect-stdinc.h"])
 AC_CHECK_HEADERS(pcap/nflog.h,,,[#include "netdissect-stdinc.h"])
-AC_CHECK_HEADERS(pcap/usb.h,,,[#include "netdissect-stdinc.h"])
 CPPFLAGS="$savedcppflags"
 
 AC_PROG_RANLIB
index 8f2ed8d053615c1e480675de1966f366a1bfbd97..25bab1e2f5260e48fea97d0d251e3e60d87c464c 100644 (file)
--- a/extract.h
+++ b/extract.h
@@ -305,6 +305,56 @@ EXTRACT_IPV4_TO_HOST_ORDER(const void *p)
                    ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
 #endif /* unaligned access checks */
 
+/*
+ * Extract numerical values in *host* byte order.  (Some metadata
+ * headers are in the byte order of the host that wrote the file,
+ * and libpcap translate them to the byte order of the host
+ * reading the file.  This means that if a program on that host
+ * reads with libpcap and writes to a new file, the new file will
+ * be written in the byte order of the host writing the file.  Thus,
+ * the magic number in pcap files and byte-order magic in pcapng
+ * files can be used to determine the byte order in those metadata
+ * headers.)
+ *
+ * XXX - on platforms that can do unaligned accesses, just cast and
+ * dereference the pointer.
+ */
+static inline uint16_t
+EXTRACT_HE_U_2(const void *p)
+{
+       uint16_t val;
+
+       UNALIGNED_MEMCPY(&val, p, sizeof(uint16_t));
+       return val;
+}
+
+static inline uint16_t
+EXTRACT_HE_S_2(const void *p)
+{
+       int16_t val;
+
+       UNALIGNED_MEMCPY(&val, p, sizeof(int16_t));
+       return val;
+}
+
+static inline uint16_t
+EXTRACT_HE_U_4(const void *p)
+{
+       uint32_t val;
+
+       UNALIGNED_MEMCPY(&val, p, sizeof(uint32_t));
+       return val;
+}
+
+static inline uint16_t
+EXTRACT_HE_S_4(const void *p)
+{
+       int32_t val;
+
+       UNALIGNED_MEMCPY(&val, p, sizeof(int32_t));
+       return val;
+}
+
 /*
  * Extract an IPv4 address, which is in network byte order, and which
  * is not necessarily aligned on a 4-byte boundary, and provide the
index e809e04ad2933b72f8ddc3d32b62a9434e825e6c..360c1eb953f3864a414efc45755553cb3aec875e 100644 (file)
@@ -61,6 +61,7 @@ typedef signed char nd_int8_t[1];
  * individual bytes while they're being assembled.
  */
 typedef unsigned char nd_int32_t[4];
+typedef unsigned char nd_int64_t[8];
 
 /*
  * Use this for IPv4 addresses and netmasks.
index 9031f2757fdeaf6f9fbc3f11d1741d405dae69a5..d3018d7aba763b7984b144def083782a905c4b0a 100644 (file)
 #include <netdissect-stdinc.h>
 
 #include "netdissect.h"
+#include "extract.h"
 
+#ifdef DLT_USB_LINUX
+/*
+ * possible transfer mode
+ */
+#define URB_TRANSFER_IN   0x80
+#define URB_ISOCHRONOUS   0x0
+#define URB_INTERRUPT     0x1
+#define URB_CONTROL       0x2
+#define URB_BULK          0x3
+
+/*
+ * possible event type
+ */
+#define URB_SUBMIT        'S'
+#define URB_COMPLETE      'C'
+#define URB_ERROR         'E'
+
+/*
+ * USB setup header as defined in USB specification.
+ * Appears at the front of each Control S-type packet in DLT_USB captures.
+ */
+typedef struct _usb_setup {
+       nd_uint8_t bmRequestType;
+       nd_uint8_t bRequest;
+       nd_uint16_t wValue;
+       nd_uint16_t wIndex;
+       nd_uint16_t wLength;
+} pcap_usb_setup;
+
+/*
+ * Information from the URB for Isochronous transfers.
+ */
+typedef struct _iso_rec {
+       nd_int32_t      error_count;
+       nd_int32_t      numdesc;
+} iso_rec;
+
+/*
+ * Header prepended by linux kernel to each event.
+ * Appears at the front of each packet in DLT_USB_LINUX captures.
+ */
+typedef struct _usb_header {
+       nd_uint64_t id;
+       nd_uint8_t event_type;
+       nd_uint8_t transfer_type;
+       nd_uint8_t endpoint_number;
+       nd_uint8_t device_address;
+       nd_uint16_t bus_id;
+       nd_uint8_t setup_flag;/*if !=0 the urb setup header is not present*/
+       nd_uint8_t data_flag; /*if !=0 no urb data is present*/
+       nd_int64_t ts_sec;
+       nd_int32_t ts_usec;
+       nd_int32_t status;
+       nd_uint32_t urb_len;
+       nd_uint32_t data_len; /* amount of urb data really present in this event*/
+       pcap_usb_setup setup;
+} pcap_usb_header;
+
+/*
+ * Header prepended by linux kernel to each event for the 2.6.31
+ * and later kernels; for the 2.6.21 through 2.6.30 kernels, the
+ * "iso_rec" information, and the fields starting with "interval"
+ * are zeroed-out padding fields.
+ *
+ * Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures.
+ */
+typedef struct _usb_header_mmapped {
+       nd_uint64_t id;
+       nd_uint8_t event_type;
+       nd_uint8_t transfer_type;
+       nd_uint8_t endpoint_number;
+       nd_uint8_t device_address;
+       nd_uint16_t bus_id;
+       nd_uint8_t setup_flag;/*if !=0 the urb setup header is not present*/
+       nd_uint8_t data_flag; /*if !=0 no urb data is present*/
+       nd_int64_t ts_sec;
+       nd_int32_t ts_usec;
+       nd_int32_t status;
+       nd_uint32_t urb_len;
+       nd_uint32_t data_len; /* amount of urb data really present in this event*/
+       union {
+               pcap_usb_setup setup;
+               iso_rec iso;
+       } s;
+       nd_int32_t interval;    /* for Interrupt and Isochronous events */
+       nd_int32_t start_frame; /* for Isochronous events */
+       nd_uint32_t xfer_flags; /* copy of URB's transfer flags */
+       nd_uint32_t ndesc;      /* number of isochronous descriptors */
+} pcap_usb_header_mmapped;
 
-#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX)
-#include <pcap/usb.h>
+/*
+ * Isochronous descriptors; for isochronous transfers there might be
+ * one or more of these at the beginning of the packet data.  The
+ * number of descriptors is given by the "ndesc" field in the header;
+ * as indicated, in older kernels that don't put the descriptors at
+ * the beginning of the packet, that field is zeroed out, so that field
+ * can be trusted even in captures from older kernels.
+ */
+typedef struct _usb_isodesc {
+       nd_int32_t      status;
+       nd_uint32_t     offset;
+       nd_uint32_t     len;
+       nd_byte         pad[4];
+} usb_isodesc;
 
 static const char tstr[] = "[|usb]";
 
@@ -84,8 +186,10 @@ static void
 usb_header_print(netdissect_options *ndo, const pcap_usb_header *uh)
 {
        int direction;
+       uint8_t transfer_type, event_type;
 
-       switch(uh->transfer_type)
+       transfer_type = EXTRACT_U_1(uh->transfer_type);
+       switch(transfer_type)
        {
                case URB_ISOCHRONOUS:
                        ND_PRINT("ISOCHRONOUS");
@@ -103,7 +207,8 @@ usb_header_print(netdissect_options *ndo, const pcap_usb_header *uh)
                        ND_PRINT(" ?");
        }
 
-       switch(uh->event_type)
+       event_type = EXTRACT_U_1(uh->event_type);
+       switch(event_type)
        {
                case URB_SUBMIT:
                        ND_PRINT(" SUBMIT");
@@ -118,12 +223,12 @@ usb_header_print(netdissect_options *ndo, const pcap_usb_header *uh)
                        ND_PRINT(" ?");
        }
 
-       direction = get_direction(uh->transfer_type, uh->event_type);
+       direction = get_direction(transfer_type, event_type);
        if(direction == 1)
                ND_PRINT(" from");
        else if(direction == 2)
                ND_PRINT(" to");
-       ND_PRINT(" %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f);
+       ND_PRINT(" %u:%u:%u", EXTRACT_HE_U_2(uh->bus_id), EXTRACT_U_1(uh->device_address), EXTRACT_U_1(uh->endpoint_number) & 0x7f);
 }
 
 /*
@@ -172,5 +277,5 @@ usb_linux_64_byte_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
 }
 #endif /* DLT_USB_LINUX_MMAPPED */
 
-#endif /* defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) */
+#endif /* DLT_USB_LINUX */
 
diff --git a/print.c b/print.c
index 1e2e5f3fe951dd1482c6883c9e21ed264a2977e9..ca231f146e01f24837adb36fa8b6b60d933b43c5 100644 (file)
--- a/print.c
+++ b/print.c
@@ -99,14 +99,12 @@ static const struct printer printers[] = {
 #ifdef DLT_IPV6
        { raw_if_print,         DLT_IPV6 },
 #endif
-#ifdef HAVE_PCAP_USB_H
 #ifdef DLT_USB_LINUX
        { usb_linux_48_byte_if_print, DLT_USB_LINUX},
 #endif /* DLT_USB_LINUX */
 #ifdef DLT_USB_LINUX_MMAPPED
        { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED},
 #endif /* DLT_USB_LINUX_MMAPPED */
-#endif /* HAVE_PCAP_USB_H */
 #ifdef DLT_SYMANTEC_FIREWALL
        { symantec_if_print,    DLT_SYMANTEC_FIREWALL },
 #endif