1 /* packet-adb_service.c
2 * Routines for Android Debug Bridge Services
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>
19 #include "packet-adb_service.h"
21 static int proto_adb_service
;
23 static int hf_service
;
24 static int hf_fragment
;
26 static int hf_hex_ascii_length
;
28 static int hf_version
;
29 static int hf_hex_ascii_version
;
30 static int hf_framebuffer_version
;
31 static int hf_framebuffer_depth
;
32 static int hf_framebuffer_size
;
33 static int hf_framebuffer_width
;
34 static int hf_framebuffer_height
;
35 static int hf_framebuffer_red_offset
;
36 static int hf_framebuffer_red_length
;
37 static int hf_framebuffer_blue_offset
;
38 static int hf_framebuffer_blue_length
;
39 static int hf_framebuffer_green_offset
;
40 static int hf_framebuffer_green_length
;
41 static int hf_framebuffer_alpha_offset
;
42 static int hf_framebuffer_alpha_length
;
43 static int hf_framebuffer_pixel
;
44 static int hf_framebuffer_red_5
;
45 static int hf_framebuffer_green_6
;
46 static int hf_framebuffer_blue_5
;
47 static int hf_framebuffer_red
;
48 static int hf_framebuffer_green
;
49 static int hf_framebuffer_blue
;
50 static int hf_framebuffer_alpha
;
51 static int hf_framebuffer_unused
;
52 static int hf_devices
;
58 static expert_field ei_incomplete_message
;
60 static int ett_adb_service
;
61 static int ett_length
;
62 static int ett_version
;
66 static dissector_handle_t adb_service_handle
;
67 static dissector_handle_t logcat_handle
;
69 static bool pref_dissect_more_detail_framebuffer
;
71 static wmem_tree_t
*fragments
;
72 static wmem_tree_t
*framebuffer_infos
;
73 static wmem_tree_t
*continuation_infos
;
75 typedef struct _framebuffer_data_t
{
77 uint32_t current_size
;
78 uint32_t completed_in_frame
;
83 uint32_t green_offset
;
84 uint32_t green_length
;
87 uint32_t alpha_offset
;
88 uint32_t alpha_length
;
91 typedef struct _fragment_t
{
92 int64_t reassembled_in_frame
;
97 typedef struct _continuation_data_t
{
98 uint32_t length_in_frame
;
99 uint32_t completed_in_frame
;
101 } continuation_data_t
;
103 void proto_register_adb_service(void);
104 void proto_reg_handoff_adb_service(void);
107 dissect_ascii_uint32(proto_tree
*tree
, int hf_hex_ascii
, int ett_hex_ascii
,
108 int hf_value
, tvbuff_t
*tvb
, int offset
, uint32_t *value
)
110 proto_item
*sub_item
;
111 proto_tree
*sub_tree
;
114 DISSECTOR_ASSERT(value
);
116 tvb_memcpy(tvb
, hex_ascii
, offset
, 4);
119 sub_item
= proto_tree_add_item(tree
, hf_hex_ascii
, tvb
, offset
, 4, ENC_NA
| ENC_ASCII
);
120 sub_tree
= proto_item_add_subtree(sub_item
, ett_hex_ascii
);
122 *value
= (uint32_t) g_ascii_strtoull(hex_ascii
, NULL
, 16);
124 proto_tree_add_uint(sub_tree
, hf_value
, tvb
, offset
, 4, *value
);
131 dissect_adb_service(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
133 proto_item
*main_item
;
134 proto_tree
*main_tree
;
135 proto_item
*sub_item
;
136 proto_tree
*sub_tree
;
138 adb_service_data_t
*adb_service_data
= (adb_service_data_t
*) data
;
140 wmem_tree_key_t key
[5];
141 wmem_tree_t
*subtree
;
145 main_item
= proto_tree_add_item(tree
, proto_adb_service
, tvb
, offset
, -1, ENC_NA
);
146 main_tree
= proto_item_add_subtree(main_item
, ett_adb_service
);
148 DISSECTOR_ASSERT(adb_service_data
);
150 service
= adb_service_data
->service
;
152 sub_item
= proto_tree_add_string(main_tree
, hf_service
, tvb
, offset
, 0, service
);
153 proto_item_set_generated(sub_item
);
155 if (g_strcmp0(service
, "host:version") == 0) {
157 uint32_t data_length
;
158 continuation_data_t
*continuation_data
;
160 DISSECTOR_ASSERT_HINT(adb_service_data
->session_key_length
+ 1 <= array_length(key
), "Tree session key is too small");
161 for (i_key
= 0; i_key
< adb_service_data
->session_key_length
; i_key
+= 1) {
162 key
[i_key
].length
= 1;
163 key
[i_key
].key
= &adb_service_data
->session_key
[i_key
];
165 key
[i_key
].length
= 0;
166 key
[i_key
].key
= NULL
;
168 subtree
= (wmem_tree_t
*) wmem_tree_lookup32_array(continuation_infos
, key
);
169 continuation_data
= (subtree
) ? (continuation_data_t
*) wmem_tree_lookup32_le(subtree
, pinfo
->num
) : NULL
;
170 if (continuation_data
&& continuation_data
->completed_in_frame
< pinfo
->num
)
171 continuation_data
= NULL
;
173 if (!continuation_data
|| (continuation_data
&& continuation_data
->length_in_frame
== pinfo
->num
))
174 offset
= dissect_ascii_uint32(main_tree
, hf_hex_ascii_length
, ett_length
, hf_length
, tvb
, offset
, &data_length
);
176 if (!pinfo
->fd
->visited
&& !continuation_data
&& tvb_reported_length_remaining(tvb
, offset
) < 4) {
177 key
[i_key
].length
= 1;
178 key
[i_key
++].key
= &pinfo
->num
;
179 key
[i_key
].length
= 0;
180 key
[i_key
].key
= NULL
;
182 continuation_data
= wmem_new(wmem_file_scope(), continuation_data_t
);
183 continuation_data
->length_in_frame
= pinfo
->num
;
184 continuation_data
->completed_in_frame
= UINT32_MAX
;
185 continuation_data
->length
= data_length
;
187 wmem_tree_insert32_array(continuation_infos
, key
, continuation_data
);
188 continuation_data
= NULL
;
191 if (tvb_reported_length_remaining(tvb
, offset
) >= 4 ||
192 (continuation_data
&& continuation_data
->completed_in_frame
== pinfo
->num
)) {
193 if (!pinfo
->fd
->visited
&& continuation_data
) {
194 continuation_data
->completed_in_frame
= pinfo
->num
;
196 offset
= dissect_ascii_uint32(main_tree
, hf_hex_ascii_version
, ett_version
, hf_version
, tvb
, offset
, &version
);
198 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Version=%u", version
);
201 } else if (g_strcmp0(service
, "host:devices") == 0 ||
202 g_strcmp0(service
, "host:devices-l") == 0 ||
203 g_strcmp0(service
, "host:track-devices") == 0) {
204 uint32_t data_length
;
206 offset
= dissect_ascii_uint32(main_tree
, hf_hex_ascii_length
, ett_length
, hf_length
, tvb
, offset
, &data_length
);
208 sub_item
= proto_tree_add_item(main_tree
, hf_devices
, tvb
, offset
, -1, ENC_NA
| ENC_ASCII
);
209 if ((int64_t) data_length
< tvb_reported_length_remaining(tvb
, offset
)) {
210 expert_add_info(pinfo
, sub_item
, &ei_incomplete_message
);
212 } else if (g_strcmp0(service
, "host:get-state") == 0 ||
213 g_strcmp0(service
, "host:get-serialno") == 0 ||
214 g_strcmp0(service
, "host:get-devpath") == 0 ||
215 g_str_has_prefix(service
, "connect:") ||
216 g_str_has_prefix(service
, "disconnect:")) {
217 uint32_t data_length
;
219 offset
= dissect_ascii_uint32(main_tree
, hf_hex_ascii_length
, ett_length
, hf_length
, tvb
, offset
, &data_length
);
221 sub_item
= proto_tree_add_item(main_tree
, hf_result
, tvb
, offset
, -1, ENC_NA
| ENC_ASCII
);
222 if ((int64_t) data_length
< tvb_reported_length_remaining(tvb
, offset
)) {
223 expert_add_info(pinfo
, sub_item
, &ei_incomplete_message
);
225 } else if (g_str_has_prefix(service
, "framebuffer:")) {
226 framebuffer_data_t
*framebuffer_data
= NULL
;
228 DISSECTOR_ASSERT_HINT(adb_service_data
->session_key_length
+ 1 <= array_length(key
), "Tree session key is too small");
229 for (i_key
= 0; i_key
< adb_service_data
->session_key_length
; i_key
+= 1) {
230 key
[i_key
].length
= 1;
231 key
[i_key
].key
= &adb_service_data
->session_key
[i_key
];
233 key
[i_key
].length
= 0;
234 key
[i_key
].key
= NULL
;
236 subtree
= (wmem_tree_t
*) wmem_tree_lookup32_array(framebuffer_infos
, key
);
237 framebuffer_data
= (subtree
) ? (framebuffer_data_t
*) wmem_tree_lookup32_le(subtree
, pinfo
->num
) : NULL
;
238 if (framebuffer_data
&& framebuffer_data
->completed_in_frame
< pinfo
->num
)
239 framebuffer_data
= NULL
;
241 if (!pinfo
->fd
->visited
&& !framebuffer_data
) {
242 key
[i_key
].length
= 1;
243 key
[i_key
++].key
= &pinfo
->num
;
244 key
[i_key
].length
= 0;
245 key
[i_key
].key
= NULL
;
247 framebuffer_data
= wmem_new(wmem_file_scope(), framebuffer_data_t
);
248 framebuffer_data
->data_in
= pinfo
->num
;
249 framebuffer_data
->current_size
= 0;
250 framebuffer_data
->completed_in_frame
= UINT32_MAX
;
251 framebuffer_data
->size
= tvb_get_letohl(tvb
, offset
+ 4 * 2);
252 framebuffer_data
->red_offset
= tvb_get_letohl(tvb
, offset
+ 4 * 5);
253 framebuffer_data
->red_length
= tvb_get_letohl(tvb
, offset
+ 4 * 6);
254 framebuffer_data
->green_offset
= tvb_get_letohl(tvb
, offset
+ 4 * 7);
255 framebuffer_data
->green_length
= tvb_get_letohl(tvb
, offset
+ 4 * 8);
256 framebuffer_data
->blue_offset
= tvb_get_letohl(tvb
, offset
+ 4 * 9);
257 framebuffer_data
->blue_length
= tvb_get_letohl(tvb
, offset
+ 4 * 10);
258 framebuffer_data
->alpha_offset
= tvb_get_letohl(tvb
, offset
+ 4 * 11);
259 framebuffer_data
->alpha_length
= tvb_get_letohl(tvb
, offset
+ 4 * 12);
261 wmem_tree_insert32_array(framebuffer_infos
, key
, framebuffer_data
);
264 if (framebuffer_data
&& framebuffer_data
->data_in
== pinfo
->num
) {
265 proto_tree_add_item(main_tree
, hf_framebuffer_version
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
268 proto_tree_add_item(main_tree
, hf_framebuffer_depth
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
271 proto_tree_add_item(main_tree
, hf_framebuffer_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
274 proto_tree_add_item(main_tree
, hf_framebuffer_width
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
277 proto_tree_add_item(main_tree
, hf_framebuffer_height
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
280 proto_tree_add_item(main_tree
, hf_framebuffer_red_offset
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
283 proto_tree_add_item(main_tree
, hf_framebuffer_red_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
286 proto_tree_add_item(main_tree
, hf_framebuffer_blue_offset
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
289 proto_tree_add_item(main_tree
, hf_framebuffer_blue_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
292 proto_tree_add_item(main_tree
, hf_framebuffer_green_offset
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
295 proto_tree_add_item(main_tree
, hf_framebuffer_green_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
298 proto_tree_add_item(main_tree
, hf_framebuffer_alpha_offset
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
301 proto_tree_add_item(main_tree
, hf_framebuffer_alpha_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
305 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
306 sub_item
= proto_tree_add_item(main_tree
, hf_data
, tvb
, offset
, -1, ENC_NA
);
307 sub_tree
= proto_item_add_subtree(sub_item
, ett_data
);
309 if (!pinfo
->fd
->visited
&& framebuffer_data
) {
310 framebuffer_data
->current_size
+= tvb_captured_length_remaining(tvb
, offset
);
311 if (framebuffer_data
->current_size
>= framebuffer_data
->size
)
312 framebuffer_data
->completed_in_frame
= pinfo
->num
;
315 if (pref_dissect_more_detail_framebuffer
) {
316 proto_item
*pixel_item
;
317 proto_tree
*pixel_tree
;
319 if (framebuffer_data
&&
320 framebuffer_data
->red_length
== 5 &&
321 framebuffer_data
->green_length
== 6 &&
322 framebuffer_data
->blue_length
== 5 &&
323 framebuffer_data
->red_offset
== 11 &&
324 framebuffer_data
->green_offset
== 5 &&
325 framebuffer_data
->blue_offset
== 0) {
326 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
327 if (tvb_reported_length_remaining(tvb
, offset
) < 2) {
328 proto_tree_add_item(main_tree
, hf_fragment
, tvb
, offset
, -1, ENC_NA
);
332 pixel_item
= proto_tree_add_item(sub_tree
, hf_framebuffer_pixel
, tvb
, offset
, 2, ENC_NA
);
333 pixel_tree
= proto_item_add_subtree(pixel_item
, ett_pixel
);
335 proto_tree_add_item(pixel_tree
, hf_framebuffer_blue_5
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
336 proto_tree_add_item(pixel_tree
, hf_framebuffer_green_6
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
337 proto_tree_add_item(pixel_tree
, hf_framebuffer_red_5
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
340 } else if (framebuffer_data
&&
341 framebuffer_data
->red_length
== 8 &&
342 framebuffer_data
->green_length
== 8 &&
343 framebuffer_data
->blue_length
== 8 &&
344 (framebuffer_data
->alpha_length
== 0 ||
345 framebuffer_data
->alpha_length
== 8)) {
346 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
347 if (tvb_reported_length_remaining(tvb
, offset
) < 3 || (tvb_reported_length_remaining(tvb
, offset
) < 4 && framebuffer_data
->alpha_offset
> 0)) {
348 proto_tree_add_item(main_tree
, hf_fragment
, tvb
, offset
, -1, ENC_NA
);
349 offset
= tvb_captured_length(tvb
);
353 pixel_item
= proto_tree_add_item(sub_tree
, hf_framebuffer_pixel
, tvb
, offset
, 3, ENC_NA
);
354 pixel_tree
= proto_item_add_subtree(pixel_item
, ett_pixel
);
356 proto_tree_add_item(pixel_tree
, hf_framebuffer_red
, tvb
, offset
+ framebuffer_data
->red_offset
/ 8, 1, ENC_LITTLE_ENDIAN
);
357 proto_tree_add_item(pixel_tree
, hf_framebuffer_green
, tvb
, offset
+ framebuffer_data
->green_offset
/ 8, 1, ENC_LITTLE_ENDIAN
);
358 proto_tree_add_item(pixel_tree
, hf_framebuffer_blue
, tvb
, offset
+ framebuffer_data
->blue_offset
/ 8, 1, ENC_LITTLE_ENDIAN
);
360 if (framebuffer_data
->alpha_offset
> 0) {
361 if (framebuffer_data
->alpha_length
== 0)
362 proto_tree_add_item(pixel_tree
, hf_framebuffer_unused
, tvb
, offset
+ framebuffer_data
->alpha_offset
/ 8, 1, ENC_LITTLE_ENDIAN
);
364 proto_tree_add_item(pixel_tree
, hf_framebuffer_alpha
, tvb
, offset
+ framebuffer_data
->alpha_offset
/ 8, 1, ENC_LITTLE_ENDIAN
);
366 proto_item_set_len(pixel_item
, 4);
371 offset
= tvb_captured_length(tvb
);
374 offset
= tvb_captured_length(tvb
);
377 } else if (g_strcmp0(service
, "track-jdwp") == 0) {
378 uint32_t data_length
;
380 offset
= dissect_ascii_uint32(main_tree
, hf_hex_ascii_length
, ett_length
, hf_length
, tvb
, offset
, &data_length
);
382 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
383 sub_item
= proto_tree_add_item(main_tree
, hf_pids
, tvb
, offset
, -1, ENC_NA
| ENC_ASCII
);
384 if ((int64_t) data_length
< tvb_reported_length_remaining(tvb
, offset
)) {
385 expert_add_info(pinfo
, sub_item
, &ei_incomplete_message
);
388 offset
= tvb_captured_length(tvb
);
389 } else if ((g_strcmp0(service
, "shell:export ANDROID_LOG_TAGS=\"\" ; exec logcat -B") == 0) ||
390 (g_strcmp0(service
, "shell:logcat -B") == 0)) {
393 uint8_t *buffer
= NULL
;
395 int i_offset
= offset
;
400 uint16_t payload_length
;
401 uint16_t try_header_size
;
402 int logcat_length
= 0;
403 fragment_t
*fragment
;
405 DISSECTOR_ASSERT_HINT(adb_service_data
->session_key_length
+ 1 <= array_length(key
), "Tree session key is too small");
406 for (i_key
= 0; i_key
< adb_service_data
->session_key_length
; i_key
+= 1) {
407 key
[i_key
].length
= 1;
408 key
[i_key
].key
= &adb_service_data
->session_key
[i_key
];
410 key
[i_key
].length
= 0;
411 key
[i_key
].key
= NULL
;
413 subtree
= (wmem_tree_t
*) wmem_tree_lookup32_array(fragments
, key
);
414 fragment
= (subtree
) ? (fragment_t
*) wmem_tree_lookup32_le(subtree
, pinfo
->num
- 1) : NULL
;
416 if (!pinfo
->fd
->visited
&& fragment
->reassembled_in_frame
== -1)
417 fragment
->reassembled_in_frame
= pinfo
->num
;
419 if (fragment
->reassembled_in_frame
== pinfo
->num
) {
420 size
+= fragment
->length
;
421 i_char
+= fragment
->length
;
425 size
+= tvb_reported_length_remaining(tvb
, i_offset
);
427 buffer
= (uint8_t *) wmem_alloc(pinfo
->pool
, size
);
428 if (fragment
&& i_char
> 0)
429 memcpy(buffer
, fragment
->data
, i_char
);
431 if (i_char
>= 1 && buffer
[i_char
- 1] == '\r' && tvb_get_uint8(tvb
, i_offset
) == '\n') {
432 buffer
[i_char
- 1] = '\n';
436 c1
= tvb_get_uint8(tvb
, i_offset
);
438 old_offset
= i_offset
;
440 while (tvb_reported_length_remaining(tvb
, i_offset
) > 0) {
441 c2
= tvb_get_uint8(tvb
, i_offset
);
443 if (c1
== '\r' && c2
== '\n') {
445 if (tvb_reported_length_remaining(tvb
, i_offset
) > 1) {
446 c1
= tvb_get_uint8(tvb
, i_offset
+ 1);
462 if (tvb_reported_length_remaining(tvb
, old_offset
) == 0) {
465 } else if (tvb_reported_length_remaining(tvb
, old_offset
) > 0) {
470 next_tvb
= tvb_new_child_real_data(tvb
, buffer
, i_char
, i_char
);
471 add_new_data_source(pinfo
, next_tvb
, "Logcat");
474 while (tvb_reported_length_remaining(next_tvb
, i_offset
) > 0) {
475 if (tvb_reported_length_remaining(next_tvb
, i_offset
) >= 4) {
476 payload_length
= tvb_get_letohs(next_tvb
, i_offset
);
477 try_header_size
= tvb_get_letohs(next_tvb
, i_offset
+ 2);
479 if (try_header_size
!= 24)
480 logcat_length
= payload_length
+ 20;
482 logcat_length
= payload_length
+ 24;
485 if (tvb_reported_length_remaining(next_tvb
, i_offset
) >= 4 && tvb_reported_length_remaining(next_tvb
, i_offset
) >= logcat_length
) {
486 new_tvb
= tvb_new_subset_length(next_tvb
, i_offset
, logcat_length
);
488 call_dissector(logcat_handle
, new_tvb
, pinfo
, main_tree
);
489 i_offset
+= logcat_length
;
492 if (!pinfo
->fd
->visited
) {
493 DISSECTOR_ASSERT_HINT(adb_service_data
->session_key_length
+ 2 <= array_length(key
), "Tree session key is too small");
494 for (i_key
= 0; i_key
< adb_service_data
->session_key_length
; i_key
+= 1) {
495 key
[i_key
].length
= 1;
496 key
[i_key
].key
= &adb_service_data
->session_key
[i_key
];
498 key
[i_key
].length
= 1;
499 key
[i_key
++].key
= &pinfo
->num
;
500 key
[i_key
].length
= 0;
501 key
[i_key
].key
= NULL
;
503 fragment
= wmem_new(wmem_file_scope(), fragment_t
);
505 fragment
->length
= tvb_captured_length_remaining(next_tvb
, i_offset
);
506 fragment
->data
= (uint8_t *) wmem_alloc(wmem_file_scope(), fragment
->length
);
507 tvb_memcpy(next_tvb
, fragment
->data
, i_offset
, fragment
->length
);
508 fragment
->reassembled_in_frame
= -1;
510 wmem_tree_insert32_array(fragments
, key
, fragment
);
513 proto_tree_add_item(main_tree
, hf_fragment
, next_tvb
, i_offset
, -1, ENC_NA
);
514 i_offset
= tvb_captured_length(next_tvb
);
519 offset
= tvb_captured_length(tvb
);
520 } else if (g_str_has_prefix(service
, "shell:")) {
521 if (adb_service_data
->direction
== P2P_DIR_SENT
) {
522 proto_tree_add_item_ret_display_string(main_tree
, hf_stdin
, tvb
, offset
, -1, ENC_ASCII
, pinfo
->pool
, &display_str
);
523 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Stdin=<%s>", display_str
);
526 proto_tree_add_item_ret_display_string(main_tree
, hf_stdout
, tvb
, offset
, -1, ENC_ASCII
, pinfo
->pool
, &display_str
);
527 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Stdout=<%s>", display_str
);
529 offset
= tvb_captured_length(tvb
);
530 } else if (g_str_has_prefix(service
, "jdwp:")) {
532 proto_tree_add_item(main_tree
, hf_data
, tvb
, offset
, -1, ENC_NA
);
533 offset
= tvb_captured_length(tvb
);
534 } else if (g_str_has_prefix(service
, "sync:")) {
536 proto_tree_add_item(main_tree
, hf_data
, tvb
, offset
, -1, ENC_NA
);
537 offset
= tvb_captured_length(tvb
);
538 } else if (g_strcmp0(service
, "host:list-forward") == 0 ||
539 g_str_has_prefix(service
, "root:") ||
540 g_str_has_prefix(service
, "remount:") ||
541 g_str_has_prefix(service
, "tcpip:") ||
542 g_str_has_prefix(service
, "usb:")) {
543 if (tvb_reported_length_remaining(tvb
, offset
)) {
544 proto_tree_add_item_ret_display_string(main_tree
, hf_result
, tvb
, offset
, -1, ENC_ASCII
, pinfo
->pool
, &display_str
);
545 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Result=<%s>", display_str
);
547 offset
= tvb_captured_length(tvb
);
550 proto_tree_add_item(main_tree
, hf_data
, tvb
, offset
, -1, ENC_NA
);
551 offset
= tvb_captured_length(tvb
);
559 proto_register_adb_service(void)
562 expert_module_t
*expert_module
;
564 static hf_register_info hf
[] = {
566 { "Service", "adb_service.service",
567 FT_STRING
, BASE_NONE
, NULL
, 0x00,
571 { "Fragment", "adb_service.fragment",
572 FT_NONE
, BASE_NONE
, NULL
, 0x00,
576 { "Data", "adb_service.data",
577 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
580 { &hf_hex_ascii_length
,
581 { "Hex ASCII String Length", "adb_service.hex_ascii_length",
582 FT_STRING
, BASE_NONE
, NULL
, 0x00,
586 { "Length", "adb_service.length",
587 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x00,
590 { &hf_framebuffer_version
,
591 { "Version", "adb_service.framebuffer.version",
592 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
595 { &hf_hex_ascii_version
,
596 { "Hex ASCII String Version", "adb_service.hex_ascii_version",
597 FT_STRING
, BASE_NONE
, NULL
, 0x00,
601 { "Version", "adb_service.version",
602 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0x00,
605 { &hf_framebuffer_depth
,
606 { "Depth", "adb_service.framebuffer.depth",
607 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
610 { &hf_framebuffer_size
,
611 { "Size", "adb_service.framebuffer.size",
612 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
615 { &hf_framebuffer_width
,
616 { "Width", "adb_service.framebuffer.width",
617 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
620 { &hf_framebuffer_height
,
621 { "Height", "adb_service.framebuffer.height",
622 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
625 { &hf_framebuffer_red_offset
,
626 { "Red Offset", "adb_service.framebuffer.red_offset",
627 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
630 { &hf_framebuffer_red_length
,
631 { "Red Length", "adb_service.framebuffer.red_length",
632 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
635 { &hf_framebuffer_blue_offset
,
636 { "Blue Offset", "adb_service.framebuffer.blue_offset",
637 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
640 { &hf_framebuffer_blue_length
,
641 { "Blue Length", "adb_service.framebuffer.blue_length",
642 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
645 { &hf_framebuffer_green_offset
,
646 { "Green Offset", "adb_service.framebuffer.green_offset",
647 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
650 { &hf_framebuffer_green_length
,
651 { "Green Length", "adb_service.framebuffer.green_length",
652 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
655 { &hf_framebuffer_alpha_offset
,
656 { "Alpha Offset", "adb_service.framebuffer.alpha_offset",
657 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
660 { &hf_framebuffer_alpha_length
,
661 { "Alpha Length", "adb_service.framebuffer.alpha_length",
662 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
665 { &hf_framebuffer_pixel
,
666 { "Pixel", "adb_service.framebuffer.pixel",
667 FT_NONE
, BASE_NONE
, NULL
, 0x00,
670 { &hf_framebuffer_blue_5
,
671 { "Blue", "adb_service.framebuffer.pixel.blue",
672 FT_UINT16
, BASE_DEC
, NULL
, 0xF800,
675 { &hf_framebuffer_green_6
,
676 { "Green", "adb_service.framebuffer.pixel.green",
677 FT_UINT16
, BASE_DEC
, NULL
, 0x07E0,
680 { &hf_framebuffer_red_5
,
681 { "Red", "adb_service.framebuffer.pixel.red",
682 FT_UINT16
, BASE_DEC
, NULL
, 0x001F,
685 { &hf_framebuffer_blue
,
686 { "Blue", "adb_service.framebuffer.pixel.blue",
687 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
690 { &hf_framebuffer_green
,
691 { "Green", "adb_service.framebuffer.pixel.green",
692 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
695 { &hf_framebuffer_red
,
696 { "Red", "adb_service.framebuffer.pixel.red",
697 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
700 { &hf_framebuffer_alpha
,
701 { "Alpha", "adb_service.framebuffer.pixel.alpha",
702 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
705 { &hf_framebuffer_unused
,
706 { "Unused", "adb_service.framebuffer.pixel.unused",
707 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
711 { "Devices", "adb_service.devices",
712 FT_STRING
, BASE_NONE
, NULL
, 0x00,
716 { "Stdin", "adb_service.stdin",
717 FT_STRING
, BASE_NONE
, NULL
, 0x00,
721 { "Stdout", "adb_service.stdout",
722 FT_STRING
, BASE_NONE
, NULL
, 0x00,
726 { "Result", "adb_service.result",
727 FT_STRING
, BASE_NONE
, NULL
, 0x00,
731 { "PIDs", "adb_service.pids",
732 FT_STRING
, BASE_NONE
, NULL
, 0x00,
737 static int *ett
[] = {
745 static ei_register_info ei
[] = {
746 { &ei_incomplete_message
, { "adb_service.expert.incomplete_message", PI_PROTOCOL
, PI_WARN
, "Incomplete message", EXPFILL
}},
749 fragments
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
750 framebuffer_infos
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
751 continuation_infos
= wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
753 proto_adb_service
= proto_register_protocol("Android Debug Bridge Service", "ADB Service", "adb_service");
754 adb_service_handle
= register_dissector("adb_service", dissect_adb_service
, proto_adb_service
);
756 proto_register_field_array(proto_adb_service
, hf
, array_length(hf
));
757 proto_register_subtree_array(ett
, array_length(ett
));
758 expert_module
= expert_register_protocol(proto_adb_service
);
759 expert_register_field_array(expert_module
, ei
, array_length(ei
));
761 module
= prefs_register_protocol(proto_adb_service
, NULL
);
762 prefs_register_static_text_preference(module
, "version",
763 "ADB Service protocol version is compatible prior to: adb 1.0.31",
764 "Version of protocol supported by this dissector.");
766 prefs_register_bool_preference(module
, "framebuffer_more_details",
767 "Dissect more detail for framebuffer service",
768 "Dissect more detail for framebuffer service",
769 &pref_dissect_more_detail_framebuffer
);
774 proto_reg_handoff_adb_service(void)
776 logcat_handle
= find_dissector_add_dependency("logcat", proto_adb_service
);
780 * Editor modelines - https://www.wireshark.org/tools/modelines.html
785 * indent-tabs-mode: nil
788 * vi: set shiftwidth=4 tabstop=8 expandtab:
789 * :indentSize=4:tabSize=8:noTabs=true: