WireShark是个非常不错的工具,现在的版本已经集成了测试USB抓包的工具USBPcap,该工具官网在,
https://desowin.org/usbpcap/
抓包的格式在这里有说明
https://desowin.org/usbpcap/captureformat.html
具体内容我附在后面,方便查找。
重点要注意的是,USBPcap pseudoheader(伪头)不属于发送内容部分,是USBPcap控制程序的部分,这个Pseudoheader后面的部分,才是真正要发送或接收到的内容。这也是很多人刚开始抓包的时候,主要让人迷糊的地方。
例子如下,
这个例子里面,USB URB 就是这个Pseudoheader,占0x1C=28个字节,后面的80060001 00001200才是真正发送的内容,也就是URB setup。
同样,下面这个例子里面,
前面28个字节也是Pesudoheader,不属于发送内容(称之为控制相关信息是否更恰当?),真正从USB-device接收到的内容是后在的18个字节。这个内容就不解释了,USB规范2.0表(Table 9-8. Standard Device Descriptor)中已有详细规定,下载地址在这里,
https://usb.org/sites/default/files/usb_20_20190524.zip
如果你对这些包的内容的发送与解析感兴趣,建议参考
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-control-transfer
例如TOKEN PACKET的格式是这样的,
注意:(1) 一般(如HANDSHAKE PACKET/TOKEN PACKET/DATA PACKET)的包中的某些信息SYN/PID/EOP等等信息,一般情况下在硬件底层会自动处理掉,不会涉及到操作系统的层次,在我们用单片机编程时,一般也不会涉及。
(2) USB的传输方式(USB transfer types)有四种类型:bulk, isochronous, interrupt, control, 相关知识点太多,这里就不展开了,图文并茂的解释大致如下图所示,
https://desowin.org/usbpcap/captureformat.html
Following document describes the LINKTYPE_USBPCAP used in USBPcap. This merely describes the packet data mentioned in pcap file format.
General notesThe types presented below are described in Windows DDK 7.1.0. Short description:
-
UCHAR - 8 bit unsigned value
-
USHORT - 16 bit unsigned value
-
UINT32 - 32 bit unsigned value
-
UINT64 - 64 bit unsigned value
-
ULONG - 64 bit unsigned value
-
USBD_STATUS - 32 bit unsigned value
All multi-byte values are LITTLE-ENDIAN.
Base packet headerThe USBPCAP_BUFFER_PACKET_HEADER as defined in USBPcapBuffer.h:
#pragma pack(1)
typedef struct
{
USHORT headerLen; /* This header length */
UINT64 irpId; /* I/O Request packet ID */
USBD_STATUS status; /* USB status code
(on return from host controller) */
USHORT function; /* URB Function */
UCHAR info; /* I/O Request info */
USHORT bus; /* bus (RootHub) number */
USHORT device; /* device address */
UCHAR endpoint; /* endpoint number and transfer direction */
UCHAR transfer; /* transfer type */
UINT32 dataLength;/* Data length */
} USBPCAP_BUFFER_PACKET_HEADER, *PUSBPCAP_BUFFER_PACKET_HEADER;
-
headerLen (offset 0) describes the total length, in bytes, of the header (including all transfer-specific header data).
-
irpId (offset 2) is merely a pointer to IRP casted to the UINT64. This value can be used to match the request with respons.
-
status (offset 10) is valid only on return from host-controller. This field corrensponds to the Status member of _URB_HEADER
-
function (offset 14) corrensponds to the Function member of _URB_HEADER
-
info (offset 16) is descibed on the bit-field basis. Currently only the least significant bit (USBPCAP_INFO_PDO_TO_FDO) is defined: it is 0 when IRP goes from FDO to PDO, 1 the other way round. The remaining bits are reserved and must be set to 0.
-
bus (offset 17) is the root hub identifier used to distingush between multiple root hubs.
-
device (offset 19) is USB device number. This field is, contary to the USB specification, 16-bit because the Windows uses 16-bits value for that matter. Check DeviceAddress field of USB_NODE_CONNECTION_INFORMATION
-
endpoint (offset 21) is the endpoint number used on the USB bus (the MSB describes transfer direction)
-
transfer (offset 22) determines the transfer type and thus the header type. See below for details.
-
dataLength (offset 23) specifies the total length of transfer data to follow directly after the header (at offset headerLen).
All transfer-specific headers inherit the USBPCAP_BUFFER_PACKET_HEADER, so first there is the USBPCAP_BUFFER_PACKET_HEADER, then (if any) additional transfer-specific header data and then the transfer data.
USBPCAP_TRANSFER_ISOCHRONOUSWhen transfer is equal to USBPCAP_TRANSFER_ISOCHRONOUS (0) the header type is USBPCAP_BUFFER_ISOCH_HEADER
/* Note about isochronous packets:
* packet[x].length, packet[x].status and errorCount are only relevant
* when USBPCAP_INFO_PDO_TO_FDO is set
*
* packet[x].length is not used for isochronous OUT transfers.
*
* Buffer data is attached to:
* * for isochronous OUT transactions (write to device)
* Requests (USBPCAP_INFO_PDO_TO_FDO is not set)
* * for isochronous IN transactions (read from device)
* Responses (USBPCAP_INFO_PDO_TO_FDO is set)
*/
#pragma pack(1)
typedef struct
{
ULONG offset;
ULONG length;
USBD_STATUS status;
} USBPCAP_BUFFER_ISO_PACKET, *PUSBPCAP_BUFFER_ISO_PACKET;
#pragma pack(1)
typedef struct
{
USBPCAP_BUFFER_PACKET_HEADER header;
ULONG startFrame;
ULONG numberOfPackets;
ULONG errorCount;
USBPCAP_BUFFER_ISO_PACKET packet[1];
} USBPCAP_BUFFER_ISOCH_HEADER, *PUSBPCAP_BUFFER_ISOCH_HEADER;
USBPCAP_TRANSFER_INTERRUPT
When transfer is equal to USBPCAP_TRANSFER_INTERRUPT (1) the header type is USBPCAP_BUFFER_PACKET_HEADER
USBPCAP_TRANSFER_CONTROLWhen transfer is equal to USBPCAP_TRANSFER_CONTROL (2) the header type is USBPCAP_BUFFER_CONTROL_HEADER
/* USBPcap versions before 1.5.0.0 recorded control transactions as two
* or three pcap packets:
* * USBPCAP_CONTROL_STAGE_SETUP with 8 bytes USB SETUP data
* * Optional USBPCAP_CONTROL_STAGE_DATA with either DATA OUT or IN
* * USBPCAP_CONTROL_STAGE_STATUS without data on IRP completion
*
* Such capture was considered unnecessary complex. Due to that, since
* USBPcap 1.5.0.0, the control transactions are recorded as two packets:
* * USBPCAP_CONTROL_STAGE_SETUP with 8 bytes USB SETUP data and
* optional DATA OUT
* * USBPCAP_CONTROL_STAGE_COMPLETE without payload or with the DATA IN
*
* The merit behind this change was that Wireshark dissector, since the
* very first time when Wireshark understood USBPcap format, was really
* expecting the USBPCAP_CONTROL_STAGE_SETUP to contain SETUP + DATA OUT.
* Even if Wireshark version doesn't recognize USBPCAP_CONTROL_STAGE_COMPLETE
* it will still process the payload correctly.
*/
#define USBPCAP_CONTROL_STAGE_SETUP 0
#define USBPCAP_CONTROL_STAGE_DATA 1
#define USBPCAP_CONTROL_STAGE_STATUS 2
#define USBPCAP_CONTROL_STAGE_COMPLETE 3
#pragma pack(1)
typedef struct
{
USBPCAP_BUFFER_PACKET_HEADER header;
UCHAR stage;
} USBPCAP_BUFFER_CONTROL_HEADER, *PUSBPCAP_BUFFER_CONTROL_HEADER;
Where stage determines the control transfer stage.
USBPCAP_TRANSFER_BULKWhen transfer is equal to USBPCAP_TRANSFER_BULK (3) the header type is USBPCAP_BUFFER_PACKET_HEADER