aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2010-04-21 20:51:22 +0000
committerGuy Harris <guy@alum.mit.edu>2010-04-21 20:51:22 +0000
commit21a210b77763224e0ac15611842cf7203d07fa08 (patch)
tree8bcb5aa12a0e02936ac8737faf20ddbae72d0998 /wiretap
parentc1729024c520afc5c8824abc04b3a3cc9eacb716 (diff)
From Chris Maynard:
Support PPP-over-USB. Don't remove the USB pseudo-header from the packet data for Linux USB packets, just byte-swap it if necessary and have the USB dissector fetch the pseudo-header from the raw packet data. Update USB language ID values. svn path=/trunk/; revision=32534
Diffstat (limited to 'wiretap')
-rw-r--r--wiretap/libpcap.c11
-rw-r--r--wiretap/pcap-common.c123
-rw-r--r--wiretap/pcap-common.h6
-rw-r--r--wiretap/pcapng.c7
-rw-r--r--wiretap/wtap-int.h18
-rw-r--r--wiretap/wtap.h11
6 files changed, 92 insertions, 84 deletions
diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c
index 6a0d9aaecc..117409c25a 100644
--- a/wiretap/libpcap.c
+++ b/wiretap/libpcap.c
@@ -643,8 +643,8 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
libpcap = (libpcap_t *)wth->priv;
phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type,
- wth->file_encap, libpcap->byte_swapped, packet_size,
- TRUE, &wth->phdr, &wth->pseudo_header, err, err_info);
+ wth->file_encap, packet_size, TRUE, &wth->phdr,
+ &wth->pseudo_header, err, err_info);
if (phdr_len < 0)
return FALSE; /* error */
@@ -698,6 +698,8 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
}
}
+ pcap_read_post_process(wth->file_encap, wth->phdr.caplen,
+ libpcap->byte_swapped, buffer_start_ptr(wth->frame_buffer));
return TRUE;
}
@@ -714,8 +716,7 @@ libpcap_seek_read(wtap *wth, gint64 seek_off,
libpcap = (libpcap_t *)wth->priv;
phdr_len = pcap_process_pseudo_header(wth->random_fh, wth->file_type,
- wth->file_encap, libpcap->byte_swapped, length,
- FALSE, NULL, pseudo_header, err, err_info);
+ wth->file_encap, length, FALSE, NULL, pseudo_header, err, err_info);
if (phdr_len < 0)
return FALSE; /* error */
@@ -746,6 +747,8 @@ libpcap_seek_read(wtap *wth, gint64 seek_off,
atm_guess_lane_type(pd, length, pseudo_header);
}
}
+ pcap_read_post_process(wth->file_encap, length,
+ libpcap->byte_swapped, pd);
return TRUE;
}
diff --git a/wiretap/pcap-common.c b/wiretap/pcap-common.c
index d404859ca8..7344543b72 100644
--- a/wiretap/pcap-common.c
+++ b/wiretap/pcap-common.c
@@ -924,33 +924,44 @@ pcap_read_sita_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
return TRUE;
}
-static gboolean
-pcap_read_linux_usb_pseudoheader(FILE_T fh,
- union wtap_pseudo_header *pseudo_header, gboolean byte_swapped, int *err)
-{
- int bytes_read;
+/*
+ * Offset of the *end* of a field within a particular structure.
+ */
+#define END_OFFSETOF(basep, fieldp) \
+ (((char *)(void *)(fieldp)) - ((char *)(void *)(basep)) + \
+ sizeof(*fieldp))
- errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(&pseudo_header->linux_usb, 1,
- sizeof (struct linux_usb_phdr), fh);
- if (bytes_read != sizeof (struct linux_usb_phdr)) {
- *err = file_error(fh);
- if (*err == 0)
- *err = WTAP_ERR_SHORT_READ;
- return FALSE;
- }
+static void
+pcap_process_linux_usb_pseudoheader(guint packet_size, gboolean byte_swapped,
+ guint8 *pd)
+{
+ struct linux_usb_phdr *phdr;
if (byte_swapped) {
- pseudo_header->linux_usb.id = GUINT64_SWAP_LE_BE(pseudo_header->linux_usb.id);
- pseudo_header->linux_usb.bus_id = GUINT16_SWAP_LE_BE(pseudo_header->linux_usb.bus_id);
- pseudo_header->linux_usb.ts_sec = GUINT64_SWAP_LE_BE(pseudo_header->linux_usb.ts_sec);
- pseudo_header->linux_usb.ts_usec = GUINT32_SWAP_LE_BE(pseudo_header->linux_usb.ts_usec);
- pseudo_header->linux_usb.status = GUINT32_SWAP_LE_BE(pseudo_header->linux_usb.status);
- pseudo_header->linux_usb.urb_len = GUINT32_SWAP_LE_BE(pseudo_header->linux_usb.urb_len);
- pseudo_header->linux_usb.data_len = GUINT32_SWAP_LE_BE(pseudo_header->linux_usb.data_len);
+ phdr = (struct linux_usb_phdr *)pd;
+
+ 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);
}
-
- return TRUE;
}
static gboolean
@@ -1144,8 +1155,8 @@ pcap_read_i2c_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, i
}
int
-pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, gboolean bytes_swapped, guint packet_size,
- gboolean check_packet_size, struct wtap_pkthdr *phdr,
+pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
+ guint packet_size, gboolean check_packet_size, struct wtap_pkthdr *phdr,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
{
int phdr_len = 0;
@@ -1289,26 +1300,6 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, gboolean by
phdr_len = SITA_HDR_LEN;
break;
- case WTAP_ENCAP_USB_LINUX:
- case WTAP_ENCAP_USB_LINUX_MMAPPED:
- if (check_packet_size &&
- packet_size < sizeof (struct linux_usb_phdr)) {
- /*
- * Uh-oh, the packet isn't big enough to even
- * have a pseudo-header.
- */
- *err = WTAP_ERR_BAD_RECORD;
- *err_info = g_strdup_printf("pcap: Linux USB file has a %u-byte packet, too small to have even a Linux USB pseudo-header",
- packet_size);
- return -1;
- }
- if (!pcap_read_linux_usb_pseudoheader(fh,
- pseudo_header, bytes_swapped, err))
- return -1; /* Read error */
-
- phdr_len = (int)sizeof (struct linux_usb_phdr);
- break;
-
case WTAP_ENCAP_BLUETOOTH_H4:
/* We don't have pseudoheader, so just pretend we received everything. */
pseudo_header->p2p.sent = FALSE;
@@ -1412,6 +1403,23 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap, gboolean by
return phdr_len;
}
+void
+pcap_read_post_process(int wtap_encap, guint packet_size,
+ gboolean bytes_swapped, guchar *pd)
+{
+ switch (wtap_encap) {
+
+ case WTAP_ENCAP_USB_LINUX:
+ case WTAP_ENCAP_USB_LINUX_MMAPPED:
+ pcap_process_linux_usb_pseudoheader(packet_size,
+ bytes_swapped, pd);
+ break;
+
+ default:
+ break;
+ }
+}
+
int
pcap_get_phdr_size(int encap, const union wtap_pseudo_header *pseudo_header)
{
@@ -1439,11 +1447,6 @@ pcap_get_phdr_size(int encap, const union wtap_pseudo_header *pseudo_header)
hdrsize = SITA_HDR_LEN;
break;
- case WTAP_ENCAP_USB_LINUX:
- case WTAP_ENCAP_USB_LINUX_MMAPPED:
- hdrsize = (int)sizeof (struct linux_usb_phdr);
- break;
-
case WTAP_ENCAP_ERF:
hdrsize = (int)sizeof (struct erf_phdr);
if (pseudo_header->erf.phdr.type & 0x80)
@@ -1636,26 +1639,6 @@ pcap_write_phdr(wtap_dumper *wdh, int encap, const union wtap_pseudo_header *pse
wdh->bytes_dumped += sizeof(sita_hdr);
break;
- case WTAP_ENCAP_USB_LINUX:
- case WTAP_ENCAP_USB_LINUX_MMAPPED:
- /*
- * Write out the pseudo-header; it has the same format
- * as the Linux USB header, and that header is supposed
- * to be written in the host byte order of the machine
- * writing the file.
- */
- nwritten = fwrite(&pseudo_header->linux_usb, 1,
- sizeof(pseudo_header->linux_usb), wdh->fh);
- if (nwritten != sizeof(pseudo_header->linux_usb)) {
- if (nwritten == 0 && ferror(wdh->fh))
- *err = errno;
- else
- *err = WTAP_ERR_SHORT_WRITE;
- return FALSE;
- }
- wdh->bytes_dumped += sizeof(lapd_hdr);
- break;
-
case WTAP_ENCAP_ERF:
/*
* Write the ERF header.
diff --git a/wiretap/pcap-common.h b/wiretap/pcap-common.h
index 60762abe77..9477ad0ae4 100644
--- a/wiretap/pcap-common.h
+++ b/wiretap/pcap-common.h
@@ -25,10 +25,12 @@
*/
extern int pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
- gboolean byte_swapped, guint packet_size,
- gboolean check_packet_size, struct wtap_pkthdr *phdr,
+ guint packet_size, gboolean check_packet_size, struct wtap_pkthdr *phdr,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
+extern void pcap_read_post_process(int wtap_encap, guint packet_size,
+ gboolean bytes_swapped, guchar *pd);
+
extern int pcap_get_phdr_size(int encap,
const union wtap_pseudo_header *pseudo_header);
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c
index fb793fea10..5c0a4e4caa 100644
--- a/wiretap/pcapng.c
+++ b/wiretap/pcapng.c
@@ -829,7 +829,6 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
pseudo_header_len = pcap_process_pseudo_header(fh,
WTAP_FILE_PCAPNG,
wtap_encap,
- pn->byte_swapped,
wblock->data.packet.cap_len,
TRUE,
wblock->packet_header,
@@ -935,6 +934,9 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
}
}
+ pcap_read_post_process(wtap_encap,
+ (int) (wblock->data.packet.cap_len - pseudo_header_len),
+ pn->byte_swapped, (guchar *) (wblock->frame_buffer));
return block_read;
}
@@ -987,7 +989,6 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
pseudo_header_len = pcap_process_pseudo_header(fh,
WTAP_FILE_PCAPNG,
encap,
- pn->byte_swapped,
wblock->data.simple_packet.cap_len,
TRUE,
wblock->packet_header,
@@ -1035,6 +1036,8 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
block_read += 4 - (wblock->data.simple_packet.cap_len % 4);
}
+ pcap_read_post_process(encap, (int) wblock->data.simple_packet.cap_len,
+ pn->byte_swapped, (guchar *) (wblock->frame_buffer));
return block_read;
}
diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h
index c85c26af15..1967457cf9 100644
--- a/wiretap/wtap-int.h
+++ b/wiretap/wtap-int.h
@@ -122,9 +122,25 @@ extern gint wtap_num_file_types;
((((x)&0xFF00)>>8) | \
(((x)&0x00FF)<<8))
-/* Macros to byte-swap possibly-unaligned 32-bit and 16-bit quantities;
+/* Macros to byte-swap possibly-unaligned 64-bit, 32-bit and 16-bit quantities;
* they take a pointer to the quantity, and byte-swap it in place.
*/
+#define PBSWAP64(p) \
+ { \
+ guint8 tmp; \
+ tmp = (p)[7]; \
+ (p)[7] = (p)[0]; \
+ (p)[0] = tmp; \
+ tmp = (p)[6]; \
+ (p)[6] = (p)[1]; \
+ (p)[1] = tmp; \
+ tmp = (p)[5]; \
+ (p)[5] = (p)[2]; \
+ (p)[2] = tmp; \
+ tmp = (p)[4]; \
+ (p)[4] = (p)[3]; \
+ (p)[3] = tmp; \
+ }
#define PBSWAP32(p) \
{ \
guint8 tmp; \
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index c7757b0e68..6e89159389 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -633,6 +633,7 @@ struct catapult_dct2000_phdr
/*
* USB setup header as defined in USB specification
* See usb_20.pdf, Chapter 9.3 'USB Device Requests' for details.
+ * http://www.usb.org/developers/docs/usb_20_122909-2.zip
*/
struct usb_device_setup_hdr {
gint8 bmRequestType;
@@ -658,7 +659,7 @@ struct linux_usb_phdr {
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 present */
+ 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;
@@ -837,12 +838,11 @@ union wtap_pseudo_header {
struct cosine_phdr cosine;
struct irda_phdr irda;
struct nettl_phdr nettl;
- struct mtp2_phdr mtp2;
+ struct mtp2_phdr mtp2;
struct k12_phdr k12;
struct lapd_phdr lapd;
struct catapult_dct2000_phdr dct2000;
- struct linux_usb_phdr linux_usb;
- struct erf_mc_phdr erf;
+ struct erf_mc_phdr erf;
struct sita_phdr sita;
struct bthci_phdr bthci;
struct l1event_phdr l1event;
@@ -863,7 +863,6 @@ struct wtap_pkthdr {
int pkt_encap;
};
-struct wtap;
struct Buffer;
struct wtap_dumper;
@@ -1025,6 +1024,8 @@ int wtap_register_encap_type(char* name, char* short_name);
/* We're trying to open the standard input for random access */
#define WTAP_ERR_COMPRESSION_NOT_SUPPORTED -19
/* The filetype doesn't support output compression */
+#define WTAP_ERR_CANT_SEEK -20
+ /* An attempt to seek failed, reason unknown */
/* Errors from zlib; zlib error Z_xxx turns into Wiretap error
WTAP_ERR_ZLIB + Z_xxx.