2 * Routines for USB Communications and CDC Control dissection
3 * Copyright 2013, Pascal Quantin <pascal@wireshark.org>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/expert.h>
16 #include <epan/follow.h>
17 #include <epan/conversation.h>
19 #include <epan/unit_strings.h>
20 #include "packet-usb.h"
22 static int cdc_data_follow_tap
;
25 /* protocols and header fields */
26 static int proto_usb_com
;
27 static int hf_usb_com_descriptor_subtype
;
28 static int hf_usb_com_descriptor_cdc
;
29 static int hf_usb_com_descriptor_payload
;
30 static int hf_usb_com_control_subclass
;
31 static int hf_usb_com_control_request_code
;
32 static int hf_usb_com_control_value
;
33 static int hf_usb_com_control_index
;
34 static int hf_usb_com_control_length
;
35 static int hf_usb_com_control_response_code
;
36 static int hf_usb_com_control_payload
;
37 static int hf_usb_com_get_ntb_params_length
;
38 static int hf_usb_com_get_ntb_params_ntb_formats_supported
;
39 static int hf_usb_com_get_ntb_params_ntb_formats_supported_16bit
;
40 static int hf_usb_com_get_ntb_params_ntb_formats_supported_32bit
;
41 static int hf_usb_com_get_ntb_params_ntb_in_max_size
;
42 static int hf_usb_com_get_ntb_params_ndp_in_divisor
;
43 static int hf_usb_com_get_ntb_params_ndp_in_payload_remainder
;
44 static int hf_usb_com_get_ntb_params_ndp_in_alignment
;
45 static int hf_usb_com_get_ntb_params_reserved
;
46 static int hf_usb_com_get_ntb_params_ntb_out_max_size
;
47 static int hf_usb_com_get_ntb_params_ndp_out_divisor
;
48 static int hf_usb_com_get_ntb_params_ndp_out_payload_remainder
;
49 static int hf_usb_com_get_ntb_params_ndp_out_alignment
;
50 static int hf_usb_com_get_ntb_params_ntb_out_max_datagrams
;
51 static int hf_usb_com_get_net_address_eui48
;
52 static int hf_usb_com_set_net_address_eui48
;
53 static int hf_usb_com_get_ntb_format_ntb_format
;
54 static int hf_usb_com_set_ntb_format_ntb_format
;
55 static int hf_usb_com_get_ntb_input_size_ntb_in_max_size
;
56 static int hf_usb_com_get_ntb_input_size_ntb_in_max_datagrams
;
57 static int hf_usb_com_get_ntb_input_size_reserved
;
58 static int hf_usb_com_set_ntb_input_size_ntb_in_max_size
;
59 static int hf_usb_com_set_ntb_input_size_ntb_in_max_datagrams
;
60 static int hf_usb_com_set_ntb_input_size_reserved
;
61 static int hf_usb_com_get_max_datagram_size_size
;
62 static int hf_usb_com_set_max_datagram_size_size
;
63 static int hf_usb_com_get_crc_mode_crc_mode
;
64 static int hf_usb_com_set_crc_mode_crc_mode
;
65 static int hf_usb_com_capabilities
;
66 static int hf_usb_com_descriptor_acm_capabilities_reserved
;
67 static int hf_usb_com_descriptor_acm_capabilities_network_connection
;
68 static int hf_usb_com_descriptor_acm_capabilities_send_break
;
69 static int hf_usb_com_descriptor_acm_capabilities_line_and_state
;
70 static int hf_usb_com_descriptor_acm_capabilities_comm_features
;
71 static int hf_usb_com_descriptor_control_interface
;
72 static int hf_usb_com_descriptor_subordinate_interface
;
73 static int hf_usb_com_descriptor_cm_capabilities_reserved
;
74 static int hf_usb_com_descriptor_cm_capabilities_call_management_over_data_class_interface
;
75 static int hf_usb_com_descriptor_cm_capabilities_call_management
;
76 static int hf_usb_com_descriptor_cm_data_interface
;
77 static int hf_usb_com_descriptor_ecm_mac_address
;
78 static int hf_usb_com_descriptor_ecm_eth_stats
;
79 static int hf_usb_com_descriptor_ecm_eth_stats_reserved
;
80 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_late_collisions
;
81 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_times_crs_lost
;
82 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_heartbeat_failure
;
83 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_underrun
;
84 static int hf_usb_com_descriptor_ecm_eth_stats_rcv_overrun
;
85 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_max_collisions
;
86 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_deferred
;
87 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_more_collisions
;
88 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_one_collision
;
89 static int hf_usb_com_descriptor_ecm_eth_stats_rcv_error_alignment
;
90 static int hf_usb_com_descriptor_ecm_eth_stats_transmit_queue_length
;
91 static int hf_usb_com_descriptor_ecm_eth_stats_rcv_crc_error
;
92 static int hf_usb_com_descriptor_ecm_eth_stats_broadcast_frames_rcv
;
93 static int hf_usb_com_descriptor_ecm_eth_stats_broadcast_bytes_rcv
;
94 static int hf_usb_com_descriptor_ecm_eth_stats_multicast_frames_rcv
;
95 static int hf_usb_com_descriptor_ecm_eth_stats_multicast_bytes_rcv
;
96 static int hf_usb_com_descriptor_ecm_eth_stats_directed_frames_rcv
;
97 static int hf_usb_com_descriptor_ecm_eth_stats_directed_bytes_rcv
;
98 static int hf_usb_com_descriptor_ecm_eth_stats_broadcast_frames_xmit
;
99 static int hf_usb_com_descriptor_ecm_eth_stats_broadcast_bytes_xmit
;
100 static int hf_usb_com_descriptor_ecm_eth_stats_multicast_frames_xmit
;
101 static int hf_usb_com_descriptor_ecm_eth_stats_multicast_bytes_xmit
;
102 static int hf_usb_com_descriptor_ecm_eth_stats_directed_frames_xmit
;
103 static int hf_usb_com_descriptor_ecm_eth_stats_directed_bytes_xmit
;
104 static int hf_usb_com_descriptor_ecm_eth_stats_rcv_no_buffer
;
105 static int hf_usb_com_descriptor_ecm_eth_stats_rcv_error
;
106 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_error
;
107 static int hf_usb_com_descriptor_ecm_eth_stats_rvc_ok
;
108 static int hf_usb_com_descriptor_ecm_eth_stats_xmit_ok
;
109 static int hf_usb_com_descriptor_ecm_max_segment_size
;
110 static int hf_usb_com_descriptor_ecm_nb_mc_filters
;
111 static int hf_usb_com_descriptor_ecm_nb_mc_filters_mc_address_filtering
;
112 static int hf_usb_com_descriptor_ecm_nb_mc_filters_nb_filters_supported
;
113 static int hf_usb_com_descriptor_ecm_nb_power_filters
;
114 static int hf_usb_com_interrupt_request_type
;
115 static int hf_usb_com_interrupt_notif_code
;
116 static int hf_usb_com_interrupt_value
;
117 static int hf_usb_com_interrupt_value_nw_conn
;
118 static int hf_usb_com_interrupt_index
;
119 static int hf_usb_com_interrupt_length
;
120 static int hf_usb_com_interrupt_dl_bitrate
;
121 static int hf_usb_com_interrupt_ul_bitrate
;
122 static int hf_usb_com_interrupt_payload
;
123 static int hf_usb_com_data_stream
;
124 static int hf_usb_com_data_in_payload
;
125 static int hf_usb_com_data_out_payload
;
127 static int ett_usb_com
;
128 static int ett_usb_com_capabilities
;
129 static int ett_usb_com_bitmap
;
130 static int ett_usb_com_descriptor_ecm_eth_stats
;
131 static int ett_usb_com_descriptor_ecm_nb_mc_filters
;
133 static dissector_handle_t usb_com_descriptor_handle
;
134 static dissector_handle_t usb_com_control_handle
;
135 static dissector_handle_t usb_com_bulk_handle
;
136 static dissector_handle_t usb_com_interrupt_handle
;
138 static dissector_handle_t mbim_control_handle
;
139 static dissector_handle_t mbim_descriptor_handle
;
140 static dissector_handle_t mbim_bulk_handle
;
141 static dissector_handle_t eth_withoutfcs_handle
;
143 static expert_field ei_unexpected_controlling_iface
;
145 static wmem_tree_t
* controlling_ifaces
;
147 typedef struct _controlling_iface
{
148 uint16_t interfaceClass
;
149 uint16_t interfaceSubclass
;
150 uint16_t interfaceProtocol
;
151 } controlling_iface_t
;
153 static uint32_t cdc_data_stream_count
;
155 typedef struct _cdc_data_conv
{
159 #define CS_INTERFACE 0x24
160 #define CS_ENDPOINT 0x25
162 static const value_string usb_com_descriptor_type_vals
[] = {
163 { CS_INTERFACE
, "CS_INTERFACE"},
164 { CS_ENDPOINT
, "CS_ENDPOINT"},
167 static value_string_ext usb_com_descriptor_type_vals_ext
= VALUE_STRING_EXT_INIT(usb_com_descriptor_type_vals
);
169 static const value_string usb_com_descriptor_subtype_vals
[] = {
170 { 0x00, "Header Functional Descriptor"},
171 { 0x01, "Call Management Functional Descriptor"},
172 { 0x02, "Abstract Control Management Functional Descriptor"},
173 { 0x03, "Direct Line Management Functional Descriptor"},
174 { 0x04, "Telephone Ringer Functional Descriptor"},
175 { 0x05, "Telephone Call and Line State Reporting Capabilities Functional Descriptor"},
176 { 0x06, "Union Functional Descriptor"},
177 { 0x07, "Country Selection Functional Descriptor"},
178 { 0x08, "Telephone Operational Modes Functional Descriptor"},
179 { 0x09, "USB Terminal Functional Descriptor"},
180 { 0x0A, "Network Channel Terminal Descriptor"},
181 { 0x0B, "Protocol Unit Functional Descriptor"},
182 { 0x0C, "Extension Unit Functional Descriptor"},
183 { 0x0D, "Multi-Channel Management Functional Descriptor"},
184 { 0x0E, "CAPI Control Management Functional Descriptor"},
185 { 0x0F, "Ethernet Networking Functional Descriptor"},
186 { 0x10, "ATM Networking Functional Descriptor"},
187 { 0x11, "Wireless Handset Control Model Functional Descriptor"},
188 { 0x12, "Mobile Direct Line Model Functional Descriptor"},
189 { 0x13, "MDLM Detail Functional Descriptor"},
190 { 0x14, "Device Management Model Functional Descriptor"},
191 { 0x15, "OBEX Functional Descriptor"},
192 { 0x16, "Command Set Functional Descriptor"},
193 { 0x17, "Command Set Detail Functional Descriptor"},
194 { 0x18, "Telephone Control Model Functional Descriptor"},
195 { 0x19, "OBEX Service Identifier Functional Descriptor"},
196 { 0x1A, "NCM Functional Descriptor"},
197 { 0x1B, "MBIM Functional Descriptor"},
198 { 0x1C, "MBIM Extended Functional Descriptor"},
201 static value_string_ext usb_com_descriptor_subtype_vals_ext
= VALUE_STRING_EXT_INIT(usb_com_descriptor_subtype_vals
);
203 #define COM_SUBCLASS_RESERVED 0x00
204 #define COM_SUBCLASS_DLCM 0x01
205 #define COM_SUBCLASS_ACM 0x02
206 #define COM_SUBCLASS_TCM 0x03
207 #define COM_SUBCLASS_MCCM 0x04
208 #define COM_SUBCLASS_CCM 0x05
209 #define COM_SUBCLASS_ENCM 0x06
210 #define COM_SUBCLASS_ANCM 0x07
211 #define COM_SUBCLASS_WHCM 0x08
212 #define COM_SUBCLASS_DM 0x09
213 #define COM_SUBCLASS_MDLM 0x0a
214 #define COM_SUBCLASS_OBEX 0x0b
215 #define COM_SUBCLASS_EEM 0x0c
216 #define COM_SUBCLASS_NCM 0x0d
217 #define COM_SUBCLASS_MBIM 0x0e
219 static const value_string usb_com_subclass_vals
[] = {
220 {COM_SUBCLASS_RESERVED
, "RESERVED"},
221 {COM_SUBCLASS_DLCM
, "Direct Line Control Model"},
222 {COM_SUBCLASS_ACM
, "Abstract Control Model"},
223 {COM_SUBCLASS_TCM
, "Telephone Control Model"},
224 {COM_SUBCLASS_MCCM
, "Multi-Channel Control Model"},
225 {COM_SUBCLASS_CCM
, "CAPI Control Model"},
226 {COM_SUBCLASS_ENCM
, "Ethernet Networking Control Model"},
227 {COM_SUBCLASS_ANCM
, "ATM Networking Control Model"},
228 {COM_SUBCLASS_WHCM
, "Wireless Handset Control Model"},
229 {COM_SUBCLASS_DM
, "Device Management"},
230 {COM_SUBCLASS_MDLM
, "Mobile Direct Line Model"},
231 {COM_SUBCLASS_OBEX
, "OBEX"},
232 {COM_SUBCLASS_EEM
, "Ethernet Emulation Model"},
233 {COM_SUBCLASS_NCM
, "Network Control Model"},
234 {COM_SUBCLASS_MBIM
, "Mobile Broadband Interface Model"},
237 value_string_ext ext_usb_com_subclass_vals
= VALUE_STRING_EXT_INIT(usb_com_subclass_vals
);
239 #define SEND_ENCAPSULATED_COMMAND 0x00
240 #define GET_ENCAPSULATED_RESPONSE 0x01
241 #define SET_COMM_FEATURE 0x02
242 #define GET_COMM_FEATURE 0x03
243 #define CLEAR_COMM_FEATURE 0x04
244 #define RESET_FUNCTION 0x05
245 #define SET_AUX_LINE_STATE 0x10
246 #define SET_HOOK_STATE 0x11
247 #define PULSE_SETUP 0x12
248 #define SEND_PULSE 0x13
249 #define SET_PULSE_TIME 0x14
250 #define RING_AUX_JACK 0x15
251 #define SET_LINE_CODING 0x20
252 #define GET_LINE_CODING 0x21
253 #define SET_CONTROL_LINE_STATE 0x22
254 #define SEND_BREAK 0x23
255 #define SET_RINGER_PARMS 0x30
256 #define GET_RINGER_PARMS 0x31
257 #define SET_OPERATION_PARMS 0x32
258 #define GET_OPERATION_PARMS 0x33
259 #define SET_LINE_PARMS 0x34
260 #define GET_LINE_PARMS 0x35
261 #define DIAL_DIGITS 0x36
262 #define SET_UNIT_PARAMETER 0x37
263 #define GET_UNIT_PARAMETER 0x38
264 #define CLEAR_UNIT_PARAMETER 0x39
265 #define GET_PROFILE 0x3a
266 #define SET_ETHERNET_MULTICAST_FILTERS 0x40
267 #define SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x41
268 #define GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x42
269 #define SET_ETHERNET_PACKET_FILTER 0x43
270 #define GET_ETHERNET_STATISTIC 0x44
271 #define SET_ATM_DATA_FORMAT 0x50
272 #define GET_ATM_DEVICE_STATISTICS 0x51
273 #define SET_ATM_DEFAULT_VC 0x52
274 #define GET_ATM_VC_STATISTICS 0x53
275 #define GET_NTB_PARAMETERS 0x80
276 #define GET_NET_ADDRESS 0x81
277 #define SET_NET_ADDRESS 0x82
278 #define GET_NTB_FORMAT 0x83
279 #define SET_NTB_FORMAT 0x84
280 #define GET_NTB_INPUT_SIZE 0x85
281 #define SET_NTB_INPUT_SIZE 0x86
282 #define GET_MAX_DATAGRAM_SIZE 0x87
283 #define SET_MAX_DATAGRAM_SIZE 0x88
284 #define GET_CRC_MODE 0x89
285 #define SET_CRC_MODE 0x8a
287 static const value_string usb_com_setup_request_vals
[] = {
288 {SEND_ENCAPSULATED_COMMAND
, "SEND ENCAPSULATED COMMAND"},
289 {GET_ENCAPSULATED_RESPONSE
, "GET ENCAPSULATED RESPONSE"},
290 {SET_COMM_FEATURE
, "SET COMM FEATURE"},
291 {GET_COMM_FEATURE
, "GET COMM FEATURE"},
292 {CLEAR_COMM_FEATURE
, "CLEAR COMM FEATURE"},
293 {RESET_FUNCTION
, "RESET FUNCTION"},
294 {SET_AUX_LINE_STATE
, "SET AUX LINE STATE"},
295 {SET_HOOK_STATE
, "SET HOOK STATE"},
296 {PULSE_SETUP
, "PULSE SETUP"},
297 {SEND_PULSE
, "SEND PULSE"},
298 {SET_PULSE_TIME
, "SET PULSE TIME"},
299 {RING_AUX_JACK
, "RING AUX JACK"},
300 {SET_LINE_CODING
, "SET LINE CODING"},
301 {GET_LINE_CODING
, "GET LINE CODING"},
302 {SET_CONTROL_LINE_STATE
, "SET CONTROL LINE STATE"},
303 {SEND_BREAK
, "SEND BREAK"},
304 {SET_RINGER_PARMS
, "SET RINGER PARMS"},
305 {GET_RINGER_PARMS
, "GET RINGER PARMS"},
306 {SET_OPERATION_PARMS
, "SET OPERATION PARMS"},
307 {GET_OPERATION_PARMS
, "GET OPERATION PARMS"},
308 {SET_LINE_PARMS
, "SET LINE PARMS"},
309 {GET_LINE_PARMS
, "GET LINE PARMS"},
310 {DIAL_DIGITS
, "DIAL DIGITS"},
311 {SET_UNIT_PARAMETER
, "SET UNIT PARAMETER"},
312 {GET_UNIT_PARAMETER
, "GET UNIT PARAMETER"},
313 {CLEAR_UNIT_PARAMETER
, "CLEAR UNIT PARAMETER"},
314 {GET_PROFILE
, "GET PROFILE"},
315 {SET_ETHERNET_MULTICAST_FILTERS
, "SET ETHERNET MULTICAST FILTERS"},
316 {SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER
, "SET ETHERNET POWER MANAGEMENT PATTERN FILTER"},
317 {GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER
, "GET ETHERNET POWER MANAGEMENT PATTERN FILTER"},
318 {SET_ETHERNET_PACKET_FILTER
, "SET ETHERNET PACKET FILTER"},
319 {GET_ETHERNET_STATISTIC
, "GET ETHERNET STATISTIC"},
320 {SET_ATM_DATA_FORMAT
, "SET ATM DATA FORMAT"},
321 {GET_ATM_DEVICE_STATISTICS
, "GET ATM DEVICE STATISTICS"},
322 {SET_ATM_DEFAULT_VC
, "SET ATM DEFAULT VC"},
323 {GET_ATM_VC_STATISTICS
, "GET ATM VC STATISTICS"},
324 {GET_NTB_PARAMETERS
, "GET NTB PARAMETERS"},
325 {GET_NET_ADDRESS
, "GET NET ADDRESS"},
326 {SET_NET_ADDRESS
, "SET NET ADDRESS"},
327 {GET_NTB_FORMAT
, "GET NTB FORMAT"},
328 {SET_NTB_FORMAT
, "SET NTB FORMAT"},
329 {GET_NTB_INPUT_SIZE
, "GET NTB INPUT SIZE"},
330 {SET_NTB_INPUT_SIZE
, "SET NTB INPUT SIZE"},
331 {GET_MAX_DATAGRAM_SIZE
, "GET MAX DATAGRAM SIZE"},
332 {SET_MAX_DATAGRAM_SIZE
, "SET MAX DATAGRAM SIZE"},
333 {GET_CRC_MODE
, "GET CRC MODE"},
334 {SET_CRC_MODE
, "SET CRC MODE"},
337 static value_string_ext usb_com_setup_request_vals_ext
= VALUE_STRING_EXT_INIT(usb_com_setup_request_vals
);
339 static int * const usb_com_get_ntb_params_ntb_formats_supported_fields
[] = {
340 &hf_usb_com_get_ntb_params_ntb_formats_supported_16bit
,
341 &hf_usb_com_get_ntb_params_ntb_formats_supported_32bit
,
345 static const value_string usb_com_ntb_format_vals
[] = {
351 static const value_string usb_com_crc_mode_vals
[] = {
352 { 0x0000, "CRCs shall not be appended"},
353 { 0x0001, "CRCs shall be appended"},
357 static int * const ecm_eth_stats
[] = {
358 &hf_usb_com_descriptor_ecm_eth_stats_reserved
,
359 &hf_usb_com_descriptor_ecm_eth_stats_xmit_late_collisions
,
360 &hf_usb_com_descriptor_ecm_eth_stats_xmit_times_crs_lost
,
361 &hf_usb_com_descriptor_ecm_eth_stats_xmit_heartbeat_failure
,
362 &hf_usb_com_descriptor_ecm_eth_stats_xmit_underrun
,
363 &hf_usb_com_descriptor_ecm_eth_stats_rcv_overrun
,
364 &hf_usb_com_descriptor_ecm_eth_stats_xmit_max_collisions
,
365 &hf_usb_com_descriptor_ecm_eth_stats_xmit_deferred
,
366 &hf_usb_com_descriptor_ecm_eth_stats_xmit_more_collisions
,
367 &hf_usb_com_descriptor_ecm_eth_stats_xmit_one_collision
,
368 &hf_usb_com_descriptor_ecm_eth_stats_rcv_error_alignment
,
369 &hf_usb_com_descriptor_ecm_eth_stats_transmit_queue_length
,
370 &hf_usb_com_descriptor_ecm_eth_stats_rcv_crc_error
,
371 &hf_usb_com_descriptor_ecm_eth_stats_broadcast_frames_rcv
,
372 &hf_usb_com_descriptor_ecm_eth_stats_broadcast_bytes_rcv
,
373 &hf_usb_com_descriptor_ecm_eth_stats_multicast_frames_rcv
,
374 &hf_usb_com_descriptor_ecm_eth_stats_multicast_bytes_rcv
,
375 &hf_usb_com_descriptor_ecm_eth_stats_directed_frames_rcv
,
376 &hf_usb_com_descriptor_ecm_eth_stats_directed_bytes_rcv
,
377 &hf_usb_com_descriptor_ecm_eth_stats_broadcast_frames_xmit
,
378 &hf_usb_com_descriptor_ecm_eth_stats_broadcast_bytes_xmit
,
379 &hf_usb_com_descriptor_ecm_eth_stats_multicast_frames_xmit
,
380 &hf_usb_com_descriptor_ecm_eth_stats_multicast_bytes_xmit
,
381 &hf_usb_com_descriptor_ecm_eth_stats_directed_frames_xmit
,
382 &hf_usb_com_descriptor_ecm_eth_stats_directed_bytes_xmit
,
383 &hf_usb_com_descriptor_ecm_eth_stats_rcv_no_buffer
,
384 &hf_usb_com_descriptor_ecm_eth_stats_rcv_error
,
385 &hf_usb_com_descriptor_ecm_eth_stats_xmit_error
,
386 &hf_usb_com_descriptor_ecm_eth_stats_rvc_ok
,
387 &hf_usb_com_descriptor_ecm_eth_stats_xmit_ok
,
391 static const true_false_string usb_com_ecm_mc_address_filtering
= {
396 static int * const ecm_nb_mc_filters
[] = {
397 &hf_usb_com_descriptor_ecm_nb_mc_filters_mc_address_filtering
,
398 &hf_usb_com_descriptor_ecm_nb_mc_filters_nb_filters_supported
,
402 #define NETWORK_CONNECTION 0x00
403 #define RESPONSE_AVAILABLE 0x01
404 #define AUX_JACK_HOOK_STATE 0x08
405 #define RING_DETECT 0x09
406 #define SERIAL_STATE 0x20
407 #define CALL_STATE_CHANGE 0x28
408 #define LINE_STATE_CHANGE 0x29
409 #define CONNECTION_SPEED_CHANGE 0x2a
411 static const value_string usb_com_interrupt_notif_code_vals
[] = {
412 {NETWORK_CONNECTION
, "NETWORK CONNECTION"},
413 {RESPONSE_AVAILABLE
, "RESPONSE AVAILABLE"},
414 {AUX_JACK_HOOK_STATE
, "AUX JACK HOOK STATE"},
415 {RING_DETECT
, "RING DETECT"},
416 {SERIAL_STATE
, "SERIAL STATE"},
417 {CALL_STATE_CHANGE
, "CALL STATE CHANGE"},
418 {LINE_STATE_CHANGE
, "LINE STATE CHANGE"},
419 {CONNECTION_SPEED_CHANGE
, "CONNECTION SPEED CHANGE"},
423 static const value_string usb_com_interrupt_value_nw_conn_vals
[] = {
429 void proto_register_usb_com(void);
430 void proto_reg_handoff_usb_com(void);
433 dissect_usb_com_descriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
435 urb_info_t
*urb
= (urb_info_t
*)data
;
437 uint8_t type
, subtype
;
439 proto_tree
*subtree_capabilities
;
440 proto_item
*subitem_capabilities
;
446 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
, tvb_captured_length(tvb
), ett_usb_com
, NULL
, "COMMUNICATIONS DESCRIPTOR");
448 dissect_usb_descriptor_header(subtree
, tvb
, offset
, &usb_com_descriptor_type_vals_ext
);
451 type
= tvb_get_uint8(tvb
, 1);
454 subtype
= tvb_get_uint8(tvb
, offset
);
455 proto_tree_add_uint(subtree
, hf_usb_com_descriptor_subtype
, tvb
, offset
, 1, subtype
);
459 proto_tree_add_item(subtree
, hf_usb_com_descriptor_cdc
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
463 subitem_capabilities
= proto_tree_add_item(subtree
, hf_usb_com_capabilities
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
464 subtree_capabilities
= proto_item_add_subtree(subitem_capabilities
, ett_usb_com_capabilities
);
466 proto_tree_add_item(subtree_capabilities
, hf_usb_com_descriptor_cm_capabilities_reserved
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
467 proto_tree_add_item(subtree_capabilities
, hf_usb_com_descriptor_cm_capabilities_call_management_over_data_class_interface
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
468 proto_tree_add_item(subtree_capabilities
, hf_usb_com_descriptor_cm_capabilities_call_management
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
470 proto_tree_add_item(subtree
, hf_usb_com_descriptor_cm_data_interface
, tvb
, 4, 1, ENC_LITTLE_ENDIAN
);
474 subitem_capabilities
= proto_tree_add_item(subtree
, hf_usb_com_capabilities
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
475 subtree_capabilities
= proto_item_add_subtree(subitem_capabilities
, ett_usb_com_capabilities
);
477 proto_tree_add_item(subtree_capabilities
, hf_usb_com_descriptor_acm_capabilities_reserved
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
478 proto_tree_add_item(subtree_capabilities
, hf_usb_com_descriptor_acm_capabilities_network_connection
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
479 proto_tree_add_item(subtree_capabilities
, hf_usb_com_descriptor_acm_capabilities_send_break
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
480 proto_tree_add_item(subtree_capabilities
, hf_usb_com_descriptor_acm_capabilities_line_and_state
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
481 proto_tree_add_item(subtree_capabilities
, hf_usb_com_descriptor_acm_capabilities_comm_features
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
485 proto_item
*control_item
;
487 uint32_t k_device_address
;
488 uint32_t k_subordinate_id
;
489 uint32_t k_frame_number
;
490 wmem_tree_key_t key
[] = {
491 { .length
= 1, .key
= &k_bus_id
},
492 { .length
= 1, .key
= &k_device_address
},
493 { .length
= 1, .key
= &k_subordinate_id
},
494 { .length
= 1, .key
= &k_frame_number
},
495 { .length
= 0, .key
= NULL
},
497 controlling_iface_t
*master_info
= NULL
;
500 k_bus_id
= urb
->bus_id
;
501 k_device_address
= urb
->device_address
;
502 k_frame_number
= pinfo
->num
;
504 control_item
= proto_tree_add_item_ret_uint(subtree
, hf_usb_com_descriptor_control_interface
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &master
);
506 if (master
!= urb
->conv
->interfaceNum
) {
507 expert_add_info(pinfo
, control_item
, &ei_unexpected_controlling_iface
);
508 } else if (!PINFO_FD_VISITED(pinfo
)) {
509 master_info
= wmem_new(wmem_file_scope(), controlling_iface_t
);
510 master_info
->interfaceClass
= urb
->conv
->interfaceClass
;
511 master_info
->interfaceSubclass
= urb
->conv
->interfaceSubclass
;
512 master_info
->interfaceProtocol
= urb
->conv
->interfaceProtocol
;
516 while (tvb_reported_length_remaining(tvb
,offset
) > 0) {
517 proto_tree_add_item_ret_uint(subtree
, hf_usb_com_descriptor_subordinate_interface
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &k_subordinate_id
);
521 wmem_tree_insert32_array(controlling_ifaces
, key
, master_info
);
527 proto_tree_add_item(subtree
, hf_usb_com_descriptor_ecm_mac_address
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
529 proto_tree_add_bitmask_with_flags(subtree
, tvb
, offset
, hf_usb_com_descriptor_ecm_eth_stats
,
530 ett_usb_com_descriptor_ecm_eth_stats
, ecm_eth_stats
,
531 ENC_LITTLE_ENDIAN
, BMT_NO_APPEND
);
533 proto_tree_add_item(subtree
, hf_usb_com_descriptor_ecm_max_segment_size
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
535 proto_tree_add_bitmask_with_flags(subtree
, tvb
, offset
, hf_usb_com_descriptor_ecm_nb_mc_filters
,
536 ett_usb_com_descriptor_ecm_nb_mc_filters
, ecm_nb_mc_filters
,
537 ENC_LITTLE_ENDIAN
, BMT_NO_APPEND
);
539 proto_tree_add_item(subtree
, hf_usb_com_descriptor_ecm_nb_power_filters
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
544 offset
= call_dissector_only(mbim_descriptor_handle
, tvb
, pinfo
, subtree
, data
);
555 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
556 proto_tree_add_item(subtree
, hf_usb_com_descriptor_payload
, tvb
, offset
, -1, ENC_NA
);
558 return tvb_captured_length(tvb
);
562 dissect_usb_com_get_ntb_params(tvbuff_t
*tvb
, proto_tree
*tree
, int base_offset
)
564 int offset
= base_offset
;
566 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
568 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_com_get_ntb_params_ntb_formats_supported
, ett_usb_com_bitmap
,
569 usb_com_get_ntb_params_ntb_formats_supported_fields
, ENC_LITTLE_ENDIAN
);
571 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ntb_in_max_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
573 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ndp_in_divisor
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
575 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ndp_in_payload_remainder
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
577 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ndp_in_alignment
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
579 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_reserved
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
581 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ntb_out_max_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
583 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ndp_out_divisor
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
585 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ndp_out_payload_remainder
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
587 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ndp_out_alignment
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
589 proto_tree_add_item(tree
, hf_usb_com_get_ntb_params_ntb_out_max_datagrams
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
596 dissect_usb_com_ntb_input_size(tvbuff_t
*tvb
, proto_tree
*tree
, int base_offset
, bool is_set
)
598 int offset
= base_offset
;
600 proto_tree_add_item(tree
, is_set
? hf_usb_com_set_ntb_input_size_ntb_in_max_size
:
601 hf_usb_com_get_ntb_input_size_ntb_in_max_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
603 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
604 proto_tree_add_item(tree
, is_set
? hf_usb_com_set_ntb_input_size_ntb_in_max_datagrams
:
605 hf_usb_com_get_ntb_input_size_ntb_in_max_datagrams
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
607 proto_tree_add_item(tree
, is_set
? hf_usb_com_set_ntb_input_size_reserved
:
608 hf_usb_com_get_ntb_input_size_reserved
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
616 dissect_usb_com_control(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
618 urb_info_t
*urb
= (urb_info_t
*)data
;
619 usb_trans_info_t
*usb_trans_info
;
625 if (tvb_reported_length(tvb
) == 0) {
629 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "USBCOM");
631 ti
= proto_tree_add_item(tree
, proto_usb_com
, tvb
, 0, -1, ENC_NA
);
632 subtree
= proto_item_add_subtree(ti
, ett_usb_com
);
635 usb_trans_info
= urb
->usb_trans_info
;
637 ti
= proto_tree_add_uint(subtree
, hf_usb_com_control_subclass
, tvb
, 0, 0,
638 urb
->conv
->interfaceSubclass
);
639 proto_item_set_generated(ti
);
641 is_request
= (pinfo
->srcport
==NO_ENDPOINT
);
642 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s",
643 val_to_str_ext(usb_trans_info
->setup
.request
, &usb_com_setup_request_vals_ext
, "Unknown type %x"),
644 is_request
? "Request" : "Response");
647 proto_tree_add_item(subtree
, hf_usb_com_control_request_code
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
649 proto_tree_add_item(subtree
, hf_usb_com_control_value
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
651 proto_tree_add_item(subtree
, hf_usb_com_control_index
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
653 proto_tree_add_item(subtree
, hf_usb_com_control_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
656 ti
= proto_tree_add_uint(subtree
, hf_usb_com_control_response_code
, tvb
, 0, 0,
657 usb_trans_info
->setup
.request
);
658 proto_item_set_generated(ti
);
661 switch (usb_trans_info
->setup
.request
)
663 case SEND_ENCAPSULATED_COMMAND
:
664 if ((urb
->conv
->interfaceSubclass
== COM_SUBCLASS_MBIM
) && is_request
) {
665 tvbuff_t
*mbim_tvb
= tvb_new_subset_remaining(tvb
, offset
);
666 offset
+= call_dissector_only(mbim_control_handle
, mbim_tvb
, pinfo
, tree
, urb
);
669 case GET_ENCAPSULATED_RESPONSE
:
670 if ((urb
->conv
->interfaceSubclass
== COM_SUBCLASS_MBIM
) && !is_request
) {
671 offset
+= call_dissector_only(mbim_control_handle
, tvb
, pinfo
, tree
, urb
);
674 case GET_NTB_PARAMETERS
:
676 offset
= dissect_usb_com_get_ntb_params(tvb
, subtree
, offset
);
679 case GET_NET_ADDRESS
:
681 proto_tree_add_item(subtree
, hf_usb_com_get_net_address_eui48
, tvb
, offset
, 6, ENC_NA
);
685 case SET_NET_ADDRESS
:
687 proto_tree_add_item(subtree
, hf_usb_com_set_net_address_eui48
, tvb
, offset
, 6, ENC_NA
);
693 proto_tree_add_item(subtree
, hf_usb_com_get_ntb_format_ntb_format
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
699 proto_tree_add_item(subtree
, hf_usb_com_set_ntb_format_ntb_format
, tvb
, offset
-6, 2, ENC_LITTLE_ENDIAN
);
702 case GET_NTB_INPUT_SIZE
:
704 offset
= dissect_usb_com_ntb_input_size(tvb
, subtree
, offset
, false);
707 case SET_NTB_INPUT_SIZE
:
709 offset
= dissect_usb_com_ntb_input_size(tvb
, subtree
, offset
, true);
712 case GET_MAX_DATAGRAM_SIZE
:
714 proto_tree_add_item(subtree
, hf_usb_com_get_max_datagram_size_size
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
718 case SET_MAX_DATAGRAM_SIZE
:
720 proto_tree_add_item(subtree
, hf_usb_com_set_max_datagram_size_size
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
726 proto_tree_add_item(subtree
, hf_usb_com_get_crc_mode_crc_mode
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
732 proto_tree_add_item(subtree
, hf_usb_com_set_crc_mode_crc_mode
, tvb
, offset
-6, 2, ENC_LITTLE_ENDIAN
);
740 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
741 proto_tree_add_item(subtree
, hf_usb_com_control_payload
, tvb
, offset
, -1, ENC_NA
);
743 return tvb_captured_length(tvb
);
747 dissect_usb_com_bulk(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
749 urb_info_t
*urb
= (urb_info_t
*)data
;
750 usb_conv_info_t
*usb_conv_info
;
751 cdc_data_conv_t
*cdc_data_info
;
753 uint32_t k_device_address
;
754 uint32_t k_subordinate_id
;
755 wmem_tree_key_t key
[] = {
756 { .length
= 1, .key
= &k_bus_id
},
757 { .length
= 1, .key
= &k_device_address
},
758 { .length
= 1, .key
= &k_subordinate_id
},
759 { .length
= 0, .key
= NULL
},
761 wmem_tree_t
*wmem_tree
;
762 controlling_iface_t
*master_iface
= NULL
;
766 if (!urb
|| !urb
->conv
) {
770 usb_conv_info
= urb
->conv
;
772 if ((usb_conv_info
->interfaceClass
!= IF_CLASS_CDC_DATA
) || (usb_conv_info
->interfaceSubclass
!= 0)) {
773 /* As per Communications Device Class Revision 1.2 subclass is currently unused for CDC Data and should be zero
774 * If it is not, then we are either dealing with malformed descriptor or a new CDC Revision.
779 /* Generic handling to allow follow stream functionality regardless if data
780 * is passed to higher layer dissector or not.
782 cdc_data_info
= (cdc_data_conv_t
*)usb_conv_info
->class_data
;
783 if (!cdc_data_info
) {
784 cdc_data_info
= wmem_new(wmem_file_scope(), cdc_data_conv_t
);
785 cdc_data_info
->stream
= cdc_data_stream_count
++;
786 usb_conv_info
->class_data
= cdc_data_info
;
787 usb_conv_info
->class_data_type
= USB_CONV_CDC_DATA
;
788 } else if (usb_conv_info
->class_data_type
!= USB_CONV_CDC_DATA
) {
789 /* Don't dissect if another USB type is in the conversation */
793 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "USBCOM");
795 item
= proto_tree_add_item(tree
, proto_usb_com
, tvb
, 0, -1, ENC_NA
);
796 subtree
= proto_item_add_subtree(item
, ett_usb_com
);
798 item
= proto_tree_add_uint(subtree
, hf_usb_com_data_stream
, tvb
, 0, 0, cdc_data_info
->stream
);
799 proto_item_set_generated(item
);
801 if (pinfo
->p2p_dir
== P2P_DIR_RECV
) {
802 proto_tree_add_item(subtree
, hf_usb_com_data_in_payload
, tvb
, 0, -1, ENC_NA
);
804 proto_tree_add_item(subtree
, hf_usb_com_data_out_payload
, tvb
, 0, -1, ENC_NA
);
807 if (have_tap_listener(cdc_data_follow_tap
)) {
808 tap_queue_packet(cdc_data_follow_tap
, pinfo
, tvb
);
811 k_bus_id
= urb
->bus_id
;
812 k_device_address
= urb
->device_address
;
813 k_subordinate_id
= usb_conv_info
->interfaceNum
;
815 wmem_tree
= (wmem_tree_t
*)wmem_tree_lookup32_array(controlling_ifaces
, key
);
817 master_iface
= (controlling_iface_t
*)wmem_tree_lookup32_le(wmem_tree
, pinfo
->num
);
821 if (master_iface
->interfaceClass
== IF_CLASS_COMMUNICATIONS
) {
822 if ((master_iface
->interfaceSubclass
== COM_SUBCLASS_ENCM
) &&
823 (master_iface
->interfaceProtocol
== 0) &&
824 (usb_conv_info
->interfaceProtocol
== 0)) {
825 /* Ethernet without FCS */
826 return call_dissector_only(eth_withoutfcs_handle
, tvb
, pinfo
, tree
, NULL
);
832 switch (usb_conv_info
->interfaceProtocol
) {
833 case 0x01: /* Network Transfer Block */
834 case 0x02: /* Network Transfer Block (IP + DSS) */
835 return call_dissector_only(mbim_bulk_handle
, tvb
, pinfo
, tree
, NULL
);
840 /* Unknown (class, subclass, protocol) tuple. No further dissection. */
841 return tvb_captured_length(tvb
);
845 dissect_usb_com_interrupt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
852 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "USBCOM");
854 it
= proto_tree_add_item(tree
, proto_usb_com
, tvb
, 0, -1, ENC_NA
);
855 subtree
= proto_item_add_subtree(it
, ett_usb_com
);
857 proto_tree_add_item(subtree
, hf_usb_com_interrupt_request_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
859 proto_tree_add_item_ret_uint(subtree
, hf_usb_com_interrupt_notif_code
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, ¬if_code
);
861 col_add_str(pinfo
->cinfo
, COL_INFO
, val_to_str(notif_code
, usb_com_interrupt_notif_code_vals
, "Unknown type %x"));
862 switch (notif_code
) {
863 case NETWORK_CONNECTION
:
864 proto_tree_add_item(subtree
, hf_usb_com_interrupt_value_nw_conn
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
866 proto_tree_add_item(subtree
, hf_usb_com_interrupt_index
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
868 proto_tree_add_item(subtree
, hf_usb_com_interrupt_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
871 case RESPONSE_AVAILABLE
:
872 proto_tree_add_item(subtree
, hf_usb_com_interrupt_value
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
874 proto_tree_add_item(subtree
, hf_usb_com_interrupt_index
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
876 proto_tree_add_item(subtree
, hf_usb_com_interrupt_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
879 case CONNECTION_SPEED_CHANGE
:
880 proto_tree_add_item(subtree
, hf_usb_com_interrupt_value
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
882 proto_tree_add_item(subtree
, hf_usb_com_interrupt_index
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
884 proto_tree_add_item(subtree
, hf_usb_com_interrupt_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
886 proto_tree_add_item(subtree
, hf_usb_com_interrupt_dl_bitrate
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
888 proto_tree_add_item(subtree
, hf_usb_com_interrupt_ul_bitrate
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
895 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
896 proto_tree_add_item(subtree
, hf_usb_com_interrupt_payload
, tvb
, offset
, -1, ENC_NA
);
898 return tvb_captured_length(tvb
);
901 static cdc_data_conv_t
*get_cdc_data_conv(packet_info
*pinfo
)
903 conversation_t
*conversation
;
904 usb_conv_info_t
*usb_conv_info
;
906 if (pinfo
->ptype
!= PT_USB
) {
910 conversation
= find_conversation(pinfo
->num
, &pinfo
->src
, &pinfo
->dst
, CONVERSATION_USB
,
911 pinfo
->srcport
, pinfo
->destport
, 0);
916 usb_conv_info
= (usb_conv_info_t
*)conversation_get_proto_data(conversation
, proto_usb
);
917 if (!usb_conv_info
|| (usb_conv_info
->class_data_type
!= USB_CONV_CDC_DATA
)) {
921 return (cdc_data_conv_t
*)usb_conv_info
->class_data
;
924 static char *cdc_data_follow_conv_filter(epan_dissect_t
*edt _U_
, packet_info
*pinfo
, unsigned *stream
, unsigned *sub_stream _U_
)
926 cdc_data_conv_t
*cdc_data_info
;
928 cdc_data_info
= get_cdc_data_conv(pinfo
);
930 *stream
= cdc_data_info
->stream
;
931 return ws_strdup_printf("usbcom.data.stream eq %u", cdc_data_info
->stream
);
937 static char *cdc_data_follow_index_filter(unsigned stream
, unsigned sub_stream _U_
)
939 return ws_strdup_printf("usbcom.data.stream eq %u", stream
);
942 static char *cdc_data_follow_address_filter(address
*src_addr _U_
, address
*dst_addr _U_
, int src_port _U_
, int dst_port _U_
)
944 /* We always just filter stream based on an arbitrarily generated index. */
948 static char *cdc_data_port_to_display(wmem_allocator_t
*allocator
, unsigned port
)
950 return wmem_strdup(allocator
, port
== NO_ENDPOINT
? "host" : "device");
953 static tap_packet_status
954 follow_cdc_data_tap_listener(void *tapdata
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
,
955 const void *data
, tap_flags_t flags _U_
)
957 follow_record_t
*follow_record
;
958 follow_info_t
*follow_info
= (follow_info_t
*)tapdata
;
959 tvbuff_t
*tvb
= (tvbuff_t
*)data
;
960 uint32_t data_length
= tvb_captured_length(tvb
);
963 if (follow_info
->client_port
== 0) {
964 /* XXX: Client/Server does not quite match how USB works. Simply assume
965 * that host is "server" but it is important to note that client port
966 * will be set to either IN or OUT endpoint (whichever transmits data
967 * first). Client "receive" is OUT endpoint while client "transmit" is
968 * IN endpoint. The "other end" is always host.
970 if (pinfo
->srcport
== NO_ENDPOINT
) {
971 follow_info
->client_port
= pinfo
->destport
;
972 copy_address(&follow_info
->client_ip
, &pinfo
->dst
);
973 follow_info
->server_port
= pinfo
->srcport
;
974 copy_address(&follow_info
->server_ip
, &pinfo
->src
);
976 follow_info
->client_port
= pinfo
->srcport
;
977 copy_address(&follow_info
->client_ip
, &pinfo
->src
);
978 follow_info
->server_port
= pinfo
->destport
;
979 copy_address(&follow_info
->server_ip
, &pinfo
->dst
);
983 is_server
= pinfo
->srcport
== NO_ENDPOINT
;
985 follow_record
= g_new0(follow_record_t
, 1);
986 follow_record
->is_server
= is_server
;
987 follow_record
->packet_num
= pinfo
->fd
->num
;
988 follow_record
->abs_ts
= pinfo
->fd
->abs_ts
;
989 follow_record
->data
= g_byte_array_append(g_byte_array_new(),
990 tvb_get_ptr(tvb
, 0, data_length
),
993 follow_info
->bytes_written
[is_server
] += follow_record
->data
->len
;
994 follow_info
->payload
= g_list_prepend(follow_info
->payload
, follow_record
);
996 return TAP_PACKET_DONT_REDRAW
;
999 static uint32_t get_cdc_data_stream_count(void)
1001 return cdc_data_stream_count
;
1005 usb_com_cleanup_data(void)
1007 cdc_data_stream_count
= 0;
1011 proto_register_usb_com(void)
1013 static hf_register_info hf
[] = {
1014 { &hf_usb_com_descriptor_subtype
,
1015 { "Descriptor Subtype", "usbcom.descriptor.subtype", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
,
1016 &usb_com_descriptor_subtype_vals_ext
, 0, NULL
, HFILL
}},
1017 { &hf_usb_com_descriptor_cdc
,
1018 { "CDC", "usbcom.descriptor.cdc", FT_UINT16
, BASE_HEX
,
1019 NULL
, 0, NULL
, HFILL
}},
1020 { &hf_usb_com_descriptor_payload
,
1021 { "Payload", "usbcom.descriptor.payload", FT_BYTES
, BASE_NONE
,
1022 NULL
, 0, NULL
, HFILL
}},
1023 { &hf_usb_com_control_subclass
,
1024 { "Subclass", "usbcom.control.subclass", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
,
1025 &ext_usb_com_subclass_vals
, 0, NULL
, HFILL
}},
1026 { &hf_usb_com_control_request_code
,
1027 { "Request Code", "usbcom.control.request_code", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
,
1028 &usb_com_setup_request_vals_ext
, 0, NULL
, HFILL
}},
1029 { &hf_usb_com_control_value
,
1030 { "Value", "usbcom.control.value", FT_UINT16
, BASE_DEC
,
1031 NULL
, 0, NULL
, HFILL
}},
1032 { &hf_usb_com_control_index
,
1033 { "Index", "usbcom.control.index", FT_UINT16
, BASE_DEC
,
1034 NULL
, 0, NULL
, HFILL
}},
1035 { &hf_usb_com_control_length
,
1036 { "Length", "usbcom.control.length", FT_UINT16
, BASE_DEC
,
1037 NULL
, 0, NULL
, HFILL
}},
1038 { &hf_usb_com_control_response_code
,
1039 { "Response Code", "usbcom.control.response_code", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
,
1040 &usb_com_setup_request_vals_ext
, 0, NULL
, HFILL
}},
1041 { &hf_usb_com_get_ntb_params_length
,
1042 { "Length", "usbcom.control.get_ntb_params.length", FT_UINT16
, BASE_DEC
,
1043 NULL
, 0, NULL
, HFILL
}},
1044 { &hf_usb_com_get_ntb_params_ntb_formats_supported
,
1045 { "NTB Formats Supported", "usbcom.control.get_ntb_params.ntb_formats_supported", FT_UINT16
, BASE_HEX
,
1046 NULL
, 0, NULL
, HFILL
}},
1047 { &hf_usb_com_get_ntb_params_ntb_formats_supported_16bit
,
1048 { "16-bit NTB", "usbcom.control.get_ntb_params.ntb_formats_supported.16bit", FT_BOOLEAN
, 16,
1049 TFS(&tfs_supported_not_supported
), 0x0001, NULL
, HFILL
}},
1050 { &hf_usb_com_get_ntb_params_ntb_formats_supported_32bit
,
1051 { "32-bit NTB", "usbcom.control.get_ntb_params.ntb_formats_supported.32bit", FT_BOOLEAN
, 16,
1052 TFS(&tfs_supported_not_supported
), 0x0002, NULL
, HFILL
}},
1053 { &hf_usb_com_get_ntb_params_ntb_in_max_size
,
1054 { "NTB IN Max Size", "usbcom.control.get_ntb_params.ntb_in_max_size", FT_UINT32
, BASE_DEC
,
1055 NULL
, 0, NULL
, HFILL
}},
1056 { &hf_usb_com_get_ntb_params_ndp_in_divisor
,
1057 { "NDP IN Divisor", "usbcom.control.get_ntb_params.ndp_in_divisor", FT_UINT16
, BASE_DEC
,
1058 NULL
, 0, NULL
, HFILL
}},
1059 { &hf_usb_com_get_ntb_params_ndp_in_payload_remainder
,
1060 { "NDP IN Payload Remainder", "usbcom.control.get_ntb_params.ndp_in_payload_remainder", FT_UINT16
, BASE_DEC
,
1061 NULL
, 0, NULL
, HFILL
}},
1062 { &hf_usb_com_get_ntb_params_ndp_in_alignment
,
1063 { "NDP IN Alignment", "usbcom.control.get_ntb_params.ndp_in_alignment", FT_UINT16
, BASE_DEC
,
1064 NULL
, 0, NULL
, HFILL
}},
1065 { &hf_usb_com_get_ntb_params_reserved
,
1066 { "Reserved", "usbcom.control.get_ntb_params.reserved", FT_UINT16
, BASE_HEX
,
1067 NULL
, 0, NULL
, HFILL
}},
1068 { &hf_usb_com_get_ntb_params_ntb_out_max_size
,
1069 { "NTB OUT Max Size", "usbcom.control.get_ntb_params.ntb_out_max_size", FT_UINT32
, BASE_DEC
,
1070 NULL
, 0, NULL
, HFILL
}},
1071 { &hf_usb_com_get_ntb_params_ndp_out_divisor
,
1072 { "NDP OUT Divisor", "usbcom.control.get_ntb_params.ndp_out_divisor", FT_UINT16
, BASE_DEC
,
1073 NULL
, 0, NULL
, HFILL
}},
1074 { &hf_usb_com_get_ntb_params_ndp_out_payload_remainder
,
1075 { "NDP OUT Payload Remainder", "usbcom.control.get_ntb_params.ndp_out_payload_remainder", FT_UINT16
, BASE_DEC
,
1076 NULL
, 0, NULL
, HFILL
}},
1077 { &hf_usb_com_get_ntb_params_ndp_out_alignment
,
1078 { "NDP OUT Alignment", "usbcom.control.get_ntb_params.ndp_out_alignment", FT_UINT16
, BASE_DEC
,
1079 NULL
, 0, NULL
, HFILL
}},
1080 { &hf_usb_com_get_ntb_params_ntb_out_max_datagrams
,
1081 { "NTB OUT Max Datagrams", "usbcom.control.get_ntb_params.ntb_out_max_datagrams", FT_UINT16
, BASE_DEC
,
1082 NULL
, 0, NULL
, HFILL
}},
1083 { &hf_usb_com_get_net_address_eui48
,
1084 { "EUI-48", "usbcom.control.get_net_address.eui48", FT_ETHER
, BASE_NONE
,
1085 NULL
, 0, NULL
, HFILL
}},
1086 { &hf_usb_com_set_net_address_eui48
,
1087 { "EUI-48", "usbcom.control.set_net_address.eui48", FT_ETHER
, BASE_NONE
,
1088 NULL
, 0, NULL
, HFILL
}},
1089 { &hf_usb_com_get_ntb_format_ntb_format
,
1090 { "NTB Format", "usbcom.control.get_net_address.ntb_format", FT_UINT16
, BASE_HEX
,
1091 VALS(usb_com_ntb_format_vals
), 0, NULL
, HFILL
}},
1092 { &hf_usb_com_set_ntb_format_ntb_format
,
1093 { "NTB Format", "usbcom.control.set_net_address.ntb_format", FT_UINT16
, BASE_HEX
,
1094 VALS(usb_com_ntb_format_vals
), 0, NULL
, HFILL
}},
1095 { &hf_usb_com_get_ntb_input_size_ntb_in_max_size
,
1096 { "NTB IN Max Size", "usbcom.control.get_ntb_input_size.ntb_in_max_size", FT_UINT32
, BASE_DEC
,
1097 NULL
, 0, NULL
, HFILL
}},
1098 { &hf_usb_com_get_ntb_input_size_ntb_in_max_datagrams
,
1099 { "NTB IN Max Datagrams", "usbcom.control.get_ntb_input_size.ntb_in_max_datagrams", FT_UINT16
, BASE_DEC
,
1100 NULL
, 0, NULL
, HFILL
}},
1101 { &hf_usb_com_get_ntb_input_size_reserved
,
1102 { "Reserved", "usbcom.control.get_ntb_input_size.reserved", FT_UINT16
, BASE_HEX
,
1103 NULL
, 0, NULL
, HFILL
}},
1104 { &hf_usb_com_set_ntb_input_size_ntb_in_max_size
,
1105 { "NTB IN Max Size", "usbcom.control.set_ntb_input_size.ntb_in_max_size", FT_UINT32
, BASE_DEC
,
1106 NULL
, 0, NULL
, HFILL
}},
1107 { &hf_usb_com_set_ntb_input_size_ntb_in_max_datagrams
,
1108 { "NTB IN Max Datagrams", "usbcom.control.set_ntb_input_size.ntb_in_max_datagrams", FT_UINT16
, BASE_DEC
,
1109 NULL
, 0, NULL
, HFILL
}},
1110 { &hf_usb_com_set_ntb_input_size_reserved
,
1111 { "Reserved", "usbcom.control.set_ntb_input_size.reserved", FT_UINT16
, BASE_HEX
,
1112 NULL
, 0, NULL
, HFILL
}},
1113 { &hf_usb_com_get_max_datagram_size_size
,
1114 { "Max Datagram Size", "usbcom.control.get_max_datagram_size.size", FT_UINT16
, BASE_DEC
,
1115 NULL
, 0, NULL
, HFILL
}},
1116 { &hf_usb_com_set_max_datagram_size_size
,
1117 { "Max Datagram Size", "usbcom.control.set_max_datagram_size.size", FT_UINT16
, BASE_DEC
,
1118 NULL
, 0, NULL
, HFILL
}},
1119 { &hf_usb_com_get_crc_mode_crc_mode
,
1120 { "CRC Mode", "usbcom.control.get_crc_mode.crc_mode", FT_UINT16
, BASE_HEX
,
1121 VALS(usb_com_crc_mode_vals
), 0, NULL
, HFILL
}},
1122 { &hf_usb_com_set_crc_mode_crc_mode
,
1123 { "CRC Mode", "usbcom.control.set_crc_mode.crc_mode", FT_UINT16
, BASE_HEX
,
1124 VALS(usb_com_crc_mode_vals
), 0, NULL
, HFILL
}},
1125 { &hf_usb_com_control_payload
,
1126 { "Payload", "usbcom.control.payload", FT_BYTES
, BASE_NONE
,
1127 NULL
, 0, NULL
, HFILL
}},
1128 { &hf_usb_com_capabilities
,
1129 { "bmCapabilities", "usbcom.descriptor.capabilities", FT_UINT8
, BASE_HEX
,
1130 NULL
, 0, NULL
, HFILL
}},
1131 { &hf_usb_com_descriptor_acm_capabilities_reserved
,
1132 { "Reserved", "usbcom.descriptor.acm.capabilities.reserved", FT_UINT8
, BASE_HEX
,
1133 NULL
, 0xF0, NULL
, HFILL
}},
1134 { &hf_usb_com_descriptor_acm_capabilities_network_connection
,
1135 { "Network_Connection", "usbcom.descriptor.acm.capabilities.network_connection", FT_BOOLEAN
, 8,
1136 TFS(&tfs_supported_not_supported
), 0x08, NULL
, HFILL
}},
1137 { &hf_usb_com_descriptor_acm_capabilities_send_break
,
1138 { "Send_Break", "usbcom.descriptor.acm.capabilities.send_break", FT_BOOLEAN
, 8,
1139 TFS(&tfs_supported_not_supported
), 0x04, NULL
, HFILL
}},
1140 { &hf_usb_com_descriptor_acm_capabilities_line_and_state
,
1141 { "Line Requests and State Notification", "usbcom.descriptor.acm.capabilities.line_and_state", FT_BOOLEAN
, 8,
1142 TFS(&tfs_supported_not_supported
), 0x02, NULL
, HFILL
}},
1143 { &hf_usb_com_descriptor_acm_capabilities_comm_features
,
1144 { "Comm Features Combinations", "usbcom.descriptor.acm.capabilities.comm_features", FT_BOOLEAN
, 8,
1145 TFS(&tfs_supported_not_supported
), 0x01, NULL
, HFILL
}},
1146 { &hf_usb_com_descriptor_control_interface
,
1147 { "Control Interface", "usbcom.descriptor.control_interface", FT_UINT8
, BASE_HEX
,
1148 NULL
, 0, NULL
, HFILL
}},
1149 { &hf_usb_com_descriptor_subordinate_interface
,
1150 { "Subordinate Interface", "usbcom.descriptor.subordinate_interface", FT_UINT8
, BASE_HEX
,
1151 NULL
, 0, NULL
, HFILL
}},
1152 { &hf_usb_com_descriptor_cm_capabilities_reserved
,
1153 { "Reserved", "usbcom.descriptor.cm.capabilities.reserved", FT_UINT8
, BASE_HEX
,
1154 NULL
, 0xFC, NULL
, HFILL
}},
1155 { &hf_usb_com_descriptor_cm_capabilities_call_management_over_data_class_interface
,
1156 { "Call Management over Data Class Interface", "usbcom.descriptor.cm.capabilities.call_management_over_data_class_interface", FT_BOOLEAN
, 8,
1157 TFS(&tfs_supported_not_supported
), 0x02, NULL
, HFILL
}},
1158 { &hf_usb_com_descriptor_cm_capabilities_call_management
,
1159 { "Call Management", "usbcom.descriptor.cm.capabilities.call_management", FT_BOOLEAN
, 8,
1160 TFS(&tfs_supported_not_supported
), 0x01, NULL
, HFILL
}},
1161 { &hf_usb_com_descriptor_cm_data_interface
,
1162 { "Data Interface", "usbcom.descriptor.cm.data_interface", FT_UINT8
, BASE_HEX
,
1163 NULL
, 0, NULL
, HFILL
}},
1164 { &hf_usb_com_descriptor_ecm_mac_address
,
1165 { "MAC Address", "usbcom.descriptor.ecm.mac_address", FT_UINT8
, BASE_HEX
,
1166 NULL
, 0, NULL
, HFILL
}},
1167 { &hf_usb_com_descriptor_ecm_eth_stats
,
1168 { "Ethernet Statistics", "usbcom.descriptor.ecm.eth_stats", FT_UINT32
, BASE_HEX
,
1169 NULL
, 0, NULL
, HFILL
}},
1170 { &hf_usb_com_descriptor_ecm_eth_stats_reserved
,
1171 { "Reserved", "usbcom.descriptor.ecm.eth_stats.reserved", FT_UINT32
, BASE_HEX
,
1172 NULL
, 0xe0000000, NULL
, HFILL
}},
1173 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_late_collisions
,
1174 { "XMIT Late Collisions", "usbcom.descriptor.ecm.eth_stats.xmit_late_collisions", FT_BOOLEAN
, 32,
1175 TFS(&tfs_supported_not_supported
), 0x10000000, NULL
, HFILL
}},
1176 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_times_crs_lost
,
1177 { "XMIT TImes CRS Lost", "usbcom.descriptor.ecm.eth_stats.xmit_times_crs_lost", FT_BOOLEAN
, 32,
1178 TFS(&tfs_supported_not_supported
), 0x08000000, NULL
, HFILL
}},
1179 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_heartbeat_failure
,
1180 { "XMIT Heartbeat Failure", "usbcom.descriptor.ecm.eth_stats.xmit_heartbeat_failure", FT_BOOLEAN
, 32,
1181 TFS(&tfs_supported_not_supported
), 0x04000000, NULL
, HFILL
}},
1182 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_underrun
,
1183 { "XMIT Underrun", "usbcom.descriptor.ecm.eth_stats.xmit_underrun", FT_BOOLEAN
, 32,
1184 TFS(&tfs_supported_not_supported
), 0x02000000, NULL
, HFILL
}},
1185 { &hf_usb_com_descriptor_ecm_eth_stats_rcv_overrun
,
1186 { "RCV Overrun", "usbcom.descriptor.ecm.eth_stats.rcv_overrun", FT_BOOLEAN
, 32,
1187 TFS(&tfs_supported_not_supported
), 0x01000000, NULL
, HFILL
}},
1188 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_max_collisions
,
1189 { "XMIT Max Collisions", "usbcom.descriptor.ecm.eth_stats.xmit_max_collisions", FT_BOOLEAN
, 32,
1190 TFS(&tfs_supported_not_supported
), 0x00800000, NULL
, HFILL
}},
1191 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_deferred
,
1192 { "XMIT Deferred", "usbcom.descriptor.ecm.eth_stats.xmit_deferred", FT_BOOLEAN
, 32,
1193 TFS(&tfs_supported_not_supported
), 0x00400000, NULL
, HFILL
}},
1194 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_more_collisions
,
1195 { "XMIT More Collisions", "usbcom.descriptor.ecm.eth_stats.xmit_more_collisions", FT_BOOLEAN
, 32,
1196 TFS(&tfs_supported_not_supported
), 0x00200000, NULL
, HFILL
}},
1197 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_one_collision
,
1198 { "XMIT One Collision", "usbcom.descriptor.ecm.eth_stats.xmit_one_collision", FT_BOOLEAN
, 32,
1199 TFS(&tfs_supported_not_supported
), 0x00100000, NULL
, HFILL
}},
1200 { &hf_usb_com_descriptor_ecm_eth_stats_rcv_error_alignment
,
1201 { "RCV Error Alignment", "usbcom.descriptor.ecm.eth_stats.rcv_error_alignment", FT_BOOLEAN
, 32,
1202 TFS(&tfs_supported_not_supported
), 0x00080000, NULL
, HFILL
}},
1203 { &hf_usb_com_descriptor_ecm_eth_stats_transmit_queue_length
,
1204 { "Transmit Queue Length", "usbcom.descriptor.ecm.eth_stats.transmit_queue_length", FT_BOOLEAN
, 32,
1205 TFS(&tfs_supported_not_supported
), 0x00040000, NULL
, HFILL
}},
1206 { &hf_usb_com_descriptor_ecm_eth_stats_rcv_crc_error
,
1207 { "RCV CRC Error", "usbcom.descriptor.ecm.eth_stats.rcv_crc_error", FT_BOOLEAN
, 32,
1208 TFS(&tfs_supported_not_supported
), 0x00020000, NULL
, HFILL
}},
1209 { &hf_usb_com_descriptor_ecm_eth_stats_broadcast_frames_rcv
,
1210 { "Broadcast Frames RCV", "usbcom.descriptor.ecm.eth_stats.broadcast_frames_rcv", FT_BOOLEAN
, 32,
1211 TFS(&tfs_supported_not_supported
), 0x00010000, NULL
, HFILL
}},
1212 { &hf_usb_com_descriptor_ecm_eth_stats_broadcast_bytes_rcv
,
1213 { "Broadcast Bytes RCV", "usbcom.descriptor.ecm.eth_stats.broadcast_bytes_rcv", FT_BOOLEAN
, 32,
1214 TFS(&tfs_supported_not_supported
), 0x00008000, NULL
, HFILL
}},
1215 { &hf_usb_com_descriptor_ecm_eth_stats_multicast_frames_rcv
,
1216 { "Multicast Frames RCV", "usbcom.descriptor.ecm.eth_stats.multicast_frames_rcv", FT_BOOLEAN
, 32,
1217 TFS(&tfs_supported_not_supported
), 0x00004000, NULL
, HFILL
}},
1218 { &hf_usb_com_descriptor_ecm_eth_stats_multicast_bytes_rcv
,
1219 { "Multicast Bytes RCV", "usbcom.descriptor.ecm.eth_stats.multicast_bytes_rcv", FT_BOOLEAN
, 32,
1220 TFS(&tfs_supported_not_supported
), 0x00002000, NULL
, HFILL
}},
1221 { &hf_usb_com_descriptor_ecm_eth_stats_directed_frames_rcv
,
1222 { "Directed Frames RCV", "usbcom.descriptor.ecm.eth_stats.directed_frames_rcv", FT_BOOLEAN
, 32,
1223 TFS(&tfs_supported_not_supported
), 0x00001000, NULL
, HFILL
}},
1224 { &hf_usb_com_descriptor_ecm_eth_stats_directed_bytes_rcv
,
1225 { "Directed Bytes RCV", "usbcom.descriptor.ecm.eth_stats.directed_bytes_rcv", FT_BOOLEAN
, 32,
1226 TFS(&tfs_supported_not_supported
), 0x00000800, NULL
, HFILL
}},
1227 { &hf_usb_com_descriptor_ecm_eth_stats_broadcast_frames_xmit
,
1228 { "Broadcast Frames XMIT", "usbcom.descriptor.ecm.eth_stats.broadcast_frames_xmit", FT_BOOLEAN
, 32,
1229 TFS(&tfs_supported_not_supported
), 0x00000400, NULL
, HFILL
}},
1230 { &hf_usb_com_descriptor_ecm_eth_stats_broadcast_bytes_xmit
,
1231 { "Broadcast Bytes XMIT", "usbcom.descriptor.ecm.eth_stats.broadcast_bytes_xmit", FT_BOOLEAN
, 32,
1232 TFS(&tfs_supported_not_supported
), 0x00000200, NULL
, HFILL
}},
1233 { &hf_usb_com_descriptor_ecm_eth_stats_multicast_frames_xmit
,
1234 { "Multicast Frames XMIT", "usbcom.descriptor.ecm.eth_stats.multicast_frames_xmit", FT_BOOLEAN
, 32,
1235 TFS(&tfs_supported_not_supported
), 0x00000100, NULL
, HFILL
}},
1236 { &hf_usb_com_descriptor_ecm_eth_stats_multicast_bytes_xmit
,
1237 { "Multicast Bytes XMIT", "usbcom.descriptor.ecm.eth_stats.multicast_bytes_xmit", FT_BOOLEAN
, 32,
1238 TFS(&tfs_supported_not_supported
), 0x00000080, NULL
, HFILL
}},
1239 { &hf_usb_com_descriptor_ecm_eth_stats_directed_frames_xmit
,
1240 { "Directed Frames XMIT", "usbcom.descriptor.ecm.eth_stats.directed_frames_xmit", FT_BOOLEAN
, 32,
1241 TFS(&tfs_supported_not_supported
), 0x00000040, NULL
, HFILL
}},
1242 { &hf_usb_com_descriptor_ecm_eth_stats_directed_bytes_xmit
,
1243 { "Directed Bytes XMIT", "usbcom.descriptor.ecm.eth_stats.directed_bytes_xmit", FT_BOOLEAN
, 32,
1244 TFS(&tfs_supported_not_supported
), 0x00000020, NULL
, HFILL
}},
1245 { &hf_usb_com_descriptor_ecm_eth_stats_rcv_no_buffer
,
1246 { "RCV No Buffer", "usbcom.descriptor.ecm.eth_stats.rcv_no_buffer", FT_BOOLEAN
, 32,
1247 TFS(&tfs_supported_not_supported
), 0x00000010, NULL
, HFILL
}},
1248 { &hf_usb_com_descriptor_ecm_eth_stats_rcv_error
,
1249 { "RCV Error", "usbcom.descriptor.ecm.eth_stats.rcv_error", FT_BOOLEAN
, 32,
1250 TFS(&tfs_supported_not_supported
), 0x00000008, NULL
, HFILL
}},
1251 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_error
,
1252 { "XMIT Error", "usbcom.descriptor.ecm.eth_stats.xmit_error", FT_BOOLEAN
, 32,
1253 TFS(&tfs_supported_not_supported
), 0x00000004, NULL
, HFILL
}},
1254 { &hf_usb_com_descriptor_ecm_eth_stats_rvc_ok
,
1255 { "RCV OK", "usbcom.descriptor.ecm.eth_stats.rvc_ok", FT_BOOLEAN
, 32,
1256 TFS(&tfs_supported_not_supported
), 0x00000002, NULL
, HFILL
}},
1257 { &hf_usb_com_descriptor_ecm_eth_stats_xmit_ok
,
1258 { "XMIT OK", "usbcom.descriptor.ecm.eth_stats.xmit_ok", FT_BOOLEAN
, 32,
1259 TFS(&tfs_supported_not_supported
), 0x00000001, NULL
, HFILL
}},
1260 { &hf_usb_com_descriptor_ecm_max_segment_size
,
1261 { "Max Segment Size", "usbcom.descriptor.ecm.max_segment_size", FT_UINT16
, BASE_DEC
,
1262 NULL
, 0, NULL
, HFILL
}},
1263 { &hf_usb_com_descriptor_ecm_nb_mc_filters
,
1264 { "Number MC Filters", "usbcom.descriptor.ecm.nb_mc_filters", FT_UINT16
, BASE_HEX
,
1265 NULL
, 0, NULL
, HFILL
}},
1266 { &hf_usb_com_descriptor_ecm_nb_mc_filters_mc_address_filtering
,
1267 { "Multicast Address Filtering", "usbcom.descriptor.ecm.nb_mc_filters.mc_address_filtering", FT_BOOLEAN
, 16,
1268 TFS(&usb_com_ecm_mc_address_filtering
), 0x8000, NULL
, HFILL
}},
1269 { &hf_usb_com_descriptor_ecm_nb_mc_filters_nb_filters_supported
,
1270 { "Number of Multicast Address Filters Supported", "usbcom.descriptor.ecm.nb_mc_filters.nb_filters_supported", FT_UINT16
, BASE_DEC
,
1271 NULL
, 0x7fff, NULL
, HFILL
}},
1272 { &hf_usb_com_descriptor_ecm_nb_power_filters
,
1273 { "Number Power Filters", "usbcom.descriptor.ecm.nb_power_filters", FT_UINT8
, BASE_DEC
,
1274 NULL
, 0, NULL
, HFILL
}},
1275 { &hf_usb_com_interrupt_request_type
,
1276 { "Request Type", "usbcom.interrupt.request_type", FT_UINT8
, BASE_HEX
,
1277 NULL
, 0, NULL
, HFILL
}},
1278 { &hf_usb_com_interrupt_notif_code
,
1279 { "Notification Code", "usbcom.interrupt.notification_code", FT_UINT8
, BASE_HEX
,
1280 VALS(usb_com_interrupt_notif_code_vals
), 0, NULL
, HFILL
}},
1281 { &hf_usb_com_interrupt_value
,
1282 { "Value", "usbcom.interrupt.value", FT_UINT16
, BASE_HEX
,
1283 NULL
, 0, NULL
, HFILL
}},
1284 { &hf_usb_com_interrupt_value_nw_conn
,
1285 { "Value", "usbcom.interrupt.value", FT_UINT16
, BASE_HEX
,
1286 VALS(usb_com_interrupt_value_nw_conn_vals
), 0, NULL
, HFILL
}},
1287 { &hf_usb_com_interrupt_index
,
1288 { "Index", "usbcom.interrupt.index", FT_UINT16
, BASE_DEC
,
1289 NULL
, 0, NULL
, HFILL
}},
1290 { &hf_usb_com_interrupt_length
,
1291 { "Length", "usbcom.interrupt.length", FT_UINT16
, BASE_DEC
,
1292 NULL
, 0, NULL
, HFILL
}},
1293 { &hf_usb_com_interrupt_dl_bitrate
,
1294 { "DL Bitrate", "usbcom.interrupt.conn_speed_change.dl_bitrate", FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
,
1295 UNS(&units_bit_sec
), 0, NULL
, HFILL
}},
1296 { &hf_usb_com_interrupt_ul_bitrate
,
1297 { "UL Bitrate", "usbcom.interrupt.conn_speed_change.ul_bitrate", FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
,
1298 UNS(&units_bit_sec
), 0, NULL
, HFILL
}},
1299 { &hf_usb_com_interrupt_payload
,
1300 { "Payload", "usbcom.interrupt.payload", FT_BYTES
, BASE_NONE
,
1301 NULL
, 0, NULL
, HFILL
}},
1302 { &hf_usb_com_data_stream
,
1303 { "Stream index", "usbcom.data.stream", FT_UINT32
, BASE_DEC
,
1304 NULL
, 0, NULL
, HFILL
}},
1305 { &hf_usb_com_data_in_payload
,
1306 { "IN payload", "usbcom.data.in_payload", FT_BYTES
, BASE_NONE
,
1307 NULL
, 0, NULL
, HFILL
}},
1308 { &hf_usb_com_data_out_payload
,
1309 { "OUT payload", "usbcom.data.out_payload", FT_BYTES
, BASE_NONE
,
1310 NULL
, 0, NULL
, HFILL
}},
1313 static int *usb_com_ett
[] = {
1315 &ett_usb_com_capabilities
,
1316 &ett_usb_com_bitmap
,
1317 &ett_usb_com_descriptor_ecm_eth_stats
,
1318 &ett_usb_com_descriptor_ecm_nb_mc_filters
1321 static ei_register_info ei
[] = {
1322 { &ei_unexpected_controlling_iface
, { "usbcom.descriptor.control_interface.unexpected_iface", PI_MALFORMED
, PI_ERROR
, "Unexpected controlling interface index (report to wireshark.org)", EXPFILL
}},
1325 expert_module_t
* expert_usb_com
;
1327 controlling_ifaces
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
1329 proto_usb_com
= proto_register_protocol("USB Communications and CDC Control", "USBCOM", "usbcom");
1330 proto_register_field_array(proto_usb_com
, hf
, array_length(hf
));
1331 proto_register_subtree_array(usb_com_ett
, array_length(usb_com_ett
));
1333 usb_com_descriptor_handle
= register_dissector("usbcom.descriptor", dissect_usb_com_descriptor
, proto_usb_com
);
1334 usb_com_control_handle
= register_dissector("usbcom.control", dissect_usb_com_control
, proto_usb_com
);
1335 usb_com_bulk_handle
= register_dissector("usbcom.bulk", dissect_usb_com_bulk
, proto_usb_com
);
1336 usb_com_interrupt_handle
= register_dissector("usbcom.interrupt", dissect_usb_com_interrupt
, proto_usb_com
);
1338 expert_usb_com
= expert_register_protocol(proto_usb_com
);
1339 expert_register_field_array(expert_usb_com
, ei
, array_length(ei
));
1341 register_cleanup_routine(usb_com_cleanup_data
);
1343 cdc_data_follow_tap
= register_tap("cdc_data_follow");
1344 register_follow_stream(proto_usb_com
, "cdc_data_follow", cdc_data_follow_conv_filter
, cdc_data_follow_index_filter
,
1345 cdc_data_follow_address_filter
, cdc_data_port_to_display
, follow_cdc_data_tap_listener
,
1346 get_cdc_data_stream_count
, NULL
);
1350 proto_reg_handoff_usb_com(void)
1352 dissector_add_uint("usb.descriptor", IF_CLASS_COMMUNICATIONS
, usb_com_descriptor_handle
);
1353 dissector_add_uint("usb.control", IF_CLASS_COMMUNICATIONS
, usb_com_control_handle
);
1354 dissector_add_uint("usb.bulk", IF_CLASS_CDC_DATA
, usb_com_bulk_handle
);
1355 dissector_add_uint("usb.interrupt", IF_CLASS_COMMUNICATIONS
, usb_com_interrupt_handle
);
1356 mbim_control_handle
= find_dissector_add_dependency("mbim.control", proto_usb_com
);
1357 mbim_descriptor_handle
= find_dissector_add_dependency("mbim.descriptor", proto_usb_com
);
1358 mbim_bulk_handle
= find_dissector_add_dependency("mbim.bulk", proto_usb_com
);
1359 eth_withoutfcs_handle
= find_dissector_add_dependency("eth_withoutfcs", proto_usb_com
);
1361 proto_usb
= proto_get_id_by_filter_name("usb");
1365 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1370 * indent-tabs-mode: nil
1373 * vi: set shiftwidth=4 tabstop=8 expandtab:
1374 * :indentSize=4:tabSize=8:noTabs=true: