Skip to content

Commit

Permalink
From Paolo Abeni:
Browse files Browse the repository at this point in the history
	The USB pseudo-header in DLT_USB_LINUX captures is in the host
	byte order for the machine on which the capture was done.  When
	reading a capture file, convert the pseudo-header to the host
	byte order of the host on which the file is being read.

	There's a 64-bit quantity in that pseudo-header; move the 64-bit
	byte-swap macro from the DAG code to pcap-int.h for use by other
	code.
  • Loading branch information
yuguy committed Jan 29, 2007
1 parent 6db2ddb commit b4c382f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 17 deletions.
17 changes: 2 additions & 15 deletions pcap-dag.c
Expand Up @@ -17,7 +17,7 @@

#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.26 2006-09-25 18:18:18 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.27 2007-01-29 20:08:06 guy Exp $ (LBL)";
#endif

#ifdef HAVE_CONFIG_H
Expand Down Expand Up @@ -68,19 +68,6 @@ static const unsigned short endian_test_word = 0x0100;

#define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))

/*
* Swap byte ordering of unsigned long long timestamp on a big endian
* machine.
*/
#define SWAP_TS(ull) ((ull & 0xff00000000000000LL) >> 56) | \
((ull & 0x00ff000000000000LL) >> 40) | \
((ull & 0x0000ff0000000000LL) >> 24) | \
((ull & 0x000000ff00000000LL) >> 8) | \
((ull & 0x00000000ff000000LL) << 8) | \
((ull & 0x0000000000ff0000LL) << 24) | \
((ull & 0x000000000000ff00LL) << 40) | \
((ull & 0x00000000000000ffLL) << 56)


#ifdef DAG_ONLY
/* This code is required when compiling for a DAG device only. */
Expand Down Expand Up @@ -417,7 +404,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
register unsigned long long ts;

if (IS_BIGENDIAN()) {
ts = SWAP_TS(header->ts);
ts = SWAPLL(header->ts);
} else {
ts = header->ts;
}
Expand Down
15 changes: 14 additions & 1 deletion pcap-int.h
Expand Up @@ -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.78 2006-02-22 17:09:02 gianluca Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.79 2007-01-29 20:08:06 guy Exp $ (LBL)
*/

#ifndef pcap_int_h
Expand All @@ -51,6 +51,19 @@ extern "C" {
#include <io.h>
#endif

/*
* Swap byte ordering of unsigned long long timestamp on a big endian
* machine.
*/
#define SWAPLL(ull) ((ull & 0xff00000000000000LL) >> 56) | \
((ull & 0x00ff000000000000LL) >> 40) | \
((ull & 0x0000ff0000000000LL) >> 24) | \
((ull & 0x000000ff00000000LL) >> 8) | \
((ull & 0x00000000ff000000LL) << 8) | \
((ull & 0x0000000000ff0000LL) << 24) | \
((ull & 0x000000000000ff00LL) << 40) | \
((ull & 0x00000000000000ffLL) << 56)

/*
* Savefile
*/
Expand Down
41 changes: 40 additions & 1 deletion savefile.c
Expand Up @@ -30,7 +30,7 @@

#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.149 2006-12-20 03:30:32 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.150 2007-01-29 20:08:06 guy Exp $ (LBL)";
#endif

#ifdef HAVE_CONFIG_H
Expand All @@ -44,6 +44,7 @@ static const char rcsid[] _U_ =
#include <string.h>

#include "pcap-int.h"
#include "pcap/usb.h"

#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
Expand Down Expand Up @@ -1197,6 +1198,44 @@ sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, u_int buflen)
return (-1);
}
}

/*
* The DLT_USB_LINUX header is in host byte order when capturing
* (it's supplied directly from a memory-mapped buffer shared
* by the kernel).
*
* When reading a DLT_USB_LINUX capture file, we need to convert
* it from the capturing host's byte order to the reading host's
* byte order.
*/
if (p->sf.swapped && p->linktype == DLT_USB_LINUX) {
pcap_usb_header* uhdr = (pcap_usb_header*) buf;
/*
* The URB id is a totally opaque value; do we really need to
* converte it to the reading host's byte order???
*/
if (hdr->caplen < 8)
return 0;
uhdr->id = SWAPLL(uhdr->id);
if (hdr->caplen < 14)
return 0;
uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
if (hdr->caplen < 24)
return 0;
uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
if (hdr->caplen < 28)
return 0;
uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
if (hdr->caplen < 32)
return 0;
uhdr->status = SWAPLONG(uhdr->status);
if (hdr->caplen < 36)
return 0;
uhdr->urb_len = SWAPLONG(uhdr->urb_len);
if (hdr->caplen < 40)
return 0;
uhdr->data_len = SWAPLONG(uhdr->data_len);
}
return (0);
}

Expand Down

0 comments on commit b4c382f

Please sign in to comment.