dect
/
libpcap
Archived
13
0
Fork 0

From Paolo Abeni:

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.
This commit is contained in:
guy 2007-01-29 20:08:06 +00:00
parent 6db2ddb56a
commit b4c382fd7e
3 changed files with 56 additions and 17 deletions

View File

@ -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
@ -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. */
@ -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;
}

View 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.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
@ -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
*/

View File

@ -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
@ -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"
@ -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);
}