1/*
2 * Copyright (c) 2006 Paolo Abeni (Italy)
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * USB sniffing API implementation for Linux platform
31 * By Paolo Abeni <paolo.abeni@email.it>
32 * Modifications: Kris Katterjohn <katterjohn@gmail.com>
33 *
34 */
35#ifndef lint
36static const char rcsid[] _U_ =
37    "@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.33 2008-12-23 21:38:50 guy Exp $ (LBL)";
38#endif
39
40#ifdef HAVE_CONFIG_H
41#include "config.h"
42#endif
43
44#include "pcap-int.h"
45#include "pcap-usb-linux.h"
46#include "pcap/usb.h"
47
48#ifdef NEED_STRERROR_H
49#include "strerror.h"
50#endif
51
52#include <ctype.h>
53#include <errno.h>
54#include <stdlib.h>
55#include <unistd.h>
56#include <fcntl.h>
57#include <string.h>
58#include <dirent.h>
59#include <byteswap.h>
60#include <netinet/in.h>
61#include <sys/ioctl.h>
62#include <sys/mman.h>
63#ifdef HAVE_LINUX_USBDEVICE_FS_H
64/*
65 * We might need <linux/compiler.h> to define __user for
66 * <linux/usbdevice_fs.h>.
67 */
68#ifdef HAVE_LINUX_COMPILER_H
69#include <linux/compiler.h>
70#endif /* HAVE_LINUX_COMPILER_H */
71#include <linux/usbdevice_fs.h>
72#endif /* HAVE_LINUX_USBDEVICE_FS_H */
73
74#define USB_IFACE "usbmon"
75#define USB_TEXT_DIR_OLD "/sys/kernel/debug/usbmon"
76#define USB_TEXT_DIR "/sys/kernel/debug/usb/usbmon"
77#define SYS_USB_BUS_DIR "/sys/bus/usb/devices"
78#define PROC_USB_BUS_DIR "/proc/bus/usb"
79#define USB_LINE_LEN 4096
80
81#if __BYTE_ORDER == __LITTLE_ENDIAN
82#define htols(s) s
83#define htoll(l) l
84#define htol64(ll) ll
85#else
86#define htols(s) bswap_16(s)
87#define htoll(l) bswap_32(l)
88#define htol64(ll) bswap_64(ll)
89#endif
90
91struct mon_bin_stats {
92	u_int32_t queued;
93	u_int32_t dropped;
94};
95
96struct mon_bin_get {
97	pcap_usb_header *hdr;
98	void *data;
99	size_t data_len;   /* Length of data (can be zero) */
100};
101
102struct mon_bin_mfetch {
103	int32_t *offvec;   /* Vector of events fetched */
104	int32_t nfetch;    /* Number of events to fetch (out: fetched) */
105	int32_t nflush;    /* Number of events to flush */
106};
107
108#define MON_IOC_MAGIC 0x92
109
110#define MON_IOCQ_URB_LEN _IO(MON_IOC_MAGIC, 1)
111#define MON_IOCX_URB  _IOWR(MON_IOC_MAGIC, 2, struct mon_bin_hdr)
112#define MON_IOCG_STATS _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats)
113#define MON_IOCT_RING_SIZE _IO(MON_IOC_MAGIC, 4)
114#define MON_IOCQ_RING_SIZE _IO(MON_IOC_MAGIC, 5)
115#define MON_IOCX_GET   _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get)
116#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
117#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
118
119#define MON_BIN_SETUP 	0x1 /* setup hdr is present*/
120#define MON_BIN_SETUP_ZERO 	0x2 /* setup buffer is not available */
121#define MON_BIN_DATA_ZERO 	0x4 /* data buffer is not available */
122#define MON_BIN_ERROR 	0x8
123
124/*
125 * Private data for capturing on Linux USB.
126 */
127struct pcap_usb_linux {
128	u_char *mmapbuf;	/* memory-mapped region pointer */
129	size_t mmapbuflen;	/* size of region */
130	int bus_index;
131	u_int packets_read;
132};
133
134/* forward declaration */
135static int usb_activate(pcap_t *);
136static int usb_stats_linux(pcap_t *, struct pcap_stat *);
137static int usb_stats_linux_bin(pcap_t *, struct pcap_stat *);
138static int usb_read_linux(pcap_t *, int , pcap_handler , u_char *);
139static int usb_read_linux_bin(pcap_t *, int , pcap_handler , u_char *);
140static int usb_read_linux_mmap(pcap_t *, int , pcap_handler , u_char *);
141static int usb_inject_linux(pcap_t *, const void *, size_t);
142static int usb_setdirection_linux(pcap_t *, pcap_direction_t);
143static void usb_cleanup_linux_mmap(pcap_t *);
144
145/* facility to add an USB device to the device list*/
146static int
147usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str)
148{
149	char dev_name[10];
150	char dev_descr[30];
151	snprintf(dev_name, 10, USB_IFACE"%d", n);
152	snprintf(dev_descr, 30, "USB bus number %d", n);
153
154	if (pcap_add_if(alldevsp, dev_name, 0,
155	    dev_descr, err_str) < 0)
156		return -1;
157	return 0;
158}
159
160int
161usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
162{
163	struct dirent* data;
164	int ret = 0;
165	DIR* dir;
166	int n;
167	char* name;
168	size_t len;
169
170	/* try scanning sysfs usb bus directory */
171	dir = opendir(SYS_USB_BUS_DIR);
172	if (dir != NULL) {
173		while ((ret == 0) && ((data = readdir(dir)) != 0)) {
174			name = data->d_name;
175
176			if (strncmp(name, "usb", 3) != 0)
177				continue;
178
179			if (sscanf(&name[3], "%d", &n) == 0)
180				continue;
181
182			ret = usb_dev_add(alldevsp, n, err_str);
183		}
184
185		closedir(dir);
186		return ret;
187	}
188
189	/* that didn't work; try scanning procfs usb bus directory */
190	dir = opendir(PROC_USB_BUS_DIR);
191	if (dir != NULL) {
192		while ((ret == 0) && ((data = readdir(dir)) != 0)) {
193			name = data->d_name;
194			len = strlen(name);
195
196			/* if this file name does not end with a number it's not of our interest */
197			if ((len < 1) || !isdigit(name[--len]))
198				continue;
199			while (isdigit(name[--len]));
200			if (sscanf(&name[len+1], "%d", &n) != 1)
201				continue;
202
203			ret = usb_dev_add(alldevsp, n, err_str);
204		}
205
206		closedir(dir);
207		return ret;
208	}
209
210	/* neither of them worked */
211	return 0;
212}
213
214static
215int usb_mmap(pcap_t* handle)
216{
217	struct pcap_usb_linux *handlep = handle->priv;
218	int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
219	if (len < 0)
220		return 0;
221
222	handlep->mmapbuflen = len;
223	handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ,
224	    MAP_SHARED, handle->fd, 0);
225	return handlep->mmapbuf != MAP_FAILED;
226}
227
228#define CTRL_TIMEOUT    (5*1000)        /* milliseconds */
229
230#define USB_DIR_IN		0x80
231#define USB_TYPE_STANDARD	0x00
232#define USB_RECIP_DEVICE	0x00
233
234#define USB_REQ_GET_DESCRIPTOR	6
235
236#define USB_DT_DEVICE		1
237
238/* probe the descriptors of the devices attached to the bus */
239/* the descriptors will end up in the captured packet stream */
240/* and be decoded by external apps like wireshark */
241/* without these identifying probes packet data can't be fully decoded */
242static void
243probe_devices(int bus)
244{
245	struct usbdevfs_ctrltransfer ctrl;
246	struct dirent* data;
247	int ret = 0;
248	char buf[40];
249	DIR* dir;
250
251	/* scan usb bus directories for device nodes */
252	snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d", bus);
253	dir = opendir(buf);
254	if (!dir)
255		return;
256
257	while ((ret >= 0) && ((data = readdir(dir)) != 0)) {
258		int fd;
259		char* name = data->d_name;
260
261		if (name[0] == '.')
262			continue;
263
264		snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d/%s", bus, data->d_name);
265
266		fd = open(buf, O_RDWR);
267		if (fd == -1)
268			continue;
269
270		/*
271		 * Sigh.  Different kernels have different member names
272		 * for this structure.
273		 */
274#ifdef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
275		ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
276		ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
277		ctrl.wValue = USB_DT_DEVICE << 8;
278		ctrl.wIndex = 0;
279 		ctrl.wLength = sizeof(buf);
280#else
281		ctrl.requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
282		ctrl.request = USB_REQ_GET_DESCRIPTOR;
283		ctrl.value = USB_DT_DEVICE << 8;
284		ctrl.index = 0;
285 		ctrl.length = sizeof(buf);
286#endif
287		ctrl.data = buf;
288		ctrl.timeout = CTRL_TIMEOUT;
289
290		ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
291
292		close(fd);
293	}
294	closedir(dir);
295}
296
297pcap_t *
298usb_create(const char *device, char *ebuf, int *is_ours)
299{
300	const char *cp;
301	char *cpend;
302	long devnum;
303	pcap_t *p;
304
305	/* Does this look like a USB monitoring device? */
306	cp = strrchr(device, '/');
307	if (cp == NULL)
308		cp = device;
309	/* Does it begin with USB_IFACE? */
310	if (strncmp(cp, USB_IFACE, sizeof USB_IFACE - 1) != 0) {
311		/* Nope, doesn't begin with USB_IFACE */
312		*is_ours = 0;
313		return NULL;
314	}
315	/* Yes - is USB_IFACE followed by a number? */
316	cp += sizeof USB_IFACE - 1;
317	devnum = strtol(cp, &cpend, 10);
318	if (cpend == cp || *cpend != '\0') {
319		/* Not followed by a number. */
320		*is_ours = 0;
321		return NULL;
322	}
323	if (devnum < 0) {
324		/* Followed by a non-valid number. */
325		*is_ours = 0;
326		return NULL;
327	}
328
329	/* OK, it's probably ours. */
330	*is_ours = 1;
331
332	p = pcap_create_common(device, ebuf, sizeof (struct pcap_usb_linux));
333	if (p == NULL)
334		return (NULL);
335
336	p->activate_op = usb_activate;
337	return (p);
338}
339
340static int
341usb_activate(pcap_t* handle)
342{
343	struct pcap_usb_linux *handlep = handle->priv;
344	char 		full_path[USB_LINE_LEN];
345
346	/* Initialize some components of the pcap structure. */
347	handle->bufsize = handle->snapshot;
348	handle->offset = 0;
349	handle->linktype = DLT_USB_LINUX;
350
351	handle->inject_op = usb_inject_linux;
352	handle->setfilter_op = install_bpf_program; /* no kernel filtering */
353	handle->setdirection_op = usb_setdirection_linux;
354	handle->set_datalink_op = NULL;	/* can't change data link type */
355	handle->getnonblock_op = pcap_getnonblock_fd;
356	handle->setnonblock_op = pcap_setnonblock_fd;
357
358	/*get usb bus index from device name */
359	if (sscanf(handle->opt.source, USB_IFACE"%d", &handlep->bus_index) != 1)
360	{
361		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
362			"Can't get USB bus index from %s", handle->opt.source);
363		return PCAP_ERROR;
364	}
365
366	/*now select the read method: try to open binary interface */
367	snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);
368	handle->fd = open(full_path, O_RDONLY, 0);
369	if (handle->fd >= 0)
370	{
371		if (handle->opt.rfmon) {
372			/*
373			 * Monitor mode doesn't apply to USB devices.
374			 */
375			close(handle->fd);
376			return PCAP_ERROR_RFMON_NOTSUP;
377		}
378
379		/* binary api is available, try to use fast mmap access */
380		if (usb_mmap(handle)) {
381			handle->linktype = DLT_USB_LINUX_MMAPPED;
382			handle->stats_op = usb_stats_linux_bin;
383			handle->read_op = usb_read_linux_mmap;
384			handle->cleanup_op = usb_cleanup_linux_mmap;
385			probe_devices(handlep->bus_index);
386
387			/*
388			 * "handle->fd" is a real file, so "select()" and
389			 * "poll()" work on it.
390			 */
391			handle->selectable_fd = handle->fd;
392			return 0;
393		}
394
395		/* can't mmap, use plain binary interface access */
396		handle->stats_op = usb_stats_linux_bin;
397		handle->read_op = usb_read_linux_bin;
398		probe_devices(handlep->bus_index);
399	}
400	else {
401		/*Binary interface not available, try open text interface */
402		snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index);
403		handle->fd = open(full_path, O_RDONLY, 0);
404		if (handle->fd < 0)
405		{
406			if (errno == ENOENT)
407			{
408				/*
409				 * Not found at the new location; try
410				 * the old location.
411				 */
412				snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index);
413				handle->fd = open(full_path, O_RDONLY, 0);
414			}
415			if (handle->fd < 0) {
416				/* no more fallback, give it up*/
417				snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
418					"Can't open USB bus file %s: %s", full_path, strerror(errno));
419				return PCAP_ERROR;
420			}
421		}
422
423		if (handle->opt.rfmon) {
424			/*
425			 * Monitor mode doesn't apply to USB devices.
426			 */
427			close(handle->fd);
428			return PCAP_ERROR_RFMON_NOTSUP;
429		}
430
431		handle->stats_op = usb_stats_linux;
432		handle->read_op = usb_read_linux;
433	}
434
435	/*
436	 * "handle->fd" is a real file, so "select()" and "poll()"
437	 * work on it.
438	 */
439	handle->selectable_fd = handle->fd;
440
441	/* for plain binary access and text access we need to allocate the read
442	 * buffer */
443	handle->buffer = malloc(handle->bufsize);
444	if (!handle->buffer) {
445		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
446			 "malloc: %s", pcap_strerror(errno));
447		close(handle->fd);
448		return PCAP_ERROR;
449	}
450	return 0;
451}
452
453static inline int
454ascii_to_int(char c)
455{
456	return c < 'A' ? c- '0': ((c<'a') ? c - 'A' + 10: c-'a'+10);
457}
458
459/*
460 * see <linux-kernel-source>/Documentation/usb/usbmon.txt and
461 * <linux-kernel-source>/drivers/usb/mon/mon_text.c for urb string
462 * format description
463 */
464static int
465usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
466{
467	/* see:
468	* /usr/src/linux/Documentation/usb/usbmon.txt
469	* for message format
470	*/
471	struct pcap_usb_linux *handlep = handle->priv;
472	unsigned timestamp;
473	int tag, cnt, ep_num, dev_addr, dummy, ret, urb_len, data_len;
474	char etype, pipeid1, pipeid2, status[16], urb_tag, line[USB_LINE_LEN];
475	char *string = line;
476	u_char * rawdata = handle->buffer;
477	struct pcap_pkthdr pkth;
478	pcap_usb_header* uhdr = (pcap_usb_header*)handle->buffer;
479	u_char urb_transfer=0;
480	int incoming=0;
481
482	/* ignore interrupt system call errors */
483	do {
484		ret = read(handle->fd, line, USB_LINE_LEN - 1);
485		if (handle->break_loop)
486		{
487			handle->break_loop = 0;
488			return -2;
489		}
490	} while ((ret == -1) && (errno == EINTR));
491	if (ret < 0)
492	{
493		if (errno == EAGAIN)
494			return 0;	/* no data there */
495
496		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
497		    "Can't read from fd %d: %s", handle->fd, strerror(errno));
498		return -1;
499	}
500
501	/* read urb header; %n argument may increment return value, but it's
502	* not mandatory, so does not count on it*/
503	string[ret] = 0;
504	ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, &timestamp, &etype,
505		&pipeid1, &pipeid2, &dev_addr, &ep_num, status,
506		&cnt);
507	if (ret < 8)
508	{
509		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
510		    "Can't parse USB bus message '%s', too few tokens (expected 8 got %d)",
511		    string, ret);
512		return -1;
513	}
514	uhdr->id = tag;
515	uhdr->device_address = dev_addr;
516	uhdr->bus_id = handlep->bus_index;
517	uhdr->status = 0;
518	string += cnt;
519
520	/* don't use usbmon provided timestamp, since it have low precision*/
521	if (gettimeofday(&pkth.ts, NULL) < 0)
522	{
523		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
524			"Can't get timestamp for message '%s' %d:%s",
525			string, errno, strerror(errno));
526		return -1;
527	}
528	uhdr->ts_sec = pkth.ts.tv_sec;
529	uhdr->ts_usec = pkth.ts.tv_usec;
530
531	/* parse endpoint information */
532	if (pipeid1 == 'C')
533		urb_transfer = URB_CONTROL;
534	else if (pipeid1 == 'Z')
535		urb_transfer = URB_ISOCHRONOUS;
536	else if (pipeid1 == 'I')
537		urb_transfer = URB_INTERRUPT;
538	else if (pipeid1 == 'B')
539		urb_transfer = URB_BULK;
540	if (pipeid2 == 'i') {
541		ep_num |= URB_TRANSFER_IN;
542		incoming = 1;
543	}
544	if (etype == 'C')
545		incoming = !incoming;
546
547	/* direction check*/
548	if (incoming)
549	{
550		if (handle->direction == PCAP_D_OUT)
551			return 0;
552	}
553	else
554		if (handle->direction == PCAP_D_IN)
555			return 0;
556	uhdr->event_type = etype;
557	uhdr->transfer_type = urb_transfer;
558	uhdr->endpoint_number = ep_num;
559	pkth.caplen = sizeof(pcap_usb_header);
560	rawdata += sizeof(pcap_usb_header);
561
562	/* check if this is a setup packet */
563	ret = sscanf(status, "%d", &dummy);
564	if (ret != 1)
565	{
566		/* this a setup packet, setup data can be filled with underscore if
567		* usbmon has not been able to read them, so we must parse this fields as
568		* strings */
569		pcap_usb_setup* shdr;
570		char str1[3], str2[3], str3[5], str4[5], str5[5];
571		ret = sscanf(string, "%s %s %s %s %s%n", str1, str2, str3, str4,
572		str5, &cnt);
573		if (ret < 5)
574		{
575			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
576				"Can't parse USB bus message '%s', too few tokens (expected 5 got %d)",
577				string, ret);
578			return -1;
579		}
580		string += cnt;
581
582		/* try to convert to corresponding integer */
583		shdr = &uhdr->setup;
584		shdr->bmRequestType = strtoul(str1, 0, 16);
585		shdr->bRequest = strtoul(str2, 0, 16);
586		shdr->wValue = htols(strtoul(str3, 0, 16));
587		shdr->wIndex = htols(strtoul(str4, 0, 16));
588		shdr->wLength = htols(strtoul(str5, 0, 16));
589
590		uhdr->setup_flag = 0;
591	}
592	else
593		uhdr->setup_flag = 1;
594
595	/* read urb data */
596	ret = sscanf(string, " %d%n", &urb_len, &cnt);
597	if (ret < 1)
598	{
599		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
600		  "Can't parse urb length from '%s'", string);
601		return -1;
602	}
603	string += cnt;
604
605	/* urb tag is not present if urb length is 0, so we can stop here
606	 * text parsing */
607	pkth.len = urb_len+pkth.caplen;
608	uhdr->urb_len = urb_len;
609	uhdr->data_flag = 1;
610	data_len = 0;
611	if (uhdr->urb_len == 0)
612		goto got;
613
614	/* check for data presence; data is present if and only if urb tag is '=' */
615	if (sscanf(string, " %c", &urb_tag) != 1)
616	{
617		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
618			"Can't parse urb tag from '%s'", string);
619		return -1;
620	}
621
622	if (urb_tag != '=')
623		goto got;
624
625	/* skip urb tag and following space */
626	string += 3;
627
628	/* if we reach this point we got some urb data*/
629	uhdr->data_flag = 0;
630
631	/* read all urb data; if urb length is greater then the usbmon internal
632	 * buffer length used by the kernel to spool the URB, we get only
633	 * a partial information.
634	 * At least until linux 2.6.17 there is no way to set usbmon intenal buffer
635	 * length and default value is 130. */
636	while ((string[0] != 0) && (string[1] != 0) && (pkth.caplen < handle->snapshot))
637	{
638		rawdata[0] = ascii_to_int(string[0]) * 16 + ascii_to_int(string[1]);
639		rawdata++;
640		string+=2;
641		if (string[0] == ' ')
642			string++;
643		pkth.caplen++;
644		data_len++;
645	}
646
647got:
648	uhdr->data_len = data_len;
649	if (pkth.caplen > handle->snapshot)
650		pkth.caplen = handle->snapshot;
651
652	if (handle->fcode.bf_insns == NULL ||
653	    bpf_filter(handle->fcode.bf_insns, handle->buffer,
654	      pkth.len, pkth.caplen)) {
655		handlep->packets_read++;
656		callback(user, &pkth, handle->buffer);
657		return 1;
658	}
659	return 0;	/* didn't pass filter */
660}
661
662static int
663usb_inject_linux(pcap_t *handle, const void *buf, size_t size)
664{
665	snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
666		"USB devices");
667	return (-1);
668}
669
670static int
671usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
672{
673	struct pcap_usb_linux *handlep = handle->priv;
674	int dummy, ret, consumed, cnt;
675	char string[USB_LINE_LEN];
676	char token[USB_LINE_LEN];
677	char * ptr = string;
678	int fd;
679
680	snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handlep->bus_index);
681	fd = open(string, O_RDONLY, 0);
682	if (fd < 0)
683	{
684		if (errno == ENOENT)
685		{
686			/*
687			 * Not found at the new location; try the old
688			 * location.
689			 */
690			snprintf(string, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%ds", handlep->bus_index);
691			fd = open(string, O_RDONLY, 0);
692		}
693		if (fd < 0) {
694			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
695				"Can't open USB stats file %s: %s",
696				string, strerror(errno));
697			return -1;
698		}
699	}
700
701	/* read stats line */
702	do {
703		ret = read(fd, string, USB_LINE_LEN-1);
704	} while ((ret == -1) && (errno == EINTR));
705	close(fd);
706
707	if (ret < 0)
708	{
709		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
710			"Can't read stats from fd %d ", fd);
711		return -1;
712	}
713	string[ret] = 0;
714
715	/* extract info on dropped urbs */
716	for (consumed=0; consumed < ret; ) {
717		/* from the sscanf man page:
718 		 * The C standard says: "Execution of a %n directive does
719 		 * not increment the assignment count returned at the completion
720		 * of  execution" but the Corrigendum seems to contradict this.
721		 * Do not make any assumptions on the effect of %n conversions
722		 * on the return value and explicitly check for cnt assignmet*/
723		int ntok;
724
725		cnt = -1;
726		ntok = sscanf(ptr, "%s%n", token, &cnt);
727		if ((ntok < 1) || (cnt < 0))
728			break;
729		consumed += cnt;
730		ptr += cnt;
731		if (strcmp(token, "nreaders") == 0)
732			ret = sscanf(ptr, "%d", &stats->ps_drop);
733		else
734			ret = sscanf(ptr, "%d", &dummy);
735		if (ntok != 1)
736			break;
737		consumed += cnt;
738		ptr += cnt;
739	}
740
741	stats->ps_recv = handlep->packets_read;
742	stats->ps_ifdrop = 0;
743	return 0;
744}
745
746static int
747usb_setdirection_linux(pcap_t *p, pcap_direction_t d)
748{
749	p->direction = d;
750	return 0;
751}
752
753
754static int
755usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
756{
757	struct pcap_usb_linux *handlep = handle->priv;
758	int ret;
759	struct mon_bin_stats st;
760	ret = ioctl(handle->fd, MON_IOCG_STATS, &st);
761	if (ret < 0)
762	{
763		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
764			"Can't read stats from fd %d:%s ", handle->fd, strerror(errno));
765		return -1;
766	}
767
768	stats->ps_recv = handlep->packets_read + st.queued;
769	stats->ps_drop = st.dropped;
770	stats->ps_ifdrop = 0;
771	return 0;
772}
773
774/*
775 * see <linux-kernel-source>/Documentation/usb/usbmon.txt and
776 * <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
777 */
778static int
779usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
780{
781	struct pcap_usb_linux *handlep = handle->priv;
782	struct mon_bin_get info;
783	int ret;
784	struct pcap_pkthdr pkth;
785	int clen = handle->snapshot - sizeof(pcap_usb_header);
786
787	/* the usb header is going to be part of 'packet' data*/
788	info.hdr = (pcap_usb_header*) handle->buffer;
789	info.data = handle->buffer + sizeof(pcap_usb_header);
790	info.data_len = clen;
791
792	/* ignore interrupt system call errors */
793	do {
794		ret = ioctl(handle->fd, MON_IOCX_GET, &info);
795		if (handle->break_loop)
796		{
797			handle->break_loop = 0;
798			return -2;
799		}
800	} while ((ret == -1) && (errno == EINTR));
801	if (ret < 0)
802	{
803		if (errno == EAGAIN)
804			return 0;	/* no data there */
805
806		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
807		    "Can't read from fd %d: %s", handle->fd, strerror(errno));
808		return -1;
809	}
810
811	/* we can get less that than really captured from kernel, depending on
812	 * snaplen, so adjust header accordingly */
813	if (info.hdr->data_len < clen)
814		clen = info.hdr->data_len;
815	info.hdr->data_len = clen;
816	pkth.caplen = clen + sizeof(pcap_usb_header);
817	pkth.len = info.hdr->data_len + sizeof(pcap_usb_header);
818	pkth.ts.tv_sec = info.hdr->ts_sec;
819	pkth.ts.tv_usec = info.hdr->ts_usec;
820
821	if (handle->fcode.bf_insns == NULL ||
822	    bpf_filter(handle->fcode.bf_insns, handle->buffer,
823	      pkth.len, pkth.caplen)) {
824		handlep->packets_read++;
825		callback(user, &pkth, handle->buffer);
826		return 1;
827	}
828
829	return 0;	/* didn't pass filter */
830}
831
832/*
833 * see <linux-kernel-source>/Documentation/usb/usbmon.txt and
834 * <linux-kernel-source>/drivers/usb/mon/mon_bin.c binary ABI
835 */
836#define VEC_SIZE 32
837static int
838usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
839{
840	struct pcap_usb_linux *handlep = handle->priv;
841	struct mon_bin_mfetch fetch;
842	int32_t vec[VEC_SIZE];
843	struct pcap_pkthdr pkth;
844	pcap_usb_header* hdr;
845	int nflush = 0;
846	int packets = 0;
847	int clen, max_clen;
848
849	max_clen = handle->snapshot - sizeof(pcap_usb_header);
850
851	for (;;) {
852		int i, ret;
853		int limit = max_packets - packets;
854		if (limit <= 0)
855			limit = VEC_SIZE;
856		if (limit > VEC_SIZE)
857			limit = VEC_SIZE;
858
859		/* try to fetch as many events as possible*/
860		fetch.offvec = vec;
861		fetch.nfetch = limit;
862		fetch.nflush = nflush;
863		/* ignore interrupt system call errors */
864		do {
865			ret = ioctl(handle->fd, MON_IOCX_MFETCH, &fetch);
866			if (handle->break_loop)
867			{
868				handle->break_loop = 0;
869				return -2;
870			}
871		} while ((ret == -1) && (errno == EINTR));
872		if (ret < 0)
873		{
874			if (errno == EAGAIN)
875				return 0;	/* no data there */
876
877			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
878			    "Can't mfetch fd %d: %s", handle->fd, strerror(errno));
879			return -1;
880		}
881
882		/* keep track of processed events, we will flush them later */
883		nflush = fetch.nfetch;
884		for (i=0; i<fetch.nfetch; ++i) {
885			/* discard filler */
886			hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]];
887			if (hdr->event_type == '@')
888				continue;
889
890			/* we can get less that than really captured from kernel, depending on
891	 		* snaplen, so adjust header accordingly */
892			clen = max_clen;
893			if (hdr->data_len < clen)
894				clen = hdr->data_len;
895
896			/* get packet info from header*/
897			pkth.caplen = clen + sizeof(pcap_usb_header_mmapped);
898			pkth.len = hdr->data_len + sizeof(pcap_usb_header_mmapped);
899			pkth.ts.tv_sec = hdr->ts_sec;
900			pkth.ts.tv_usec = hdr->ts_usec;
901
902			if (handle->fcode.bf_insns == NULL ||
903			    bpf_filter(handle->fcode.bf_insns, (u_char*) hdr,
904			      pkth.len, pkth.caplen)) {
905				handlep->packets_read++;
906				callback(user, &pkth, (u_char*) hdr);
907				packets++;
908			}
909		}
910
911		/* with max_packets specifying "unlimited" we stop afer the first chunk*/
912		if (PACKET_COUNT_IS_UNLIMITED(max_packets) || (packets == max_packets))
913			break;
914	}
915
916	/* flush pending events*/
917	ioctl(handle->fd, MON_IOCH_MFLUSH, nflush);
918	return packets;
919}
920
921static void
922usb_cleanup_linux_mmap(pcap_t* handle)
923{
924	struct pcap_usb_linux *handlep = handle->priv;
925
926	/* if we have a memory-mapped buffer, unmap it */
927	if (handlep->mmapbuf != NULL) {
928		munmap(handlep->mmapbuf, handlep->mmapbuflen);
929		handlep->mmapbuf = NULL;
930	}
931	pcap_cleanup_live_common(handle);
932}
933