IEEE 1909.3: Add version 3 dissection.
Bug: 13766 Change-Id: Ia4d7856d6692961cf0dab773c2a33b4f319add50 Reviewed-on: https://code.wireshark.org/review/29998 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
84447550ef
commit
e4bae7be9b
|
@ -9,12 +9,14 @@
|
|||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Ref IEEE 1609.3
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/etypes.h>
|
||||
#include <epan/expert.h>
|
||||
|
||||
/* elemenID Types */
|
||||
#define TRANSMITPW 0x04
|
||||
|
@ -46,31 +48,233 @@ static int hf_wsmp_WAVEid = -1;
|
|||
static int hf_wsmp_wsmlength = -1;
|
||||
static int hf_wsmp_WSMP_S_data = -1;
|
||||
|
||||
/* Savari function to get the length of a psid based on the number of
|
||||
successive 1s in the most sig bits of the most sig octet. Taken
|
||||
from libwme
|
||||
*/
|
||||
static int wme_getpsidlen (guint8 *psid)
|
||||
{
|
||||
int length = 0;
|
||||
if ((psid[0] & 0xF0) == 0xF0) {
|
||||
length = 255;
|
||||
} else if ( (psid[0] & 0xF0) == 0xE0) {
|
||||
length = 4;
|
||||
} else if ( (psid[0] & 0xE0) == 0xC0) {
|
||||
length = 3;
|
||||
} else if ( (psid[0] & 0xC0) == 0x80) {
|
||||
length = 2;
|
||||
} else if ((psid[0] & 0x80) == 0x00) {
|
||||
length = 1;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
static int hf_wsmp_subtype = -1;
|
||||
static int hf_wsmp_N_header_opt_ind = -1;
|
||||
static int hf_wsmp_version_v3 = -1;
|
||||
static int hf_wsmp_no_elements = -1;
|
||||
static int hf_wsmp_wave_ie = -1;
|
||||
static int hf_wsmp_wave_ie_len = -1;
|
||||
static int hf_wsmp_wave_ie_data = -1;
|
||||
static int hf_wsmp_tpid = -1;
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static gint ett_wsmp = -1;
|
||||
static gint ett_wsmdata = -1;
|
||||
static int ett_wsmp = -1;
|
||||
static int ett_wsmdata = -1;
|
||||
static int ett_wsmp_n_hdr = -1;
|
||||
static int ett_wsmp_t_hdr = -1;
|
||||
static int ett_wsmp_ie_ext = -1;
|
||||
static int ett_wsmp_ie = -1;
|
||||
|
||||
static expert_field ei_wsmp_length_field_err = EI_INIT;
|
||||
|
||||
static const value_string wsmp_subtype_vals[] = {
|
||||
{ 0x0, "Null-networking protocol" },
|
||||
{ 0x1, "ITS station-internal forwarding" },
|
||||
{ 0x2, "N-hop forwarding" },
|
||||
{ 0x3, "Enables the features of GeoNetworking" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const value_string wsmp_wave_information_elements_vals[] = {
|
||||
{ 0, "Reserved" },
|
||||
{ 1, "Reserved" },
|
||||
{ 2, "Reserved" },
|
||||
{ 3, "Reserved" },
|
||||
{ 4, "Transmit Power Used" }, /* WSMP - N - Header 8.3.4.4 */
|
||||
{ 5, "2D Location" }, /* WSA header 8.2.2.6 */
|
||||
{ 6, "3D Location" }, /* WSA header 8.2.2.6 */
|
||||
{ 7, "Advertiser Identifier" }, /* WSA header 8.2.2.6 */
|
||||
{ 8, "Provider Service Context" }, /* WSA Service Info 8.2.3.5 */
|
||||
{ 9, "IPv6 Address" }, /* WSA Service Info 8.2.3.5 */
|
||||
{ 10, "Service Por" }, /* WSA Service Info 8.2.3.5 */
|
||||
{ 11, "Provider MAC Address" }, /* WSA Service Info 8.2.3.5 */
|
||||
{ 12, "EDCA Parameter Set" }, /* WSA Channel Info 8.2.4.8 */
|
||||
{ 13, "Secondary DNS" }, /* WSA WRA 8.2.5.7 */
|
||||
{ 14, "Gateway MAC Address" }, /* WSA WRA 8.2.5.7 */
|
||||
{ 15, "Channel Number" }, /* WSMP - N - Header 8.3.4.2 */
|
||||
{ 16, "Data Rate" }, /* WSMP - N - Header 8.3.4.3 */
|
||||
{ 17, "Repeat Rate" }, /* WSA header 8.2.2.6 */
|
||||
{ 18, "Reserved" },
|
||||
{ 19, "RCPI Threshold" }, /* WSA Service Info 8.2.3.5 */
|
||||
{ 20, "WSA Count Threshold" }, /* WSA Service Info 8.2.3.5 */
|
||||
{ 21, "Channel Access" }, /* WSA Channel Info 8.2.4.8 */
|
||||
{ 22, "WSA Count Threshold Interval" }, /* WSA Service Info 8.2.3.5 */
|
||||
{ 23, "Channel Load" }, /* WSMP-N-Header 8.3.4.5 */
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const value_string wsmp_tpid_vals[] = {
|
||||
{ 0, "The Address Info field contains a PSID and a WAVE Information Element Extension field is not present" },
|
||||
{ 1, "The Address Info field contains a PSID and a WAVE Information Element Extension field is present" },
|
||||
{ 2, "The Address Info field contains source and destination ITS port numbers and a WAVE Information Element Extension field is not present" },
|
||||
{ 3, "The Address Info field contains source and destination ITS port numbers and a WAVE Information Element Extension field is present" },
|
||||
{ 4, "LPP mode and a WAVE Information Element Extension field is not present" },
|
||||
{ 5, "LPP mode and a WAVE Information Element Extension field is present" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
dissect_wsmp_psid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint32 *psid)
|
||||
{
|
||||
guint8 oct;
|
||||
guint32 psidLen = 0;
|
||||
|
||||
oct = tvb_get_guint8(tvb, offset);
|
||||
|
||||
if ((oct & 0xF0) == 0xF0) {
|
||||
psidLen = 255;
|
||||
} else if ((oct & 0xF0) == 0xE0) {
|
||||
psidLen = 4;
|
||||
} else if ((oct & 0xE0) == 0xC0) {
|
||||
psidLen = 3;
|
||||
} else if ((oct & 0xC0) == 0x80) {
|
||||
psidLen = 2;
|
||||
} else if ((oct & 0x80) == 0x00) {
|
||||
psidLen = 1;
|
||||
}
|
||||
|
||||
if (psidLen == 1)
|
||||
*psid = oct;
|
||||
else if (psidLen == 2)
|
||||
*psid = tvb_get_ntohs(tvb, offset);
|
||||
else if (psidLen == 3)
|
||||
*psid = tvb_get_ntoh24(tvb, offset);
|
||||
else if (psidLen == 4)
|
||||
*psid = tvb_get_ntohl(tvb, offset);
|
||||
|
||||
proto_tree_add_item(tree, hf_wsmp_psid, tvb, offset, psidLen, ENC_BIG_ENDIAN);
|
||||
offset += psidLen;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* 8.1.3 Length and Count field encoding*/
|
||||
static int
|
||||
dissect_wsmp_length_and_count(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_id, guint16* value)
|
||||
{
|
||||
guint8 oct, len;
|
||||
guint16 val;
|
||||
/* For values in the range of 0 through 127, Length and Count values
|
||||
* are represented in a single-octet encoded as an unsigned integer. For values in the range 128 through 16
|
||||
* 383, values are represented as two octets encoded as follows. If the most significant bit of the field is 0b0,
|
||||
* then this indicates a one-octet Length or Count field. If the two most significant bits of the field are 0b10,
|
||||
* the Length or Count field is a two-octet field, with the remaining 14 bits representing the value encoded as
|
||||
* an unsigned integer.*/
|
||||
|
||||
oct = tvb_get_guint8(tvb, offset);
|
||||
if ((oct & 0x80) == 0x80) {
|
||||
if ((oct & 0xc0) == 0x80) {
|
||||
/* Two bytes */
|
||||
val = tvb_get_ntohs(tvb, offset) & 0x3fff;
|
||||
len = 2;
|
||||
} else {
|
||||
/* Error */
|
||||
proto_tree_add_expert(tree, pinfo, &ei_wsmp_length_field_err, tvb, offset, 1);
|
||||
val = tvb_get_ntohs(tvb, offset) & 0x3fff;
|
||||
len = 2;
|
||||
}
|
||||
}else{
|
||||
/* One byte */
|
||||
val = oct;
|
||||
len = 1;
|
||||
}
|
||||
|
||||
proto_tree_add_uint(tree, hf_id, tvb, offset, len, val);
|
||||
offset += len;
|
||||
|
||||
if (value){
|
||||
*value = val;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_wsmp_v3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 oct)
|
||||
{
|
||||
proto_tree *sub_tree, *n_tree, *t_tree;
|
||||
proto_item *item;
|
||||
int offset = 0, ie_start, len_to_set;
|
||||
guint8 header_opt_ind = oct & 0x08 >> 3;
|
||||
guint8 ie;
|
||||
guint16 count, ie_len, wsm_len;
|
||||
guint32 tpid, psid;
|
||||
|
||||
static const int * flags[] = {
|
||||
&hf_wsmp_subtype,
|
||||
&hf_wsmp_N_header_opt_ind,
|
||||
&hf_wsmp_version_v3,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* 8.3.2 WSMP Network Header (WSMP-N-Header) */
|
||||
|
||||
n_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_wsmp_n_hdr, &item, "WSMP-N-Header");
|
||||
/* In Version 3
|
||||
* B7 B4 B3 B2 B0 | Variable | 1 octet
|
||||
* Subtype |WSMP-NHeader | WSMP Version | WAVE Information Element Extension | TPID
|
||||
* | Option Indicator | | |
|
||||
*/
|
||||
|
||||
proto_tree_add_bitmask_list(n_tree, tvb, offset, 1, flags, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
|
||||
/* WAVE Information Element Extension */
|
||||
if (header_opt_ind) {
|
||||
sub_tree = proto_tree_add_subtree(n_tree, tvb, offset, -1, ett_wsmp_ie_ext, &item, "WAVE Information Element Extension");
|
||||
/* Figure 14 WAVE Information Element Extension */
|
||||
/* 8.1.3 Length and Count field encoding*/
|
||||
/* Count( Number of WAVE Information Elements )*/
|
||||
offset = dissect_wsmp_length_and_count(tvb, pinfo, sub_tree, offset, hf_wsmp_no_elements, &count);
|
||||
|
||||
while (count) {
|
||||
proto_tree* ie_tree;
|
||||
ie_start = offset;
|
||||
/* WAVE Element ID 1 octet*/
|
||||
ie = tvb_get_guint8(tvb, offset);
|
||||
ie_tree = proto_tree_add_subtree_format(sub_tree, tvb, offset, -1, ett_wsmp_ie, &item, "%s",
|
||||
val_to_str_const(ie, wsmp_wave_information_elements_vals, "Unknown"));
|
||||
|
||||
proto_tree_add_item(ie_tree, hf_wsmp_wave_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
|
||||
/* Length */
|
||||
offset = dissect_wsmp_length_and_count(tvb, pinfo, ie_tree, offset, hf_wsmp_wave_ie_len, &ie_len);
|
||||
|
||||
proto_tree_add_item(ie_tree, hf_wsmp_wave_ie_data, tvb, offset, ie_len, ENC_NA);
|
||||
offset += ie_len;
|
||||
|
||||
len_to_set = offset - ie_start;
|
||||
proto_item_set_len(item, len_to_set);
|
||||
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
/* TPID */
|
||||
proto_tree_add_item_ret_uint(n_tree, hf_wsmp_tpid, tvb, offset, 1, ENC_BIG_ENDIAN, &tpid);
|
||||
offset++;
|
||||
|
||||
/* WSMP-T-Header */
|
||||
t_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_wsmp_t_hdr, &item, "WSMP-T-Header");
|
||||
switch (tpid) {
|
||||
case 0:
|
||||
/* The Address Info field contains a PSID and a WAVE Information Element Extension field is not present.*/
|
||||
offset = dissect_wsmp_psid(tvb, pinfo, t_tree, offset, &psid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* WSM Length */
|
||||
offset = dissect_wsmp_length_and_count(tvb, pinfo, t_tree, offset, hf_wsmp_wave_ie_len, &wsm_len);
|
||||
|
||||
/* WSM Data */
|
||||
proto_tree_add_subtree(tree, tvb, offset, wsm_len, ett_wsmdata, NULL, "Wave Short Message");
|
||||
|
||||
return tvb_captured_length(tvb);
|
||||
}
|
||||
static int
|
||||
dissect_wsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
||||
{
|
||||
|
@ -78,9 +282,9 @@ dissect_wsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
|
|||
proto_item *ti;
|
||||
proto_tree *wsmp_tree, *wsmdata_tree;
|
||||
tvbuff_t *wsmdata_tvb;
|
||||
guint16 wsmlength, offset;
|
||||
guint32 psidLen, psid, supLen;
|
||||
guint8 elemenId, elemenLen, msb;
|
||||
guint16 wsmlength, offset = 0;
|
||||
guint32 psid, supLen;
|
||||
guint8 elemenId, elemenLen, msb, oct, version;
|
||||
|
||||
/* Make entries in Protocol column and Info column on summary display */
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSMP");
|
||||
|
@ -89,29 +293,24 @@ dissect_wsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
|
|||
|
||||
/* create display subtree for the protocol */
|
||||
ti = proto_tree_add_item(tree, proto_wsmp, tvb, 0, -1, ENC_NA);
|
||||
|
||||
wsmp_tree = proto_item_add_subtree(ti, ett_wsmp);
|
||||
|
||||
offset = 0;
|
||||
proto_tree_add_item(wsmp_tree,
|
||||
hf_wsmp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
/* In Version 3
|
||||
* B7 B4 B3 B2 B0
|
||||
* Subtype |WSMP-NHeader | WSMP Version
|
||||
* | Option Indicator
|
||||
*/
|
||||
oct = tvb_get_guint8(tvb, offset);
|
||||
version = oct & 0x07;
|
||||
if (version == 3) {
|
||||
/* Version 3 */
|
||||
return dissect_wsmp_v3(tvb, pinfo, wsmp_tree, oct);
|
||||
}
|
||||
|
||||
proto_tree_add_item(wsmp_tree, hf_wsmp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset++;
|
||||
|
||||
psid = tvb_get_guint8(tvb, offset);
|
||||
psidLen = (guint32)wme_getpsidlen((guint8*)&psid);
|
||||
|
||||
|
||||
if (psidLen == 2)
|
||||
psid = tvb_get_ntohs(tvb, offset);
|
||||
else if (psidLen == 3)
|
||||
psid = tvb_get_ntoh24(tvb, offset);
|
||||
else if (psidLen == 4)
|
||||
psid = tvb_get_ntohl(tvb, offset);
|
||||
|
||||
proto_tree_add_item(wsmp_tree,
|
||||
hf_wsmp_psid, tvb, offset, psidLen, ENC_BIG_ENDIAN);
|
||||
offset += psidLen;
|
||||
|
||||
offset = dissect_wsmp_psid(tvb, pinfo, wsmp_tree, offset, &psid);
|
||||
|
||||
/* TLV decoder that does not display the T and L elements */
|
||||
elemenId = tvb_get_guint8(tvb, offset);
|
||||
|
@ -220,14 +419,57 @@ proto_register_wsmp(void)
|
|||
{ &hf_wsmp_WSMP_S_data,
|
||||
{ "WAVE Supplement Data", "wsmp.supplement", FT_UINT8, BASE_HEX, NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_wsmp_subtype,
|
||||
{ "Subtype", "wsmp.subtype", FT_UINT8, BASE_DEC, VALS(wsmp_subtype_vals), 0xF0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_wsmp_N_header_opt_ind,
|
||||
{ "WSMP-NHeader Option Indicator(WAVE Information Element Extension)", "wsmp.N_header_opt_ind", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x08,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_wsmp_version_v3,
|
||||
{ "Version", "wsmp.version_v3", FT_UINT8, BASE_DEC, NULL, 0x07,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_wsmp_no_elements,
|
||||
{ "Count", "wsmp.no_elements", FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_wsmp_wave_ie,
|
||||
{ "WAVE IE", "wsmp.wave_ie", FT_UINT8, BASE_DEC, VALS(wsmp_wave_information_elements_vals), 0x0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_wsmp_wave_ie_len,
|
||||
{ "Length", "wsmp.wave_ie_len", FT_UINT16, BASE_DEC, NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_wsmp_wave_ie_data,
|
||||
{ "Data", "wsmp.wave_ie_data", FT_BYTES, BASE_NONE, NULL, 0x0,
|
||||
NULL, HFILL }},
|
||||
|
||||
{ &hf_wsmp_tpid,
|
||||
{ "TPID", "wsmp.wave_ie", FT_UINT8, BASE_DEC, VALS(wsmp_tpid_vals), 0x0,
|
||||
NULL, HFILL }},
|
||||
};
|
||||
|
||||
/* Setup protocol subtree array */
|
||||
static gint *ett[] = {
|
||||
&ett_wsmp,
|
||||
&ett_wsmdata,
|
||||
&ett_wsmp_n_hdr,
|
||||
&ett_wsmp_t_hdr,
|
||||
&ett_wsmp_ie_ext,
|
||||
&ett_wsmp_ie,
|
||||
};
|
||||
|
||||
static ei_register_info ei[] = {
|
||||
{ &ei_wsmp_length_field_err, { "wsmp.length_field_err", PI_PROTOCOL, PI_ERROR,
|
||||
"Length field wrongly encoded, b6 not 0. The rest of the dissection is suspect", EXPFILL }},
|
||||
};
|
||||
|
||||
expert_module_t* expert_wsmp;
|
||||
|
||||
/* Register the protocol name and description */
|
||||
proto_wsmp = proto_register_protocol("Wave Short Message Protocol(IEEE P1609.3)",
|
||||
"WSMP", "wsmp");
|
||||
|
@ -235,6 +477,9 @@ proto_register_wsmp(void)
|
|||
/* Required function calls to register the header fields and subtrees used */
|
||||
proto_register_field_array(proto_wsmp, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
expert_wsmp = expert_register_protocol(proto_wsmp);
|
||||
expert_register_field_array(expert_wsmp, ei, array_length(ei));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue