forked from osmocom/wireshark
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
This commit is contained in:
parent
c1729024c5
commit
21a210b777
1
AUTHORS
1
AUTHORS
|
@ -2256,6 +2256,7 @@ Chris Maynard <Christopher.Maynard [AT] GTECH.COM> {
|
|||
Add Doxygen comments to the CRC-16 and CRC-32 headers
|
||||
Add support for RFC 2520: NHRP with Mobile NHCs
|
||||
and RFC 2735: NHRP Support for Virtual Private Networks
|
||||
Add support for PPP-over-USB
|
||||
}
|
||||
|
||||
SEKINE Hideki <sekineh [AT] gf7.so-net.ne.jp> {
|
||||
|
|
|
@ -46,8 +46,9 @@
|
|||
#include <epan/crc16.h>
|
||||
#include <epan/crc32.h>
|
||||
#include <epan/ipproto.h>
|
||||
#include "packet-usb.h"
|
||||
|
||||
#define ppp_min(a, b) ((a<b) ? a : b)
|
||||
#define ppp_min(a, b) (((a)<(b)) ? (a) : (b))
|
||||
|
||||
static int proto_ppp = -1;
|
||||
static int hf_ppp_direction = -1;
|
||||
|
@ -3255,7 +3256,7 @@ dissect_lcp_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
}
|
||||
|
||||
/*
|
||||
* RFC 1661.
|
||||
* RFC's 1661, 2153 and 1570.
|
||||
*/
|
||||
static void
|
||||
dissect_lcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
|
@ -4336,6 +4337,50 @@ dissect_ppp_raw_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
|
|||
} /* end while */
|
||||
}
|
||||
|
||||
/*
|
||||
* At least for the PPP/USB captures I've seen, the data either starts with
|
||||
* 0x7eff03 or 0x7eff7d23 or 0xff03, so this function performs that heuristic
|
||||
* matching first before calling dissect_ppp_raw_hdlc(). Otherwise, if we call
|
||||
* it directly for USB captures, some captures like the following will not be
|
||||
* dissected correctly:
|
||||
* http://wiki.wireshark.org/SampleCaptures#head-886e340c31ca977f321c921f81cbec4c21bb7738
|
||||
*
|
||||
* NOTE: I don't know if these heuristics are sufficient. Time will tell ...
|
||||
*/
|
||||
static void
|
||||
dissect_ppp_usb( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
|
||||
{
|
||||
/* In some cases, the 0x03 normally in byte 3 is escaped so we must look for
|
||||
* the 2 byte sequence of 0x7d23 instead of 0x03. The 0x23 is generated by
|
||||
* 0x20^0x03 per section 4.2 of: http://tools.ietf.org/html/rfc1662.html. */
|
||||
const guchar buf1[3] = {0x7e, 0xff, 0x03};
|
||||
const guchar buf2[4] = {0x7e, 0xff, 0x7d, 0x23};
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
if ((tvb_memeql(tvb, 0, buf2, sizeof(buf2)) == 0) ||
|
||||
(tvb_memeql(tvb, 0, buf1, sizeof(buf1)) == 0)) {
|
||||
dissect_ppp_raw_hdlc(tvb, pinfo, tree);
|
||||
}
|
||||
else {
|
||||
/* See if it's missing the 0x7e framing character */
|
||||
if (tvb_memeql(tvb, 0, &buf1[1], 2) == 0) {
|
||||
/* Yup ... what TODO? Should we try faking it by sticking 0x7e in
|
||||
* front? Or try telling dissect_ppp_raw_hdlc() NOT to look for the
|
||||
* 0x7e frame deliminator? Or is this a bug in libpcap (used 1.1.0)?
|
||||
* Or a bug in the Linux kernel (tested with 2.6.24.4) Or a bug in
|
||||
* usbmon? Or is the data we're looking at really just part of the
|
||||
* payload and not control data? Well, at least in my case it's
|
||||
* definitely not, but not sure if this is always the case. Is this
|
||||
* issue applicable only to PPP/USB or PPP/XYZ, in which case a more
|
||||
* general solution should be found?
|
||||
*/
|
||||
/* For now, just try skipping the framing I guess??? */
|
||||
next_tvb = tvb_new_subset_remaining(tvb, 2);
|
||||
dissect_ppp(next_tvb, pinfo, tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
proto_register_ppp_raw_hdlc(void)
|
||||
{
|
||||
|
@ -4351,10 +4396,14 @@ void
|
|||
proto_reg_handoff_ppp_raw_hdlc(void)
|
||||
{
|
||||
dissector_handle_t ppp_raw_hdlc_handle;
|
||||
dissector_handle_t ppp_usb_handle;
|
||||
|
||||
ppp_raw_hdlc_handle = create_dissector_handle(dissect_ppp_raw_hdlc, proto_ppp);
|
||||
dissector_add("gre.proto", ETHERTYPE_CDMA2000_A10_UBS, ppp_raw_hdlc_handle);
|
||||
dissector_add("gre.proto", ETHERTYPE_3GPP2, ppp_raw_hdlc_handle);
|
||||
|
||||
ppp_usb_handle = create_dissector_handle(dissect_ppp_usb, proto_ppp);
|
||||
dissector_add("usb.bulk", IF_CLASS_UNKNOWN, ppp_usb_handle);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
* USB basic dissector
|
||||
* By Paolo Abeni <paolo.abeni@email.it>
|
||||
* Ronnie Sahlberg 2006
|
||||
* Chris Maynard 2010 <chris[dot]maynard[at]gtech[dot]com>
|
||||
*
|
||||
* http://www.usb.org/developers/docs/usb_20_122909-2.zip
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -26,6 +29,7 @@
|
|||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <isprint.h>
|
||||
#include <glib.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/etypes.h>
|
||||
|
@ -49,6 +53,8 @@ static int hf_usb_device_address = -1;
|
|||
static int hf_usb_bus_id = -1;
|
||||
static int hf_usb_setup_flag = -1;
|
||||
static int hf_usb_data_flag = -1;
|
||||
static int hf_usb_urb_ts_sec = -1;
|
||||
static int hf_usb_urb_ts_usec = -1;
|
||||
static int hf_usb_urb_status = -1;
|
||||
static int hf_usb_urb_len = -1;
|
||||
static int hf_usb_data_len = -1;
|
||||
|
@ -131,9 +137,157 @@ static int usb_tap = -1;
|
|||
static dissector_table_t usb_bulk_dissector_table;
|
||||
static dissector_table_t usb_control_dissector_table;
|
||||
|
||||
/* http://www.usb.org/developers/docs/USB_LANGIDs.pdf */
|
||||
static const value_string usb_langid_vals[] = {
|
||||
{0x0000, "no language specified"},
|
||||
{0x0409, "English (United States)"},
|
||||
{0x0000, "no language specified"},
|
||||
{0x0436, "Afrikaans"},
|
||||
{0x041c, "Albanian"},
|
||||
{0x0401, "Arabic (Saudi Arabia)"},
|
||||
{0x0801, "Arabic (Iraq)"},
|
||||
{0x0c01, "Arabic (Egypt)"},
|
||||
{0x1001, "Arabic (Libya)"},
|
||||
{0x1401, "Arabic (Algeria)"},
|
||||
{0x1801, "Arabic (Morocco)"},
|
||||
{0x1c01, "Arabic (Tunisia)"},
|
||||
{0x2001, "Arabic (Oman)"},
|
||||
{0x2401, "Arabic (Yemen)"},
|
||||
{0x2801, "Arabic (Syria)"},
|
||||
{0x2c01, "Arabic (Jordan)"},
|
||||
{0x3001, "Arabic (Lebanon)"},
|
||||
{0x3401, "Arabic (Kuwait)"},
|
||||
{0x3801, "Arabic (U.A.E.)"},
|
||||
{0x3c01, "Arabic (Bahrain)"},
|
||||
{0x4001, "Arabic (Qatar)"},
|
||||
{0x042b, "Armenian"},
|
||||
{0x044d, "Assamese"},
|
||||
{0x042c, "Azeri (Latin)"},
|
||||
{0x082c, "Azeri (Cyrillic)"},
|
||||
{0x042d, "Basque"},
|
||||
{0x0423, "Belarussian"},
|
||||
{0x0445, "Bengali"},
|
||||
{0x0402, "Bulgarian"},
|
||||
{0x0455, "Burmese"},
|
||||
{0x0403, "Catalan"},
|
||||
{0x0404, "Chinese (Taiwan)"},
|
||||
{0x0804, "Chinese (PRC)"},
|
||||
{0x0c04, "Chinese (Hong Kong SAR, PRC)"},
|
||||
{0x1004, "Chinese (Singapore)"},
|
||||
{0x1404, "Chinese (Macau SAR)"},
|
||||
{0x041a, "Croatian"},
|
||||
{0x0405, "Czech"},
|
||||
{0x0406, "Danish"},
|
||||
{0x0413, "Dutch (Netherlands)"},
|
||||
{0x0813, "Dutch (Belgium)"},
|
||||
{0x0409, "English (United States)"},
|
||||
{0x0809, "English (United Kingdom)"},
|
||||
{0x0c09, "English (Australian)"},
|
||||
{0x1009, "English (Canadian)"},
|
||||
{0x1409, "English (New Zealand)"},
|
||||
{0x1809, "English (Ireland)"},
|
||||
{0x1c09, "English (South Africa)"},
|
||||
{0x2009, "English (Jamaica)"},
|
||||
{0x2409, "English (Caribbean)"},
|
||||
{0x2809, "English (Belize)"},
|
||||
{0x2c09, "English (Trinidad)"},
|
||||
{0x3009, "English (Zimbabwe)"},
|
||||
{0x3409, "English (Philippines)"},
|
||||
{0x0425, "Estonian"},
|
||||
{0x0438, "Faeroese"},
|
||||
{0x0429, "Farsi"},
|
||||
{0x040b, "Finnish"},
|
||||
{0x040c, "French (Standard)"},
|
||||
{0x080c, "French (Belgian)"},
|
||||
{0x0c0c, "French (Canadian)"},
|
||||
{0x100c, "French (Switzerland)"},
|
||||
{0x140c, "French (Luxembourg)"},
|
||||
{0x180c, "French (Monaco)"},
|
||||
{0x0437, "Georgian"},
|
||||
{0x0407, "German (Standard)"},
|
||||
{0x0807, "German (Switzerland)"},
|
||||
{0x0c07, "German (Austria)"},
|
||||
{0x1007, "German (Luxembourg)"},
|
||||
{0x1407, "German (Liechtenstein)"},
|
||||
{0x0408, "Greek"},
|
||||
{0x0447, "Gujarati"},
|
||||
{0x040d, "Hebrew"},
|
||||
{0x0439, "Hindi"},
|
||||
{0x040e, "Hungarian"},
|
||||
{0x040f, "Icelandic"},
|
||||
{0x0421, "Indonesian"},
|
||||
{0x0410, "Italian (Standard)"},
|
||||
{0x0810, "Italian (Switzerland)"},
|
||||
{0x0411, "Japanese"},
|
||||
{0x044b, "Kannada"},
|
||||
{0x0860, "Kashmiri (India)"},
|
||||
{0x043f, "Kazakh"},
|
||||
{0x0457, "Konkani"},
|
||||
{0x0412, "Korean"},
|
||||
{0x0812, "Korean (Johab)"},
|
||||
{0x0426, "Latvian"},
|
||||
{0x0427, "Lithuanian"},
|
||||
{0x0827, "Lithuanian (Classic)"},
|
||||
{0x042f, "Macedonian"},
|
||||
{0x043e, "Malay (Malaysian)"},
|
||||
{0x083e, "Malay (Brunei Darussalam)"},
|
||||
{0x044c, "Malayalam"},
|
||||
{0x0458, "Manipuri"},
|
||||
{0x044e, "Marathi"},
|
||||
{0x0861, "Nepali (India)"},
|
||||
{0x0414, "Norwegian (Bokmal)"},
|
||||
{0x0814, "Norwegian (Nynorsk)"},
|
||||
{0x0448, "Oriya"},
|
||||
{0x0415, "Polish"},
|
||||
{0x0416, "Portuguese (Brazil)"},
|
||||
{0x0816, "Portuguese (Standard)"},
|
||||
{0x0446, "Punjabi"},
|
||||
{0x0418, "Romanian"},
|
||||
{0x0419, "Russian"},
|
||||
{0x044f, "Sanskrit"},
|
||||
{0x0c1a, "Serbian (Cyrillic)"},
|
||||
{0x081a, "Serbian (Latin)"},
|
||||
{0x0459, "Sindhi"},
|
||||
{0x041b, "Slovak"},
|
||||
{0x0424, "Slovenian"},
|
||||
{0x040a, "Spanish (Traditional Sort)"},
|
||||
{0x080a, "Spanish (Mexican)"},
|
||||
{0x0c0a, "Spanish (Modern Sort)"},
|
||||
{0x100a, "Spanish (Guatemala)"},
|
||||
{0x140a, "Spanish (Costa Rica)"},
|
||||
{0x180a, "Spanish (Panama)"},
|
||||
{0x1c0a, "Spanish (Dominican Republic)"},
|
||||
{0x200a, "Spanish (Venezuela)"},
|
||||
{0x240a, "Spanish (Colombia)"},
|
||||
{0x280a, "Spanish (Peru)"},
|
||||
{0x2c0a, "Spanish (Argentina)"},
|
||||
{0x300a, "Spanish (Ecuador)"},
|
||||
{0x340a, "Spanish (Chile)"},
|
||||
{0x380a, "Spanish (Uruguay)"},
|
||||
{0x3c0a, "Spanish (Paraguay)"},
|
||||
{0x400a, "Spanish (Bolivia)"},
|
||||
{0x440a, "Spanish (El Salvador)"},
|
||||
{0x480a, "Spanish (Honduras)"},
|
||||
{0x4c0a, "Spanish (Nicaragua)"},
|
||||
{0x500a, "Spanish (Puerto Rico)"},
|
||||
{0x0430, "Sutu"},
|
||||
{0x0441, "Swahili (Kenya)"},
|
||||
{0x041d, "Swedish"},
|
||||
{0x081d, "Swedish (Finland)"},
|
||||
{0x0449, "Tamil"},
|
||||
{0x0444, "Tatar (Tatarstan)"},
|
||||
{0x044a, "Telugu"},
|
||||
{0x041e, "Thai"},
|
||||
{0x041f, "Turkish"},
|
||||
{0x0422, "Ukrainian"},
|
||||
{0x0420, "Urdu (Pakistan)"},
|
||||
{0x0820, "Urdu (India)"},
|
||||
{0x0443, "Uzbek (Latin)"},
|
||||
{0x0843, "Uzbek (Cyrillic)"},
|
||||
{0x042a, "Vietnamese"},
|
||||
{0x04ff, "HID (Usage Data Descriptor)"},
|
||||
{0xf0ff, "HID (Vendor Defined 1)"},
|
||||
{0xf4ff, "HID (Vendor Defined 2)"},
|
||||
{0xf8ff, "HID (Vendor Defined 3)"},
|
||||
{0xfcff, "HID (Vendor Defined 4)"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
@ -979,7 +1133,7 @@ dissect_usb_endpoint_descriptor(packet_info *pinfo, proto_tree *parent_tree, tvb
|
|||
/* bmAttributes */
|
||||
if (tree) {
|
||||
ep_attrib_item=proto_tree_add_item(tree, hf_usb_bmAttributes, tvb, offset, 1, TRUE);
|
||||
ep_attrib_tree=proto_item_add_subtree(ep_attrib_item, ett_endpoint_bmAttributes);
|
||||
ep_attrib_tree=proto_item_add_subtree(ep_attrib_item, ett_endpoint_bmAttributes);
|
||||
}
|
||||
proto_tree_add_item(ep_attrib_tree, hf_usb_bEndpointAttributeTransfer, tvb, offset, 1, TRUE);
|
||||
/* isochronous only */
|
||||
|
@ -1192,6 +1346,8 @@ static int
|
|||
dissect_usb_setup_get_descriptor_response(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, usb_trans_info_t *usb_trans_info, usb_conv_info_t *usb_conv_info)
|
||||
{
|
||||
proto_item *item=NULL;
|
||||
guint32 data_len;
|
||||
|
||||
if (check_col(pinfo->cinfo, COL_INFO)) {
|
||||
col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
|
||||
val_to_str(usb_trans_info->u.get_descriptor.type, descriptor_type_vals, "Unknown type %u"));
|
||||
|
@ -1225,8 +1381,9 @@ dissect_usb_setup_get_descriptor_response(packet_info *pinfo, proto_tree *tree,
|
|||
/* XXX dissect the descriptor coming back from the device */
|
||||
item=proto_tree_add_text(tree, tvb, offset, -1, "GET DESCRIPTOR data (unknown descriptor type)");
|
||||
tree=proto_item_add_subtree(item, ett_descriptor_device);
|
||||
proto_tree_add_item(tree, hf_usb_data, tvb, offset, pinfo->pseudo_header->linux_usb.data_len, FALSE);
|
||||
offset += pinfo->pseudo_header->linux_usb.data_len;
|
||||
tvb_memcpy(tvb, (guint8 *)&data_len, offset, 4);
|
||||
proto_tree_add_uint(tree, hf_usb_data, tvb, offset, 4, data_len);
|
||||
offset += data_len;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1537,8 +1694,8 @@ static const value_string setup_request_names_vals[] = {
|
|||
|
||||
|
||||
static const true_false_string tfs_bmrequesttype_direction = {
|
||||
"Device-to-host",
|
||||
"Host-to-device"
|
||||
"Device-to-host",
|
||||
"Host-to-device"
|
||||
};
|
||||
|
||||
static const value_string bmrequesttype_type_vals[] = {
|
||||
|
@ -1560,106 +1717,94 @@ static int
|
|||
dissect_usb_bmrequesttype(proto_tree *parent_tree, tvbuff_t *tvb, int offset,
|
||||
int *type)
|
||||
{
|
||||
proto_item *item=NULL;
|
||||
proto_tree *tree=NULL;
|
||||
guint8 bmRequestType;
|
||||
proto_item *item=NULL;
|
||||
proto_tree *tree=NULL;
|
||||
|
||||
if(parent_tree){
|
||||
item=proto_tree_add_item(parent_tree, hf_usb_bmRequestType, tvb, offset, 1, TRUE);
|
||||
tree = proto_item_add_subtree(item, ett_usb_setup_bmrequesttype);
|
||||
}
|
||||
if(parent_tree){
|
||||
item=proto_tree_add_item(parent_tree, hf_usb_bmRequestType, tvb, offset, 1, TRUE);
|
||||
tree = proto_item_add_subtree(item, ett_usb_setup_bmrequesttype);
|
||||
}
|
||||
|
||||
bmRequestType = tvb_get_guint8(tvb, offset);
|
||||
*type = (bmRequestType & USB_TYPE_MASK) >>5;
|
||||
proto_tree_add_item(tree, hf_usb_bmRequestType_direction, tvb, offset, 1, TRUE);
|
||||
proto_tree_add_item(tree, hf_usb_bmRequestType_type, tvb, offset, 1, TRUE);
|
||||
proto_tree_add_item(tree, hf_usb_bmRequestType_recipient, tvb, offset, 1, TRUE);
|
||||
*type = USB_TYPE(tvb_get_guint8(tvb, offset));
|
||||
proto_tree_add_item(tree, hf_usb_bmRequestType_direction, tvb, offset, 1, TRUE);
|
||||
proto_tree_add_item(tree, hf_usb_bmRequestType_type, tvb, offset, 1, TRUE);
|
||||
proto_tree_add_item(tree, hf_usb_bmRequestType_recipient, tvb, offset, 1, TRUE);
|
||||
|
||||
offset++;
|
||||
return offset;
|
||||
return ++offset;
|
||||
}
|
||||
|
||||
/* Adds the Linux USB pseudo header fields to the tree.
|
||||
* NOTE: The multi-byte fields in this header (and only this header) are in
|
||||
* host-endian format so we can't use proto_tree_add_item() nor the
|
||||
* tvb_get_xyz() routines and is the reason for the tvb_memcpy() and
|
||||
* proto_tree_add_uint[64]() pairs below. */
|
||||
static void
|
||||
dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
guint8 transfer_type;
|
||||
const gchar* val_str;
|
||||
guint8 type, flag;
|
||||
guint16 val16;
|
||||
guint32 val32;
|
||||
guint64 val64;
|
||||
|
||||
proto_tree_add_uint64(tree, hf_usb_urb_id, tvb, 0, 0,
|
||||
pinfo->pseudo_header->linux_usb.id);
|
||||
tvb_memcpy(tvb, (guint8 *)&val64, 0, 8);
|
||||
proto_tree_add_uint64(tree, hf_usb_urb_id, tvb, 0, 8, val64);
|
||||
|
||||
/* show the event type of this URB as string and as a character */
|
||||
val_str = val_to_str(pinfo->pseudo_header->linux_usb.event_type,
|
||||
usb_urb_type_vals, "Unknown %d");
|
||||
proto_tree_add_string_format_value(tree, hf_usb_urb_type, tvb, 0, 0,
|
||||
&(pinfo->pseudo_header->linux_usb.event_type),
|
||||
"%s ('%c')", val_str,
|
||||
pinfo->pseudo_header->linux_usb.event_type);
|
||||
|
||||
transfer_type = pinfo->pseudo_header->linux_usb.transfer_type;
|
||||
proto_tree_add_uint(tree, hf_usb_transfer_type, tvb, 0, 0, transfer_type);
|
||||
type = tvb_get_guint8(tvb, 8);
|
||||
val_str = val_to_str(type, usb_urb_type_vals, "Unknown %d");
|
||||
proto_tree_add_string_format_value(tree, hf_usb_urb_type, tvb, 8, 1,
|
||||
&type, "%s ('%c')", val_str, isprint(type) ? type : '.');
|
||||
|
||||
proto_tree_add_item(tree, hf_usb_transfer_type, tvb, 9, 1, FALSE);
|
||||
|
||||
if (check_col(pinfo->cinfo, COL_INFO)) {
|
||||
transfer_type = tvb_get_guint8(tvb, 9);
|
||||
col_append_str(pinfo->cinfo, COL_INFO,
|
||||
val_to_str(transfer_type, usb_transfer_type_vals, "Unknown type %x"));
|
||||
}
|
||||
|
||||
proto_tree_add_uint(tree, hf_usb_endpoint_number, tvb, 0, 0,
|
||||
pinfo->pseudo_header->linux_usb.endpoint_number);
|
||||
proto_tree_add_item(tree, hf_usb_endpoint_number, tvb, 10, 1, FALSE);
|
||||
proto_tree_add_item(tree, hf_usb_device_address, tvb, 11, 1, FALSE);
|
||||
|
||||
proto_tree_add_uint(tree, hf_usb_device_address, tvb, 0, 0,
|
||||
pinfo->pseudo_header->linux_usb.device_address);
|
||||
|
||||
proto_tree_add_uint(tree, hf_usb_bus_id, tvb, 0, 0,
|
||||
pinfo->pseudo_header->linux_usb.bus_id);
|
||||
tvb_memcpy(tvb, (guint8 *)&val16, 12, 2);
|
||||
proto_tree_add_uint(tree, hf_usb_bus_id, tvb, 12, 2, val16);
|
||||
|
||||
/* Right after the pseudo header we always have
|
||||
* sizeof(struct usb_device_setup_hdr)=8 bytes. The content of these
|
||||
* bytes have only meaning in case setup_flag == 0.
|
||||
* sizeof(struct usb_device_setup_hdr) bytes. The content of these
|
||||
* bytes only have meaning in case setup_flag == 0.
|
||||
*/
|
||||
if (pinfo->pseudo_header->linux_usb.setup_flag == 0) {
|
||||
proto_tree_add_string_format_value(tree, hf_usb_setup_flag, tvb,
|
||||
0, 0,
|
||||
&(pinfo->pseudo_header->linux_usb.setup_flag),
|
||||
"present (%d)",
|
||||
pinfo->pseudo_header->linux_usb.setup_flag);
|
||||
flag = tvb_get_guint8(tvb, 14);
|
||||
if (flag == 0) {
|
||||
proto_tree_add_string(tree, hf_usb_setup_flag, tvb, 14, 1, "relevant (0)");
|
||||
} else {
|
||||
proto_tree_add_string_format_value(tree, hf_usb_setup_flag, tvb,
|
||||
0, 0,
|
||||
&(pinfo->pseudo_header->linux_usb.setup_flag),
|
||||
"not present ('%c')",
|
||||
pinfo->pseudo_header->linux_usb.setup_flag);
|
||||
14, 1, &flag, "not relevant ('%c')", isprint(flag) ? flag: '.');
|
||||
}
|
||||
|
||||
if (pinfo->pseudo_header->linux_usb.data_flag == 0) {
|
||||
proto_tree_add_string_format_value(tree, hf_usb_data_flag, tvb,
|
||||
0, 0,
|
||||
&(pinfo->pseudo_header->linux_usb.data_flag),
|
||||
"present (%d)",
|
||||
pinfo->pseudo_header->linux_usb.data_flag);
|
||||
flag = tvb_get_guint8(tvb, 15);
|
||||
if (flag == 0) {
|
||||
proto_tree_add_string(tree, hf_usb_data_flag, tvb, 15, 1, "present (0)");
|
||||
} else {
|
||||
proto_tree_add_string_format_value(tree, hf_usb_data_flag, tvb,
|
||||
0, 0,
|
||||
&(pinfo->pseudo_header->linux_usb.data_flag),
|
||||
"not present ('%c')",
|
||||
pinfo->pseudo_header->linux_usb.data_flag);
|
||||
15, 1, &flag, "not present ('%c')", isprint(flag) ? flag : '.');
|
||||
}
|
||||
|
||||
/* Timestamp was already processed by libpcap,
|
||||
* skip it for now:
|
||||
* pinfo->pseudo_header->linux_usb.ts_sec
|
||||
* pinfo->pseudo_header->linux_usb.ts_usec
|
||||
*/
|
||||
tvb_memcpy(tvb, (guint8 *)&val64, 16, 8);
|
||||
proto_tree_add_uint64(tree, hf_usb_urb_ts_sec, tvb, 16, 8, val64);
|
||||
|
||||
tvb_memcpy(tvb, (guint8 *)&val32, 24, 4);
|
||||
proto_tree_add_uint(tree, hf_usb_urb_ts_usec, tvb, 24, 4, val32);
|
||||
|
||||
proto_tree_add_int(tree, hf_usb_urb_status, tvb, 0, 0,
|
||||
pinfo->pseudo_header->linux_usb.status);
|
||||
tvb_memcpy(tvb, (guint8 *)&val32, 28, 4);
|
||||
proto_tree_add_int(tree, hf_usb_urb_status, tvb, 28, 4, val32);
|
||||
|
||||
proto_tree_add_uint(tree, hf_usb_urb_len, tvb, 0, 0,
|
||||
pinfo->pseudo_header->linux_usb.urb_len);
|
||||
|
||||
proto_tree_add_uint(tree, hf_usb_data_len, tvb, 0, 0,
|
||||
pinfo->pseudo_header->linux_usb.data_len);
|
||||
tvb_memcpy(tvb, (guint8 *)&val32, 32, 4);
|
||||
proto_tree_add_uint(tree, hf_usb_urb_len, tvb, 32, 4, val32);
|
||||
|
||||
tvb_memcpy(tvb, (guint8 *)&val32, 36, 4);
|
||||
proto_tree_add_uint(tree, hf_usb_data_len, tvb, 36, 4, val32);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1684,21 +1829,18 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
/* add usb hdr*/
|
||||
if (parent) {
|
||||
proto_item *ti = NULL;
|
||||
ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0, sizeof(struct usb_device_setup_hdr), "USB URB");
|
||||
|
||||
ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0,
|
||||
sizeof(struct linux_usb_phdr) + sizeof(struct usb_device_setup_hdr), "USB URB");
|
||||
tree = proto_item_add_subtree(ti, usb_hdr);
|
||||
}
|
||||
|
||||
dissect_linux_usb_pseudo_header(tvb, pinfo, tree);
|
||||
|
||||
type = pinfo->pseudo_header->linux_usb.transfer_type;
|
||||
|
||||
endpoint = pinfo->pseudo_header->linux_usb.endpoint_number & (~URB_TRANSFER_IN);
|
||||
|
||||
tmp_addr = pinfo->pseudo_header->linux_usb.device_address;
|
||||
setup_flag = pinfo->pseudo_header->linux_usb.setup_flag;
|
||||
|
||||
is_request = (pinfo->pseudo_header->linux_usb.event_type == URB_SUBMIT) ? TRUE : FALSE;
|
||||
dissect_linux_usb_pseudo_header(tvb, pinfo, tree);
|
||||
is_request = (tvb_get_guint8(tvb, 8) == URB_SUBMIT) ? TRUE : FALSE;
|
||||
type = tvb_get_guint8(tvb, 9);
|
||||
endpoint = tvb_get_guint8(tvb, 10) & (~URB_TRANSFER_IN);
|
||||
tmp_addr = tvb_get_guint8(tvb, 11);
|
||||
setup_flag = tvb_get_guint8(tvb, 14);
|
||||
offset += sizeof(struct linux_usb_phdr); /* skip pseudo header */
|
||||
|
||||
/* Set up addresses and ports. */
|
||||
if (is_request) {
|
||||
|
@ -1775,7 +1917,7 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
}
|
||||
|
||||
tap_data=ep_alloc(sizeof(usb_tap_data_t));
|
||||
tap_data->urb_type=(guint8)pinfo->pseudo_header->linux_usb.event_type;
|
||||
tap_data->urb_type=tvb_get_guint8(tvb, 8);
|
||||
tap_data->transfer_type=(guint8)type;
|
||||
tap_data->conv_info=usb_conv_info;
|
||||
tap_data->trans_info=usb_trans_info;
|
||||
|
@ -1790,22 +1932,16 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
item=proto_tree_add_uint(tree, hf_usb_bInterfaceClass, tvb, 0, 0, usb_conv_info->interfaceClass);
|
||||
PROTO_ITEM_SET_GENERATED(item);
|
||||
|
||||
/* Skip setup header - it's never present */
|
||||
offset += 8;
|
||||
/* Skip setup header - it's not applicable */
|
||||
offset += sizeof(struct usb_device_setup_hdr);
|
||||
|
||||
/*
|
||||
* If this is padded (as is the case if the capture is done in
|
||||
* memory-mapped mode), skip the padding; it's padded to a multiple
|
||||
* of 64 bits *after* the pseudo-header and setup header. The
|
||||
* pseudo-header is 40 bytes, and the setup header is 8 bytes,
|
||||
* so that's 16 bytes of padding to 64 bytes. (The pseudo-header
|
||||
* was removed from the packet data by Wiretap, so the offset
|
||||
* is relative to the beginning of the setup header, not relative
|
||||
* to the beginning of the raw packet data, so we can't just
|
||||
* round it up to a multiple of 64.)
|
||||
* of 64 bits *after* the pseudo-header and setup header.
|
||||
*/
|
||||
if (padded)
|
||||
offset += 16;
|
||||
offset += (64 - ((sizeof(struct linux_usb_phdr) + sizeof(struct usb_device_setup_hdr)) % 64)) % 64;
|
||||
|
||||
if(tvb_reported_length_remaining(tvb, offset)){
|
||||
tvbuff_t *next_tvb;
|
||||
|
@ -1836,7 +1972,7 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
|
||||
/* this is a request */
|
||||
|
||||
/* Dissect the setup header - it's present */
|
||||
/* Dissect the setup header - it's applicable */
|
||||
|
||||
ti = proto_tree_add_protocol_format(tree, proto_usb, tvb, offset, sizeof(struct usb_device_setup_hdr), "URB setup");
|
||||
setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
|
||||
|
@ -1857,7 +1993,7 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
* dissector
|
||||
*/
|
||||
proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, TRUE);
|
||||
offset += 1;
|
||||
offset++;
|
||||
|
||||
if (check_col(pinfo->cinfo, COL_INFO)) {
|
||||
col_add_fstr(pinfo->cinfo, COL_INFO, "%s Request",
|
||||
|
@ -1887,18 +2023,10 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
* If this is padded (as is the case if the capture
|
||||
* is done in memory-mapped mode), skip the padding;
|
||||
* it's padded to a multiple of 64 bits *after* the
|
||||
* pseudo-header and setup header. The pseudo-header
|
||||
* is 40 bytes, and the setup header is 8 bytes, so
|
||||
* that's 16 bytes of padding to 64 bytes. (The
|
||||
* pseudo-header was removed from the packet data by
|
||||
* Wiretap, so the offset is relative to the beginning
|
||||
* of the setup header, not relative to the beginning
|
||||
* of the raw packet data, so we can't just round it up
|
||||
* to a multiple of 64.)
|
||||
* pseudo-header and setup header.
|
||||
*/
|
||||
if (padded)
|
||||
offset += 16;
|
||||
|
||||
offset += (64 - ((sizeof(struct linux_usb_phdr) + sizeof(struct usb_device_setup_hdr)) % 64)) % 64;
|
||||
break;
|
||||
|
||||
case RQT_SETUP_TYPE_CLASS:
|
||||
|
@ -1909,7 +2037,7 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
}
|
||||
/* Else no class dissector, just display generic fields */
|
||||
proto_tree_add_item(setup_tree, hf_usb_request_unknown_class, tvb, offset, 1, TRUE);
|
||||
offset += 1;
|
||||
offset++;
|
||||
proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, TRUE);
|
||||
offset += 2;
|
||||
proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, TRUE);
|
||||
|
@ -1917,9 +2045,10 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
proto_tree_add_item(setup_tree, hf_usb_length, tvb, offset, 2, TRUE);
|
||||
offset += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
proto_tree_add_item(setup_tree, hf_usb_request_unknown_class, tvb, offset, 1, TRUE);
|
||||
offset += 1;
|
||||
offset++;
|
||||
proto_tree_add_item(setup_tree, hf_usb_value, tvb, offset, 2, TRUE);
|
||||
offset += 2;
|
||||
proto_tree_add_item(setup_tree, hf_usb_index, tvb, offset, 2, TRUE);
|
||||
|
@ -1928,46 +2057,33 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
offset += 2;
|
||||
}
|
||||
} else {
|
||||
/* Skip setup header - it's not present */
|
||||
|
||||
offset += 8;
|
||||
/* Skip setup header - it's not applicable */
|
||||
offset += sizeof(struct usb_device_setup_hdr);
|
||||
|
||||
/*
|
||||
* If this is padded (as is the case if the capture is done
|
||||
* in memory-mapped mode), skip the padding; it's padded to
|
||||
* a multiple of 64 bits *after* the pseudo-header and setup
|
||||
* header. The pseudo-header is 40 bytes, and the setup
|
||||
* header is 8 bytes, so that's 16 bytes of padding to 64
|
||||
* bytes. (The pseudo-header was removed from the packet
|
||||
* data by Wiretap, so the offset is relative to the beginning
|
||||
* of the setup header, not relative to the beginning of the
|
||||
* raw packet data, so we can't just round it up to a multiple
|
||||
* of 64.)
|
||||
* header.
|
||||
*/
|
||||
if (padded)
|
||||
offset += 16;
|
||||
offset += (64 - ((sizeof(struct linux_usb_phdr) + sizeof(struct usb_device_setup_hdr)) % 64)) % 64;
|
||||
}
|
||||
} else {
|
||||
tvbuff_t *next_tvb;
|
||||
|
||||
/* this is a response */
|
||||
|
||||
/* Skip setup header - it's never present for responses */
|
||||
offset += 8;
|
||||
/* Skip setup header - it's never applicable for responses */
|
||||
offset += sizeof(struct usb_device_setup_hdr);
|
||||
|
||||
/*
|
||||
* If this is padded (as is the case if the capture is done in
|
||||
* memory-mapped mode), skip the padding; it's padded to a multiple
|
||||
* of 64 bits *after* the pseudo-header and setup header. The
|
||||
* pseudo-header is 40 bytes, and the setup header is 8 bytes,
|
||||
* so that's 16 bytes of padding to 64 bytes. (The pseudo-header
|
||||
* was removed from the packet data by Wiretap, so the offset
|
||||
* is relative to the beginning of the setup header, not relative
|
||||
* to the beginning of the raw packet data, so we can't just
|
||||
* round it up to a multiple of 64.)
|
||||
* of 64 bits *after* the pseudo-header and setup header.
|
||||
*/
|
||||
if (padded)
|
||||
offset += 16;
|
||||
offset += (64 - ((sizeof(struct linux_usb_phdr) + sizeof(struct usb_device_setup_hdr)) % 64)) % 64;
|
||||
|
||||
if(usb_trans_info){
|
||||
/* Try to find a class specific dissector */
|
||||
|
@ -1976,7 +2092,7 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
return;
|
||||
}
|
||||
|
||||
type_2 = (usb_trans_info->requesttype & USB_TYPE_MASK) >>5;
|
||||
type_2 = USB_TYPE(usb_trans_info->requesttype);
|
||||
switch (type_2) {
|
||||
|
||||
case RQT_SETUP_TYPE_STANDARD:
|
||||
|
@ -2028,22 +2144,16 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
if (setup_flag == 0) {
|
||||
proto_item *ti = NULL;
|
||||
proto_tree *setup_tree = NULL;
|
||||
guint8 requesttype, request;
|
||||
int type_2;
|
||||
|
||||
/* Dissect the setup header - it's present */
|
||||
/* Dissect the setup header - it's applicable */
|
||||
|
||||
ti = proto_tree_add_protocol_format(tree, proto_usb, tvb, offset, sizeof(struct usb_device_setup_hdr), "URB setup");
|
||||
setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
|
||||
|
||||
|
||||
requesttype=tvb_get_guint8(tvb, offset);
|
||||
offset=dissect_usb_bmrequesttype(setup_tree, tvb, offset, &type_2);
|
||||
|
||||
request=tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_item(setup_tree, hf_usb_request, tvb, offset, 1, TRUE);
|
||||
offset += 1;
|
||||
|
||||
offset++;
|
||||
proto_tree_add_item(tree, hf_usb_value, tvb, offset, 2, TRUE);
|
||||
offset += 2;
|
||||
proto_tree_add_item(tree, hf_usb_index, tvb, offset, 2, TRUE);
|
||||
|
@ -2051,25 +2161,17 @@ dissect_linux_usb_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent,
|
|||
proto_tree_add_item(tree, hf_usb_length, tvb, offset, 2, TRUE);
|
||||
offset += 2;
|
||||
} else {
|
||||
/* Skip setup header - it's not present */
|
||||
|
||||
offset += 8;
|
||||
/* Skip setup header - it's not applicable */
|
||||
offset += sizeof(struct usb_device_setup_hdr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is padded (as is the case if the capture is done in
|
||||
* memory-mapped mode), skip the padding; it's padded to a multiple
|
||||
* of 64 bits *after* the pseudo-header and setup header. The
|
||||
* pseudo-header is 40 bytes, and the setup header is 8 bytes,
|
||||
* so that's 16 bytes of padding to 64 bytes. (The pseudo-header
|
||||
* was removed from the packet data by Wiretap, so the offset
|
||||
* is relative to the beginning of the setup header, not relative
|
||||
* to the beginning of the raw packet data, so we can't just
|
||||
* round it up to a multiple of 64.)
|
||||
* of 64 bits *after* the pseudo-header and setup header.
|
||||
*/
|
||||
if (padded)
|
||||
offset += 16;
|
||||
|
||||
offset += (64 - ((sizeof(struct linux_usb_phdr) + sizeof(struct usb_device_setup_hdr)) % 64)) % 64;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2128,13 +2230,23 @@ proto_register_usb(void)
|
|||
{ &hf_usb_setup_flag,
|
||||
{ "Device setup request", "usb.setup_flag", FT_STRING, BASE_NONE,
|
||||
NULL, 0x0,
|
||||
"USB device setup request is present (0) or not", HFILL }},
|
||||
"USB device setup request is relevant (0) or not", HFILL }},
|
||||
|
||||
{ &hf_usb_data_flag,
|
||||
{ "Data", "usb.data_flag", FT_STRING, BASE_NONE,
|
||||
NULL, 0x0,
|
||||
"USB data is present (0) or not", HFILL }},
|
||||
|
||||
{ &hf_usb_urb_ts_sec,
|
||||
{ "URB sec", "usb.urb_ts_sec", FT_UINT64, BASE_DEC,
|
||||
NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_usb_urb_ts_usec,
|
||||
{ "URB usec", "usb.urb_ts_usec", FT_UINT32, BASE_DEC,
|
||||
NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_usb_urb_status,
|
||||
{ "URB status", "usb.urb_status", FT_INT32, BASE_DEC,
|
||||
VALS(usb_urb_status_vals), 0x0,
|
||||
|
@ -2185,19 +2297,19 @@ proto_register_usb(void)
|
|||
|
||||
{ &hf_usb_wFeatureSelector,
|
||||
{ "wFeatureSelector", "usb.setup.wFeatureSelector", FT_UINT16, BASE_DEC,
|
||||
VALS(usb_feature_selector_vals), 0x0, NULL, HFILL }},
|
||||
VALS(usb_feature_selector_vals), 0x0, NULL, HFILL }},
|
||||
|
||||
{ &hf_usb_wInterface,
|
||||
{ "wInterface", "usb.setup.wInterface", FT_UINT16, BASE_DEC,
|
||||
NULL, 0x0, NULL, HFILL }},
|
||||
NULL, 0x0, NULL, HFILL }},
|
||||
|
||||
{ &hf_usb_wStatus,
|
||||
{ "wStatus", "usb.setup.wStatus", FT_UINT16, BASE_HEX,
|
||||
NULL, 0x0, NULL, HFILL }},
|
||||
NULL, 0x0, NULL, HFILL }},
|
||||
|
||||
{ &hf_usb_wFrameNumber,
|
||||
{ "wFrameNumber", "usb.setup.wFrameNumber", FT_UINT16, BASE_DEC,
|
||||
NULL, 0x0, NULL, HFILL }},
|
||||
NULL, 0x0, NULL, HFILL }},
|
||||
|
||||
/* --------------------------------- */
|
||||
{ &hf_usb_data,
|
||||
|
@ -2394,18 +2506,17 @@ proto_register_usb(void)
|
|||
{ "Direction", "usb.bEndpointAddress.direction", FT_BOOLEAN, 8,
|
||||
TFS(&tfs_endpoint_direction), 0x80, NULL, HFILL }},
|
||||
|
||||
{ &hf_usb_request_in,
|
||||
{ "Request in", "usb.request_in", FT_FRAMENUM, BASE_NONE,
|
||||
NULL, 0, "The request to this packet is in this packet", HFILL }},
|
||||
{ &hf_usb_request_in,
|
||||
{ "Request in", "usb.request_in", FT_FRAMENUM, BASE_NONE,
|
||||
NULL, 0, "The request to this packet is in this packet", HFILL }},
|
||||
|
||||
{ &hf_usb_time,
|
||||
{ "Time from request", "usb.time", FT_RELATIVE_TIME, BASE_NONE,
|
||||
NULL, 0, "Time between Request and Response for USB cmds", HFILL }},
|
||||
|
||||
{ &hf_usb_response_in,
|
||||
{ "Response in", "usb.response_in", FT_FRAMENUM, BASE_NONE,
|
||||
NULL, 0, "The response to this packet is in this packet", HFILL }},
|
||||
{ &hf_usb_time,
|
||||
{ "Time from request", "usb.time", FT_RELATIVE_TIME, BASE_NONE,
|
||||
NULL, 0, "Time between Request and Response for USB cmds", HFILL }},
|
||||
|
||||
{ &hf_usb_response_in,
|
||||
{ "Response in", "usb.response_in", FT_FRAMENUM, BASE_NONE,
|
||||
NULL, 0, "The response to this packet is in this packet", HFILL }},
|
||||
};
|
||||
|
||||
static gint *usb_subtrees[] = {
|
||||
|
|
|
@ -106,6 +106,7 @@ typedef struct _usb_tap_data_t {
|
|||
#define USB_DIR_IN 0x80 /* to host */
|
||||
|
||||
#define USB_TYPE_MASK (0x03 << 5)
|
||||
#define USB_TYPE(type) (((type) & USB_TYPE_MASK) >> 5)
|
||||
#define RQT_SETUP_TYPE_STANDARD 0
|
||||
#define RQT_SETUP_TYPE_CLASS 1
|
||||
#define RQT_SETUP_TYPE_VENDOR 2
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
return TRUE;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue