2 * Routines for WAVE Short Message dissection (WSMP)
3 * Copyright 2013, Savari Networks (http://www.savarinetworks.com) (email: smooney@savarinetworks.com)
4 * Based on packet-wsmp.c implemented by
5 * Arada Systems (http://www.aradasystems.com) (email: siva@aradasystems.com)
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
32 #include <epan/packet.h>
33 #include <epan/etypes.h>
40 #define TRANSMITPW 0x04
42 static const value_string wsmp_elemenid_names
[] = {
50 static dissector_handle_t data_handle
;
52 /* Initialize the protocol and registered fields */
53 static int proto_wsmp
= -1;
54 static int hf_wsmp_version
= -1;
55 static int hf_wsmp_psid
= -1;
56 static int hf_wsmp_rate
= -1;
57 static int hf_wsmp_channel
= -1;
58 static int hf_wsmp_txpower
= -1;
59 static int hf_wsmp_WAVEid
= -1;
60 static int hf_wsmp_wsmlength
= -1;
61 static int hf_wsmp_WSMP_S_data
= -1;
63 /* Savari function to get the length of a psid based on the number of
64 successive 1s in the most sig bits of the most sig octet. Taken
67 int wme_getpsidlen (guint8
*psid
)
70 if ((psid
[0] & 0xF0) == 0xF0) {
72 } else if ( (psid
[0] & 0xE0) == 0xE0) {
74 } else if ( (psid
[0] & 0xE0) == 0xC0) {
76 } else if ( (psid
[0] & 0xC0) == 0x80) {
78 } else if ((psid
[0] & 0x80) == 0x00) {
84 /* Initialize the subtree pointers */
85 static gint ett_wsmp
= -1;
86 static gint ett_wsmdata
= -1;
89 dissect_wsmp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
91 /* Set up structures needed to add the protocol subtree and manage it */
92 proto_item
*ti
, *wsmdata_item
;
93 proto_tree
*wsmp_tree
, *wsmdata_tree
;
94 tvbuff_t
*wsmdata_tvb
;
95 guint16 wsmlength
, offset
;
96 guint32 psidLen
, psid
, supLen
;
97 guint8 elemenId
, elemenLen
, msb
;
99 /* Make entries in Protocol column and Info column on summary display */
100 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "WSMP");
102 col_set_str(pinfo
->cinfo
, COL_INFO
, "WAVE Short Message Protocol IEEE P1609.3");
104 /* create display subtree for the protocol */
105 ti
= proto_tree_add_item(tree
, proto_wsmp
, tvb
, 0, -1, ENC_NA
);
107 wsmp_tree
= proto_item_add_subtree(ti
, ett_wsmp
);
110 proto_tree_add_item(wsmp_tree
,
111 hf_wsmp_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
114 psid
= tvb_get_guint8(tvb
, offset
);
115 psidLen
= (guint32
)wme_getpsidlen((guint8
*)&psid
);
119 psid
= tvb_get_ntohs(tvb
, offset
);
120 else if (psidLen
== 3)
122 psid
= tvb_get_ntohl(tvb
, offset
);
123 psid
= psid
& 0x00FFFF; /* three bytes */
126 else if (psidLen
== 4)
127 psid
= tvb_get_ntohl(tvb
, offset
);
129 proto_tree_add_item(wsmp_tree
,
130 hf_wsmp_psid
, tvb
, offset
, psidLen
, ENC_BIG_ENDIAN
);
134 elemenId
= tvb_get_guint8(tvb
, offset
);
135 while ((elemenId
!= WSMP
) && (elemenId
!= WSMP_S
) && (elemenId
!= WSMP_I
))
138 if (elemenId
== CHANNUM
)
141 elemenLen
= tvb_get_guint8(tvb
, offset
);
143 proto_tree_add_item(wsmp_tree
,
144 hf_wsmp_channel
, tvb
, offset
, elemenLen
, ENC_BIG_ENDIAN
);
147 else if (elemenId
== DATARATE
)
150 elemenLen
= tvb_get_guint8(tvb
, offset
);
152 proto_tree_add_item(wsmp_tree
,
153 hf_wsmp_rate
, tvb
, offset
, elemenLen
, ENC_BIG_ENDIAN
);
156 else if (elemenId
== TRANSMITPW
)
159 elemenLen
= tvb_get_guint8(tvb
, offset
);
161 proto_tree_add_item(wsmp_tree
,
162 hf_wsmp_txpower
, tvb
, offset
, elemenLen
, ENC_BIG_ENDIAN
);
165 elemenId
= tvb_get_guint8(tvb
, offset
);
168 proto_tree_add_item(wsmp_tree
,
169 hf_wsmp_WAVEid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
172 wsmlength
= tvb_get_letohs( tvb
, offset
);
173 proto_tree_add_item(wsmp_tree
,
174 hf_wsmp_wsmlength
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
177 if (elemenId
== WSMP_S
)
183 msb
= tvb_get_guint8(tvb
, offset
+ supLen
);
187 proto_tree_add_item(wsmp_tree
,
188 hf_wsmp_WSMP_S_data
, tvb
, offset
, supLen
, ENC_BIG_ENDIAN
);
193 wsmdata_item
= proto_tree_add_text (wsmp_tree
, tvb
, offset
, wsmlength
,
194 "Wave Short Message");
195 wsmdata_tree
= proto_item_add_subtree(wsmdata_item
, ett_wsmdata
);
197 wsmdata_tvb
= tvb_new_subset(tvb
, offset
, -1, wsmlength
);
199 /* TODO: Branch on the application context and display accordingly
200 * Default: call the data dissector
204 call_dissector(data_handle
, wsmdata_tvb
, pinfo
, wsmdata_tree
);
209 proto_register_wsmp(void)
211 /* Setup list of header fields See Section 1.6.1 for details*/
212 static hf_register_info hf
[] = {
214 { "Version", "wsmp.version", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
218 { "PSID", "wsmp.psid", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
222 { "Channel", "wsmp.channel", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
226 { "Data Rate", "wsmp.rate", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
230 { "Transmit Power", "wsmp.txpower", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
234 { "WAVE element id", "wsmp.WAVEid", FT_UINT8
, BASE_DEC
, VALS(wsmp_elemenid_names
), 0x0,
237 { &hf_wsmp_wsmlength
,
238 { "WSM Length", "wsmp.wsmlength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
241 { &hf_wsmp_WSMP_S_data
,
242 { "WAVE Supplement Data", "wsmp.supplement", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
246 /* Setup protocol subtree array */
247 static gint
*ett
[] = {
252 /* Register the protocol name and description */
253 proto_wsmp
= proto_register_protocol("Wave Short Message Protocol(IEEE P1609.3)",
256 /* Required function calls to register the header fields and subtrees used */
257 proto_register_field_array(proto_wsmp
, hf
, array_length(hf
));
258 proto_register_subtree_array(ett
, array_length(ett
));
262 proto_reg_handoff_wsmp(void)
264 dissector_handle_t wsmp_handle
;
266 wsmp_handle
= create_dissector_handle(dissect_wsmp
, proto_wsmp
);
267 dissector_add_uint("ethertype", ETHERTYPE_WSMP
, wsmp_handle
);
268 data_handle
= find_dissector("data");