2 * Routines for Android Debug Bridge Transport Protocol
4 * Copyright 2014 Michal Labedzki for Tieto Corporation
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <epan/expert.h>
20 #include <wiretap/wtap.h>
22 #include "packet-adb_service.h"
23 #include "packet-usb.h"
26 static int hf_command
;
27 static int hf_argument_0
;
28 static int hf_argument_1
;
29 static int hf_data_length
;
30 static int hf_data_crc32
;
32 static int hf_local_id
;
33 static int hf_remote_id
;
34 static int hf_version
;
35 static int hf_max_data
;
37 static int hf_sequence
;
39 static int hf_auth_type
;
41 static int hf_service
;
42 static int hf_data_fragment
;
43 static int hf_command_in_frame
;
44 static int hf_completed_in_frame
;
45 static int hf_service_start_in_frame
;
46 static int hf_close_local_in_frame
;
47 static int hf_close_remote_in_frame
;
48 static int hf_connection_info
;
51 static int ett_adb_arg0
;
52 static int ett_adb_arg1
;
53 static int ett_adb_crc
;
54 static int ett_adb_magic
;
56 static expert_field ei_invalid_magic
;
57 static expert_field ei_invalid_crc
;
58 static expert_field ei_invalid_data
;
60 static dissector_handle_t adb_handle
;
61 static dissector_handle_t adb_service_handle
;
66 static wmem_tree_t
*command_info
;
67 static wmem_tree_t
*service_info
;
69 typedef struct service_data_t
{
70 uint32_t start_in_frame
;
72 uint32_t close_local_in_frame
;
73 uint32_t close_remote_in_frame
;
81 typedef struct command_data_t
{
84 uint32_t command_in_frame
;
85 uint32_t response_in_frame
;
93 uint32_t completed_in_frame
;
94 uint32_t reassemble_data_length
;
95 uint8_t *reassemble_data
;
96 uint32_t reassemble_error_in_frame
;
99 static uint32_t max_in_frame
= UINT32_MAX
;
101 static const value_string command_vals
[] = {
102 { 0x434e5953, "Synchronize" },
103 { 0x45534c43, "Close" },
104 { 0x45545257, "Write" },
105 { 0x48545541, "Authenticate" },
106 { 0x4e584e43, "Connect" },
107 { 0x4e45504f, "Open" },
108 { 0x59414b4f, "Okay" },
112 static const value_string magic_vals
[] = {
113 { 0xFFFFFFFF ^ 0x434e5953, "Synchronize" },
114 { 0xFFFFFFFF ^ 0x45534c43, "Close" },
115 { 0xFFFFFFFF ^ 0x45545257, "Write" },
116 { 0xFFFFFFFF ^ 0x48545541, "Authenticate" },
117 { 0xFFFFFFFF ^ 0x4e584e43, "Connect" },
118 { 0xFFFFFFFF ^ 0x4e45504f, "Open" },
119 { 0xFFFFFFFF ^ 0x59414b4f, "Okay" },
123 static const value_string auth_type_vals
[] = {
126 { 3, "RSA Public Key" },
130 #define A_SYNC 0x434e5953
131 #define A_CLSE 0x45534c43
132 #define A_WRTE 0x45545257
133 #define A_AUTH 0x48545541
134 #define A_CNXN 0x4e584e43
135 #define A_OPEN 0x4e45504f
136 #define A_OKAY 0x59414b4f
138 #define ADB_TCP_PORT 5555
140 void proto_register_adb(void);
141 void proto_reg_handoff_adb(void);
144 save_command(uint32_t cmd
, uint32_t arg0
, uint32_t arg1
, uint32_t data_length
,
145 uint32_t crc32
, service_data_t
*service_data
, int proto
, void *data
,
146 packet_info
*pinfo
, service_data_t
**returned_service_data
,
147 command_data_t
**returned_command_data
)
149 wmem_tree_key_t key
[6];
150 uint32_t interface_id
;
152 uint32_t device_address
;
154 uint32_t frame_number
;
155 command_data_t
*command_data
;
156 wmem_tree_t
*wmem_tree
;
157 int direction
= P2P_DIR_UNKNOWN
;
158 urb_info_t
*urb
= (urb_info_t
*) data
;
160 frame_number
= pinfo
->num
;
162 if (pinfo
->rec
->presence_flags
& WTAP_HAS_INTERFACE_ID
)
163 interface_id
= pinfo
->rec
->rec_header
.packet_header
.interface_id
;
167 if (proto
== proto_usb
) {
168 urb
= (urb_info_t
*) data
;
169 DISSECTOR_ASSERT(urb
);
171 direction
= urb
->direction
;
173 bus_id
= urb
->bus_id
;
174 device_address
= urb
->device_address
;
177 key
[0].key
= &interface_id
;
179 key
[1].key
= &bus_id
;
181 key
[2].key
= &device_address
;
183 key
[3].key
= &side_id
;
185 key
[4].key
= &frame_number
;
189 if (pinfo
->destport
== ADB_TCP_PORT
)
190 direction
= P2P_DIR_SENT
;
192 direction
= P2P_DIR_RECV
;
195 key
[0].key
= &interface_id
;
198 if (direction
== P2P_DIR_SENT
) {
199 key
[1].key
= &pinfo
->srcport
;
200 key
[2].key
= &pinfo
->destport
;
202 key
[1].key
= &pinfo
->destport
;
203 key
[2].key
= &pinfo
->srcport
;
206 key
[3].key
= &side_id
;
208 key
[4].key
= &frame_number
;
213 if (direction
== P2P_DIR_SENT
)
215 side_id
= arg1
; /* OUT: local id */
217 side_id
= arg0
; /* OUT: local id */
219 side_id
= arg1
; /* IN: remote id */
222 service_data
= wmem_new(wmem_file_scope(), service_data_t
);
224 service_data
->start_in_frame
= pinfo
->num
;
225 service_data
->close_local_in_frame
= max_in_frame
;
226 service_data
->close_remote_in_frame
= max_in_frame
;
228 service_data
->local_id
= arg0
;
229 service_data
->remote_id
= arg1
;
231 service_data
->service
= "unknown";
233 wmem_tree_insert32_array(service_info
, key
, service_data
);
236 command_data
= wmem_new(wmem_file_scope(), command_data_t
);
238 command_data
->command
= cmd
;
239 command_data
->arg0
= arg0
;
240 command_data
->arg1
= arg1
;
242 command_data
->command_in_frame
= pinfo
->num
;
243 command_data
->response_in_frame
= max_in_frame
;
245 command_data
->crc32
= crc32
;
246 command_data
->data_length
= data_length
;
247 if (data_length
== 0)
248 command_data
->completed_in_frame
= pinfo
->num
;
250 command_data
->completed_in_frame
= max_in_frame
;
251 command_data
->reassemble_data_length
= 0;
252 command_data
->reassemble_data
= (uint8_t *) wmem_alloc(wmem_file_scope(), command_data
->data_length
);
253 command_data
->reassemble_error_in_frame
= 0;
256 key
[3].key
= &frame_number
;
259 wmem_tree_insert32_array(command_info
, key
, command_data
);
261 if (direction
== P2P_DIR_SENT
)
262 if (command_data
->command
== A_CLSE
)
263 side_id
= command_data
->arg1
; /* OUT: local id */
265 side_id
= command_data
->arg0
; /* OUT: local id */
267 side_id
= command_data
->arg1
; /* IN: remote id */
270 key
[3].key
= &side_id
;
274 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(service_info
, key
);
276 service_data
= (service_data_t
*) wmem_tree_lookup32_le(wmem_tree
, frame_number
);
281 if (direction
== P2P_DIR_SENT
)
282 side_id
= command_data
->arg0
; /* OUT: local id */
284 side_id
= command_data
->arg1
; /* IN: remote id */
286 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(service_info
, key
);
288 service_data
= (service_data_t
*) wmem_tree_lookup32_le(wmem_tree
, frame_number
);
292 if (service_data
&& service_data
->remote_id
== 0 && direction
== P2P_DIR_RECV
) {
293 if (direction
== P2P_DIR_SENT
) {
294 service_data
->remote_id
= arg1
;
296 service_data
->remote_id
= arg0
;
299 side_id
= service_data
->remote_id
;
302 key
[4].key
= &frame_number
;
306 wmem_tree_insert32_array(service_info
, key
, service_data
);
308 } else if (cmd
== A_CLSE
) {
310 if (direction
== P2P_DIR_RECV
&& service_data
->local_id
== arg1
)
311 service_data
->close_local_in_frame
= pinfo
->num
;
312 else if (direction
== P2P_DIR_SENT
&& service_data
->remote_id
== arg1
)
313 service_data
->close_remote_in_frame
= pinfo
->num
;
317 DISSECTOR_ASSERT(returned_service_data
&& returned_command_data
);
318 *returned_service_data
= service_data
;
319 *returned_command_data
= command_data
;
323 dissect_adb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
325 proto_item
*main_item
;
326 proto_tree
*main_tree
;
327 proto_item
*arg0_item
;
328 proto_tree
*arg0_tree
;
329 proto_item
*arg1_item
;
330 proto_tree
*arg1_tree
;
331 proto_item
*magic_item
;
332 proto_item
*crc_item
;
333 proto_tree
*crc_tree
= NULL
;
334 proto_item
*sub_item
;
339 uint32_t data_length
= 0;
341 urb_info_t
*urb
= NULL
;
342 wmem_tree_key_t key
[5];
343 uint32_t interface_id
;
345 uint32_t device_address
;
347 uint32_t frame_number
;
348 bool is_command
= true;
349 bool is_next_fragment
= false;
350 bool is_service
= false;
352 int direction
= P2P_DIR_UNKNOWN
;
353 wmem_tree_t
*wmem_tree
;
354 command_data_t
*command_data
= NULL
;
355 service_data_t
*service_data
= NULL
;
357 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ADB");
358 col_clear(pinfo
->cinfo
, COL_INFO
);
360 main_item
= proto_tree_add_item(tree
, proto_adb
, tvb
, offset
, -1, ENC_NA
);
361 main_tree
= proto_item_add_subtree(main_item
, ett_adb
);
363 frame_number
= pinfo
->num
;
365 /* XXX: Why? If interface is USB only first try is correct
366 * (and seems strange...), in other cases standard check for
367 * previous protocol is correct */
368 proto
= (int) GPOINTER_TO_INT(wmem_list_frame_data(/*wmem_list_frame_prev*/(wmem_list_tail(pinfo
->layers
))));
369 if (proto
!= proto_usb
) {
370 proto
= (int) GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo
->layers
))));
373 if (proto
== proto_usb
) {
374 urb
= (urb_info_t
*) data
;
375 DISSECTOR_ASSERT(urb
);
377 direction
= urb
->direction
;
378 } else if (proto
== proto_tcp
) {
379 if (pinfo
->destport
== ADB_TCP_PORT
)
380 direction
= P2P_DIR_SENT
;
382 direction
= P2P_DIR_RECV
;
387 if (pinfo
->rec
->presence_flags
& WTAP_HAS_INTERFACE_ID
)
388 interface_id
= pinfo
->rec
->rec_header
.packet_header
.interface_id
;
392 if (proto
== proto_usb
) {
393 bus_id
= urb
->bus_id
;
394 device_address
= urb
->device_address
;
397 key
[0].key
= &interface_id
;
399 key
[1].key
= &bus_id
;
401 key
[2].key
= &device_address
;
406 key
[0].key
= &interface_id
;
409 if (direction
== P2P_DIR_SENT
) {
410 key
[1].key
= &pinfo
->srcport
;
411 key
[2].key
= &pinfo
->destport
;
413 key
[1].key
= &pinfo
->destport
;
414 key
[2].key
= &pinfo
->srcport
;
420 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(command_info
, key
);
422 command_data
= (command_data_t
*) wmem_tree_lookup32_le(wmem_tree
, frame_number
);
423 if (command_data
&& command_data
->completed_in_frame
>= frame_number
&&
424 command_data
->command_in_frame
<= frame_number
) {
426 if (command_data
->command_in_frame
!= frame_number
) {
428 is_next_fragment
= true;
431 data_length
= command_data
->data_length
;
432 crc32
= command_data
->crc32
;
434 if (direction
== P2P_DIR_SENT
) {
435 if (command_data
->command
== A_CLSE
)
436 side_id
= command_data
->arg1
; /* OUT: local id */
438 side_id
= command_data
->arg0
; /* OUT: local id */
440 side_id
= command_data
->arg1
; /* IN: remote id */
444 key
[3].key
= &side_id
;
448 wmem_tree
= (wmem_tree_t
*) wmem_tree_lookup32_array(service_info
, key
);
450 service_data
= (service_data_t
*) wmem_tree_lookup32_le(wmem_tree
, frame_number
);
451 if (service_data
&& command_data
->command
== A_OPEN
) {
458 /* Simple heuristics to check if packet is command or data */
459 if ((command_data
&& command_data
->completed_in_frame
<= frame_number
) || !command_data
) {
460 if (tvb_reported_length(tvb
) < 24) {
462 } else if (tvb_reported_length(tvb
) >= 24) {
463 command
= tvb_get_letohl(tvb
, offset
);
465 if (command
!= A_SYNC
&& command
!= A_CLSE
&& command
!= A_WRTE
&&
466 command
!= A_AUTH
&& command
!= A_CNXN
&& command
!= A_OPEN
&& command
!= A_OKAY
)
468 else if (command
!= (0xFFFFFFFF ^ tvb_get_letohl(tvb
, offset
+ 20)))
472 data_length
= tvb_get_letohl(tvb
, offset
+ 12);
473 crc32
= tvb_get_letohl(tvb
, offset
+ 16);
475 if (command
== A_OPEN
) is_service
= true;
479 if (service_data
&& !(command_data
->command
== A_OPEN
&& is_next_fragment
)) {
480 sub_item
= proto_tree_add_string(main_tree
, hf_service
, tvb
, offset
, 0, service_data
->service
);
481 proto_item_set_generated(sub_item
);
485 sub_item
= proto_tree_add_uint(main_tree
, hf_service_start_in_frame
, tvb
, offset
, 0, service_data
->start_in_frame
);
486 proto_item_set_generated(sub_item
);
488 if (service_data
->close_local_in_frame
< max_in_frame
) {
489 sub_item
= proto_tree_add_uint(main_tree
, hf_close_local_in_frame
, tvb
, offset
, 0, service_data
->close_local_in_frame
);
490 proto_item_set_generated(sub_item
);
493 if (service_data
->close_remote_in_frame
< max_in_frame
) {
494 sub_item
= proto_tree_add_uint(main_tree
, hf_close_remote_in_frame
, tvb
, offset
, 0, service_data
->close_remote_in_frame
);
495 proto_item_set_generated(sub_item
);
500 proto_tree_add_item(main_tree
, hf_command
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
501 command
= tvb_get_letohl(tvb
, offset
);
504 col_append_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(command
, command_vals
, "Unknown command"));
506 arg0_item
= proto_tree_add_item(main_tree
, hf_argument_0
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
507 arg0_tree
= proto_item_add_subtree(arg0_item
, ett_adb_arg0
);
508 arg0
= tvb_get_letohl(tvb
, offset
);
511 arg1_item
= proto_tree_add_item(main_tree
, hf_argument_1
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
512 arg1_tree
= proto_item_add_subtree(arg1_item
, ett_adb_arg1
);
513 arg1
= tvb_get_letohl(tvb
, offset
);
518 proto_tree_add_item(arg0_tree
, hf_version
, tvb
, offset
- 8, 4, ENC_LITTLE_ENDIAN
);
519 proto_tree_add_item(arg1_tree
, hf_max_data
, tvb
, offset
- 4, 4, ENC_LITTLE_ENDIAN
);
521 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(version=%u.%u.%u, max_data=%u)", tvb_get_uint8(tvb
, offset
- 5), tvb_get_uint8(tvb
, offset
- 6), tvb_get_letohs(tvb
, offset
- 7), tvb_get_letohl(tvb
, offset
- 4));
524 proto_tree_add_item(arg0_tree
, hf_auth_type
, tvb
, offset
- 8, 4, ENC_LITTLE_ENDIAN
);
525 proto_tree_add_item(arg1_tree
, hf_zero
, tvb
, offset
- 4, 4, ENC_LITTLE_ENDIAN
);
527 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(type=%s, 0)", val_to_str_const(tvb_get_letohl(tvb
, offset
- 8), auth_type_vals
, "Unknown"));
530 proto_tree_add_item(arg0_tree
, hf_local_id
, tvb
, offset
- 8, 4, ENC_LITTLE_ENDIAN
);
531 proto_tree_add_item(arg1_tree
, hf_zero
, tvb
, offset
- 4, 4, ENC_LITTLE_ENDIAN
);
533 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(local=%u, 0)", tvb_get_letohl(tvb
, offset
- 8));
536 proto_tree_add_item(arg0_tree
, hf_local_id
, tvb
, offset
- 8, 4, ENC_LITTLE_ENDIAN
);
537 proto_tree_add_item(arg1_tree
, hf_remote_id
, tvb
, offset
- 4, 4, ENC_LITTLE_ENDIAN
);
539 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(local=%u, remote=%u)", arg0
, arg1
);
543 proto_tree_add_item(arg0_tree
, hf_local_id
, tvb
, offset
- 8, 4, ENC_LITTLE_ENDIAN
);
544 proto_tree_add_item(arg1_tree
, hf_remote_id
, tvb
, offset
- 4, 4, ENC_LITTLE_ENDIAN
);
546 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(local=%u, remote=%u)", tvb_get_letohl(tvb
, offset
- 8), tvb_get_letohl(tvb
, offset
- 4));
549 proto_tree_add_item(arg0_tree
, hf_online
, tvb
, offset
- 8, 4, ENC_LITTLE_ENDIAN
);
550 proto_tree_add_item(arg1_tree
, hf_sequence
, tvb
, offset
- 4, 4, ENC_LITTLE_ENDIAN
);
552 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "(online=%s, sequence=%u)", tvb_get_letohl(tvb
, offset
- 8) ? "Yes": "No", tvb_get_letohl(tvb
, offset
- 4));
556 proto_tree_add_item(main_tree
, hf_data_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
560 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " length=%u ", data_length
);
562 crc_item
= proto_tree_add_item(main_tree
, hf_data_crc32
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
563 crc_tree
= proto_item_add_subtree(crc_item
, ett_adb_crc
);
564 crc32
= tvb_get_letohl(tvb
, offset
);
567 magic_item
= proto_tree_add_item(main_tree
, hf_magic
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
568 if ((tvb_get_letohl(tvb
, offset
) ^ 0xFFFFFFFF) != command
) {
569 proto_tree
*expert_tree
;
571 expert_tree
= proto_item_add_subtree(magic_item
, ett_adb_magic
);
572 proto_tree_add_expert(expert_tree
, pinfo
, &ei_invalid_magic
, tvb
, offset
, 4);
575 if (!pinfo
->fd
->visited
)
576 save_command(command
, arg0
, arg1
, data_length
, crc32
, service_data
, proto
, data
, pinfo
, &service_data
, &command_data
);
580 if (!pinfo
->fd
->visited
&& command_data
) {
581 if (command_data
->command_in_frame
!= frame_number
) {
583 is_next_fragment
= true;
586 data_length
= command_data
->data_length
;
587 crc32
= command_data
->crc32
;
589 if ((command_data
->command_in_frame
!= frame_number
&& tvb_captured_length(tvb
) == data_length
) ||
590 (command_data
->command_in_frame
== frame_number
&& tvb_captured_length(tvb
) == data_length
+ 24)
592 command_data
->reassemble_data_length
= command_data
->data_length
;
593 command_data
->completed_in_frame
= frame_number
;
597 if (is_next_fragment
&& command_data
) {
598 sub_item
= proto_tree_add_uint(main_tree
, hf_command_in_frame
, tvb
, offset
, 0, command_data
->command_in_frame
);
599 proto_item_set_generated(sub_item
);
601 sub_item
= proto_tree_add_uint(main_tree
, hf_command
, tvb
, offset
, 0, command_data
->command
);
602 proto_item_set_generated(sub_item
);
604 sub_item
= proto_tree_add_uint(main_tree
, hf_data_length
, tvb
, offset
, 0, command_data
->data_length
);
605 proto_item_set_generated(sub_item
);
607 crc_item
= proto_tree_add_uint(main_tree
, hf_data_crc32
, tvb
, offset
, 0, command_data
->crc32
);
608 crc_tree
= proto_item_add_subtree(crc_item
, ett_adb_crc
);
609 proto_item_set_generated(crc_item
);
612 if (command_data
&& command_data
->completed_in_frame
!= frame_number
) {
613 sub_item
= proto_tree_add_uint(main_tree
, hf_completed_in_frame
, tvb
, offset
, 0, command_data
->completed_in_frame
);
614 proto_item_set_generated(sub_item
);
618 if (tvb_captured_length_remaining(tvb
, offset
) > 0 && (!is_command
|| data_length
> 0)) {
622 /* First pass: store message payload (usually a single packet, but
623 * potentially multiple fragments). */
624 if (!pinfo
->fd
->visited
&& command_data
&& command_data
->reassemble_data_length
< command_data
->data_length
) {
625 unsigned chunklen
= tvb_captured_length_remaining(tvb
, offset
);
626 if (chunklen
> command_data
->data_length
- command_data
->reassemble_data_length
) {
627 chunklen
= command_data
->data_length
- command_data
->reassemble_data_length
;
628 /* This should never happen, but when it does, then either we
629 * have a malicious application OR we failed to correctly match
630 * this payload with a message header. */
631 command_data
->reassemble_error_in_frame
= frame_number
;
634 tvb_memcpy(tvb
, command_data
->reassemble_data
+ command_data
->reassemble_data_length
, offset
, chunklen
);
635 command_data
->reassemble_data_length
+= chunklen
;
637 if (command_data
->reassemble_data_length
>= command_data
->data_length
)
638 command_data
->completed_in_frame
= frame_number
;
641 if (frame_number
== command_data
->reassemble_error_in_frame
) {
642 /* data reassembly error was detected in the first pass. */
643 proto_tree_add_expert(main_tree
, pinfo
, &ei_invalid_data
, tvb
, offset
, -1);
646 if ((!pinfo
->fd
->visited
&& command_data
&& command_data
->reassemble_data_length
< command_data
->data_length
) || data_length
> (uint32_t) tvb_captured_length_remaining(tvb
, offset
)) { /* need reassemble */
647 proto_tree_add_item(main_tree
, hf_data_fragment
, tvb
, offset
, -1, ENC_NA
);
648 col_append_str(pinfo
->cinfo
, COL_INFO
, "Data Fragment");
649 offset
= tvb_captured_length(tvb
);
651 if (service_data
&& command_data
&& command_data
->reassemble_data_length
>= command_data
->data_length
&& frame_number
== command_data
->completed_in_frame
) {
653 adb_service_data_t adb_service_data
;
655 next_tvb
= tvb_new_child_real_data(tvb
, command_data
->reassemble_data
, command_data
->reassemble_data_length
, command_data
->reassemble_data_length
);
656 add_new_data_source(pinfo
, next_tvb
, "ADB Reassembled Data");
658 adb_service_data
.service
= service_data
->service
;
659 adb_service_data
.direction
= direction
;
661 adb_service_data
.session_key_length
= 3;
662 adb_service_data
.session_key
= (uint32_t *) wmem_alloc(pinfo
->pool
, adb_service_data
.session_key_length
* sizeof(uint32_t));
663 adb_service_data
.session_key
[0] = interface_id
;
665 if (proto
== proto_usb
) {
666 adb_service_data
.session_key
[1] = urb
->bus_id
;
667 adb_service_data
.session_key
[2] = urb
->device_address
;
669 if (direction
== P2P_DIR_SENT
) {
670 adb_service_data
.session_key
[1] = pinfo
->srcport
;
671 adb_service_data
.session_key
[2] = pinfo
->destport
;
673 adb_service_data
.session_key
[1] = pinfo
->destport
;
674 adb_service_data
.session_key
[2] = pinfo
->srcport
;
678 call_dissector_with_data(adb_service_handle
, next_tvb
, pinfo
, tree
, &adb_service_data
);
680 } else { /* full message */
681 for (i_offset
= 0; i_offset
< data_length
; ++i_offset
)
682 crc
+= tvb_get_uint8(tvb
, offset
+ i_offset
);
684 if (crc32
> 0 && crc32
!= crc
)
685 proto_tree_add_expert(crc_tree
, pinfo
, &ei_invalid_crc
, tvb
, offset
, -1);
688 proto_tree_add_item(main_tree
, hf_service
, tvb
, offset
, -1, ENC_ASCII
| ENC_NA
);
689 if (!pinfo
->fd
->visited
&& service_data
) {
690 service_data
->service
= (char *) tvb_get_stringz_enc(wmem_file_scope(), tvb
, offset
, NULL
, ENC_ASCII
);
692 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Service: %s", tvb_get_stringz_enc(pinfo
->pool
, tvb
, offset
, NULL
, ENC_ASCII
));
693 offset
= tvb_captured_length(tvb
);
694 } else if (command_data
&& command_data
->command
== A_CNXN
) {
698 * Format: "<systemtype>:<serialno>:<banner>".
699 * Previously adb used "device::ro.product.name=...;...;\0" as
700 * human-readable banner, but since platform/system/core commit
701 * 1792c23cb8 (2015-05-18) it is a ";"-separated feature list.
704 proto_tree_add_item_ret_string(main_tree
, hf_connection_info
, tvb
, offset
, -1, ENC_ASCII
| ENC_NA
, pinfo
->pool
, &info
);
705 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Connection Info: %s", info
);
706 offset
= tvb_captured_length(tvb
);
708 col_append_str(pinfo
->cinfo
, COL_INFO
, "Data");
710 /* Decode service payload */
713 adb_service_data_t adb_service_data
;
715 adb_service_data
.service
= service_data
->service
;
716 adb_service_data
.direction
= direction
;
718 adb_service_data
.session_key_length
= 3;
719 adb_service_data
.session_key
= (uint32_t *) wmem_alloc(pinfo
->pool
, adb_service_data
.session_key_length
* sizeof(uint32_t));
720 adb_service_data
.session_key
[0] = interface_id
;
722 if (proto
== proto_usb
) {
723 adb_service_data
.session_key
[1] = urb
->bus_id
;
724 adb_service_data
.session_key
[2] = urb
->device_address
;
726 if (direction
== P2P_DIR_SENT
) {
727 adb_service_data
.session_key
[1] = pinfo
->srcport
;
728 adb_service_data
.session_key
[2] = pinfo
->destport
;
730 adb_service_data
.session_key
[1] = pinfo
->destport
;
731 adb_service_data
.session_key
[2] = pinfo
->srcport
;
735 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
736 call_dissector_with_data(adb_service_handle
, next_tvb
, pinfo
, tree
, &adb_service_data
);
739 proto_item
*data_item
;
742 data_item
= proto_tree_add_item(main_tree
, hf_data
, tvb
, offset
, data_length
, ENC_NA
);
743 data_str
= tvb_format_text(pinfo
->pool
, tvb
, offset
, data_length
);
744 proto_item_append_text(data_item
, ": %s", data_str
);
745 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Raw: %s", data_str
);
748 offset
= tvb_captured_length(tvb
);
757 proto_register_adb(void)
760 expert_module_t
*expert_module
;
762 static hf_register_info hf
[] = {
764 { "Command", "adb.command",
765 FT_UINT32
, BASE_HEX
, VALS(command_vals
), 0x00,
769 { "Argument 0", "adb.argument.0",
770 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
774 { "Argument 1", "adb.argument.1",
775 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
779 { "Data Length", "adb.data_length",
780 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
784 { "Data CRC32", "adb.data_crc32",
785 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
789 { "Magic", "adb.magic",
790 FT_UINT32
, BASE_HEX
, VALS(magic_vals
), 0x00,
794 { "Version", "adb.version",
795 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
799 { "Max Data", "adb.max_data",
800 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
804 { "Type", "adb.auth_type",
805 FT_UINT32
, BASE_HEX
, VALS(auth_type_vals
), 0x00,
809 { "Online", "adb.online",
810 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_no_yes
), 0x00,
814 { "Sequence", "adb.sequence",
815 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
819 { "Zero", "adb.zero",
820 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
824 { "Local ID", "adb.local_id",
825 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
829 { "Remote ID", "adb.remote_id",
830 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
834 { "Data", "adb.data",
835 FT_NONE
, BASE_NONE
, NULL
, 0x00,
839 { "Service", "adb.service",
840 FT_STRING
, BASE_NONE
, NULL
, 0x00,
844 { "Data Fragment", "adb.data_fragment",
845 FT_NONE
, BASE_NONE
, NULL
, 0x00,
848 { &hf_service_start_in_frame
,
849 { "Service Start in Frame", "adb.service_start_in_frame",
850 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
853 { &hf_close_local_in_frame
,
854 { "Local Service Close in Frame", "adb.close_local_in_frame",
855 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
858 { &hf_close_remote_in_frame
,
859 { "Remote Service Close in Frame", "adb.close_remote_in_frame",
860 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
863 { &hf_command_in_frame
,
864 { "Command in Frame", "adb.command_in_frame",
865 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
868 { &hf_completed_in_frame
,
869 { "Completed in Frame", "adb.completed_in_frame",
870 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x00,
873 { &hf_connection_info
,
874 { "Info", "adb.connection_info",
875 FT_STRING
, BASE_NONE
, NULL
, 0x00,
880 static int *ett
[] = {
888 static ei_register_info ei
[] = {
889 { &ei_invalid_magic
, { "adb.expert.invalid_magic", PI_PROTOCOL
, PI_WARN
, "Invalid Magic", EXPFILL
}},
890 { &ei_invalid_crc
, { "adb.expert.crc_error", PI_PROTOCOL
, PI_ERROR
, "CRC32 Error", EXPFILL
}},
891 { &ei_invalid_data
, { "adb.expert.data_error", PI_PROTOCOL
, PI_ERROR
, "Mismatch between message payload size and data length", EXPFILL
}},
894 command_info
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
895 service_info
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
897 proto_adb
= proto_register_protocol("Android Debug Bridge", "ADB", "adb");
898 adb_handle
= register_dissector("adb", dissect_adb
, proto_adb
);
900 proto_register_field_array(proto_adb
, hf
, array_length(hf
));
901 proto_register_subtree_array(ett
, array_length(ett
));
902 expert_module
= expert_register_protocol(proto_adb
);
903 expert_register_field_array(expert_module
, ei
, array_length(ei
));
905 module
= prefs_register_protocol(proto_adb
, NULL
);
906 prefs_register_static_text_preference(module
, "version",
907 "ADB protocol version is compatible prior to: adb 1.0.31",
908 "Version of protocol supported by this dissector.");
912 proto_reg_handoff_adb(void)
914 adb_service_handle
= find_dissector_add_dependency("adb_service", proto_adb
);
916 dissector_add_for_decode_as_with_preference("tcp.port", adb_handle
);
917 dissector_add_for_decode_as("usb.device", adb_handle
);
918 dissector_add_for_decode_as("usb.product", adb_handle
);
919 dissector_add_for_decode_as("usb.protocol", adb_handle
);
921 proto_tcp
= proto_get_id_by_filter_name("tcp");
922 proto_usb
= proto_get_id_by_filter_name("usb");
926 * Editor modelines - https://www.wireshark.org/tools/modelines.html
931 * indent-tabs-mode: nil
934 * vi: set shiftwidth=4 tabstop=8 expandtab:
935 * :indentSize=4:tabSize=8:noTabs=true: