PCLI: Expand protocol support

1. Implement "Decode As" for PCLI payload instead of assuming IP.
   Currently supported subdissectors are Ethernet and IP.

2. Implement multiple "flavors" of PCLI with different header formats:
        pcli: 4 byte CCCID
        pcli8: 8 byte header (including CCCID)
        pcli12: 4 byte CCCID, 8 byte NTP timestamp
        pcli20: 4 byte CCCID, 8 byte NTP timestamp, 8 byte case ID
   All flavors currently using "Decode As" for payload.

3. Optionally append CCCID to protocol item in tree
   using preference "pcli.summary_in_tree".

4. Obsolete preference "pcli.udp_port".

Bug: 9266
Bug: 11220

Change-Id: Ie4bca06665985ef1eb77db767771a5a82357e242
Reviewed-on: https://code.wireshark.org/review/8608
Reviewed-by: Evan Huus <eapache@gmail.com>
Petri-Dish: Evan Huus <eapache@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Luke Mewburn 2015-07-19 17:31:46 +10:00 committed by Michael Mann
parent 6e7f302ade
commit 83dc308f36
3 changed files with 160 additions and 43 deletions

View File

@ -1050,6 +1050,8 @@ proto_reg_handoff_eth(void)
* the UDP port is user-defined.
*/
dissector_add_for_decode_as("udp.port", eth_withoutfcs_handle);
dissector_add_for_decode_as("pcli.payload", eth_withoutfcs_handle);
}
/*

View File

@ -3147,6 +3147,7 @@ proto_reg_handoff_ip(void)
dissector_add_uint("sflow_245.header_protocol", SFLOW_245_HEADER_IPv4, ip_handle);
dissector_add_uint("l2tp.pw_type", L2TPv3_PROTOCOL_IP, ip_handle);
dissector_add_for_decode_as("udp.port", ip_handle);
dissector_add_for_decode_as("pcli.payload", ip_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_RAW_IP4, ip_handle);
heur_dissector_add("tipc", dissect_ip_heur, "IP over TIPC", "ip_tipc", proto_ip, HEURISTIC_ENABLE);

View File

@ -65,23 +65,26 @@
#include "config.h"
#include <epan/decode_as.h>
#include <epan/packet.h>
#include <epan/prefs.h>
void proto_register_pcli(void);
void proto_reg_handoff_pcli(void);
/* Define udp_port for lawful intercept */
#define UDP_PORT_PCLI 0
/* Define the pcli proto */
static int proto_pcli = -1;
static int proto_pcli8 = -1;
static int proto_pcli12 = -1;
static int proto_pcli20 = -1;
/* Define headers for pcli */
static int hf_pcli_cccid = -1;
static int hf_pcli_header = -1;
static int hf_pcli_timestamp = -1;
static int hf_pcli_case_id = -1;
/* Define the tree for pcli */
@ -92,51 +95,139 @@ static int ett_pcli = -1;
* for pcli
*/
static guint global_udp_port_pcli = UDP_PORT_PCLI;
static gboolean pcli_summary_in_tree = TRUE;
/* A static handle for the ip dissector */
static dissector_handle_t ip_handle;
static dissector_handle_t data_handle;
static void
dissect_pcli(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
static dissector_table_t pcli_subdissector_table;
static proto_tree *
dissect_pcli_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int* offset)
{
guint32 cccid;
proto_tree *ti,*pcli_tree;
tvbuff_t * next_tvb;
proto_tree *pcli_tree;
proto_item *pcli_item;
/* Set the protocol column */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCLI");
/* Get the CCCID */
cccid = tvb_get_ntohl(tvb,0);
/* Set the info column */
col_add_fstr(pinfo->cinfo, COL_INFO, "CCCID: %u",cccid);
/*
*If we have a non-null tree (ie we are building the proto_tree
* instead of just filling out the columns ), then add a PLCI
* tree node and put a CCCID header element under it.
*/
if(tree) {
ti = proto_tree_add_item(tree, proto_pcli, tvb, 0, 0, ENC_NA);
pcli_tree = proto_item_add_subtree(ti,ett_pcli);
proto_tree_add_uint(pcli_tree, hf_pcli_cccid, tvb, 0, 4, cccid);
pcli_item = proto_tree_add_item(tree, proto_pcli, tvb, *offset, 4, ENC_NA);
pcli_tree = proto_item_add_subtree(pcli_item, ett_pcli);
proto_tree_add_item_ret_uint(pcli_tree, hf_pcli_cccid, tvb, *offset, 4, ENC_BIG_ENDIAN, &cccid);
(*offset) += 4;
if (pcli_summary_in_tree) {
proto_item_append_text(pcli_item, ", CCCID: %u", cccid);
}
/* Set the info column */
col_add_fstr(pinfo->cinfo, COL_INFO, "CCCID: %u", cccid);
return pcli_tree;
}
static void
dissect_pcli_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
{
tvbuff_t * next_tvb;
next_tvb = tvb_new_subset_remaining(tvb, offset);
/*
* Hand off to the IP dissector.
* Implement "Decode As", as PCLI doesn't
* have a unique identifier to determine subdissector
*/
next_tvb = tvb_new_subset_remaining(tvb,4);
call_dissector(ip_handle,next_tvb,pinfo,tree);
if (!dissector_try_uint(pcli_subdissector_table, 0, next_tvb, pinfo, tree)) {
call_dissector(data_handle, next_tvb, pinfo, tree);
}
}
static void
dissect_pcli(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int offset = 0;
dissect_pcli_common(tvb, pinfo, tree, &offset);
dissect_pcli_payload(tvb, pinfo, tree, offset);
}
static void
dissect_pcli8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *pcli_tree;
int offset = 0;
pcli_tree = dissect_pcli_common(tvb, pinfo, tree, &offset);
proto_tree_add_item(pcli_tree, hf_pcli_header, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
dissect_pcli_payload(tvb, pinfo, tree, offset);
}
static void
dissect_pcli12(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *pcli_tree;
int offset = 0;
pcli_tree = dissect_pcli_common(tvb, pinfo, tree, &offset);
proto_tree_add_item(pcli_tree, hf_pcli_timestamp, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
offset += 8;
dissect_pcli_payload(tvb, pinfo, tree, offset);
}
static void
dissect_pcli20(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *pcli_tree;
int offset = 0;
pcli_tree = dissect_pcli_common(tvb, pinfo, tree, &offset);
proto_tree_add_item(pcli_tree, hf_pcli_timestamp, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
offset += 8;
proto_tree_add_item(pcli_tree, hf_pcli_case_id, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
dissect_pcli_payload(tvb, pinfo, tree, offset);
}
static void
pcli_prompt(packet_info *pinfo _U_, gchar* result)
{
g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "PCLI payload as");
}
static gpointer
pcli_value(packet_info *pinfo _U_)
{
return NULL;
}
void
proto_register_pcli(void) {
proto_register_pcli(void)
{
static hf_register_info hf[] = {
{ &hf_pcli_cccid,
{ "CCCID", "pcli.cccid", FT_UINT32, BASE_DEC, NULL, 0x0,
"Call Content Connection Identifier", HFILL }},
{ &hf_pcli_header,
{ "CCCID", "pcli.header", FT_UINT32, BASE_HEX, NULL, 0x0,
"Part of 8 byte header (including CCCID?)", HFILL }},
{ &hf_pcli_timestamp,
{ "Timestamp", "pcli.timestamp", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
NULL, HFILL }},
{ &hf_pcli_case_id,
{ "Case ID", "pcli.case_id", FT_UINT64, BASE_HEX, NULL, 0x0,
NULL, HFILL }},
};
static gint *ett[] = {
@ -145,40 +236,63 @@ proto_register_pcli(void) {
module_t *pcli_module;
proto_pcli = proto_register_protocol("Packet Cable Lawful Intercept",
"PCLI","pcli");
/* Decode As handling */
static build_valid_func pcli_payload_da_build_value[1] = {pcli_value};
static decode_as_value_t pcli_payload_da_values = {pcli_prompt, 1, pcli_payload_da_build_value};
static decode_as_t pcli_payload_da = {
"pcli", "PCLI payload", "pcli.payload", 1, 0,
&pcli_payload_da_values, NULL, NULL,
decode_as_default_populate_list,
decode_as_default_reset,
decode_as_default_change,
NULL,
};
proto_pcli = proto_register_protocol("Packet Cable Lawful Intercept", "PCLI", "pcli");
/* Create "placeholders" to remove confusion with Decode As" */
proto_pcli8 = proto_register_protocol("Packet Cable Lawful Intercept (8 byte CCCID)", "PCLI8 (8 byte CCCID)", "pcli8");
proto_pcli12 = proto_register_protocol("Packet Cable Lawful Intercept (timestamp)", "PCLI12 (timestamp)", "pcli12");
proto_pcli20 = proto_register_protocol("Packet Cable Lawful Intercept (timestamp, case ID)", "PCLI20 (timestamp, case ID)", "pcli20");
proto_register_field_array(proto_pcli,hf,array_length(hf));
proto_register_subtree_array(ett,array_length(ett));
pcli_module = prefs_register_protocol(proto_pcli, proto_reg_handoff_pcli);
prefs_register_uint_preference(pcli_module, "udp_port",
"PCLI UDP Port",
"The UDP port on which "
"Packet Cable Lawful Intercept "
"packets will be sent",
10,&global_udp_port_pcli);
prefs_register_obsolete_preference(pcli_module, "udp_port");
prefs_register_bool_preference(pcli_module, "summary_in_tree",
"Show PCLI summary in protocol tree",
"Whether the PCLI summary line should be shown in the protocol tree",
&pcli_summary_in_tree);
pcli_subdissector_table = register_dissector_table(
"pcli.payload", "PCLI payload dissector",
FT_UINT32, BASE_DEC);
register_decode_as(&pcli_payload_da);
}
/* The registration hand-off routing */
void
proto_reg_handoff_pcli(void) {
proto_reg_handoff_pcli(void)
{
static gboolean pcli_initialized = FALSE;
static dissector_handle_t pcli_handle;
static guint udp_port_pcli;
static dissector_handle_t pcli_handle, pcli_handle8, pcli_handle12, pcli_handle20;
if(!pcli_initialized) {
pcli_handle = create_dissector_handle(dissect_pcli,proto_pcli);
ip_handle = find_dissector("ip");
pcli_handle = create_dissector_handle(dissect_pcli, proto_pcli);
pcli_handle8 = create_dissector_handle(dissect_pcli8, proto_pcli8);
pcli_handle12 = create_dissector_handle(dissect_pcli12, proto_pcli12);
pcli_handle20 = create_dissector_handle(dissect_pcli20, proto_pcli20);
data_handle = find_dissector("data");
pcli_initialized = TRUE;
} else {
dissector_delete_uint("udp.port",udp_port_pcli,pcli_handle);
}
udp_port_pcli = global_udp_port_pcli;
dissector_add_uint("udp.port",global_udp_port_pcli,pcli_handle);
dissector_add_for_decode_as("udp.port", pcli_handle);
dissector_add_for_decode_as("udp.port", pcli_handle8);
dissector_add_for_decode_as("udp.port", pcli_handle12);
dissector_add_for_decode_as("udp.port", pcli_handle20);
}
/*