On 1/19/21 8:44 PM, Gerd Hoffmann wrote: > Log all traffic of a specific usb device to a pcap file for later > inspection. File format is compatible with linux usb monitor. > > Usage: > qemu -device usb-${somedevice},pcap=file.pcap > wireshark file.pcap
Great! > Signed-off-by: Gerd Hoffmann <kra...@redhat.com> > --- > include/hw/usb.h | 8 ++ > hw/usb/bus.c | 16 +++ > hw/usb/core.c | 17 ++++ > hw/usb/pcap.c | 242 +++++++++++++++++++++++++++++++++++++++++++++ > hw/usb/meson.build | 1 + > 5 files changed, 284 insertions(+) > create mode 100644 hw/usb/pcap.c ... > diff --git a/hw/usb/pcap.c b/hw/usb/pcap.c > new file mode 100644 > index 000000000000..d3162d65e5fe > --- /dev/null > +++ b/hw/usb/pcap.c > @@ -0,0 +1,242 @@ Missing license. > +#include "qemu/osdep.h" > +#include "hw/usb.h" > + > +#define PCAP_MAGIC 0xa1b2c3d4 > +#define PCAP_MAJOR 2 > +#define PCAP_MINOR 4 > + > +/* https://wiki.wireshark.org/Development/LibpcapFileFormat */ > + > +struct pcap_hdr { > + uint32_t magic_number; /* magic number */ > + uint16_t version_major; /* major version number */ > + uint16_t version_minor; /* minor version number */ > + int32_t thiszone; /* GMT to local correction */ > + uint32_t sigfigs; /* accuracy of timestamps */ > + uint32_t snaplen; /* max length of captured packets, in octets */ > + uint32_t network; /* data link type */ > +}; QEMU_PACKED? > + > +struct pcaprec_hdr { > + uint32_t ts_sec; /* timestamp seconds */ > + uint32_t ts_usec; /* timestamp microseconds */ > + uint32_t incl_len; /* number of octets of packet saved in file */ > + uint32_t orig_len; /* actual length of packet */ > +}; QEMU_PACKED? > + > +/* https://www.tcpdump.org/linktypes.html */ > +/* linux: Documentation/usb/usbmon.rst */ > +/* linux: drivers/usb/mon/mon_bin.c */ > + > +#define LINKTYPE_USB_LINUX 189 /* first 48 bytes only */ > +#define LINKTYPE_USB_LINUX_MMAPPED 220 /* full 64 byte header */ > + > +struct usbmon_packet { > + uint64_t id; /* 0: URB ID - from submission to callback */ > + unsigned char type; /* 8: Same as text; extensible. */ > + unsigned char xfer_type; /* ISO (0), Intr, Control, Bulk (3) */ > + unsigned char epnum; /* Endpoint number and transfer direction */ > + unsigned char devnum; /* Device address */ > + uint16_t busnum; /* 12: Bus number */ > + char flag_setup; /* 14: Same as text */ > + char flag_data; /* 15: Same as text; Binary zero is OK. */ > + int64_t ts_sec; /* 16: gettimeofday */ > + int32_t ts_usec; /* 24: gettimeofday */ > + int32_t status; /* 28: */ > + unsigned int length; /* 32: Length of data (submitted or actual) */ > + unsigned int len_cap; /* 36: Delivered length */ > + union { /* 40: */ > + unsigned char setup[8]; /* Only for Control S-type */ > + struct iso_rec { /* Only for ISO */ > + int32_t error_count; > + int32_t numdesc; > + } iso; > + } s; > + int32_t interval; /* 48: Only for Interrupt and ISO */ > + int32_t start_frame; /* 52: For ISO */ > + uint32_t xfer_flags; /* 56: copy of URB's transfer_flags */ > + uint32_t ndesc; /* 60: Actual number of ISO descriptors */ > +}; /* 64 total length */ QEMU_PACKED? Otherwise: Reviewed-by: Philippe Mathieu-Daudé <phi...@redhat.com>