From Márton Németh:

Clean up the Linux USB pseudoheader dissection.

svn path=/trunk/; revision=25990
This commit is contained in:
Anders Broman 2008-08-12 20:24:50 +00:00
parent a7e6165f15
commit c1e67bc6d0
2 changed files with 420 additions and 57 deletions

View File

@ -40,14 +40,20 @@
/* protocols and header fields */
static int proto_usb = -1;
/* Linux USB pseudoheader fields */
static int hf_usb_urb_id = -1;
static int hf_usb_bus_id = -1;
static int hf_usb_transfer_type = -1;
static int hf_usb_urb_type = -1;
static int hf_usb_device_address = -1;
static int hf_usb_data_flag = -1;
static int hf_usb_setup_flag = -1;
static int hf_usb_transfer_type = -1;
static int hf_usb_endpoint_number = -1;
static int hf_usb_device_address = -1;
static int hf_usb_bus_id = -1;
static int hf_usb_setup_flag = -1;
static int hf_usb_data_flag = -1;
static int hf_usb_urb_status = -1;
static int hf_usb_urb_len = -1;
static int hf_usb_data_len = -1;
static int hf_usb_src_endpoint_number = -1;
static int hf_usb_dst_endpoint_number = -1;
static int hf_usb_request = -1;
@ -232,6 +238,282 @@ static const value_string usb_bmAttributes_behaviour_vals[] = {
{0,NULL}
};
/* from linux/include/asm-generic/errno.h */
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
/* from linux/include/asm-generic/errno.h*/
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ECANCELED 125 /* Operation Canceled */
#define ENOKEY 126 /* Required key not available */
#define EKEYEXPIRED 127 /* Key has expired */
#define EKEYREVOKED 128 /* Key has been revoked */
#define EKEYREJECTED 129 /* Key was rejected by service */
/* for robust mutexes */
#define EOWNERDEAD 130 /* Owner died */
#define ENOTRECOVERABLE 131 /* State not recoverable */
static const value_string usb_urb_status_vals[] = {
{ 0, "Success"},
{ -EPERM, "Operation not permitted (-EPERM)" },
{ -ENOENT, "No such file or directory (-ENOENT)" },
{ -ESRCH, "No such process (-ESRCH)" },
{ -EINTR, "Interrupted system call (-EINTR)" },
{ -EIO, "I/O error (-EIO)" },
{ -ENXIO, "No such device or address (-ENXIO)" },
{ -E2BIG, "Argument list too long (-E2BIG)" },
{ -ENOEXEC, "Exec format error (-ENOEXEC)" },
{ -EBADF, "Bad file number (-EBADF)" },
{ -ECHILD, "No child processes (-ECHILD)" },
{ -EAGAIN, "Try again (-EAGAIN)" },
{ -ENOMEM, "Out of memory (-ENOMEM)" },
{ -EACCES, "Permission denied (-EACCES)" },
{ -EFAULT, "Bad address (-EFAULT)" },
{ -ENOTBLK, "Block device required (-ENOTBLK)" },
{ -EBUSY, "Device or resource busy (-EBUSY)" },
{ -EEXIST, "File exists (-EEXIST)" },
{ -EXDEV, "Cross-device link (-EXDEV)" },
{ -ENODEV, "No such device (-ENODEV)" },
{ -ENOTDIR, "Not a directory (-ENOTDIR)" },
{ -EISDIR, "Is a directory (-EISDIR)" },
{ -EINVAL, "Invalid argument (-EINVAL)" },
{ -ENFILE, "File table overflow (-ENFILE)" },
{ -EMFILE, "Too many open files (-EMFILE)" },
{ -ENOTTY, "Not a typewriter (-ENOTTY)" },
{ -ETXTBSY, "Text file busy (-ETXTBSY)" },
{ -EFBIG, "File too large (-EFBIG)" },
{ -ENOSPC, "No space left on device (-ENOSPC)" },
{ -ESPIPE, "Illegal seek (-ESPIPE)" },
{ -EROFS, "Read-only file system (-EROFS)" },
{ -EMLINK, "Too many links (-EMLINK)" },
{ -EPIPE, "Broken pipe (-EPIPE)" },
{ -EDOM, "Math argument out of domain of func (-EDOM)" },
{ -ERANGE, "Math result not representable (-ERANGE)" },
{ -EDEADLK, "Resource deadlock would occur (-EDEADLK)" },
{ -ENAMETOOLONG, "File name too long (-ENAMETOOLONG)" },
{ -ENOLCK, "No record locks available (-ENOLCK)" },
{ -ENOSYS, "Function not implemented (-ENOSYS)" },
{ -ENOTEMPTY, "Directory not empty (-ENOTEMPTY)" },
{ -ELOOP, "Too many symbolic links encountered (-ELOOP)" },
{ -ENOMSG, "No message of desired type (-ENOMSG)" },
{ -EIDRM, "Identifier removed (-EIDRM)" },
{ -ECHRNG, "Channel number out of range (-ECHRNG)" },
{ -EL2NSYNC, "Level 2 not synchronized (-EL2NSYNC)" },
{ -EL3HLT, "Level 3 halted (-EL3HLT)" },
{ -EL3RST, "Level 3 reset (-EL3RST)" },
{ -ELNRNG, "Link number out of range (-ELNRNG)" },
{ -EUNATCH, "Protocol driver not attached (-EUNATCH)" },
{ -ENOCSI, "No CSI structure available (-ENOCSI)" },
{ -EL2HLT, "Level 2 halted (-EL2HLT)" },
{ -EBADE, "Invalid exchange (-EBADE)" },
{ -EBADR, "Invalid request descriptor (-EBADR)" },
{ -EXFULL, "Exchange full (-EXFULL)" },
{ -ENOANO, "No anode (-ENOANO)" },
{ -EBADRQC, "Invalid request code (-EBADRQC)" },
{ -EBADSLT, "Invalid slot (-EBADSLT)" },
{ -EBFONT, "Bad font file format (-EBFONT)" },
{ -ENOSTR, "Device not a stream (-ENOSTR)" },
{ -ENODATA, "No data available (-ENODATA)" },
{ -ETIME, "Timer expired (-ETIME)" },
{ -ENOSR, "Out of streams resources (-ENOSR)" },
{ -ENONET, "Machine is not on the network (-ENONET)" },
{ -ENOPKG, "Package not installed (-ENOPKG)" },
{ -EREMOTE, "Object is remote (-EREMOTE)" },
{ -ENOLINK, "Link has been severed (-ENOLINK)" },
{ -EADV, "Advertise error (-EADV)" },
{ -ESRMNT, "Srmount error (-ESRMNT)" },
{ -ECOMM, "Communication error on send (-ECOMM)" },
{ -EPROTO, "Protocol error (-EPROTO)" },
{ -EMULTIHOP, "Multihop attempted (-EMULTIHOP)" },
{ -EDOTDOT, "RFS specific error (-EDOTDOT)" },
{ -EBADMSG, "Not a data message (-EBADMSG)" },
{ -EOVERFLOW, "Value too large for defined data type (-EOVERFLOW)" },
{ -ENOTUNIQ, "Name not unique on network (-ENOTUNIQ)" },
{ -EBADFD, "File descriptor in bad state (-EBADFD)" },
{ -EREMCHG, "Remote address changed (-EREMCHG)" },
{ -ELIBACC, "Can not access a needed shared library (-ELIBACC)" },
{ -ELIBBAD, "Accessing a corrupted shared library (-ELIBBAD)" },
{ -ELIBSCN, ".lib section in a.out corrupted (-ELIBSCN)" },
{ -ELIBMAX, "Attempting to link in too many shared libraries (-ELIBMAX)" },
{ -ELIBEXEC, "Cannot exec a shared library directly (-ELIBEXEC)" },
{ -EILSEQ, "Illegal byte sequence (-EILSEQ)" },
{ -ERESTART, "Interrupted system call should be restarted (-ERESTART)" },
{ -ESTRPIPE, "Streams pipe error (-ESTRPIPE)" },
{ -EUSERS, "Too many users (-EUSERS)" },
{ -ENOTSOCK, "Socket operation on non-socket (-ENOTSOCK)" },
{ -EDESTADDRREQ, "Destination address required (-EDESTADDRREQ)" },
{ -EMSGSIZE, "Message too long (-EMSGSIZE)" },
{ -EPROTOTYPE, "Protocol wrong type for socket (-EPROTOTYPE)" },
{ -ENOPROTOOPT, "Protocol not available (-ENOPROTOOPT)" },
{ -EPROTONOSUPPORT, "Protocol not supported (-EPROTONOSUPPORT)" },
{ -ESOCKTNOSUPPORT, "Socket type not supported (-ESOCKTNOSUPPORT)" },
{ -EOPNOTSUPP, "Operation not supported on transport endpoint (-EOPNOTSUPP)" },
{ -EPFNOSUPPORT, "Protocol family not supported (-EPFNOSUPPORT)" },
{ -EAFNOSUPPORT, "Address family not supported by protocol (-EAFNOSUPPORT)" },
{ -EADDRINUSE, "Address already in use (-EADDRINUSE)" },
{ -EADDRNOTAVAIL, "Cannot assign requested address (-EADDRNOTAVAIL)" },
{ -ENETDOWN, "Network is down (-ENETDOWN)" },
{ -ENETUNREACH, "Network is unreachable (-ENETUNREACH)" },
{ -ENETRESET, "Network dropped connection because of reset (-ENETRESET)" },
{ -ECONNABORTED, "Software caused connection abort (-ECONNABORTED)" },
{ -ECONNRESET, "Connection reset by peer (-ECONNRESET)" },
{ -ENOBUFS, "No buffer space available (-ENOBUFS)" },
{ -EISCONN, "Transport endpoint is already connected (-EISCONN)" },
{ -ENOTCONN, "Transport endpoint is not connected (-ENOTCONN)" },
{ -ESHUTDOWN, "Cannot send after transport endpoint shutdown (-ESHUTDOWN)" },
{ -ETOOMANYREFS, "Too many references: cannot splice (-ETOOMANYREFS)" },
{ -ETIMEDOUT, "Connection timed out (-ETIMEDOUT)" },
{ -ECONNREFUSED, "Connection refused (-ECONNREFUSED)" },
{ -EHOSTDOWN, "Host is down (-EHOSTDOWN)" },
{ -EHOSTUNREACH, "No route to host (-EHOSTUNREACH)" },
{ -EALREADY, "Operation already in progress (-EALREADY)" },
{ -EINPROGRESS, "Operation now in progress (-EINPROGRESS)" },
{ -ESTALE, "Stale NFS file handle (-ESTALE)" },
{ -EUCLEAN, "Structure needs cleaning (-EUCLEAN)" },
{ -ENOTNAM, "Not a XENIX named type file (-ENOTNAM)" },
{ -ENAVAIL, "No XENIX semaphores available (-ENAVAIL)" },
{ -EISNAM, "Is a named type file (-EISNAM)" },
{ -EREMOTEIO, "Remote I/O error (-EREMOTEIO)" },
{ -EDQUOT, "Quota exceeded (-EDQUOT)" },
{ -ENOMEDIUM, "No medium found (-ENOMEDIUM)" },
{ -EMEDIUMTYPE, "Wrong medium type (-EMEDIUMTYPE)" },
{ -ECANCELED, "Operation Canceled (-ECANCELED)" },
{ -ENOKEY, "Required key not available (-ENOKEY)" },
{ -EKEYEXPIRED, "Key has expired (-EKEYEXPIRED)" },
{ -EKEYREVOKED, "Key has been revoked (-EKEYREVOKED)" },
{ -EKEYREJECTED, "Key was rejected by service (-EKEYREJECTED)" },
{ -EOWNERDEAD, "Owner died (-EOWNERDEAD)" },
{ -ENOTRECOVERABLE, "State not recoverable (-ENOTRECOVERABLE)" },
{ 0, NULL }
};
static usb_conv_info_t *
get_usb_conv_info(conversation_t *conversation)
@ -911,9 +1193,90 @@ dissect_usb_bmrequesttype(proto_tree *parent_tree, tvbuff_t *tvb, int offset,
return offset;
}
static void
dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 transfer_type;
const gchar* val_str;
proto_tree_add_uint64(tree, hf_usb_urb_id, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.id);
/* show the event type of this URB as string and as a character */
val_str = val_to_str(pinfo->pseudo_header->linux_usb.event_type,
usb_urb_type_vals, "Unknown %d");
proto_tree_add_string_format_value(tree, hf_usb_urb_type, tvb, 0, 0,
&(pinfo->pseudo_header->linux_usb.event_type),
"%s ('%c')", val_str,
pinfo->pseudo_header->linux_usb.event_type);
transfer_type = pinfo->pseudo_header->linux_usb.transfer_type;
proto_tree_add_uint(tree, hf_usb_transfer_type, tvb, 0, 0, transfer_type);
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_str(pinfo->cinfo, COL_INFO,
val_to_str(transfer_type, usb_transfer_type_vals, "Unknown type %x"));
}
proto_tree_add_uint(tree, hf_usb_endpoint_number, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.endpoint_number);
proto_tree_add_uint(tree, hf_usb_device_address, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.device_address);
proto_tree_add_uint(tree, hf_usb_bus_id, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.bus_id);
/* Right after the pseudo header we always have
* sizeof(struct usb_device_setup_hdr)=8 bytes. The content of these
* bytes have only meaning in case setup_flag == 0.
*/
if (pinfo->pseudo_header->linux_usb.setup_flag == 0) {
proto_tree_add_string_format_value(tree, hf_usb_setup_flag, tvb,
0, sizeof(struct usb_device_setup_hdr),
&(pinfo->pseudo_header->linux_usb.setup_flag),
"present (%d)",
pinfo->pseudo_header->linux_usb.setup_flag);
} else {
proto_tree_add_string_format_value(tree, hf_usb_setup_flag, tvb,
0, sizeof(struct usb_device_setup_hdr),
&(pinfo->pseudo_header->linux_usb.setup_flag),
"not present ('%c')",
pinfo->pseudo_header->linux_usb.setup_flag);
}
if (pinfo->pseudo_header->linux_usb.data_flag == 0) {
proto_tree_add_string_format_value(tree, hf_usb_data_flag, tvb,
sizeof(struct usb_device_setup_hdr), -1,
&(pinfo->pseudo_header->linux_usb.data_flag),
"present (%d)",
pinfo->pseudo_header->linux_usb.data_flag);
} else {
proto_tree_add_string_format_value(tree, hf_usb_data_flag, tvb,
sizeof(struct usb_device_setup_hdr), -1,
&(pinfo->pseudo_header->linux_usb.data_flag),
"not present ('%c')",
pinfo->pseudo_header->linux_usb.data_flag);
}
/* Timestamp was already processed by libpcap,
* skip it for now:
* pinfo->pseudo_header->linux_usb.ts_sec
* pinfo->pseudo_header->linux_usb.ts_usec
*/
proto_tree_add_int(tree, hf_usb_urb_status, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.status);
proto_tree_add_uint(tree, hf_usb_urb_len, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.urb_len);
proto_tree_add_uint(tree, hf_usb_data_len, tvb,
sizeof(struct usb_device_setup_hdr),
pinfo->pseudo_header->linux_usb.data_len,
pinfo->pseudo_header->linux_usb.data_len);
}
static void
dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
@ -937,43 +1300,22 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
/* add usb hdr*/
if (parent) {
proto_item *ti = NULL;
ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0, sizeof(struct usb_request_hdr), "USB URB");
ti = proto_tree_add_protocol_format(parent, proto_usb, tvb, 0, sizeof(struct usb_device_setup_hdr), "USB URB");
tree = proto_item_add_subtree(ti, usb_hdr);
}
proto_tree_add_uint64(tree, hf_usb_urb_id, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.id);
proto_tree_add_uint(tree, hf_usb_urb_type, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.event_type);
dissect_linux_usb_pseudo_header(tvb, pinfo, tree);
type = pinfo->pseudo_header->linux_usb.transfer_type;
proto_tree_add_uint(tree, hf_usb_transfer_type, tvb, 0, 0, type);
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_str(pinfo->cinfo, COL_INFO,
val_to_str(type, usb_transfer_type_vals, "Unknown type %x"));
}
#if 0
/* The direction flag is broken so we must strip it off */
endpoint=pinfo->pseudo_header->linux_usb.endpoint_number;
#else
endpoint=pinfo->pseudo_header->linux_usb.endpoint_number&(~URB_TRANSFER_IN);
#endif
proto_tree_add_uint(tree, hf_usb_endpoint_number, tvb, 0, 0, endpoint);
tmp_addr=pinfo->pseudo_header->linux_usb.device_address;
proto_tree_add_uint(tree, hf_usb_device_address, tvb, 0, 0, tmp_addr);
proto_tree_add_uint(tree, hf_usb_bus_id, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.bus_id);
setup_flag = pinfo->pseudo_header->linux_usb.setup_flag;
proto_tree_add_uint(tree, hf_usb_setup_flag, tvb, 0, 0, setup_flag);
proto_tree_add_uint(tree, hf_usb_data_flag, tvb, 0, 0,
pinfo->pseudo_header->linux_usb.data_flag);
#if 0
/* this is how it is supposed to work but this flag seems to be broken -- ronnie */
@ -1156,7 +1498,7 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
tvbuff_t *next_tvb;
/* this is a request */
ti = proto_tree_add_protocol_format(tree, proto_usb, tvb, offset, sizeof(struct usb_request_hdr), "URB setup");
ti = proto_tree_add_protocol_format(tree, proto_usb, tvb, offset, sizeof(struct usb_device_setup_hdr), "URB setup");
setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
usb_trans_info->requesttype=tvb_get_guint8(tvb, offset);
offset=dissect_usb_bmrequesttype(setup_tree, tvb, offset, &type);
@ -1259,7 +1601,7 @@ dissect_linux_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent)
guint8 requesttype, request;
int type;
ti = proto_tree_add_protocol_format(tree, proto_usb, tvb, offset, sizeof(struct usb_request_hdr), "URB setup");
ti = proto_tree_add_protocol_format(tree, proto_usb, tvb, offset, sizeof(struct usb_device_setup_hdr), "URB setup");
setup_tree = proto_item_add_subtree(ti, usb_setup_hdr);
@ -1290,19 +1632,15 @@ proto_register_usb(void)
{
static hf_register_info hf[] = {
/* USB packet pseudoheader members */
{ &hf_usb_urb_id,
{ "URB id", "usb.urb_id", FT_UINT64, BASE_DEC,
{ "URB id", "usb.urb_id", FT_UINT64, BASE_HEX,
NULL, 0x0,
"URB id", HFILL }},
{ &hf_usb_bus_id,
{ "URB bus id", "usb.bus_id", FT_UINT16, BASE_DEC,
NULL, 0x0,
"URB bus id", HFILL }},
{ &hf_usb_urb_type,
{ "URB type", "usb.urb_type", FT_UINT8, BASE_DEC,
VALS(usb_urb_type_vals), 0x0,
{ "URB type", "usb.urb_type", FT_STRING, BASE_NONE,
NULL, 0x0,
"URB type", HFILL }},
{ &hf_usb_transfer_type,
@ -1310,22 +1648,43 @@ proto_register_usb(void)
VALS(usb_transfer_type_vals), 0x0,
"URB transfer type", HFILL }},
{ &hf_usb_device_address,
{ "Device", "usb.device_address", FT_UINT8, BASE_DEC, NULL, 0x0,
"USB device address", HFILL }},
{ &hf_usb_data_flag,
{ "Data flag", "usb.data_flag", FT_UINT8, BASE_DEC, NULL, 0x0,
"USB data flag", HFILL }},
{ &hf_usb_setup_flag,
{ "Setup flag", "usb.setup_flag", FT_UINT8, BASE_DEC, NULL, 0x0,
"USB setup flag", HFILL }},
{ &hf_usb_endpoint_number,
{ "Endpoint", "usb.endpoint_number", FT_UINT8, BASE_HEX, NULL, 0x0,
"USB endpoint number", HFILL }},
{ &hf_usb_device_address,
{ "Device", "usb.device_address", FT_UINT8, BASE_DEC, NULL, 0x0,
"USB device address", HFILL }},
{ &hf_usb_bus_id,
{ "URB bus id", "usb.bus_id", FT_UINT16, BASE_DEC,
NULL, 0x0,
"URB bus id", HFILL }},
{ &hf_usb_setup_flag,
{ "Device setup request", "usb.setup_flag", FT_STRING, BASE_NONE,
NULL, 0x0,
"USB device setup request is present (0) or not", HFILL }},
{ &hf_usb_data_flag,
{ "Data", "usb.data_flag", FT_STRING, BASE_NONE,
NULL, 0x0,
"USB data is present (0) or not", HFILL }},
{ &hf_usb_urb_status,
{ "URB status", "usb.urb_status", FT_INT32, BASE_DEC,
VALS(usb_urb_status_vals), 0x0,
"URB status", HFILL }},
{ &hf_usb_urb_len,
{ "URB length [bytes]", "usb.urb_len", FT_UINT32, BASE_DEC, NULL, 0x0,
"URB length in bytes", HFILL }},
{ &hf_usb_data_len,
{ "Data length [bytes]", "usb.data_len", FT_UINT32, BASE_DEC, NULL, 0x0,
"URB data length in bytes", HFILL }},
/* Generated values */
{ &hf_usb_src_endpoint_number,
{ "Src Endpoint", "usb.src.endpoint", FT_UINT8, BASE_HEX, NULL, 0x0,
"Source USB endpoint number", HFILL }},
@ -1334,6 +1693,7 @@ proto_register_usb(void)
{ "Dst Endpoint", "usb.dst.endpoint", FT_UINT8, BASE_HEX, NULL, 0x0,
"Destination USB endpoint number", HFILL }},
/* Fields from usb20.pdf, Table 9-2 'Format of Setup Data' */
{ &hf_usb_bmRequestType,
{ "bmRequestType", "usb.bmRequestType", FT_UINT8, BASE_HEX, NULL, 0x0,
"", HFILL }},
@ -1354,6 +1714,7 @@ proto_register_usb(void)
{ "wLength", "usb.setup.wLength", FT_UINT16, BASE_DEC, NULL, 0x0,
"", HFILL }},
/* --------------------------------- */
{ &hf_usb_data,
{"Application Data", "usb.data",
FT_BYTES, BASE_HEX, NULL, 0x0,

View File

@ -593,8 +593,9 @@ struct catapult_dct2000_phdr
/*
* USB setup header as defined in USB specification
* See usb_20.pdf, Chapter 9.3 'USB Device Requests' for details.
*/
struct usb_request_hdr {
struct usb_device_setup_hdr {
gint8 bmRequestType;
guint8 bRequest;
guint16 wValue;
@ -604,26 +605,27 @@ struct usb_request_hdr {
/*
* Header prepended by Linux kernel to each USB event.
* Followed by a struct usb_request_hdr, although that header is valid
* Followed by a struct usb_device_setup_hdr, although that header is valid
* only if setup_flag is 0.
* (Setup flag is '-', 'D', 'Z', or 0. Data flag is '<', '>', 'Z', or 0.)
* See linux/Documentation/usb/usbmon.txt and libpcap/pcap/usb.h for details.
*
* We present this as a pseudo-header; the values are in host byte order.
*/
struct linux_usb_phdr {
guint64 id; /* urb id, to link submission and completion events*/
guint8 event_type; /* Submit ('S'), Completed ('C'), Error ('E') */
guint64 id; /* urb id, to link submission and completion events */
guint8 event_type; /* Submit ('S'), Completed ('C'), Error ('E') */
guint8 transfer_type; /* ISO (0), Intr, Control, Bulk (3) */
guint8 endpoint_number; /* Endpoint number (0-15) and transfer direction */
guint8 device_address; /* 0-127 */
guint16 bus_id;
gint8 setup_flag; /*if !=0 the urb setup header is not present*/
gint8 data_flag; /*if !=0 no urb data is present*/
gint8 setup_flag; /* 0, if the urb setup header is present */
gint8 data_flag; /* 0, if urb data is present */
gint64 ts_sec;
gint32 ts_usec;
gint32 status;
guint32 urb_len; /* whole len of urb this event refers to */
guint32 data_len; /* amount of urb data really present in this event*/
guint32 data_len; /* amount of urb data really present in this event */
};
/*