JDWP dissector for TCP transport

Bug: 16479
Change-Id: I2618bb4b664c1dd7b4663c368b6ca99ec0533dd5
Reviewed-on: https://code.wireshark.org/review/36636
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Eugene Adell 2020-03-30 22:03:27 +02:00 committed by Anders Broman
parent 9132feb4a4
commit 3a42f536ed
3 changed files with 732 additions and 0 deletions

View File

@ -61,6 +61,7 @@ OBSAI UDP-based Communication Protocol (UDPCP)
AudioCodes Debug Recording (ACDR) AudioCodes Debug Recording (ACDR)
Tunnel Extensible Authentication Protocol (TEAP) Tunnel Extensible Authentication Protocol (TEAP)
USB Printer (USBPRINTER) USB Printer (USBPRINTER)
Java Debug Wire Protocol (JDWP)
-- --
=== Updated Protocol Support === Updated Protocol Support

View File

@ -1280,6 +1280,7 @@ set(DISSECTOR_SRC
${CMAKE_CURRENT_SOURCE_DIR}/packet-ixiatrailer.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-ixiatrailer.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-ixveriwave.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-ixveriwave.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-j1939.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-j1939.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-jdwp.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-jmirror.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-jmirror.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-jpeg.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-jpeg.c
${CMAKE_CURRENT_SOURCE_DIR}/packet-json.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-json.c

View File

@ -0,0 +1,730 @@
/* packet-jdwp.c
* Routines for JDWP (Java Debug Wire Protocol) dissection
* Copyright 2020, Eugene Adell <eugene.adell@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <stdio.h>
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
#include <epan/to_str.h>
#include <epan/conversation.h>
#include <epan/wmem/wmem.h>
#include "packet-tcp.h"
void proto_register_jdwp(void);
void proto_reg_handoff_jdwp(void);
/* IMPORTANT IMPLEMENTATION NOTES
*
* You need to be looking at:
*
* https://docs.oracle.com/javase/8/docs/technotes/guides/jpda/jdwp-spec.html
*
*
*/
#define JDWP_PORT 9009 /* Not IANA registered */
#define FRAME_HEADER_LEN 11
#define JDWP_MIN_LENGTH 11
#define JDWP_HANDSHAKE_LENGTH 14
#define JDWP_HANDSHAKE_MSG "JDWP-Handshake"
#define PACKET_TYPE_COMMAND 0
#define PACKET_TYPE_REPLY 128
#define COMMAND_SET_VIRTUALMACHINE 1
#define COMMAND_SET_REFERENCETYPE 2
#define COMMAND_SET_CLASSTYPE 3
#define COMMAND_SET_ARRAYTYPE 4
#define COMMAND_SET_INTERFACETYPE 5
#define COMMAND_SET_METHOD 6
#define COMMAND_SET_FIELD 8
#define COMMAND_SET_OBJECTREFERENCE 9
#define COMMAND_SET_STRINGREFERENCE 10
#define COMMAND_SET_THREADREFERENCE 11
#define COMMAND_SET_THREADGROUPREFERENCE 12
#define COMMAND_SET_ARRAYREFERENCE 13
#define COMMAND_SET_CLASSLOADERREFERENCE 14
#define COMMAND_SET_EVENTREQUEST 15
#define COMMAND_SET_STACKFRAME 16
#define COMMAND_SET_CLASSOBJECTREFERENCE 17
#define COMMAND_SET_EVENT 64
static int proto_jdwp = -1;
static int hf_jdwp_type = -1;
static int hf_jdwp_length = -1;
static int hf_jdwp_id = -1;
static int hf_jdwp_flags = -1;
static int hf_jdwp_commandset = -1;
static int hf_jdwp_commandset_virtualmachine = -1;
static int hf_jdwp_commandset_referencetype = -1;
static int hf_jdwp_commandset_classtype = -1;
static int hf_jdwp_commandset_arraytype = -1;
static int hf_jdwp_commandset_interfacetype = -1;
static int hf_jdwp_commandset_method = -1;
static int hf_jdwp_commandset_field = -1;
static int hf_jdwp_commandset_objectreference = -1;
static int hf_jdwp_commandset_stringreference = -1;
static int hf_jdwp_commandset_threadreference = -1;
static int hf_jdwp_commandset_threadgroupreference = -1;
static int hf_jdwp_commandset_arrayreference = -1;
static int hf_jdwp_commandset_classloaderreference = -1;
static int hf_jdwp_commandset_eventrequest = -1;
static int hf_jdwp_commandset_stackframe = -1;
static int hf_jdwp_commandset_classobjectreference = -1;
static int hf_jdwp_commandset_event = -1;
static int hf_jdwp_errorcode = -1;
static int hf_jdwp_data = -1;
static gint ett_jdwp = -1;
static expert_field ei_jdwp_hlen_invalid = EI_INIT;
static expert_field ei_jdwp_flags_invalid = EI_INIT;
// contains the command set names
static const value_string commandsetnames[] = {
{1, "VirtualMachine"},
{2, "ReferenceType"},
{3, "ClassType"},
{4, "ArrayType"},
{5, "InterfaceType"},
{6, "Method"},
{8, "Field"},
{9, "ObjectReference"},
{10, "StringReference"},
{11, "ThreadReference"},
{12, "ThreadGroupReference"},
{13, "ArrayReference"},
{14, "ClassLoaderReference"},
{15, "EventRequest"},
{16, "StackFrame"},
{17, "ClassObjectReference"},
{64, "Event"},
{0, NULL}
};
// contains the commands for the command set of type Virtual Machine
static const value_string commandset_virtualmachine[] = {
{1, "Version"},
{2, "ClassesBySignature"},
{3, "AllClasses"},
{4, "AllThreads"},
{5, "TopLevelThreadGroups"},
{6, "Dispose"},
{7, "IDSizes"},
{8, "Suspend"},
{9, "Resume"},
{10, "Exit"},
{11, "CreateString"},
{12, "Capabilities"},
{13, "ClassPaths"},
{14, "DisposeObjects"},
{15, "HoldEvents"},
{16, "ReleaseEvents"},
{17, "CapabilitiesNew"},
{18, "RedefineClasses"},
{19, "SetDefaultStratum"},
{20, "AllClassesWithGeneric"},
{21, "InstanceCounts"},
{0, NULL}
};
// contains the commands for the command set of type Reference
static const value_string commandset_referencetype[] = {
{1, "Signature"},
{2, "ClassLoader"},
{3, "Modifiers"},
{4, "Fields"},
{5, "Methods"},
{6, "GetValues"},
{7, "SourceFile"},
{8, "NestedTypes"},
{9, "Status"},
{10, "Interfaces"},
{11, "ClassObject"},
{12, "SourceDebugExtension"},
{13, "SignatureWithGeneric"},
{14, "FieldsWithGeneric"},
{15, "MethodsWithGeneric"},
{16, "Instances"},
{17, "ClassFileVersion"},
{18, "ConstantPool"},
{0, NULL}
};
// contains the commands for the command set of type Class
static const value_string commandset_classtype[] = {
{1, "Superclass"},
{2, "SetValues"},
{3, "InvokeMethod"},
{4, "NewInstance"},
{0, NULL}
};
// contains the commands for the command set of type Array
static const value_string commandset_arraytype[] = {
{1, "NewInstance"},
{0, NULL}
};
// contains the commands for the command set of type Interface
static const value_string commandset_interfacetype[] = {
{1, "InvokeMethod"},
{0, NULL}
};
// contains the commands for the command set of type Method
static const value_string commandset_method[] = {
{1, "LineTable"},
{2, "VariableTable"},
{3, "Bytecodes"},
{4, "IsObsolete"},
{5, "VariableTableWithGeneric"},
{0, NULL}
};
// contains the commands for the command set of type Field
static const value_string commandset_field[] = {
{0, NULL}
};
// contains the commands for the command set of type Object Reference
static const value_string commandset_objectreference[] = {
{1, "ReferenceType"},
{2, "GetValues"},
{3, "SetValues"},
{5, "MonitorInfo"},
{6, "InvokeMethod"},
{7, "DisableCollection"},
{8, "EnableCollection"},
{9, "IsCollected"},
{10, "ReferringObjects"},
{0, NULL}
};
// contains the commands for the command set of type String Reference
static const value_string commandset_stringreference[] = {
{1, "Value"},
{0, NULL}
};
// contains the commands for the command set of type Thread Reference
static const value_string commandset_threadreference[] = {
{1, "Name"},
{2, "Suspend"},
{3, "Resume"},
{4, "Status"},
{5, "ThreadGroup"},
{6, "Frames"},
{7, "FrameCount"},
{8, "OwnedMonitors"},
{9, "CurrentContentedMonitor"},
{10, "Stop"},
{11, "Interrupt"},
{12, "SuspendCount"},
{13, "OwnedMonitorsStackDepthInfo"},
{14, "ForceEearlyReturn"},
{0, NULL}
};
// contains the commands for the command set of type ThreadGroup Reference
static const value_string commandset_threadgroupreference[] = {
{1, "Name"},
{2, "Parent"},
{3, "Children"},
{0, NULL}
};
// contains the commands for the command set of type Array Reference
static const value_string commandset_arrayreference[] = {
{1, "Length"},
{2, "GetValues"},
{3, "SetValues"},
{0, NULL}
};
// contains the commands for the command set of type ClassLoader Reference
static const value_string commandset_classloaderreference[] = {
{1, "VisibleClasses"},
{0, NULL}
};
// contains the commands for the command set of type EventRequest
static const value_string commandset_eventrequest[] = {
{1, "Set"},
{2, "Clear"},
{3, "ClearAllBreakpoints"},
{0, NULL}
};
// contains the commands for the command set of type StackFrame
static const value_string commandset_stackframe[] = {
{1, "GetValues"},
{2, "SetValues"},
{3, "ThisObject"},
{4, "PopFrames"},
{0, NULL}
};
// contains the commands for the command set of type ClassObject Reference
static const value_string commandset_classobjectreference[] = {
{1, "ReflectedType"},
{0, NULL}
};
// contains the commands for the command set of type Event
static const value_string commandset_event[] = {
{100, "Composite"},
{0, NULL}
};
/* translates the error code to human readable value
* value 0 ("NONE") means SUCCESS, all other values mean FAILURE
*/
static const value_string error_codes[] = {
{0, "NONE"},
{10, "INVALID_THREAD"},
{11, "INVALID_THREAD_GROUP"},
{12, "INVALID_PRIORITY"},
{13, "THREAD_NOT_SUSPENDED"},
{14, "THREAD_SUSPENDED"},
{20, "INVALID_OBJECT"},
{21, "INVALID_CLASS"},
{22, "CLASS_NOT_PREPARED"},
{23, "INVALID_METHODID"},
{24, "INVALID_LOCATION"},
{25, "INVALID_FIELDID"},
{30, "INVALID_FRAMEID"},
{31, "NO_MORE_FRAMES"},
{32, "OPAQUE_FRAME"},
{33, "NOT_CURRENT_FRAME"},
{34, "TYPE_MISMATCH"},
{35, "INVALID_SLOT"},
{40, "DUPLICATE"},
{41, "NOT_FOUND"},
{50, "INVALID_MONITOR"},
{51, "NOT_MONITOR_OWNER"},
{52, "INTERRUPT"},
{60, "INVALID_CLASS_FORMAT"},
{61, "CIRCULAR_CLASS_DEFINITION"},
{62, "FAILS_VERIFICATION"},
{63, "ADD_METHOD_NOT_IMPLEMENTED"},
{64, "SCHEMA_CHANGE_NOT_IMPLEMENTED"},
{65, "INVALID_TYPESTATE"},
{66, "HIERARCHY_CHANGE_NOT_IMPLEMENTED"},
{67, "DELETE_METHOD_NOT_IMPLEMENTED"},
{68, "UNSUPPORTED_VERSION"},
{69, "NAMES_DONT_MATCH"},
{70, "CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED"},
{71, "METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED"},
{99, "NOT_IMPLEMENTED"},
{100, "NULL_POINTER"},
{101, "ABSENT_INFORMATION"},
{102, "INVALID_EVENT_TYPE"},
{103, "ILLEGAL_ARGUMENT"},
{110, "OUT_OF_MEMORY"},
{111, "ACCESS_DENIED"},
{112, "VM_DEAD"},
{113, "INTERNAL"},
{115, "UNATTACHED_THREAD"},
{500, "INVALID_TAG"},
{502, "ALREADY_INVOKING"},
{503, "INVALID_INDEX"},
{504, "INVALID_LENGTH"},
{506, "INVALID_STRING"},
{507, "INVALID_CLASS_LOADER"},
{508, "INVALID_ARRAY"},
{509, "TRANSPORT_LOAD"},
{510, "TRANSPORT_INIT"},
{511, "NATIVE_METHOD"},
{512, "INVALID_COUNT"},
{0, NULL}
};
/* determine PDU length of protocol JDWP */
static guint
get_jdwp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
/* Handshake messages don't contain the length field and
* they all are strictly identical in length and content
*/
if (tvb_reported_length(tvb) == JDWP_HANDSHAKE_LENGTH) {
if (tvb_strneql(tvb, offset, JDWP_HANDSHAKE_MSG, JDWP_HANDSHAKE_LENGTH) == 0) {
return JDWP_HANDSHAKE_LENGTH;
}
}
/* All other packets are either a Command or a Reply, of different lengths
* and this length is indicated on the 4 first bytes
*/
return (guint)tvb_get_ntohl(tvb, offset);
}
static int
dissect_jdwp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
int offset = 0;
/* packet type can take 3 values (handshake, command, reply) */
gint packet_type;
/* length */
gint32 hlen = 0;
/* flag can take 2 values (0, 128) */
guint32 flags;
/* fields that need to be remembered */
guint32 mem_commandset = -1;
guint32 mem_errorcode = -1;
/* Check that there's enough data */
if (tvb_reported_length(tvb) < JDWP_MIN_LENGTH)
return 0;
/* Set the Protocol Column */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "JDWP");
col_clear(pinfo->cinfo, COL_INFO);
proto_item *ti, *hlen_item, *flags_item;
proto_tree *jdwp_tree;
/* Clear out stuff in the info column */
col_clear(pinfo->cinfo,COL_INFO);
ti = proto_tree_add_item(tree, proto_jdwp, tvb, 0, -1, ENC_NA);
jdwp_tree = proto_item_add_subtree(ti, ett_jdwp);
/* The two first packets are Handshake packets and
* their content is always "JDWP-Handshake"
* All other packets are either a Command or a Reply
*/
packet_type = 1;
if (tvb_reported_length(tvb) == JDWP_HANDSHAKE_LENGTH) {
if (tvb_strneql(tvb, offset, JDWP_HANDSHAKE_MSG, JDWP_HANDSHAKE_LENGTH) == 0) {
col_append_fstr(pinfo->cinfo, COL_INFO, "JDWP Handshake");
packet_type = 0;
}
}
if (packet_type == 0) {
proto_tree_add_item(jdwp_tree, hf_jdwp_type, tvb, offset, 14, ENC_ASCII|ENC_NA);
return tvb_captured_length(tvb);
}
/* LENGTH
*/
hlen_item = proto_tree_add_item_ret_uint(jdwp_tree, hf_jdwp_length, tvb, offset, 4, ENC_BIG_ENDIAN, &hlen);
offset += 4;
/* ID
*/
proto_tree_add_item(jdwp_tree, hf_jdwp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
/* FLAGS
*/
flags_item = proto_tree_add_item_ret_uint(jdwp_tree, hf_jdwp_flags, tvb, offset, 1, ENC_BIG_ENDIAN, &flags);
offset += 1;
/* COMMAND
*/
switch (flags) {
case PACKET_TYPE_COMMAND:
col_append_fstr(pinfo->cinfo, COL_INFO, "Command");
proto_tree_add_item_ret_uint(jdwp_tree, hf_jdwp_commandset, tvb, offset, 1, ENC_BIG_ENDIAN, &mem_commandset);
offset += 1;
switch (mem_commandset) {
case COMMAND_SET_VIRTUALMACHINE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_virtualmachine, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_REFERENCETYPE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_referencetype, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_CLASSTYPE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_classtype, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_ARRAYTYPE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_arraytype, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_INTERFACETYPE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_interfacetype, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_METHOD:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_method, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_FIELD:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_field, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_OBJECTREFERENCE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_objectreference, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_STRINGREFERENCE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_stringreference, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_THREADREFERENCE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_threadreference, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_THREADGROUPREFERENCE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_threadgroupreference, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_ARRAYREFERENCE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_arrayreference, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_CLASSLOADERREFERENCE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_classloaderreference, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_EVENTREQUEST:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_eventrequest, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_STACKFRAME:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_stackframe, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_CLASSOBJECTREFERENCE:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_classobjectreference, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
case COMMAND_SET_EVENT:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_event, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
default:
proto_tree_add_item(jdwp_tree, hf_jdwp_commandset_virtualmachine, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
break;
}
/* command comes with data when the minimal length is 12 */
if (hlen > 11) {
proto_tree_add_item(jdwp_tree, hf_jdwp_data, tvb, offset, hlen - 11, ENC_NA);
} else if (hlen < 11) {
expert_add_info(pinfo, hlen_item, &ei_jdwp_hlen_invalid);
}
break;
case PACKET_TYPE_REPLY:
proto_tree_add_item_ret_uint(jdwp_tree, hf_jdwp_errorcode, tvb, offset, 2, ENC_BIG_ENDIAN, &mem_errorcode);
offset += 2;
if(mem_errorcode == 0) {
col_append_fstr(pinfo->cinfo, COL_INFO, "Reply (Success)");
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, "Reply (Failure)");
}
/* reply comes with data when the minimal length is 12 */
if (hlen > 11) {
proto_tree_add_item(jdwp_tree, hf_jdwp_data, tvb, offset, hlen - 11, ENC_NA);
} else if (hlen < 11) {
expert_add_info(pinfo, hlen_item, &ei_jdwp_hlen_invalid);
}
break;
default:
expert_add_info(pinfo, flags_item, &ei_jdwp_flags_invalid);
break;
}
return tvb_captured_length(tvb);
}
static int
dissect_jdwp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, FRAME_HEADER_LEN,
get_jdwp_message_len, dissect_jdwp_message, data);
return tvb_captured_length(tvb);
}
void
proto_register_jdwp(void)
{
expert_module_t* expert_jdwp;
static hf_register_info hf[] = {
{ &hf_jdwp_type,
{ "Packet Type", "jdwp.type", FT_STRING, BASE_NONE, NULL, 0x0, "Type",
HFILL }
},
{ &hf_jdwp_length,
{ "Length", "jdwp.length", FT_UINT32, BASE_DEC, NULL, 0x0, "Data Length",
HFILL }
},
{ &hf_jdwp_id,
{ "id", "jdwp.id", FT_UINT32, BASE_DEC, NULL, 0x0, "unique identifier",
HFILL }
},
{ &hf_jdwp_flags,
{ "flags", "jdwp.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "tag packets as a command or reply",
HFILL }
},
{ &hf_jdwp_commandset,
{ "command set", "jdwp.commandset", FT_UINT8, BASE_DEC, VALS(commandsetnames), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_virtualmachine,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_virtualmachine), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_referencetype,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_referencetype), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_classtype,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_classtype), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_arraytype,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_arraytype), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_interfacetype,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_interfacetype), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_method,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_method), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_field,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_field), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_objectreference,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_objectreference), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_stringreference,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_stringreference), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_threadreference,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_threadreference), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_threadgroupreference,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_threadgroupreference), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_arrayreference,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_arrayreference), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_classloaderreference,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_classloaderreference), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_eventrequest,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_eventrequest), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_stackframe,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_stackframe), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_classobjectreference,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_classobjectreference), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_commandset_event,
{ "command", "jdwp.command", FT_UINT8, BASE_DEC, VALS(commandset_event), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_errorcode,
{ "error code", "jdwp.errorcode", FT_UINT8, BASE_DEC, VALS(error_codes), 0x0, NULL,
HFILL }
},
{ &hf_jdwp_data,
{ "data", "jdwp.data", FT_BYTES, BASE_NONE, NULL, 0x0, "details of the command or reply",
HFILL }
}
};
static ei_register_info ei[] = {
{ &ei_jdwp_hlen_invalid, { "jdwp.hlen.invalid", PI_MALFORMED, PI_ERROR, "Decode aborted: invalid packet length", EXPFILL }},
{ &ei_jdwp_flags_invalid, { "jdwp.flags.invalid", PI_MALFORMED, PI_ERROR, "Decode aborted: invalid flags value", EXPFILL }}
};
static gint *ett[] = {
&ett_jdwp
};
proto_jdwp = proto_register_protocol("Java Debug Wire Protocol", "JDWP", "jdwp");
proto_register_field_array(proto_jdwp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_jdwp = expert_register_protocol(proto_jdwp);
expert_register_field_array(expert_jdwp, ei, array_length(ei));
}
void
proto_reg_handoff_jdwp(void)
{
dissector_handle_t jdwp_handle;
jdwp_handle = create_dissector_handle(dissect_jdwp, proto_jdwp);
dissector_add_uint_with_preference("tcp.port", JDWP_PORT, jdwp_handle);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/