aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/pcap-common.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-02-05 00:33:45 -0800
committerGuy Harris <guy@alum.mit.edu>2014-02-06 21:35:58 +0000
commit63479adf638710b6fd272be5b4b0df23bda2daac (patch)
tree0d7fd0d6b0de10ffc163b270e387aa814305e364 /wiretap/pcap-common.c
parent1dc06a2681495b3bb2c75fc871f156f06b973260 (diff)
Make some routines take a struct wtap_pkthdr * as an argument.
For some routines that take multiple arguments that come from a struct wtap_pkthdr, pass a pointer to the struct wtap_pkthdr in question, rather than the separate arguments. Do this even if we're passing expressions that were earlier assigned to the struct wtap_pkthdr fields in question. This simplifies the calling sequences and ensures that the right values are picked up by the called routine; in at least one case we were *not* passing the right values (the code to handle Simple Packet Blocks in pcap-ng files). Also, call the byte-swapping routines for pseudo-header fields only if we need to do byte-swapping. Change-Id: I3a8badfcfeb0237dfc1d1014185a67f18c0f2ebe Reviewed-on: https://code.wireshark.org/review/119 Reviewed-by: Evan Huus <eapache@gmail.com> Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'wiretap/pcap-common.c')
-rw-r--r--wiretap/pcap-common.c203
1 files changed, 105 insertions, 98 deletions
diff --git a/wiretap/pcap-common.c b/wiretap/pcap-common.c
index 01fadec39b..f262e2be9d 100644
--- a/wiretap/pcap-common.c
+++ b/wiretap/pcap-common.c
@@ -1185,113 +1185,122 @@ struct usb_device_setup_hdr {
sizeof(*fieldp))
static void
-pcap_process_linux_usb_pseudoheader(guint packet_size, gboolean byte_swapped,
- gboolean header_len_64_bytes, guint8 *pd)
+pcap_byteswap_linux_usb_pseudoheader(struct wtap_pkthdr *phdr, guint8 *pd,
+ gboolean header_len_64_bytes)
{
- struct linux_usb_phdr *phdr;
+ guint packet_size;
+ struct linux_usb_phdr *usb_phdr;
struct linux_usb_isodesc *pisodesc;
gint32 iso_numdesc, i;
- if (byte_swapped) {
- /*
- * Greasy hack, but we never directly direference any of
- * the fields in *phdr, we just get offsets of and
- * addresses of its members, so it's safe.
- */
- phdr = (struct linux_usb_phdr *)(void *)pd;
+ /*
+ * Minimum of captured and actual length (just in case the
+ * actual length < the captured length, which Should Never
+ * Happen).
+ */
+ packet_size = phdr->caplen;
+ if (packet_size > phdr->len)
+ packet_size = phdr->len;
- if (packet_size < END_OFFSETOF(phdr, &phdr->id))
- return;
- PBSWAP64((guint8 *)&phdr->id);
- if (packet_size < END_OFFSETOF(phdr, &phdr->bus_id))
+ /*
+ * Greasy hack, but we never directly dereference any of
+ * the fields in *usb_phdr, we just get offsets of and
+ * addresses of its members and byte-swap it with a
+ * byte-at-a-time macro, so it's alignment-safe.
+ */
+ usb_phdr = (struct linux_usb_phdr *)(void *)pd;
+
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->id))
+ return;
+ PBSWAP64((guint8 *)&usb_phdr->id);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->bus_id))
+ return;
+ PBSWAP16((guint8 *)&usb_phdr->bus_id);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->ts_sec))
+ return;
+ PBSWAP64((guint8 *)&usb_phdr->ts_sec);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->ts_usec))
+ return;
+ PBSWAP32((guint8 *)&usb_phdr->ts_usec);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->status))
+ return;
+ PBSWAP32((guint8 *)&usb_phdr->status);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->urb_len))
+ return;
+ PBSWAP32((guint8 *)&usb_phdr->urb_len);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->data_len))
+ return;
+ PBSWAP32((guint8 *)&usb_phdr->data_len);
+
+ if (usb_phdr->transfer_type == URB_ISOCHRONOUS) {
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->s.iso.error_count))
return;
- PBSWAP16((guint8 *)&phdr->bus_id);
- if (packet_size < END_OFFSETOF(phdr, &phdr->ts_sec))
+ PBSWAP32((guint8 *)&usb_phdr->s.iso.error_count);
+
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->s.iso.numdesc))
return;
- PBSWAP64((guint8 *)&phdr->ts_sec);
- if (packet_size < END_OFFSETOF(phdr, &phdr->ts_usec))
+ PBSWAP32((guint8 *)&usb_phdr->s.iso.numdesc);
+ }
+
+ if (header_len_64_bytes) {
+ /*
+ * This is either the "version 1" header, with
+ * 16 bytes of additional fields at the end, or
+ * a "version 0" header from a memory-mapped
+ * capture, with 16 bytes of zeroed-out padding
+ * at the end. Byte swap them as if this were
+ * a "version 1" header.
+ *
+ * Yes, the first argument to END_OFFSETOF() should
+ * be usb_phdr, not usb_phdr_ext; we want the offset of
+ * the additional fields from the beginning of
+ * the packet.
+ */
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->interval))
return;
- PBSWAP32((guint8 *)&phdr->ts_usec);
- if (packet_size < END_OFFSETOF(phdr, &phdr->status))
+ PBSWAP32((guint8 *)&usb_phdr->interval);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->start_frame))
return;
- PBSWAP32((guint8 *)&phdr->status);
- if (packet_size < END_OFFSETOF(phdr, &phdr->urb_len))
+ PBSWAP32((guint8 *)&usb_phdr->start_frame);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->xfer_flags))
return;
- PBSWAP32((guint8 *)&phdr->urb_len);
- if (packet_size < END_OFFSETOF(phdr, &phdr->data_len))
+ PBSWAP32((guint8 *)&usb_phdr->xfer_flags);
+ if (packet_size < END_OFFSETOF(usb_phdr, &usb_phdr->ndesc))
return;
- PBSWAP32((guint8 *)&phdr->data_len);
-
- if (phdr->transfer_type == URB_ISOCHRONOUS) {
- if (packet_size < END_OFFSETOF(phdr, &phdr->s.iso.error_count))
- return;
- PBSWAP32((guint8 *)&phdr->s.iso.error_count);
-
- if (packet_size < END_OFFSETOF(phdr, &phdr->s.iso.numdesc))
- return;
- PBSWAP32((guint8 *)&phdr->s.iso.numdesc);
+ PBSWAP32((guint8 *)&usb_phdr->ndesc);
+ }
- }
+ if (usb_phdr->transfer_type == URB_ISOCHRONOUS) {
+ /* swap the values in struct linux_usb_isodesc */
+ /*
+ * See previous "Greasy hack" comment.
+ */
if (header_len_64_bytes) {
+ pisodesc = (struct linux_usb_isodesc*)(void *)(pd + 64);
+ } else {
+ pisodesc = (struct linux_usb_isodesc*)(void *)(pd + 48);
+ }
+ iso_numdesc = usb_phdr->s.iso.numdesc;
+ for (i = 0; i < iso_numdesc; i++) {
/*
- * This is either the "version 1" header, with
- * 16 bytes of additional fields at the end, or
- * a "version 0" header from a memory-mapped
- * capture, with 16 bytes of zeroed-out padding
- * at the end. Byte swap them as if this were
- * a "version 1" header.
- *
- * Yes, the first argument to END_OFFSETOF() should
- * be phdr, not phdr_ext; we want the offset of
- * the additional fields from the beginning of
- * the packet.
+ * Always check if we have enough data from the
+ * beginning of the packet (usb_phdr).
*/
- if (packet_size < END_OFFSETOF(phdr, &phdr->interval))
+ if (packet_size < END_OFFSETOF(usb_phdr, &pisodesc->iso_status))
return;
- PBSWAP32((guint8 *)&phdr->interval);
- if (packet_size < END_OFFSETOF(phdr, &phdr->start_frame))
+ PBSWAP32((guint8 *)&pisodesc->iso_status);
+ if (packet_size < END_OFFSETOF(usb_phdr, &pisodesc->iso_off))
return;
- PBSWAP32((guint8 *)&phdr->start_frame);
- if (packet_size < END_OFFSETOF(phdr, &phdr->xfer_flags))
+ PBSWAP32((guint8 *)&pisodesc->iso_off);
+ if (packet_size < END_OFFSETOF(usb_phdr, &pisodesc->iso_len))
return;
- PBSWAP32((guint8 *)&phdr->xfer_flags);
- if (packet_size < END_OFFSETOF(phdr, &phdr->ndesc))
+ PBSWAP32((guint8 *)&pisodesc->iso_len);
+ if (packet_size < END_OFFSETOF(usb_phdr, &pisodesc->_pad))
return;
- PBSWAP32((guint8 *)&phdr->ndesc);
- }
-
- if (phdr->transfer_type == URB_ISOCHRONOUS) {
- /* swap the values in struct linux_usb_isodesc */
+ PBSWAP32((guint8 *)&pisodesc->_pad);
- /*
- * See previous "Greasy hack" comment.
- */
- if (header_len_64_bytes) {
- pisodesc = (struct linux_usb_isodesc*)(void *)(pd + 64);
- } else {
- pisodesc = (struct linux_usb_isodesc*)(void *)(pd + 48);
- }
- iso_numdesc = phdr->s.iso.numdesc;
- for (i = 0; i < iso_numdesc; i++) {
- /* always check if we have enough data from the
- * beginnig of the packet (phdr)
- */
- if (packet_size < END_OFFSETOF(phdr, &pisodesc->iso_status))
- return;
- PBSWAP32((guint8 *)&pisodesc->iso_status);
- if (packet_size < END_OFFSETOF(phdr, &pisodesc->iso_off))
- return;
- PBSWAP32((guint8 *)&pisodesc->iso_off);
- if (packet_size < END_OFFSETOF(phdr, &pisodesc->iso_len))
- return;
- PBSWAP32((guint8 *)&pisodesc->iso_len);
- if (packet_size < END_OFFSETOF(phdr, &pisodesc->_pad))
- return;
- PBSWAP32((guint8 *)&pisodesc->_pad);
-
- pisodesc++;
- }
+ pisodesc++;
}
}
}
@@ -1790,8 +1799,7 @@ pcap_process_pseudo_header(FILE_T fh, int file_type, int wtap_encap,
void
pcap_read_post_process(int file_type, int wtap_encap,
- union wtap_pseudo_header *pseudo_header,
- guint8 *pd, guint packet_size, gboolean bytes_swapped, int fcs_len)
+ struct wtap_pkthdr *phdr, guint8 *pd, gboolean bytes_swapped, int fcs_len)
{
switch (wtap_encap) {
@@ -1803,7 +1811,7 @@ pcap_read_post_process(int file_type, int wtap_encap,
* Guess the traffic type based on the packet
* contents.
*/
- atm_guess_traffic_type(pd, packet_size, pseudo_header);
+ atm_guess_traffic_type(phdr, pd);
} else {
/*
* SunATM.
@@ -1812,24 +1820,23 @@ pcap_read_post_process(int file_type, int wtap_encap,
* type of LANE traffic it is based on the packet
* contents.
*/
- if (pseudo_header->atm.type == TRAF_LANE)
- atm_guess_lane_type(pd, packet_size,
- pseudo_header);
+ if (phdr->pseudo_header.atm.type == TRAF_LANE)
+ atm_guess_lane_type(phdr, pd);
}
break;
case WTAP_ENCAP_ETHERNET:
- pseudo_header->eth.fcs_len = fcs_len;
+ phdr->pseudo_header.eth.fcs_len = fcs_len;
break;
case WTAP_ENCAP_USB_LINUX:
- pcap_process_linux_usb_pseudoheader(packet_size,
- bytes_swapped, FALSE, pd);
+ if (bytes_swapped)
+ pcap_byteswap_linux_usb_pseudoheader(phdr, pd, FALSE);
break;
case WTAP_ENCAP_USB_LINUX_MMAPPED:
- pcap_process_linux_usb_pseudoheader(packet_size,
- bytes_swapped, TRUE, pd);
+ if (bytes_swapped)
+ pcap_byteswap_linux_usb_pseudoheader(phdr, pd, TRUE);
break;
case WTAP_ENCAP_NETANALYZER:
@@ -1838,7 +1845,7 @@ pcap_read_post_process(int file_type, int wtap_encap,
* dissector calls the "Ethernet with FCS"
* dissector, but we might as well set it.
*/
- pseudo_header->eth.fcs_len = 4;
+ phdr->pseudo_header.eth.fcs_len = 4;
break;
default: