1*4882a593Smuzhiyun====== 2*4882a593Smuzhiyunusbmon 3*4882a593Smuzhiyun====== 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunIntroduction 6*4882a593Smuzhiyun============ 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunThe name "usbmon" in lowercase refers to a facility in kernel which is 9*4882a593Smuzhiyunused to collect traces of I/O on the USB bus. This function is analogous 10*4882a593Smuzhiyunto a packet socket used by network monitoring tools such as tcpdump(1) 11*4882a593Smuzhiyunor Ethereal. Similarly, it is expected that a tool such as usbdump or 12*4882a593SmuzhiyunUSBMon (with uppercase letters) is used to examine raw traces produced 13*4882a593Smuzhiyunby usbmon. 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunThe usbmon reports requests made by peripheral-specific drivers to Host 16*4882a593SmuzhiyunController Drivers (HCD). So, if HCD is buggy, the traces reported by 17*4882a593Smuzhiyunusbmon may not correspond to bus transactions precisely. This is the same 18*4882a593Smuzhiyunsituation as with tcpdump. 19*4882a593Smuzhiyun 20*4882a593SmuzhiyunTwo APIs are currently implemented: "text" and "binary". The binary API 21*4882a593Smuzhiyunis available through a character device in /dev namespace and is an ABI. 22*4882a593SmuzhiyunThe text API is deprecated since 2.6.35, but available for convenience. 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunHow to use usbmon to collect raw text traces 25*4882a593Smuzhiyun============================================ 26*4882a593Smuzhiyun 27*4882a593SmuzhiyunUnlike the packet socket, usbmon has an interface which provides traces 28*4882a593Smuzhiyunin a text format. This is used for two purposes. First, it serves as a 29*4882a593Smuzhiyuncommon trace exchange format for tools while more sophisticated formats 30*4882a593Smuzhiyunare finalized. Second, humans can read it in case tools are not available. 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunTo collect a raw text trace, execute following steps. 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun1. Prepare 35*4882a593Smuzhiyun---------- 36*4882a593Smuzhiyun 37*4882a593SmuzhiyunMount debugfs (it has to be enabled in your kernel configuration), and 38*4882a593Smuzhiyunload the usbmon module (if built as module). The second step is skipped 39*4882a593Smuzhiyunif usbmon is built into the kernel:: 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun # mount -t debugfs none_debugs /sys/kernel/debug 42*4882a593Smuzhiyun # modprobe usbmon 43*4882a593Smuzhiyun # 44*4882a593Smuzhiyun 45*4882a593SmuzhiyunVerify that bus sockets are present: 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun # ls /sys/kernel/debug/usb/usbmon 48*4882a593Smuzhiyun 0s 0u 1s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u 49*4882a593Smuzhiyun # 50*4882a593Smuzhiyun 51*4882a593SmuzhiyunNow you can choose to either use the socket '0u' (to capture packets on all 52*4882a593Smuzhiyunbuses), and skip to step #3, or find the bus used by your device with step #2. 53*4882a593SmuzhiyunThis allows to filter away annoying devices that talk continuously. 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun2. Find which bus connects to the desired device 56*4882a593Smuzhiyun------------------------------------------------ 57*4882a593Smuzhiyun 58*4882a593SmuzhiyunRun "cat /sys/kernel/debug/usb/devices", and find the T-line which corresponds 59*4882a593Smuzhiyunto the device. Usually you do it by looking for the vendor string. If you have 60*4882a593Smuzhiyunmany similar devices, unplug one and compare the two 61*4882a593Smuzhiyun/sys/kernel/debug/usb/devices outputs. The T-line will have a bus number. 62*4882a593Smuzhiyun 63*4882a593SmuzhiyunExample:: 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 66*4882a593Smuzhiyun D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 67*4882a593Smuzhiyun P: Vendor=0557 ProdID=2004 Rev= 1.00 68*4882a593Smuzhiyun S: Manufacturer=ATEN 69*4882a593Smuzhiyun S: Product=UC100KM V2.00 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun"Bus=03" means it's bus 3. Alternatively, you can look at the output from 72*4882a593Smuzhiyun"lsusb" and get the bus number from the appropriate line. Example: 73*4882a593Smuzhiyun 74*4882a593SmuzhiyunBus 003 Device 002: ID 0557:2004 ATEN UC100KM V2.00 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun3. Start 'cat' 77*4882a593Smuzhiyun-------------- 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun:: 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun # cat /sys/kernel/debug/usb/usbmon/3u > /tmp/1.mon.out 82*4882a593Smuzhiyun 83*4882a593Smuzhiyunto listen on a single bus, otherwise, to listen on all buses, type:: 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun # cat /sys/kernel/debug/usb/usbmon/0u > /tmp/1.mon.out 86*4882a593Smuzhiyun 87*4882a593SmuzhiyunThis process will read until it is killed. Naturally, the output can be 88*4882a593Smuzhiyunredirected to a desirable location. This is preferred, because it is going 89*4882a593Smuzhiyunto be quite long. 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun4. Perform the desired operation on the USB bus 92*4882a593Smuzhiyun----------------------------------------------- 93*4882a593Smuzhiyun 94*4882a593SmuzhiyunThis is where you do something that creates the traffic: plug in a flash key, 95*4882a593Smuzhiyuncopy files, control a webcam, etc. 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun5. Kill cat 98*4882a593Smuzhiyun----------- 99*4882a593Smuzhiyun 100*4882a593SmuzhiyunUsually it's done with a keyboard interrupt (Control-C). 101*4882a593Smuzhiyun 102*4882a593SmuzhiyunAt this point the output file (/tmp/1.mon.out in this example) can be saved, 103*4882a593Smuzhiyunsent by e-mail, or inspected with a text editor. In the last case make sure 104*4882a593Smuzhiyunthat the file size is not excessive for your favourite editor. 105*4882a593Smuzhiyun 106*4882a593SmuzhiyunRaw text data format 107*4882a593Smuzhiyun==================== 108*4882a593Smuzhiyun 109*4882a593SmuzhiyunTwo formats are supported currently: the original, or '1t' format, and 110*4882a593Smuzhiyunthe '1u' format. The '1t' format is deprecated in kernel 2.6.21. The '1u' 111*4882a593Smuzhiyunformat adds a few fields, such as ISO frame descriptors, interval, etc. 112*4882a593SmuzhiyunIt produces slightly longer lines, but otherwise is a perfect superset 113*4882a593Smuzhiyunof '1t' format. 114*4882a593Smuzhiyun 115*4882a593SmuzhiyunIf it is desired to recognize one from the other in a program, look at the 116*4882a593Smuzhiyun"address" word (see below), where '1u' format adds a bus number. If 2 colons 117*4882a593Smuzhiyunare present, it's the '1t' format, otherwise '1u'. 118*4882a593Smuzhiyun 119*4882a593SmuzhiyunAny text format data consists of a stream of events, such as URB submission, 120*4882a593SmuzhiyunURB callback, submission error. Every event is a text line, which consists 121*4882a593Smuzhiyunof whitespace separated words. The number or position of words may depend 122*4882a593Smuzhiyunon the event type, but there is a set of words, common for all types. 123*4882a593Smuzhiyun 124*4882a593SmuzhiyunHere is the list of words, from left to right: 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun- URB Tag. This is used to identify URBs, and is normally an in-kernel address 127*4882a593Smuzhiyun of the URB structure in hexadecimal, but can be a sequence number or any 128*4882a593Smuzhiyun other unique string, within reason. 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun- Timestamp in microseconds, a decimal number. The timestamp's resolution 131*4882a593Smuzhiyun depends on available clock, and so it can be much worse than a microsecond 132*4882a593Smuzhiyun (if the implementation uses jiffies, for example). 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun- Event Type. This type refers to the format of the event, not URB type. 135*4882a593Smuzhiyun Available types are: S - submission, C - callback, E - submission error. 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun- "Address" word (formerly a "pipe"). It consists of four fields, separated by 138*4882a593Smuzhiyun colons: URB type and direction, Bus number, Device address, Endpoint number. 139*4882a593Smuzhiyun Type and direction are encoded with two bytes in the following manner: 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun == == ============================= 142*4882a593Smuzhiyun Ci Co Control input and output 143*4882a593Smuzhiyun Zi Zo Isochronous input and output 144*4882a593Smuzhiyun Ii Io Interrupt input and output 145*4882a593Smuzhiyun Bi Bo Bulk input and output 146*4882a593Smuzhiyun == == ============================= 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun Bus number, Device address, and Endpoint are decimal numbers, but they may 149*4882a593Smuzhiyun have leading zeros, for the sake of human readers. 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun- URB Status word. This is either a letter, or several numbers separated 152*4882a593Smuzhiyun by colons: URB status, interval, start frame, and error count. Unlike the 153*4882a593Smuzhiyun "address" word, all fields save the status are optional. Interval is printed 154*4882a593Smuzhiyun only for interrupt and isochronous URBs. Start frame is printed only for 155*4882a593Smuzhiyun isochronous URBs. Error count is printed only for isochronous callback 156*4882a593Smuzhiyun events. 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun The status field is a decimal number, sometimes negative, which represents 159*4882a593Smuzhiyun a "status" field of the URB. This field makes no sense for submissions, but 160*4882a593Smuzhiyun is present anyway to help scripts with parsing. When an error occurs, the 161*4882a593Smuzhiyun field contains the error code. 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun In case of a submission of a Control packet, this field contains a Setup Tag 164*4882a593Smuzhiyun instead of an group of numbers. It is easy to tell whether the Setup Tag is 165*4882a593Smuzhiyun present because it is never a number. Thus if scripts find a set of numbers 166*4882a593Smuzhiyun in this word, they proceed to read Data Length (except for isochronous URBs). 167*4882a593Smuzhiyun If they find something else, like a letter, they read the setup packet before 168*4882a593Smuzhiyun reading the Data Length or isochronous descriptors. 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun- Setup packet, if present, consists of 5 words: one of each for bmRequestType, 171*4882a593Smuzhiyun bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0. 172*4882a593Smuzhiyun These words are safe to decode if Setup Tag was 's'. Otherwise, the setup 173*4882a593Smuzhiyun packet was present, but not captured, and the fields contain filler. 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun- Number of isochronous frame descriptors and descriptors themselves. 176*4882a593Smuzhiyun If an Isochronous transfer event has a set of descriptors, a total number 177*4882a593Smuzhiyun of them in an URB is printed first, then a word per descriptor, up to a 178*4882a593Smuzhiyun total of 5. The word consists of 3 colon-separated decimal numbers for 179*4882a593Smuzhiyun status, offset, and length respectively. For submissions, initial length 180*4882a593Smuzhiyun is reported. For callbacks, actual length is reported. 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun- Data Length. For submissions, this is the requested length. For callbacks, 183*4882a593Smuzhiyun this is the actual length. 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun- Data tag. The usbmon may not always capture data, even if length is nonzero. 186*4882a593Smuzhiyun The data words are present only if this tag is '='. 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun- Data words follow, in big endian hexadecimal format. Notice that they are 189*4882a593Smuzhiyun not machine words, but really just a byte stream split into words to make 190*4882a593Smuzhiyun it easier to read. Thus, the last word may contain from one to four bytes. 191*4882a593Smuzhiyun The length of collected data is limited and can be less than the data length 192*4882a593Smuzhiyun reported in the Data Length word. In the case of an Isochronous input (Zi) 193*4882a593Smuzhiyun completion where the received data is sparse in the buffer, the length of 194*4882a593Smuzhiyun the collected data can be greater than the Data Length value (because Data 195*4882a593Smuzhiyun Length counts only the bytes that were received whereas the Data words 196*4882a593Smuzhiyun contain the entire transfer buffer). 197*4882a593Smuzhiyun 198*4882a593SmuzhiyunExamples: 199*4882a593Smuzhiyun 200*4882a593SmuzhiyunAn input control transfer to get a port status:: 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 < 203*4882a593Smuzhiyun d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000 204*4882a593Smuzhiyun 205*4882a593SmuzhiyunAn output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte 206*4882a593SmuzhiyunBulk wrapper to a storage device at address 5:: 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000 209*4882a593Smuzhiyun dd65f0e8 4128379808 C Bo:1:005:2 0 31 > 210*4882a593Smuzhiyun 211*4882a593SmuzhiyunRaw binary format and API 212*4882a593Smuzhiyun========================= 213*4882a593Smuzhiyun 214*4882a593SmuzhiyunThe overall architecture of the API is about the same as the one above, 215*4882a593Smuzhiyunonly the events are delivered in binary format. Each event is sent in 216*4882a593Smuzhiyunthe following structure (its name is made up, so that we can refer to it):: 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun struct usbmon_packet { 219*4882a593Smuzhiyun u64 id; /* 0: URB ID - from submission to callback */ 220*4882a593Smuzhiyun unsigned char type; /* 8: Same as text; extensible. */ 221*4882a593Smuzhiyun unsigned char xfer_type; /* ISO (0), Intr, Control, Bulk (3) */ 222*4882a593Smuzhiyun unsigned char epnum; /* Endpoint number and transfer direction */ 223*4882a593Smuzhiyun unsigned char devnum; /* Device address */ 224*4882a593Smuzhiyun u16 busnum; /* 12: Bus number */ 225*4882a593Smuzhiyun char flag_setup; /* 14: Same as text */ 226*4882a593Smuzhiyun char flag_data; /* 15: Same as text; Binary zero is OK. */ 227*4882a593Smuzhiyun s64 ts_sec; /* 16: gettimeofday */ 228*4882a593Smuzhiyun s32 ts_usec; /* 24: gettimeofday */ 229*4882a593Smuzhiyun int status; /* 28: */ 230*4882a593Smuzhiyun unsigned int length; /* 32: Length of data (submitted or actual) */ 231*4882a593Smuzhiyun unsigned int len_cap; /* 36: Delivered length */ 232*4882a593Smuzhiyun union { /* 40: */ 233*4882a593Smuzhiyun unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ 234*4882a593Smuzhiyun struct iso_rec { /* Only for ISO */ 235*4882a593Smuzhiyun int error_count; 236*4882a593Smuzhiyun int numdesc; 237*4882a593Smuzhiyun } iso; 238*4882a593Smuzhiyun } s; 239*4882a593Smuzhiyun int interval; /* 48: Only for Interrupt and ISO */ 240*4882a593Smuzhiyun int start_frame; /* 52: For ISO */ 241*4882a593Smuzhiyun unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */ 242*4882a593Smuzhiyun unsigned int ndesc; /* 60: Actual number of ISO descriptors */ 243*4882a593Smuzhiyun }; /* 64 total length */ 244*4882a593Smuzhiyun 245*4882a593SmuzhiyunThese events can be received from a character device by reading with read(2), 246*4882a593Smuzhiyunwith an ioctl(2), or by accessing the buffer with mmap. However, read(2) 247*4882a593Smuzhiyunonly returns first 48 bytes for compatibility reasons. 248*4882a593Smuzhiyun 249*4882a593SmuzhiyunThe character device is usually called /dev/usbmonN, where N is the USB bus 250*4882a593Smuzhiyunnumber. Number zero (/dev/usbmon0) is special and means "all buses". 251*4882a593SmuzhiyunNote that specific naming policy is set by your Linux distribution. 252*4882a593Smuzhiyun 253*4882a593SmuzhiyunIf you create /dev/usbmon0 by hand, make sure that it is owned by root 254*4882a593Smuzhiyunand has mode 0600. Otherwise, unprivileged users will be able to snoop 255*4882a593Smuzhiyunkeyboard traffic. 256*4882a593Smuzhiyun 257*4882a593SmuzhiyunThe following ioctl calls are available, with MON_IOC_MAGIC 0x92: 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun MON_IOCQ_URB_LEN, defined as _IO(MON_IOC_MAGIC, 1) 260*4882a593Smuzhiyun 261*4882a593SmuzhiyunThis call returns the length of data in the next event. Note that majority of 262*4882a593Smuzhiyunevents contain no data, so if this call returns zero, it does not mean that 263*4882a593Smuzhiyunno events are available. 264*4882a593Smuzhiyun 265*4882a593Smuzhiyun MON_IOCG_STATS, defined as _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats) 266*4882a593Smuzhiyun 267*4882a593SmuzhiyunThe argument is a pointer to the following structure:: 268*4882a593Smuzhiyun 269*4882a593Smuzhiyun struct mon_bin_stats { 270*4882a593Smuzhiyun u32 queued; 271*4882a593Smuzhiyun u32 dropped; 272*4882a593Smuzhiyun }; 273*4882a593Smuzhiyun 274*4882a593SmuzhiyunThe member "queued" refers to the number of events currently queued in the 275*4882a593Smuzhiyunbuffer (and not to the number of events processed since the last reset). 276*4882a593Smuzhiyun 277*4882a593SmuzhiyunThe member "dropped" is the number of events lost since the last call 278*4882a593Smuzhiyunto MON_IOCG_STATS. 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun MON_IOCT_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 4) 281*4882a593Smuzhiyun 282*4882a593SmuzhiyunThis call sets the buffer size. The argument is the size in bytes. 283*4882a593SmuzhiyunThe size may be rounded down to the next chunk (or page). If the requested 284*4882a593Smuzhiyunsize is out of [unspecified] bounds for this kernel, the call fails with 285*4882a593Smuzhiyun-EINVAL. 286*4882a593Smuzhiyun 287*4882a593Smuzhiyun MON_IOCQ_RING_SIZE, defined as _IO(MON_IOC_MAGIC, 5) 288*4882a593Smuzhiyun 289*4882a593SmuzhiyunThis call returns the current size of the buffer in bytes. 290*4882a593Smuzhiyun 291*4882a593Smuzhiyun MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg) 292*4882a593Smuzhiyun MON_IOCX_GETX, defined as _IOW(MON_IOC_MAGIC, 10, struct mon_get_arg) 293*4882a593Smuzhiyun 294*4882a593SmuzhiyunThese calls wait for events to arrive if none were in the kernel buffer, 295*4882a593Smuzhiyunthen return the first event. The argument is a pointer to the following 296*4882a593Smuzhiyunstructure:: 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun struct mon_get_arg { 299*4882a593Smuzhiyun struct usbmon_packet *hdr; 300*4882a593Smuzhiyun void *data; 301*4882a593Smuzhiyun size_t alloc; /* Length of data (can be zero) */ 302*4882a593Smuzhiyun }; 303*4882a593Smuzhiyun 304*4882a593SmuzhiyunBefore the call, hdr, data, and alloc should be filled. Upon return, the area 305*4882a593Smuzhiyunpointed by hdr contains the next event structure, and the data buffer contains 306*4882a593Smuzhiyunthe data, if any. The event is removed from the kernel buffer. 307*4882a593Smuzhiyun 308*4882a593SmuzhiyunThe MON_IOCX_GET copies 48 bytes to hdr area, MON_IOCX_GETX copies 64 bytes. 309*4882a593Smuzhiyun 310*4882a593Smuzhiyun MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg) 311*4882a593Smuzhiyun 312*4882a593SmuzhiyunThis ioctl is primarily used when the application accesses the buffer 313*4882a593Smuzhiyunwith mmap(2). Its argument is a pointer to the following structure:: 314*4882a593Smuzhiyun 315*4882a593Smuzhiyun struct mon_mfetch_arg { 316*4882a593Smuzhiyun uint32_t *offvec; /* Vector of events fetched */ 317*4882a593Smuzhiyun uint32_t nfetch; /* Number of events to fetch (out: fetched) */ 318*4882a593Smuzhiyun uint32_t nflush; /* Number of events to flush */ 319*4882a593Smuzhiyun }; 320*4882a593Smuzhiyun 321*4882a593SmuzhiyunThe ioctl operates in 3 stages. 322*4882a593Smuzhiyun 323*4882a593SmuzhiyunFirst, it removes and discards up to nflush events from the kernel buffer. 324*4882a593SmuzhiyunThe actual number of events discarded is returned in nflush. 325*4882a593Smuzhiyun 326*4882a593SmuzhiyunSecond, it waits for an event to be present in the buffer, unless the pseudo- 327*4882a593Smuzhiyundevice is open with O_NONBLOCK. 328*4882a593Smuzhiyun 329*4882a593SmuzhiyunThird, it extracts up to nfetch offsets into the mmap buffer, and stores 330*4882a593Smuzhiyunthem into the offvec. The actual number of event offsets is stored into 331*4882a593Smuzhiyunthe nfetch. 332*4882a593Smuzhiyun 333*4882a593Smuzhiyun MON_IOCH_MFLUSH, defined as _IO(MON_IOC_MAGIC, 8) 334*4882a593Smuzhiyun 335*4882a593SmuzhiyunThis call removes a number of events from the kernel buffer. Its argument 336*4882a593Smuzhiyunis the number of events to remove. If the buffer contains fewer events 337*4882a593Smuzhiyunthan requested, all events present are removed, and no error is reported. 338*4882a593SmuzhiyunThis works when no events are available too. 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun FIONBIO 341*4882a593Smuzhiyun 342*4882a593SmuzhiyunThe ioctl FIONBIO may be implemented in the future, if there's a need. 343*4882a593Smuzhiyun 344*4882a593SmuzhiyunIn addition to ioctl(2) and read(2), the special file of binary API can 345*4882a593Smuzhiyunbe polled with select(2) and poll(2). But lseek(2) does not work. 346*4882a593Smuzhiyun 347*4882a593Smuzhiyun* Memory-mapped access of the kernel buffer for the binary API 348*4882a593Smuzhiyun 349*4882a593SmuzhiyunThe basic idea is simple: 350*4882a593Smuzhiyun 351*4882a593SmuzhiyunTo prepare, map the buffer by getting the current size, then using mmap(2). 352*4882a593SmuzhiyunThen, execute a loop similar to the one written in pseudo-code below:: 353*4882a593Smuzhiyun 354*4882a593Smuzhiyun struct mon_mfetch_arg fetch; 355*4882a593Smuzhiyun struct usbmon_packet *hdr; 356*4882a593Smuzhiyun int nflush = 0; 357*4882a593Smuzhiyun for (;;) { 358*4882a593Smuzhiyun fetch.offvec = vec; // Has N 32-bit words 359*4882a593Smuzhiyun fetch.nfetch = N; // Or less than N 360*4882a593Smuzhiyun fetch.nflush = nflush; 361*4882a593Smuzhiyun ioctl(fd, MON_IOCX_MFETCH, &fetch); // Process errors, too 362*4882a593Smuzhiyun nflush = fetch.nfetch; // This many packets to flush when done 363*4882a593Smuzhiyun for (i = 0; i < nflush; i++) { 364*4882a593Smuzhiyun hdr = (struct ubsmon_packet *) &mmap_area[vec[i]]; 365*4882a593Smuzhiyun if (hdr->type == '@') // Filler packet 366*4882a593Smuzhiyun continue; 367*4882a593Smuzhiyun caddr_t data = &mmap_area[vec[i]] + 64; 368*4882a593Smuzhiyun process_packet(hdr, data); 369*4882a593Smuzhiyun } 370*4882a593Smuzhiyun } 371*4882a593Smuzhiyun 372*4882a593SmuzhiyunThus, the main idea is to execute only one ioctl per N events. 373*4882a593Smuzhiyun 374*4882a593SmuzhiyunAlthough the buffer is circular, the returned headers and data do not cross 375*4882a593Smuzhiyunthe end of the buffer, so the above pseudo-code does not need any gathering. 376