aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-kdsp.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2013-10-25 02:41:47 +0000
committerMichael Mann <mmann78@netscape.net>2013-10-25 02:41:47 +0000
commitcf1f098afb11c3e180dfe1d03b9b5d77d5aeea60 (patch)
treef13d656f995c35180432925bd347cf6295796826 /epan/dissectors/packet-kdsp.c
parentc09b328e137c2b320fd881e8e4afb9874f376be1 (diff)
Improvements for the KDSP dissector. Bug 8891 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8891)
From Yuri Schaeffer svn path=/trunk/; revision=52837
Diffstat (limited to 'epan/dissectors/packet-kdsp.c')
-rw-r--r--epan/dissectors/packet-kdsp.c227
1 files changed, 167 insertions, 60 deletions
diff --git a/epan/dissectors/packet-kdsp.c b/epan/dissectors/packet-kdsp.c
index ab5ff5afed..bca002ffa9 100644
--- a/epan/dissectors/packet-kdsp.c
+++ b/epan/dissectors/packet-kdsp.c
@@ -29,7 +29,8 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/prefs.h>
-#include <epan/dissectors/packet-tcp.h>
+#include <epan/expert.h>
+#include "packet-tcp.h"
#define KDSP_PORT 2502
#define FRAME_HEADER_LEN 12
@@ -63,11 +64,11 @@
#define GPS_SPD_FLAG 0x000000
#define GPS_HEADING_FLAG 0x000000
-#define DATA_UUID_FLAG 0x000000
-#define DATA_PACKLEN_FLAG 0x000000
-#define DATA_TVSEC_FLAG 0x000000
-#define DATA_TVUSEC_FLAG 0x000000
-#define DATA_DLT_FLAG 0x000000
+#define DATA_UUID_FLAG 0x000010
+#define DATA_PACKLEN_FLAG 0x000008
+#define DATA_TVSEC_FLAG 0x000004
+#define DATA_TVUSEC_FLAG 0x000002
+#define DATA_DLT_FLAG 0x000001
#define CH_UUID_FLAG 0x00000001
#define CH_CMD_FLAG 0x00000002
@@ -93,16 +94,16 @@
#define REPORT_HOP_TM_SEC_FLAG 0x000000
#define REPORT_HOP_TM_USEC_FLAG 0x000000
+#define DATALINK_WLAN 0x69
+#define DATALINK_RADIOTAP 0x7F
+
void proto_reg_handoff_kdsp(void);
static int proto_kdsp = -1;
+static dissector_table_t subdissector_dlt_table;
static guint global_kdsp_tcp_port = KDSP_PORT;
-
-static dissector_handle_t kdsp_handle;
-static dissector_handle_t ieee80211_handle;
-
static const value_string packettypenames[] = {
{0, "NULL"},
{1, "HELLO"},
@@ -114,6 +115,12 @@ static const value_string packettypenames[] = {
{0, NULL}
};
+static const value_string payloadtypenames[] = {
+ {DATALINK_WLAN, "802.11"},
+ {DATALINK_RADIOTAP, "RADIOTAP"},
+ {0, NULL}
+};
+
static const value_string channelcmds[] = {
{0, "NONE"},
{1, "SET HOP"},
@@ -172,6 +179,11 @@ static gint hf_kdsp_gps_heading = -1;
static gint hf_kdsp_cpt_data_hdr = -1;
static gint hf_kdsp_cpt_data_hdr_len = -1;
static gint hf_kdsp_cpt_data_content_bitmap = -1;
+static gint hf_kdsp_cpt_dc_flag_uuid = -1;
+static gint hf_kdsp_cpt_dc_flag_len = -1;
+static gint hf_kdsp_cpt_dc_flag_sec = -1;
+static gint hf_kdsp_cpt_dc_flag_usec = -1;
+static gint hf_kdsp_cpt_dc_flag_dlt = -1;
static gint hf_kdsp_cpt_uuid = -1;
static gint hf_kdsp_cpt_packet_len = -1;
static gint hf_kdsp_cpt_tv_sec = -1;
@@ -224,6 +236,7 @@ static gint hf_kdsp_report_hop_tm_usec = -1;
static gint ett_kdsp_pdu = -1;
static gint ett_cpt_bitmap = -1;
+static gint ett_cpt_data_content_bitmap = -1;
static gint ett_ch_bitmap = -1;
static gint ett_ch_data = -1;
static gint ett_sub_fcs = -1;
@@ -231,6 +244,11 @@ static gint ett_sub_radio = -1;
static gint ett_sub_gps = -1;
static gint ett_sub_cpt = -1;
+static expert_field ei_kdsp_payload_expected = EI_INIT;
+static expert_field ei_kdsp_payload_unexpected = EI_INIT;
+static expert_field ei_kdsp_cpt_data_hdr_len = EI_INIT;
+static expert_field ei_kdsp_cmdnum = EI_INIT;
+
/* determine PDU length of protocol */
static guint
get_kdsp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
@@ -243,20 +261,12 @@ static void
dissect_kdsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint32 offset = 0;
- guint32 command;
- guint32 length;
- guint32 numChan;
- guint32 bitmap;
- guint16 type;
- guint32 i;
- guint32 ieee80211_len;
- guint16 reported_ieee80211_len;
-
- tvbuff_t *ieee80211_tvb;
- proto_item *kdsp_item;
- proto_tree *kdsp_tree;
- proto_item *sub_item;
- proto_tree *sub_tree;
+ guint32 command, length, numChan, bitmap, cptbitmap;
+ guint32 i, datalink_type, payload_len;
+ guint16 type, reported_payload_len, data_hdr_len, data_hdr_len_check;
+ proto_item *kdsp_item, *sub_item, *subsub_item, *data_len_item, *command_item;
+ proto_tree *kdsp_tree, *sub_tree, *subsub_tree;
+ tvbuff_t *payload_tvb;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "KDSP");
col_clear(pinfo->cinfo, COL_INFO);
@@ -270,7 +280,7 @@ dissect_kdsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
kdsp_tree = proto_item_add_subtree(kdsp_item, ett_kdsp_pdu);
proto_tree_add_item(kdsp_tree, hf_kdsp_sentinel, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
- proto_tree_add_item(kdsp_tree, hf_kdsp_cmdnum, tvb, offset, 4, ENC_BIG_ENDIAN);
+ command_item = proto_tree_add_item(kdsp_tree, hf_kdsp_cmdnum, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_item_append_text(kdsp_item, ", Command %s",
val_to_str(command, packettypenames, "Unknown (0x%02x)"));
@@ -279,7 +289,9 @@ dissect_kdsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
length = tvb_get_ntohl(tvb, offset);
offset += 4;
- if (command == HELLO) {
+ switch(command)
+ {
+ case HELLO:
proto_tree_add_item(kdsp_tree, hf_kdsp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
offset +=4;
proto_tree_add_item(kdsp_tree, hf_kdsp_server_version,
@@ -287,15 +299,15 @@ dissect_kdsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset +=32;
proto_tree_add_item(kdsp_tree, hf_kdsp_hostname, tvb, offset, 32, ENC_ASCII|ENC_NA);
/*offset +=32;*/
- }
- else if (command == STRING) {
+ break;
+ case STRING:
proto_tree_add_item(kdsp_tree, hf_kdsp_str_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
offset +=4;
proto_tree_add_item(kdsp_tree, hf_kdsp_str_len, tvb, offset, 4, ENC_BIG_ENDIAN);
offset +=4;
proto_tree_add_item(kdsp_tree, hf_kdsp_str_msg, tvb, offset, -1, ENC_ASCII|ENC_NA);
- }
- else if (command == CAPPACKET) {
+ break;
+ case CAPPACKET:
sub_item = proto_tree_add_item(kdsp_tree, hf_kdsp_cpt_bitmap, tvb, offset, 4, ENC_BIG_ENDIAN);
sub_tree = proto_item_add_subtree(sub_item, ett_cpt_bitmap);
proto_tree_add_item(sub_tree, hf_kdsp_cpt_flag_cpt, tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -365,29 +377,71 @@ dissect_kdsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
sub_item = proto_tree_add_item(kdsp_tree, hf_kdsp_cpt_data_hdr, tvb, offset, 44, ENC_NA);
sub_tree = proto_item_add_subtree(sub_item, ett_sub_cpt);
- proto_tree_add_item(sub_tree, hf_kdsp_cpt_data_hdr_len, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- proto_tree_add_item(sub_tree, hf_kdsp_cpt_data_content_bitmap, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
- proto_tree_add_item(sub_tree, hf_kdsp_cpt_uuid, tvb, offset, 16, ENC_NA);
- offset += 16;
- proto_tree_add_item(sub_tree, hf_kdsp_cpt_packet_len, tvb, offset, 2, ENC_BIG_ENDIAN);
- reported_ieee80211_len = tvb_get_ntohs(tvb, offset);
+ data_len_item = proto_tree_add_item(sub_tree, hf_kdsp_cpt_data_hdr_len, tvb, offset, 2, ENC_BIG_ENDIAN);
+ data_hdr_len = tvb_get_ntohs(tvb, offset);
offset += 2;
- proto_tree_add_item(sub_tree, hf_kdsp_cpt_tv_sec, tvb, offset, 8, ENC_BIG_ENDIAN);
- offset += 8;
- proto_tree_add_item(sub_tree, hf_kdsp_cpt_tv_usec, tvb, offset, 8, ENC_BIG_ENDIAN);
- offset += 8;
- proto_tree_add_item(sub_tree, hf_kdsp_cpt_dlt, tvb, offset, 4, ENC_BIG_ENDIAN);
+
+ subsub_item = proto_tree_add_item(sub_tree, hf_kdsp_cpt_data_content_bitmap, tvb, offset, 4, ENC_BIG_ENDIAN);
+ subsub_tree = proto_item_add_subtree(subsub_item, ett_cpt_data_content_bitmap);
+ proto_tree_add_item(subsub_tree, hf_kdsp_cpt_dc_flag_uuid, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(subsub_tree, hf_kdsp_cpt_dc_flag_len, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(subsub_tree, hf_kdsp_cpt_dc_flag_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(subsub_tree, hf_kdsp_cpt_dc_flag_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(subsub_tree, hf_kdsp_cpt_dc_flag_dlt, tvb, offset, 4, ENC_BIG_ENDIAN);
+ cptbitmap = tvb_get_ntohl(tvb, offset);
offset += 4;
- ieee80211_len = (length + FRAME_HEADER_LEN) - offset;
- ieee80211_tvb = tvb_new_subset(tvb, offset, ieee80211_len, reported_ieee80211_len);
- call_dissector(ieee80211_handle, ieee80211_tvb, pinfo, tree);
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "KDSP");
+ data_hdr_len_check = 6; /* len(len) + len(bitmap) */
+ if (cptbitmap & DATA_UUID_FLAG) data_hdr_len_check += 16;
+ if (cptbitmap & DATA_PACKLEN_FLAG) data_hdr_len_check += 2;
+ if (cptbitmap & DATA_TVSEC_FLAG) data_hdr_len_check += 8;
+ if (cptbitmap & DATA_TVUSEC_FLAG) data_hdr_len_check += 8;
+ if (cptbitmap & DATA_DLT_FLAG) data_hdr_len_check += 4;
+
+ if (data_hdr_len_check != data_hdr_len) {
+ expert_add_info(pinfo, data_len_item, &ei_kdsp_cpt_data_hdr_len);
+ }
+
+ if (cptbitmap & DATA_UUID_FLAG) {
+ proto_tree_add_item(sub_tree, hf_kdsp_cpt_uuid, tvb, offset, 16, ENC_NA);
+ offset += 16;
+ }
+ if (cptbitmap & DATA_PACKLEN_FLAG) {
+ proto_tree_add_item(sub_tree, hf_kdsp_cpt_packet_len, tvb, offset, 2, ENC_BIG_ENDIAN);
+ reported_payload_len = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ }
+ if (cptbitmap & DATA_TVSEC_FLAG) {
+ proto_tree_add_item(sub_tree, hf_kdsp_cpt_tv_sec, tvb, offset, 8, ENC_BIG_ENDIAN);
+ offset += 8;
+ }
+ if (cptbitmap & DATA_TVUSEC_FLAG) {
+ proto_tree_add_item(sub_tree, hf_kdsp_cpt_tv_usec, tvb, offset, 8, ENC_BIG_ENDIAN);
+ offset += 8;
+ }
+ if (cptbitmap & DATA_DLT_FLAG) {
+ proto_tree_add_item(sub_tree, hf_kdsp_cpt_dlt, tvb, offset, 4, ENC_BIG_ENDIAN);
+ datalink_type = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+ }
+ payload_len = (length + FRAME_HEADER_LEN) - offset;
+ if (cptbitmap & DATA_PACKLEN_FLAG) {
+ payload_tvb = tvb_new_subset(tvb, offset, payload_len, reported_payload_len);
+ if (cptbitmap & DATA_DLT_FLAG) {
+ dissector_try_uint(subdissector_dlt_table, datalink_type, payload_tvb, pinfo, tree);
+
+ /* XXX - Restore protocol column */
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "KDSP");
+
+ } else if (payload_len > 0) {
+ proto_tree_add_expert(sub_tree, pinfo, &ei_kdsp_payload_expected, tvb, offset, payload_len);
+ }
+ } else if (payload_len > 0) {
+ proto_tree_add_expert(sub_tree, pinfo, &ei_kdsp_payload_unexpected, tvb, offset, payload_len);
+ }
}
- }
- else if (command == CHANNELSET) {
+ break;
+ case CHANNELSET:
proto_tree_add_item(kdsp_tree, hf_kdsp_ch_length, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
sub_item = proto_tree_add_item(kdsp_tree, hf_kdsp_ch_bitmap, tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -441,8 +495,8 @@ dissect_kdsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += 2;
proto_tree_add_item(kdsp_tree, hf_kdsp_ch_ch_dwell, tvb, offset, 2, ENC_BIG_ENDIAN);
/*offset += 2;*/
- }
- else if (command == SOURCE) {
+ break;
+ case SOURCE:
proto_tree_add_item(kdsp_tree, hf_kdsp_source_length, tvb, offset, 2, ENC_BIG_ENDIAN);
offset +=2;
sub_item = proto_tree_add_item(kdsp_tree, hf_kdsp_ch_bitmap, tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -466,8 +520,8 @@ dissect_kdsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += 2;
proto_tree_add_item(kdsp_tree, hf_kdsp_source_rate, tvb, offset, 2, ENC_BIG_ENDIAN);
/*offset += 2;*/
- }
- else if (command == REPORT) {
+ break;
+ case REPORT:
proto_tree_add_item(kdsp_tree, hf_kdsp_report_hdr_len, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(kdsp_tree, hf_kdsp_report_content_bitmap, tvb, offset, 4, ENC_BIG_ENDIAN);
@@ -480,9 +534,10 @@ dissect_kdsp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset += 4;
proto_tree_add_item(kdsp_tree, hf_kdsp_report_hop_tm_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
/*offset += 4;*/
-
+ break;
+ default:
+ expert_add_info(pinfo, command_item, &ei_kdsp_cmdnum);
}
-
}
static void
@@ -744,6 +799,36 @@ proto_register_kdsp(void)
NULL, 0x0,
NULL, HFILL }
},
+ { &hf_kdsp_cpt_dc_flag_uuid,
+ { "Capture Content UUID Flag", "kdsp.cpt.cd.flag.uuid",
+ FT_BOOLEAN, 32,
+ NULL, DATA_UUID_FLAG,
+ NULL, HFILL }
+ },
+ { &hf_kdsp_cpt_dc_flag_len,
+ { "Capture Content Length Flag", "kdsp.cpt.cd.flag.len",
+ FT_BOOLEAN, 32,
+ NULL, DATA_PACKLEN_FLAG,
+ NULL, HFILL }
+ },
+ { &hf_kdsp_cpt_dc_flag_sec,
+ { "Capture Content Second Flag", "kdsp.cpt.cd.flag.sec",
+ FT_BOOLEAN, 32,
+ NULL, DATA_TVSEC_FLAG,
+ NULL, HFILL }
+ },
+ { &hf_kdsp_cpt_dc_flag_usec,
+ { "Capture Content Microsecond Flag", "kdsp.cpt.cd.flag.usec",
+ FT_BOOLEAN, 32,
+ NULL, DATA_TVUSEC_FLAG,
+ NULL, HFILL }
+ },
+ { &hf_kdsp_cpt_dc_flag_dlt,
+ { "Capture Content Datalink Type Flag", "kdsp.cpt.cd.flag.dlt",
+ FT_BOOLEAN, 32,
+ NULL, DATA_DLT_FLAG,
+ NULL, HFILL }
+ },
{ &hf_kdsp_cpt_uuid,
{ "UUID", "kdsp.cpt.uuid",
FT_BYTES, BASE_NONE,
@@ -769,9 +854,9 @@ proto_register_kdsp(void)
NULL, HFILL }
},
{ &hf_kdsp_cpt_dlt,
- { "dlt", "kdsp.cpt.dlt",
+ { "Data Link Type", "kdsp.cpt.dlt",
FT_UINT32, BASE_DEC,
- NULL, 0x0,
+ VALS(payloadtypenames), 0x0,
NULL, HFILL }
},
{ &hf_kdsp_ch_length,
@@ -1027,6 +1112,7 @@ proto_register_kdsp(void)
static gint *ett[] = {
&ett_kdsp_pdu,
&ett_cpt_bitmap,
+ &ett_cpt_data_content_bitmap,
&ett_ch_bitmap,
&ett_ch_data,
&ett_sub_fcs,
@@ -1035,6 +1121,15 @@ proto_register_kdsp(void)
&ett_sub_cpt
};
+ static ei_register_info ei[] = {
+ { &ei_kdsp_payload_expected, { "kdsp.payload_expected", PI_MALFORMED, PI_ERROR, "Payload expected but no link type specified. Can not decode.", EXPFILL }},
+ { &ei_kdsp_payload_unexpected, { "kdsp.payload_unexpected", PI_MALFORMED, PI_ERROR, "No payload expected but found some data", EXPFILL }},
+ { &ei_kdsp_cpt_data_hdr_len, { "kdsp.cpt.length.invalid", PI_MALFORMED, PI_ERROR, "Calculated header length does not match reported header length. "
+ "It is likely the dissector does not support all flags", EXPFILL }},
+ { &ei_kdsp_cmdnum, { "kdsp.command.unknown", PI_UNDECODED, PI_WARN, "Unknown command, can not parse message", EXPFILL }},
+ };
+ expert_module_t* expert_kdsp;
+
proto_kdsp = proto_register_protocol(
"Kismet Drone/Server Protocol",
"KDSP",
@@ -1044,9 +1139,11 @@ proto_register_kdsp(void)
proto_register_field_array(proto_kdsp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
-
-
kdsp_module = prefs_register_protocol(proto_kdsp, proto_reg_handoff_kdsp);
+ expert_kdsp = expert_register_protocol(proto_kdsp);
+ expert_register_field_array(expert_kdsp, ei, array_length(ei));
+
+ subdissector_dlt_table = register_dissector_table("kdsp.cpt.dlt", "KDSP DLT Type", FT_UINT32, BASE_DEC);
prefs_register_uint_preference(kdsp_module, "tcp.port",
"Kismet Drone TCP Port",
@@ -1062,10 +1159,20 @@ proto_reg_handoff_kdsp(void)
{
static gboolean initialized = FALSE;
static guint tcp_port;
+ static dissector_handle_t kdsp_handle;
+ dissector_handle_t dlt_handle;
+
if (!initialized) {
kdsp_handle = create_dissector_handle(dissect_kdsp, proto_kdsp);
- ieee80211_handle = find_dissector("wlan");
+ dlt_handle = find_dissector("radiotap");
+ if (dlt_handle)
+ dissector_add_uint( "kdsp.cpt.dlt", DATALINK_RADIOTAP, dlt_handle);
+
+ dlt_handle = find_dissector("wlan");
+ if (dlt_handle)
+ dissector_add_uint( "kdsp.cpt.dlt", DATALINK_WLAN, dlt_handle);
+
} else {
dissector_delete_uint("tcp.port", tcp_port, kdsp_handle);
}