Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-jdwp.c
blobaaaf7519a99739863719cb25c4711eaed5653548
1 /* packet-jdwp.c
2 * Routines for JDWP (Java Debug Wire Protocol) dissection
3 * Copyright 2020, Eugene Adell <eugene.adell@gmail.com>
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
12 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/prefs.h>
16 #include <epan/expert.h>
17 #include <epan/to_str.h>
18 #include <epan/conversation.h>
19 #include <epan/wmem_scopes.h>
21 #include "packet-tcp.h"
23 void proto_register_jdwp(void);
24 void proto_reg_handoff_jdwp(void);
26 static dissector_handle_t jdwp_handle;
28 /* IMPORTANT IMPLEMENTATION NOTES
30 * You need to be looking at:
32 * https://docs.oracle.com/javase/8/docs/technotes/guides/jpda/jdwp-spec.html
34 * Last update: up to Java 19
36 * https://docs.oracle.com/en/java/javase/19/docs/specs/jdwp/jdwp-protocol.html
40 #define JDWP_PORT 9009 /* Not IANA registered */
41 #define FRAME_HEADER_LEN 11
42 #define JDWP_MIN_LENGTH 11
43 #define JDWP_HANDSHAKE_LENGTH 14
44 #define JDWP_HANDSHAKE_MSG "JDWP-Handshake"
46 #define PACKET_TYPE_COMMAND 0
47 #define PACKET_TYPE_REPLY 128
49 #define COMMAND_SET_VIRTUALMACHINE 1
50 #define COMMAND_SET_REFERENCETYPE 2
51 #define COMMAND_SET_CLASSTYPE 3
52 #define COMMAND_SET_ARRAYTYPE 4
53 #define COMMAND_SET_INTERFACETYPE 5
54 #define COMMAND_SET_METHOD 6
55 #define COMMAND_SET_FIELD 8
56 #define COMMAND_SET_OBJECTREFERENCE 9
57 #define COMMAND_SET_STRINGREFERENCE 10
58 #define COMMAND_SET_THREADREFERENCE 11
59 #define COMMAND_SET_THREADGROUPREFERENCE 12
60 #define COMMAND_SET_ARRAYREFERENCE 13
61 #define COMMAND_SET_CLASSLOADERREFERENCE 14
62 #define COMMAND_SET_EVENTREQUEST 15
63 #define COMMAND_SET_STACKFRAME 16
64 #define COMMAND_SET_CLASSOBJECTREFERENCE 17
65 #define COMMAND_SET_MODULEREFERENCE 18
66 #define COMMAND_SET_EVENT 64
68 static int proto_jdwp;
70 static int hf_jdwp_type;
71 static int hf_jdwp_length;
72 static int hf_jdwp_id;
73 static int hf_jdwp_flags;
74 static int hf_jdwp_commandset;
75 static int hf_jdwp_commandset_virtualmachine;
76 static int hf_jdwp_commandset_referencetype;
77 static int hf_jdwp_commandset_classtype;
78 static int hf_jdwp_commandset_arraytype;
79 static int hf_jdwp_commandset_interfacetype;
80 static int hf_jdwp_commandset_method;
81 static int hf_jdwp_commandset_field;
82 static int hf_jdwp_commandset_objectreference;
83 static int hf_jdwp_commandset_stringreference;
84 static int hf_jdwp_commandset_threadreference;
85 static int hf_jdwp_commandset_threadgroupreference;
86 static int hf_jdwp_commandset_arrayreference;
87 static int hf_jdwp_commandset_classloaderreference;
88 static int hf_jdwp_commandset_eventrequest;
89 static int hf_jdwp_commandset_stackframe;
90 static int hf_jdwp_commandset_classobjectreference;
91 static int hf_jdwp_commandset_modulereference;
92 static int hf_jdwp_commandset_event;
93 static int hf_jdwp_errorcode;
94 static int hf_jdwp_data;
96 static int ett_jdwp;
98 static expert_field ei_jdwp_hlen_invalid;
99 static expert_field ei_jdwp_flags_invalid;
101 // contains the command set names
102 static const value_string commandsetnames[] = {
103 {1, "VirtualMachine"},
104 {2, "ReferenceType"},
105 {3, "ClassType"},
106 {4, "ArrayType"},
107 {5, "InterfaceType"},
108 {6, "Method"},
109 {8, "Field"},
110 {9, "ObjectReference"},
111 {10, "StringReference"},
112 {11, "ThreadReference"},
113 {12, "ThreadGroupReference"},
114 {13, "ArrayReference"},
115 {14, "ClassLoaderReference"},
116 {15, "EventRequest"},
117 {16, "StackFrame"},
118 {17, "ClassObjectReference"},
119 {18, "ModuleReference"},
120 {64, "Event"},
121 {0, NULL}
124 // contains the commands for the command set of type Virtual Machine
125 static const value_string commandset_virtualmachine[] = {
126 {1, "Version"},
127 {2, "ClassesBySignature"},
128 {3, "AllClasses"},
129 {4, "AllThreads"},
130 {5, "TopLevelThreadGroups"},
131 {6, "Dispose"},
132 {7, "IDSizes"},
133 {8, "Suspend"},
134 {9, "Resume"},
135 {10, "Exit"},
136 {11, "CreateString"},
137 {12, "Capabilities"},
138 {13, "ClassPaths"},
139 {14, "DisposeObjects"},
140 {15, "HoldEvents"},
141 {16, "ReleaseEvents"},
142 {17, "CapabilitiesNew"},
143 {18, "RedefineClasses"},
144 {19, "SetDefaultStratum"},
145 {20, "AllClassesWithGeneric"},
146 {21, "InstanceCounts"},
147 {22, "AllModules"},
148 {0, NULL}
151 // contains the commands for the command set of type Reference
152 static const value_string commandset_referencetype[] = {
153 {1, "Signature"},
154 {2, "ClassLoader"},
155 {3, "Modifiers"},
156 {4, "Fields"},
157 {5, "Methods"},
158 {6, "GetValues"},
159 {7, "SourceFile"},
160 {8, "NestedTypes"},
161 {9, "Status"},
162 {10, "Interfaces"},
163 {11, "ClassObject"},
164 {12, "SourceDebugExtension"},
165 {13, "SignatureWithGeneric"},
166 {14, "FieldsWithGeneric"},
167 {15, "MethodsWithGeneric"},
168 {16, "Instances"},
169 {17, "ClassFileVersion"},
170 {18, "ConstantPool"},
171 {19, "Module"},
172 {0, NULL}
175 // contains the commands for the command set of type Class
176 static const value_string commandset_classtype[] = {
177 {1, "Superclass"},
178 {2, "SetValues"},
179 {3, "InvokeMethod"},
180 {4, "NewInstance"},
181 {0, NULL}
184 // contains the commands for the command set of type Array
185 static const value_string commandset_arraytype[] = {
186 {1, "NewInstance"},
187 {0, NULL}
190 // contains the commands for the command set of type Interface
191 static const value_string commandset_interfacetype[] = {
192 {1, "InvokeMethod"},
193 {0, NULL}
196 // contains the commands for the command set of type Method
197 static const value_string commandset_method[] = {
198 {1, "LineTable"},
199 {2, "VariableTable"},
200 {3, "Bytecodes"},
201 {4, "IsObsolete"},
202 {5, "VariableTableWithGeneric"},
203 {0, NULL}
206 // contains the commands for the command set of type Field
207 static const value_string commandset_field[] = {
208 {0, NULL}
211 // contains the commands for the command set of type Object Reference
212 static const value_string commandset_objectreference[] = {
213 {1, "ReferenceType"},
214 {2, "GetValues"},
215 {3, "SetValues"},
216 {5, "MonitorInfo"},
217 {6, "InvokeMethod"},
218 {7, "DisableCollection"},
219 {8, "EnableCollection"},
220 {9, "IsCollected"},
221 {10, "ReferringObjects"},
222 {0, NULL}
225 // contains the commands for the command set of type String Reference
226 static const value_string commandset_stringreference[] = {
227 {1, "Value"},
228 {0, NULL}
231 // contains the commands for the command set of type Thread Reference
232 static const value_string commandset_threadreference[] = {
233 {1, "Name"},
234 {2, "Suspend"},
235 {3, "Resume"},
236 {4, "Status"},
237 {5, "ThreadGroup"},
238 {6, "Frames"},
239 {7, "FrameCount"},
240 {8, "OwnedMonitors"},
241 {9, "CurrentContentedMonitor"},
242 {10, "Stop"},
243 {11, "Interrupt"},
244 {12, "SuspendCount"},
245 {13, "OwnedMonitorsStackDepthInfo"},
246 {14, "ForceEarlyReturn"},
247 {15, "IsVirtual"},
248 {0, NULL}
251 // contains the commands for the command set of type ThreadGroup Reference
252 static const value_string commandset_threadgroupreference[] = {
253 {1, "Name"},
254 {2, "Parent"},
255 {3, "Children"},
256 {0, NULL}
259 // contains the commands for the command set of type Array Reference
260 static const value_string commandset_arrayreference[] = {
261 {1, "Length"},
262 {2, "GetValues"},
263 {3, "SetValues"},
264 {0, NULL}
267 // contains the commands for the command set of type ClassLoader Reference
268 static const value_string commandset_classloaderreference[] = {
269 {1, "VisibleClasses"},
270 {0, NULL}
273 // contains the commands for the command set of type EventRequest
274 static const value_string commandset_eventrequest[] = {
275 {1, "Set"},
276 {2, "Clear"},
277 {3, "ClearAllBreakpoints"},
278 {0, NULL}
281 // contains the commands for the command set of type StackFrame
282 static const value_string commandset_stackframe[] = {
283 {1, "GetValues"},
284 {2, "SetValues"},
285 {3, "ThisObject"},
286 {4, "PopFrames"},
287 {0, NULL}
290 // contains the commands for the command set of type ClassObject Reference
291 static const value_string commandset_classobjectreference[] = {
292 {1, "ReflectedType"},
293 {0, NULL}
296 // contains the commands for the command set of type Module Reference
297 static const value_string commandset_modulereference[] = {
298 {1, "Name"},
299 {2, "ClassLoader"},
300 {0, NULL}
303 // contains the commands for the command set of type Event
304 static const value_string commandset_event[] = {
305 {100, "Composite"},
306 {0, NULL}
309 /* translates the error code to human readable value
310 * value 0 ("NONE") means SUCCESS, all other values mean FAILURE
312 static const value_string error_codes[] = {
313 {0, "NONE"},
314 {10, "INVALID_THREAD"},
315 {11, "INVALID_THREAD_GROUP"},
316 {12, "INVALID_PRIORITY"},
317 {13, "THREAD_NOT_SUSPENDED"},
318 {14, "THREAD_SUSPENDED"},
319 {20, "INVALID_OBJECT"},
320 {21, "INVALID_CLASS"},
321 {22, "CLASS_NOT_PREPARED"},
322 {23, "INVALID_METHODID"},
323 {24, "INVALID_LOCATION"},
324 {25, "INVALID_FIELDID"},
325 {30, "INVALID_FRAMEID"},
326 {31, "NO_MORE_FRAMES"},
327 {32, "OPAQUE_FRAME"},
328 {33, "NOT_CURRENT_FRAME"},
329 {34, "TYPE_MISMATCH"},
330 {35, "INVALID_SLOT"},
331 {40, "DUPLICATE"},
332 {41, "NOT_FOUND"},
333 {50, "INVALID_MONITOR"},
334 {51, "NOT_MONITOR_OWNER"},
335 {52, "INTERRUPT"},
336 {60, "INVALID_CLASS_FORMAT"},
337 {61, "CIRCULAR_CLASS_DEFINITION"},
338 {62, "FAILS_VERIFICATION"},
339 {63, "ADD_METHOD_NOT_IMPLEMENTED"},
340 {64, "SCHEMA_CHANGE_NOT_IMPLEMENTED"},
341 {65, "INVALID_TYPESTATE"},
342 {66, "HIERARCHY_CHANGE_NOT_IMPLEMENTED"},
343 {67, "DELETE_METHOD_NOT_IMPLEMENTED"},
344 {68, "UNSUPPORTED_VERSION"},
345 {69, "NAMES_DONT_MATCH"},
346 {70, "CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED"},
347 {71, "METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED"},
348 {99, "NOT_IMPLEMENTED"},
349 {100, "NULL_POINTER"},
350 {101, "ABSENT_INFORMATION"},
351 {102, "INVALID_EVENT_TYPE"},
352 {103, "ILLEGAL_ARGUMENT"},
353 {110, "OUT_OF_MEMORY"},
354 {111, "ACCESS_DENIED"},
355 {112, "VM_DEAD"},
356 {113, "INTERNAL"},
357 {115, "UNATTACHED_THREAD"},
358 {500, "INVALID_TAG"},
359 {502, "ALREADY_INVOKING"},
360 {503, "INVALID_INDEX"},
361 {504, "INVALID_LENGTH"},
362 {506, "INVALID_STRING"},
363 {507, "INVALID_CLASS_LOADER"},
364 {508, "INVALID_ARRAY"},
365 {509, "TRANSPORT_LOAD"},
366 {510, "TRANSPORT_INIT"},
367 {511, "NATIVE_METHOD"},
368 {512, "INVALID_COUNT"},
369 {0, NULL}
372 /* determine PDU length of protocol JDWP */
373 static unsigned
374 get_jdwp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
376 /* Handshake messages don't contain the length field and
377 * they all are strictly identical in length and content
379 if (tvb_reported_length(tvb) == JDWP_HANDSHAKE_LENGTH) {
380 if (tvb_strneql(tvb, offset, JDWP_HANDSHAKE_MSG, JDWP_HANDSHAKE_LENGTH) == 0) {
381 return JDWP_HANDSHAKE_LENGTH;
385 /* All other packets are either a Command or a Reply, of different lengths
386 * and this length is indicated on the 4 first bytes
388 return (unsigned)tvb_get_ntohl(tvb, offset);
391 static int
392 dissect_jdwp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
394 int offset = 0;
396 /* packet type can take 3 values (handshake, command, reply) */
397 int packet_type;
399 /* length */
400 int32_t hlen = 0;
402 /* flag can take 2 values (0, 128) */
403 uint32_t flags;
405 /* fields that need to be remembered */
406 uint32_t mem_commandset = -1;
407 uint32_t mem_errorcode = -1;
409 /* Check that there's enough data */
410 if (tvb_reported_length(tvb) < JDWP_MIN_LENGTH)
411 return 0;
413 /* Set the Protocol Column */
414 col_set_str(pinfo->cinfo, COL_PROTOCOL, "JDWP");
415 col_clear(pinfo->cinfo, COL_INFO);
417 proto_item *ti, *hlen_item, *flags_item;
418 proto_tree *jdwp_tree;
420 /* Clear out stuff in the info column */
421 col_clear(pinfo->cinfo,COL_INFO);
423 ti = proto_tree_add_item(tree, proto_jdwp, tvb, 0, -1, ENC_NA);
424 jdwp_tree = proto_item_add_subtree(ti, ett_jdwp);
426 /* The two first packets are Handshake packets and
427 * their content is always "JDWP-Handshake"
428 * All other packets are either a Command or a Reply
430 packet_type = 1;
431 if (tvb_reported_length(tvb) == JDWP_HANDSHAKE_LENGTH) {
432 if (tvb_strneql(tvb, offset, JDWP_HANDSHAKE_MSG, JDWP_HANDSHAKE_LENGTH) == 0) {
433 col_append_str(pinfo->cinfo, COL_INFO, "JDWP Handshake");
434 packet_type = 0;
438 if (packet_type == 0) {
439 proto_tree_add_item(jdwp_tree, hf_jdwp_type, tvb, offset, 14, ENC_ASCII);
440 return tvb_captured_length(tvb);
443 /* LENGTH
445 hlen_item = proto_tree_add_item_ret_uint(jdwp_tree, hf_jdwp_length, tvb, offset, 4, ENC_BIG_ENDIAN, &hlen);
446 offset += 4;
448 /* ID
450 proto_tree_add_item(jdwp_tree, hf_jdwp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
451 offset += 4;
453 /* FLAGS
455 flags_item = proto_tree_add_item_ret_uint(jdwp_tree, hf_jdwp_flags, tvb, offset, 1, ENC_BIG_ENDIAN, &flags);
456 offset += 1;
458 /* COMMAND
460 switch (flags) {
461 case PACKET_TYPE_COMMAND:
462 col_append_str(pinfo->cinfo, COL_INFO, "Command");
463 proto_tree_add_item_ret_uint(jdwp_tree, hf_jdwp_commandset, tvb, offset, 1, ENC_BIG_ENDIAN, &mem_commandset);
464 offset += 1;
466 switch (mem_commandset) {
468 case COMMAND_SET_VIRTUALMACHINE:
469 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_virtualmachine, tvb, offset, 1, ENC_BIG_ENDIAN);
470 offset += 1;
471 break;
473 case COMMAND_SET_REFERENCETYPE:
474 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_referencetype, tvb, offset, 1, ENC_BIG_ENDIAN);
475 offset += 1;
476 break;
478 case COMMAND_SET_CLASSTYPE:
479 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_classtype, tvb, offset, 1, ENC_BIG_ENDIAN);
480 offset += 1;
481 break;
483 case COMMAND_SET_ARRAYTYPE:
484 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_arraytype, tvb, offset, 1, ENC_BIG_ENDIAN);
485 offset += 1;
486 break;
488 case COMMAND_SET_INTERFACETYPE:
489 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_interfacetype, tvb, offset, 1, ENC_BIG_ENDIAN);
490 offset += 1;
491 break;
493 case COMMAND_SET_METHOD:
494 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_method, tvb, offset, 1, ENC_BIG_ENDIAN);
495 offset += 1;
496 break;
498 case COMMAND_SET_FIELD:
499 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_field, tvb, offset, 1, ENC_BIG_ENDIAN);
500 offset += 1;
501 break;
503 case COMMAND_SET_OBJECTREFERENCE:
504 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_objectreference, tvb, offset, 1, ENC_BIG_ENDIAN);
505 offset += 1;
506 break;
508 case COMMAND_SET_STRINGREFERENCE:
509 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_stringreference, tvb, offset, 1, ENC_BIG_ENDIAN);
510 offset += 1;
511 break;
513 case COMMAND_SET_THREADREFERENCE:
514 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_threadreference, tvb, offset, 1, ENC_BIG_ENDIAN);
515 offset += 1;
516 break;
518 case COMMAND_SET_THREADGROUPREFERENCE:
519 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_threadgroupreference, tvb, offset, 1, ENC_BIG_ENDIAN);
520 offset += 1;
521 break;
523 case COMMAND_SET_ARRAYREFERENCE:
524 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_arrayreference, tvb, offset, 1, ENC_BIG_ENDIAN);
525 offset += 1;
526 break;
528 case COMMAND_SET_CLASSLOADERREFERENCE:
529 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_classloaderreference, tvb, offset, 1, ENC_BIG_ENDIAN);
530 offset += 1;
531 break;
533 case COMMAND_SET_EVENTREQUEST:
534 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_eventrequest, tvb, offset, 1, ENC_BIG_ENDIAN);
535 offset += 1;
536 break;
538 case COMMAND_SET_STACKFRAME:
539 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_stackframe, tvb, offset, 1, ENC_BIG_ENDIAN);
540 offset += 1;
541 break;
543 case COMMAND_SET_CLASSOBJECTREFERENCE:
544 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_classobjectreference, tvb, offset, 1, ENC_BIG_ENDIAN);
545 offset += 1;
546 break;
548 case COMMAND_SET_MODULEREFERENCE:
549 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_modulereference, tvb, offset, 1, ENC_BIG_ENDIAN);
550 offset += 1;
551 break;
553 case COMMAND_SET_EVENT:
554 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_event, tvb, offset, 1, ENC_BIG_ENDIAN);
555 offset += 1;
556 break;
558 default:
559 proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_virtualmachine, tvb, offset, 1, ENC_BIG_ENDIAN);
560 offset += 1;
561 break;
565 /* command comes with data when the minimal length is 12 */
566 if (hlen > 11) {
567 proto_tree_add_item(jdwp_tree, hf_jdwp_data, tvb, offset, hlen - 11, ENC_NA);
568 } else if (hlen < 11) {
569 expert_add_info(pinfo, hlen_item, &ei_jdwp_hlen_invalid);
572 break;
574 case PACKET_TYPE_REPLY:
575 proto_tree_add_item_ret_uint(jdwp_tree, hf_jdwp_errorcode, tvb, offset, 2, ENC_BIG_ENDIAN, &mem_errorcode);
576 offset += 2;
578 if(mem_errorcode == 0) {
579 col_append_str(pinfo->cinfo, COL_INFO, "Reply (Success)");
580 } else {
581 col_append_str(pinfo->cinfo, COL_INFO, "Reply (Failure)");
584 /* reply comes with data when the minimal length is 12 */
585 if (hlen > 11) {
586 proto_tree_add_item(jdwp_tree, hf_jdwp_data, tvb, offset, hlen - 11, ENC_NA);
587 } else if (hlen < 11) {
588 expert_add_info(pinfo, hlen_item, &ei_jdwp_hlen_invalid);
591 break;
593 default:
594 expert_add_info(pinfo, flags_item, &ei_jdwp_flags_invalid);
595 break;
598 return tvb_captured_length(tvb);
601 static int
602 dissect_jdwp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
604 tcp_dissect_pdus(tvb, pinfo, tree, true, FRAME_HEADER_LEN,
605 get_jdwp_message_len, dissect_jdwp_message, data);
606 return tvb_captured_length(tvb);
609 void
610 proto_register_jdwp(void)
613 expert_module_t* expert_jdwp;
615 static hf_register_info hf[] = {
616 { &hf_jdwp_type,
617 { "Packet Type", "jdwp.type", FT_STRING, BASE_NONE, NULL, 0x0, NULL,
618 HFILL }
620 { &hf_jdwp_length,
621 { "Length", "jdwp.length", FT_UINT32, BASE_DEC, NULL, 0x0, "Data Length",
622 HFILL }
624 { &hf_jdwp_id,
625 { "id", "jdwp.id", FT_UINT32, BASE_DEC, NULL, 0x0, "unique identifier",
626 HFILL }
628 { &hf_jdwp_flags,
629 { "flags", "jdwp.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "tag packets as a command or reply",
630 HFILL }
632 { &hf_jdwp_commandset,
633 { "command set", "jdwp.commandset", FT_UINT8, BASE_DEC, VALS(commandsetnames), 0x0, NULL,
634 HFILL }
636 { &hf_jdwp_commandset_virtualmachine,
637 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_virtualmachine), 0x0, NULL,
638 HFILL }
640 { &hf_jdwp_commandset_referencetype,
641 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_referencetype), 0x0, NULL,
642 HFILL }
644 { &hf_jdwp_commandset_classtype,
645 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_classtype), 0x0, NULL,
646 HFILL }
648 { &hf_jdwp_commandset_arraytype,
649 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_arraytype), 0x0, NULL,
650 HFILL }
652 { &hf_jdwp_commandset_interfacetype,
653 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_interfacetype), 0x0, NULL,
654 HFILL }
656 { &hf_jdwp_commandset_method,
657 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_method), 0x0, NULL,
658 HFILL }
660 { &hf_jdwp_commandset_field,
661 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_field), 0x0, NULL,
662 HFILL }
664 { &hf_jdwp_commandset_objectreference,
665 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_objectreference), 0x0, NULL,
666 HFILL }
668 { &hf_jdwp_commandset_stringreference,
669 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_stringreference), 0x0, NULL,
670 HFILL }
672 { &hf_jdwp_commandset_threadreference,
673 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_threadreference), 0x0, NULL,
674 HFILL }
676 { &hf_jdwp_commandset_threadgroupreference,
677 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_threadgroupreference), 0x0, NULL,
678 HFILL }
680 { &hf_jdwp_commandset_arrayreference,
681 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_arrayreference), 0x0, NULL,
682 HFILL }
684 { &hf_jdwp_commandset_classloaderreference,
685 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_classloaderreference), 0x0, NULL,
686 HFILL }
688 { &hf_jdwp_commandset_eventrequest,
689 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_eventrequest), 0x0, NULL,
690 HFILL }
692 { &hf_jdwp_commandset_stackframe,
693 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_stackframe), 0x0, NULL,
694 HFILL }
696 { &hf_jdwp_commandset_classobjectreference,
697 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_classobjectreference), 0x0, NULL,
698 HFILL }
700 { &hf_jdwp_commandset_modulereference,
701 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_modulereference), 0x0, NULL,
702 HFILL }
704 { &hf_jdwp_commandset_event,
705 { "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_event), 0x0, NULL,
706 HFILL }
708 { &hf_jdwp_errorcode,
709 { "error code", "jdwp.errorcode", FT_UINT16, BASE_DEC, VALS(error_codes), 0x0, NULL,
710 HFILL }
712 { &hf_jdwp_data,
713 { "data", "jdwp.data", FT_BYTES, BASE_NONE, NULL, 0x0, "details of the command or reply",
714 HFILL }
718 static ei_register_info ei[] = {
719 { &ei_jdwp_hlen_invalid, { "jdwp.hlen.invalid", PI_MALFORMED, PI_ERROR, "Decode aborted: invalid packet length", EXPFILL }},
720 { &ei_jdwp_flags_invalid, { "jdwp.flags.invalid", PI_MALFORMED, PI_ERROR, "Decode aborted: invalid flags value", EXPFILL }}
723 static int *ett[] = {
724 &ett_jdwp
727 proto_jdwp = proto_register_protocol("Java Debug Wire Protocol", "JDWP", "jdwp");
728 jdwp_handle = register_dissector("jdwp", dissect_jdwp, proto_jdwp);
729 proto_register_field_array(proto_jdwp, hf, array_length(hf));
730 proto_register_subtree_array(ett, array_length(ett));
731 expert_jdwp = expert_register_protocol(proto_jdwp);
732 expert_register_field_array(expert_jdwp, ei, array_length(ei));
736 void
737 proto_reg_handoff_jdwp(void)
739 dissector_add_uint_with_preference("tcp.port", JDWP_PORT, jdwp_handle);
743 * Editor modelines - https://www.wireshark.org/tools/modelines.html
745 * Local variables:
746 * c-basic-offset: 2
747 * tab-width: 8
748 * indent-tabs-mode: nil
749 * End:
751 * vi: set shiftwidth=2 tabstop=8 expandtab:
752 * :indentSize=2:tabSize=8:noTabs=true: