Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 May 2012 15:18:00 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r235003 - stable/9/usr.sbin/usbdump
Message-ID:  <201205041518.q44FI0Px009658@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Fri May  4 15:18:00 2012
New Revision: 235003
URL: http://svn.freebsd.org/changeset/base/235003

Log:
  MFC r234636 and r234655:
  Improve support for USB packet filtering also when reading dumps, and
  allow filtered data to be dumped to a binary file.
  
  Add missing and probably also mandatory -h option.

Modified:
  stable/9/usr.sbin/usbdump/usbdump.8
  stable/9/usr.sbin/usbdump/usbdump.c
Directory Properties:
  stable/9/usr.sbin/usbdump/   (props changed)

Modified: stable/9/usr.sbin/usbdump/usbdump.8
==============================================================================
--- stable/9/usr.sbin/usbdump/usbdump.8	Fri May  4 15:13:25 2012	(r235002)
+++ stable/9/usr.sbin/usbdump/usbdump.8	Fri May  4 15:18:00 2012	(r235003)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 16, 2012
+.Dd April 24, 2012
 .Dt USBDUMP 8
 .Os
 .Sh NAME
@@ -39,6 +39,8 @@
 .Op Fl v
 .Op Fl w Ar file
 .Op Fl f Ar filter
+.Op Fl b Ar file
+.Op Fl h
 .Sh DESCRIPTION
 The
 .Nm
@@ -46,12 +48,17 @@ utility provides a way to dump USB packe
 .Pp
 The following options are accepted:
 .Bl -tag -width ".Fl f Ar file"
+.It Fl b Ar file
+Store data part of the USB trace in binary format to the given
+.Ar file .
+This option also works with the -r and -f options.
 .It Fl i Ar ifname
 Listen on USB bus interface
 .Ar ifname .
 .It Fl r Ar file
 Read the raw packets from
 .Ar file .
+This option also works with the -f option.
 .It Fl s Ar snaplen
 Snapshot
 .Ar snaplen
@@ -62,6 +69,7 @@ When defined multiple times the verbosit
 .It Fl w Ar file
 Write the raw packets to
 .Ar file .
+This option also works with the -s and -v options.
 .It Fl f Ar filter
 The filter argument consists of either one or two numbers separated by a dot.
 The first indicates the device unit number which should be traced.
@@ -72,6 +80,8 @@ If 128 is added to the endpoint number t
 A device unit or endpoint value of -1 means ignore this field.
 If no filters are specified, all packets are passed through using the default -1,-1 filter.
 This option can be specified multiple times.
+.It Fl h
+This option displays a summary of the command line options.
 .El
 .Sh EXAMPLES
 Capture the USB raw packets on usbus2:

