forked from osmocom/wireshark
Replace enumerated preference for choosing subdissector with a subdissector table and Decode As functionality.
This makes it much easier for other subdissectors (and plugins) to associate themselves with CAN. Change-Id: I49dd832af51651d0c91f9850c100e544d178b8c4 Reviewed-on: https://code.wireshark.org/review/7734 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
parent
da3e4f92d5
commit
f7b1678b12
|
@ -26,6 +26,7 @@
|
|||
#include <epan/packet.h>
|
||||
|
||||
void proto_register_canopen(void);
|
||||
void proto_reg_handoff_canopen(void);
|
||||
|
||||
/* Initialize the protocol and registered fields */
|
||||
static int proto_canopen = -1;
|
||||
|
@ -1376,12 +1377,19 @@ proto_register_canopen(void)
|
|||
"CANOPEN",
|
||||
"canopen");
|
||||
|
||||
new_register_dissector("canopen", dissect_canopen, proto_canopen);
|
||||
|
||||
proto_register_field_array(proto_canopen, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_canopen(void)
|
||||
{
|
||||
dissector_handle_t canopen_handle;
|
||||
|
||||
canopen_handle = new_create_dissector_handle( dissect_canopen, proto_canopen );
|
||||
dissector_add_for_decode_as("can.subdissector", canopen_handle );
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "packet-cip.h"
|
||||
|
||||
void proto_register_devicenet(void);
|
||||
void proto_reg_handoff_devicenet(void);
|
||||
|
||||
#define DEVICENET_CANID_MASK 0x7FF
|
||||
#define MESSAGE_GROUP_1_ID 0x3FF
|
||||
|
@ -428,6 +429,10 @@ static int dissect_devicenet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
|
|||
DISSECTOR_ASSERT(data);
|
||||
can_id = *((struct can_identifier*)data);
|
||||
|
||||
/* XXX - Not sure this is correct. But the capture provided in
|
||||
* bug 8564 provides CAN ID in little endian format, so this makes it work */
|
||||
can_id.id = GUINT32_SWAP_LE_BE(can_id.id);
|
||||
|
||||
if (can_id.id & (~DEVICENET_CANID_MASK))
|
||||
{
|
||||
/* Not for us */
|
||||
|
@ -1029,8 +1034,6 @@ void proto_register_devicenet(void)
|
|||
expert_devicenet = expert_register_protocol(proto_devicenet);
|
||||
expert_register_field_array(expert_devicenet, ei, array_length(ei));
|
||||
|
||||
new_register_dissector("devicenet", dissect_devicenet, proto_devicenet);
|
||||
|
||||
devicenet_address_type = address_type_dissector_register("AT_DEVICENET", "DeviceNet Address", devicenet_addr_to_str, devicenet_addr_str_len, NULL, devicenet_addr_len, NULL, NULL);
|
||||
|
||||
devicenet_module = prefs_register_protocol(proto_devicenet, NULL);
|
||||
|
@ -1056,6 +1059,15 @@ void proto_register_devicenet(void)
|
|||
devicenet_uat);
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_devicenet(void)
|
||||
{
|
||||
dissector_handle_t devicenet_handle;
|
||||
|
||||
devicenet_handle = new_create_dissector_handle( dissect_devicenet, proto_devicenet );
|
||||
dissector_add_for_decode_as("can.subdissector", devicenet_handle );
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <epan/to_str-int.h>
|
||||
|
||||
void proto_register_j1939(void);
|
||||
void proto_reg_handoff_j1939(void);
|
||||
|
||||
#define J1939_CANID_MASK 0x1FFFFFFF
|
||||
#define J1939_11BIT_ID 0x000003FF
|
||||
|
@ -347,13 +348,20 @@ void proto_register_j1939(void)
|
|||
proto_register_field_array(proto_j1939, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
new_register_dissector("j1939", dissect_j1939, proto_j1939);
|
||||
|
||||
subdissector_pgn_table = register_dissector_table("j1939.pgn", "PGN Handle", FT_UINT32, BASE_DEC);
|
||||
|
||||
j1939_address_type = address_type_dissector_register("AT_J1939", "J1939 Address", J1939_addr_to_str, J1939_addr_str_len, J1939_col_filter_str, J1939_addr_len, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
proto_reg_handoff_j1939(void)
|
||||
{
|
||||
dissector_handle_t j1939_handle;
|
||||
|
||||
j1939_handle = new_create_dissector_handle( dissect_j1939, proto_j1939 );
|
||||
dissector_add_for_decode_as("can.subdissector", j1939_handle );
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/prefs.h>
|
||||
#include <epan/decode_as.h>
|
||||
#include <wiretap/wtap.h>
|
||||
|
||||
#include "packet-sll.h"
|
||||
|
@ -58,9 +59,6 @@ static gint ett_can = -1;
|
|||
static int proto_can = -1;
|
||||
|
||||
static dissector_handle_t data_handle;
|
||||
static dissector_handle_t canopen_handle;
|
||||
static dissector_handle_t devicenet_handle;
|
||||
static dissector_handle_t j1939_handle;
|
||||
|
||||
#define LINUX_CAN_STD 0
|
||||
#define LINUX_CAN_EXT 1
|
||||
|
@ -70,13 +68,6 @@ static dissector_handle_t j1939_handle;
|
|||
#define CAN_LEN_OFFSET 4
|
||||
#define CAN_DATA_OFFSET 8
|
||||
|
||||
typedef enum {
|
||||
CAN_DATA_DISSECTOR = 1,
|
||||
CAN_CANOPEN_DISSECTOR = 2,
|
||||
CAN_DEVICENET_DISSECTOR = 3,
|
||||
CAN_J1939_DISSECTOR = 4
|
||||
} Dissector_Option;
|
||||
|
||||
/* Structure that gets passed between dissectors. Since it's just a simple 32-bit
|
||||
value, no sense in creating a header file for it. Just expect subdissectors
|
||||
to provide their own.
|
||||
|
@ -86,15 +77,7 @@ struct can_identifier
|
|||
guint32 id;
|
||||
};
|
||||
|
||||
static const enum_val_t can_high_level_protocol_dissector_options[] = {
|
||||
{ "raw", "Raw data (no further dissection)", CAN_DATA_DISSECTOR },
|
||||
{ "CANopen", "CANopen protocol", CAN_CANOPEN_DISSECTOR },
|
||||
{ "DeviceNet", "DeviceNet protocol", CAN_DEVICENET_DISSECTOR },
|
||||
{ "J1939", "J1939 protocol", CAN_J1939_DISSECTOR },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static guint can_high_level_protocol_dissector = CAN_DATA_DISSECTOR;
|
||||
static dissector_table_t subdissector_table;
|
||||
|
||||
static const value_string frame_type_vals[] =
|
||||
{
|
||||
|
@ -105,6 +88,16 @@ static const value_string frame_type_vals[] =
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static void can_prompt(packet_info *pinfo _U_, gchar* result)
|
||||
{
|
||||
g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Next level protocol as");
|
||||
}
|
||||
|
||||
static gpointer can_value(packet_info *pinfo _U_)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_socketcan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
|
@ -157,24 +150,11 @@ dissect_socketcan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
|
||||
next_tvb = tvb_new_subset_length(tvb, CAN_DATA_OFFSET, frame_len);
|
||||
|
||||
switch (can_high_level_protocol_dissector)
|
||||
/* Functionality for choosing subdissector is controlled through Decode As as CAN doesn't
|
||||
have a unique identifier to determine subdissector */
|
||||
if (!dissector_try_uint_new(subdissector_table, 0, next_tvb, pinfo, tree, FALSE, &can_id))
|
||||
{
|
||||
case CAN_DATA_DISSECTOR:
|
||||
call_dissector(data_handle, next_tvb, pinfo, tree);
|
||||
break;
|
||||
case CAN_CANOPEN_DISSECTOR:
|
||||
call_dissector_with_data(canopen_handle, next_tvb, pinfo, tree, &can_id);
|
||||
break;
|
||||
case CAN_DEVICENET_DISSECTOR:
|
||||
/* XXX - Not sure this is correct. But the capture provided in
|
||||
* bug 8564 provides CAN ID in little endian format, so this makes it work */
|
||||
can_id.id = GUINT32_SWAP_LE_BE(can_id.id);
|
||||
|
||||
call_dissector_with_data(devicenet_handle, next_tvb, pinfo, tree, &can_id);
|
||||
break;
|
||||
case CAN_J1939_DISSECTOR:
|
||||
call_dissector_with_data(j1939_handle, next_tvb, pinfo, tree, &can_id);
|
||||
break;
|
||||
call_dissector(data_handle, next_tvb, pinfo, tree);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,8 +214,15 @@ proto_register_socketcan(void)
|
|||
{
|
||||
&ett_can
|
||||
};
|
||||
|
||||
module_t *can_module;
|
||||
|
||||
/* Decode As handling */
|
||||
static build_valid_func can_da_build_value[1] = {can_value};
|
||||
static decode_as_value_t can_da_values = {can_prompt, 1, can_da_build_value};
|
||||
static decode_as_t can_da = {"can", "Network", "can.subdissector", 1, 0, &can_da_values, NULL, NULL,
|
||||
decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
|
||||
|
||||
proto_can = proto_register_protocol(
|
||||
"Controller Area Network", /* name */
|
||||
"CAN", /* short name */
|
||||
|
@ -245,17 +232,14 @@ proto_register_socketcan(void)
|
|||
proto_register_field_array(proto_can, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
|
||||
subdissector_table = register_dissector_table("can.subdissector",
|
||||
"CAN next level dissector", FT_UINT32, BASE_HEX);
|
||||
|
||||
can_module = prefs_register_protocol(proto_can, NULL);
|
||||
|
||||
prefs_register_enum_preference(
|
||||
can_module,
|
||||
"protocol",
|
||||
"Next level protocol",
|
||||
"Next level protocol like CANopen etc.",
|
||||
(gint *)&can_high_level_protocol_dissector,
|
||||
can_high_level_protocol_dissector_options,
|
||||
FALSE
|
||||
);
|
||||
prefs_register_obsolete_preference(can_module, "protocol");
|
||||
|
||||
register_decode_as(&can_da);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -267,9 +251,6 @@ proto_reg_handoff_socketcan(void)
|
|||
dissector_add_uint("wtap_encap", WTAP_ENCAP_SOCKETCAN, can_handle);
|
||||
dissector_add_uint("sll.ltype", LINUX_SLL_P_CAN, can_handle);
|
||||
|
||||
canopen_handle = find_dissector("canopen");
|
||||
devicenet_handle = find_dissector("devicenet");
|
||||
j1939_handle = find_dissector("j1939");
|
||||
data_handle = find_dissector("data");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue