diff options
author | Anders Broman <anders.broman@ericsson.com> | 2008-08-12 20:24:50 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2008-08-12 20:24:50 +0000 |
commit | c1e67bc6d00ea35f3956c60340b26c76df3ac3ff (patch) | |
tree | 49065d5cd274bed90662d699f5bc0439af327677 | |
parent | a7e6165f151c21e68090999b539f0d2751190134 (diff) |
From Márton Németh:
Clean up the Linux USB pseudoheader dissection.
svn path=/trunk/; revision=25990
-rw-r--r-- | epan/dissectors/packet-usb.c | 451 | ||||
-rw-r--r-- | wiretap/wtap.h | 16 |
2 files changed, 415 insertions, 52 deletions
diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c index ef98122543..48a35c22e3 100644 --- a/epan/dissectors/packet-usb.c +++ b/epan/dissectors/packet-usb.c @@ -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_transfer_type = -1; +static int hf_usb_endpoint_number = -1; static int hf_usb_device_address = -1; -static int hf_usb_data_flag = -1; +static int hf_usb_bus_id = -1; static int hf_usb_setup_flag = -1; -static int hf_usb_endpoint_number = -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_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_data_flag, - { "Data flag", "usb.data_flag", FT_UINT8, BASE_DEC, NULL, 0x0, - "USB data flag", 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, - { "Setup flag", "usb.setup_flag", FT_UINT8, BASE_DEC, NULL, 0x0, - "USB setup flag", HFILL }}, + { "Device setup request", "usb.setup_flag", FT_STRING, BASE_NONE, + NULL, 0x0, + "USB device setup request is present (0) or not", HFILL }}, - { &hf_usb_endpoint_number, - { "Endpoint", "usb.endpoint_number", FT_UINT8, BASE_HEX, NULL, 0x0, - "USB endpoint number", 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, diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 20416e719f..9819d2ebcf 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -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 */ }; /* |