Modified: stable/9/usr.sbin/usbdump/usbdump.c
==============================================================================
--- stable/9/usr.sbin/usbdump/usbdump.c	Fri May  4 15:13:25 2012	(r235002)
+++ stable/9/usr.sbin/usbdump/usbdump.c	Fri May  4 15:18:00 2012	(r235003)
@@ -82,6 +82,8 @@ struct usbcap {
 	int		wfd;
 	/* for -r option */
 	int		rfd;
+	/* for -b option */
+	int		bfd;
 };
 
 struct usbcap_filehdr {
@@ -112,6 +114,8 @@ static int uf_minor;
 static const char *i_arg = "usbus0";
 static const char *r_arg = NULL;
 static const char *w_arg = NULL;
+static const char *b_arg = NULL;
+static struct usbcap uc;
 static const char *errstr_table[USB_ERR_MAX] = {
 	[USB_ERR_NORMAL_COMPLETION]	= "0",
 	[USB_ERR_PENDING_REQUESTS]	= "PENDING_REQUESTS",
@@ -255,6 +259,22 @@ done:
 	pprog->bf_insns = dynamic_insn;
 }
 
+static int
+match_filter(int unit, int endpoint)
+{
+	struct usb_filt *puf;
+
+	if (STAILQ_FIRST(&usb_filt_head) == NULL)
+		return (1);
+
+	STAILQ_FOREACH(puf, &usb_filt_head, entry) {
+		if ((puf->unit == -1 || puf->unit == unit) &&
+		    (puf->endpoint == -1 || puf->endpoint == endpoint))
+			return (1);
+	}
+	return (0);
+}
+
 static void
 free_filter(struct bpf_program *pprog)
 {
@@ -462,28 +482,33 @@ print_apacket(const struct header_32 *hd
 	up->up_packet_count = le32toh(up->up_packet_count);
 	up->up_endpoint = le32toh(up->up_endpoint);
 
+	if (!match_filter(up->up_address, up->up_endpoint))
+		return;
+
 	tv.tv_sec = hdr->ts_sec;
 	tv.tv_usec = hdr->ts_usec;
 	tm = localtime(&tv.tv_sec);
 
 	len = strftime(buf, sizeof(buf), "%H:%M:%S", tm);
 
-	printf("%.*s.%06ld usbus%d.%d %s-%s-EP=%08x,SPD=%s,NFR=%d,SLEN=%d,IVAL=%d%s%s\n",
-	    (int)len, buf, tv.tv_usec,
-	    (int)up->up_busunit, (int)up->up_address,
-	    (up->up_type == USBPF_XFERTAP_SUBMIT) ? "SUBM" : "DONE",
-	    xfertype_table[up->up_xfertype],
-	    (unsigned int)up->up_endpoint,
-	    usb_speedstr(up->up_speed),
-	    (int)up->up_frames,
-	    (int)(up->up_totlen - USBPF_HDR_LEN -
-	    (USBPF_FRAME_HDR_LEN * up->up_frames)),
-	    (int)up->up_interval,
-	    (up->up_type == USBPF_XFERTAP_DONE) ? ",ERR=" : "",
-	    (up->up_type == USBPF_XFERTAP_DONE) ?
-	    usb_errstr(up->up_error) : "");
+	if (verbose >= 0) {
+		printf("%.*s.%06ld usbus%d.%d %s-%s-EP=%08x,SPD=%s,NFR=%d,SLEN=%d,IVAL=%d%s%s\n",
+		    (int)len, buf, tv.tv_usec,
+		    (int)up->up_busunit, (int)up->up_address,
+		    (up->up_type == USBPF_XFERTAP_SUBMIT) ? "SUBM" : "DONE",
+		    xfertype_table[up->up_xfertype],
+		    (unsigned int)up->up_endpoint,
+		    usb_speedstr(up->up_speed),
+		    (int)up->up_frames,
+		    (int)(up->up_totlen - USBPF_HDR_LEN -
+		    (USBPF_FRAME_HDR_LEN * up->up_frames)),
+		    (int)up->up_interval,
+		    (up->up_type == USBPF_XFERTAP_DONE) ? ",ERR=" : "",
+		    (up->up_type == USBPF_XFERTAP_DONE) ?
+		    usb_errstr(up->up_error) : "");
+	}
 
-	if (verbose >= 1) {
+	if (verbose >= 1 || b_arg != NULL) {
 		for (x = 0; x != up->up_frames; x++) {
 			const struct usbpf_framehdr *uf;
 			uint32_t framelen;
@@ -498,10 +523,12 @@ print_apacket(const struct header_32 *hd
 			framelen = le32toh(uf->length);
 			flags = le32toh(uf->flags);
 
-			printf(" frame[%u] %s %d bytes\n",
-			    (unsigned int)x,
-			    (flags & USBPF_FRAMEFLAG_READ) ? "READ" : "WRITE",
-			    (int)framelen);
+			if (verbose >= 1) {
+				printf(" frame[%u] %s %d bytes\n",
+				    (unsigned int)x,
+				    (flags & USBPF_FRAMEFLAG_READ) ? "READ" : "WRITE",
+				    (int)framelen);
+			}
 
 			if (flags & USBPF_FRAMEFLAG_DATA_FOLLOWS) {
 
@@ -515,7 +542,15 @@ print_apacket(const struct header_32 *hd
 				    (int)framelen < 0 || (int)ptr_len < 0)
 					break;
 
-				hexdump(ptr, framelen);
+				if (b_arg != NULL) {
+					struct usbcap *p = &uc;
+					int ret;
+					ret = write(p->bfd, ptr, framelen);
+					if (ret != (int)framelen)
+						err(EXIT_FAILURE, "Could not write binary data");
+				}
+				if (verbose >= 1)
+					hexdump(ptr, framelen);
 
 				ptr += tot_frame_len;
 			}
@@ -592,7 +627,7 @@ print_packets(uint8_t *data, const int d
 		if (next <= ptr)
 			err(EXIT_FAILURE, "Invalid length");
 
-		if (w_arg == NULL || r_arg != NULL) {
+		if (verbose >= 0 || r_arg != NULL || b_arg != NULL) {
 			print_apacket(&temp, ptr +
 			    temp.hdrlen, temp.caplen);
 		}
@@ -738,7 +773,9 @@ usage(void)
 	fprintf(stderr, FMT, "-r <file>", "Read the raw packets from file");
 	fprintf(stderr, FMT, "-s <snaplen>", "Snapshot bytes from each packet");
 	fprintf(stderr, FMT, "-v", "Increase the verbose level");
+	fprintf(stderr, FMT, "-b <file>", "Save raw version of all recorded data to file");
 	fprintf(stderr, FMT, "-w <file>", "Write the raw packets to file");
+	fprintf(stderr, FMT, "-h", "Display summary of command line options");
 #undef FMT
 	exit(EX_USAGE);
 }
@@ -750,7 +787,7 @@ main(int argc, char *argv[])
 	struct bpf_program total_prog;
 	struct bpf_stat us;
 	struct bpf_version bv;
-	struct usbcap uc, *p = &uc;
+	struct usbcap *p = &uc;
 	struct ifreq ifr;
 	long snapshot = 192;
 	uint32_t v;
@@ -761,9 +798,7 @@ main(int argc, char *argv[])
 	const char *optstring;
 	char *pp;
 
-	memset(&uc, 0, sizeof(struct usbcap));
-
-	optstring = "i:r:s:vw:f:";
+	optstring = "b:hi:r:s:vw:f:";
 	while ((o = getopt(argc, argv, optstring)) != -1) {
 		switch (o) {
 		case 'i':
@@ -784,6 +819,9 @@ main(int argc, char *argv[])
 			if (snapshot == 0)
 				snapshot = -1;
 			break;
+		case 'b':
+			b_arg = optarg;
+			break;
 		case 'v':
 			verbose++;
 			break;
@@ -811,6 +849,22 @@ main(int argc, char *argv[])
 		}
 	}
 
+	if (b_arg != NULL) {
+		p->bfd = open(b_arg, O_CREAT | O_TRUNC |
+		    O_WRONLY, S_IRUSR | S_IWUSR);
+		if (p->bfd < 0) {
+			err(EXIT_FAILURE, "Could not open "
+			    "'%s' for write", b_arg);
+		}
+	}
+
+	/*
+	 * Require more verbosity to print anything when -w or -b is
+	 * specified on the command line:
+	 */
+	if (w_arg != NULL || b_arg != NULL)
+		verbose--;
+
 	if (r_arg != NULL) {
 		read_file(p);
 		exit(EXIT_SUCCESS);
@@ -882,6 +936,8 @@ main(int argc, char *argv[])
 		close(p->rfd);
 	if (p->wfd > 0)
 		close(p->wfd);
+	if (p->bfd > 0)
+		close(p->bfd);
 
 	return (EXIT_SUCCESS);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205041518.q44FI0Px009658>