2 * Dissector routines for the ATMEL Lightweight Mesh 1.1.1
3 * Copyright 2013 Martin Leixner <info@sewio.net>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *------------------------------------------------------------
29 #include <epan/packet.h>
30 #include <epan/expert.h>
32 #include "packet-ieee802154.h"
35 #define LWM_HEADER_BASE_LEN 7
37 #define LWM_MULTI_HEADER_LEN 2
39 /* Bit-masks for the FCF */
40 #define LWM_FCF_ACK_REQUEST 0x01
41 #define LWM_FCF_SEC_EN 0x02
43 #define LWM_FCF_LINK_LOCAL 0x04
44 #define LWM_FCF_MULTICAST 0x08
46 #define LWM_FCF_RESERVED 0xF0
48 #define LWM_MULTI_NON_MEM_RAD_MASK 0x000F
49 #define LWM_MULTI_NON_MEM_RAD_OFFSET 0
51 #define LWM_MULTI_MAX_NON_MEM_RAD_MASK 0x00F0
52 #define LWM_MULTI_MAX_NON_MEM_RAD_OFFSET 4
54 #define LWM_MULTI_MEM_RAD_MASK 0x0F00
55 #define LWM_MULTI_MEM_RAD_OFFSET 8
57 #define LWM_MULTI_MAX_MEM_RAD_MASK 0xF000
58 #define LWM_MULTI_MAX_MEM_RAD_OFFSET 12
61 #define LWM_SRC_ENDP_MASK 0xF0
62 #define LWM_SRC_ENDP_OFFSET 4
63 #define LWM_DST_ENDP_MASK 0x0F
64 #define LWM_DST_ENDP_OFFSET 0
67 #define LWM_BCAST_ADDR 0xFFFF
70 #define LWM_CMD_ACK 0x00
71 #define LWM_CMD_ROUTE_ERR 0x01
72 #define LWM_CMD_ROUTE_REQ 0x02
73 #define LWM_CMD_ROUTE_REPLY 0x03
75 /*Lengths of command frames*/
76 #define LWM_CMD_FRAME_ACK_LEN 3
77 #define LWM_CMD_FRAME_ROUTE_ERR_LEN 6
78 #define LWM_CMD_FRAME_ROUTE_REQ_LEN 7
79 #define LWM_CMD_FRAME_ROUTE_REPLY_LEN 8
81 /*Values for multicast field*/
82 #define LWM_CMD_MULTI_ADDR_FALSE 0
83 #define LWM_CMD_MULTI_ADDR_TRUE 1
86 #define LWM_CMD_LINKQ_STRING "(Sent by Originate node)"
87 #define LWM_CMD_UNKNOWN_VAL_STRING "Unknown command (0x%02x)"
89 #define LWM_MULTI_UNICAST_STRING "(Unicast)"
90 #define LWM_MULTI_GROUP_STRING "(Group ID)"
92 /* Function declarations */
93 void proto_register_lwm(void);
94 void proto_reg_handoff_lwm(void);
96 /* Dissector handles */
97 static dissector_handle_t data_handle;
99 /* Dissection Routines. */
100 static int dissect_lwm (tvbuff_t *, packet_info *, proto_tree *, void *data);
101 static int dissect_lwm_cmd_frame_ack (tvbuff_t *, packet_info *, proto_tree *);
102 static int dissect_lwm_cmd_frame_route_err (tvbuff_t *, packet_info *, proto_tree *);
103 static int dissect_lwm_cmd_frame_route_req (tvbuff_t *, packet_info *, proto_tree *);
104 static int dissect_lwm_cmd_frame_route_reply (tvbuff_t *, packet_info *, proto_tree *);
106 /* Initialize protocol and registered fields. */
107 static int proto_lwm = -1;
109 static int hf_lwm_fcf = -1;
110 static int hf_lwm_fcf_ack_req = -1;
111 static int hf_lwm_fcf_security = -1;
112 static int hf_lwm_fcf_linklocal = -1;
113 static int hf_lwm_fcf_multicast = -1;
114 static int hf_lwm_fcf_reserved = -1;
115 static int hf_lwm_seq = -1;
116 static int hf_lwm_src_addr = -1;
117 static int hf_lwm_dst_addr = -1;
118 static int hf_lwm_src_endp = -1;
119 static int hf_lwm_dst_endp = -1;
120 static int hf_lwm_multi_nmrad = -1;
121 static int hf_lwm_multi_mnmrad = -1;
122 static int hf_lwm_multi_mrad = -1;
123 static int hf_lwm_multi_mmrad = -1;
124 static int hf_lwm_mic = -1;
125 static int hf_lwm_cmd = -1;
126 static int hf_lwm_cmd_seq = -1;
127 static int hf_lwm_cmd_cm = -1;
128 static int hf_lwm_cmd_route_src = -1;
129 static int hf_lwm_cmd_route_dst = -1;
130 static int hf_lwm_cmd_route_multi = -1;
131 static int hf_lwm_cmd_linkquality = -1;
132 static int hf_lwm_cmd_forwlinkquality = -1;
133 static int hf_lwm_cmd_revlinkquality = -1;
135 /* Initialize protocol subtrees. */
136 static gint ett_lwm = -1;
137 static gint ett_lwm_fcf = -1;
138 static gint ett_lwm_cmd_tree = -1;
139 static gint ett_lwm_multi_tree = -1;
141 static expert_field ei_lwm_mal_error = EI_INIT;
142 static expert_field ei_lwm_n_src_broad = EI_INIT;
143 static expert_field ei_lwm_mismatch_endp = EI_INIT;
144 static expert_field ei_lwm_empty_payload = EI_INIT;
147 static const value_string lwm_cmd_names[] = {
148 { LWM_CMD_ACK, "LwMesh ACK" },
149 { LWM_CMD_ROUTE_ERR, "Route Error" },
150 { LWM_CMD_ROUTE_REQ, "Route Request" },
151 { LWM_CMD_ROUTE_REPLY, "Route Reply" },
155 static const value_string lwm_cmd_multi_names[] = {
156 { LWM_CMD_MULTI_ADDR_FALSE, "FALSE" },
157 { LWM_CMD_MULTI_ADDR_TRUE, "TRUE" },
161 /*FUNCTION:------------------------------------------------------
165 * Heuristic interpreter for the Lightweight Mesh.
167 * tvbuff_t *tvb - pointer to buffer containing raw packet.
168 * packet_into *pinfo - pointer to packet information fields
169 * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
171 * Boolean value, whether it handles the packet or not.
172 *---------------------------------------------------------------
175 dissect_lwm_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
177 /* 1) first byte must have bits 0000xxxx */
178 if(tvb_get_guint8(tvb, 0) & LWM_FCF_RESERVED)
181 /* The header should be at least long enough for the base header. */
182 if (tvb_reported_length(tvb) < LWM_HEADER_BASE_LEN)
185 dissect_lwm(tvb, pinfo, tree, data);
187 } /* dissect_lwm_heur */
189 /*FUNCTION:------------------------------------------------------
193 * Lightweight Mesh packet dissection routine for Wireshark.
195 * tvbuff_t *tvb - pointer to buffer containing raw packet.
196 * packet_info *pinfo - pointer to packet information fields
197 * proto_tree *tree - pointer to data tree Wireshark uses to display packet.
199 * int - length of data processed, or 0 if not LWM.
200 *---------------------------------------------------------------
202 static int dissect_lwm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
204 guint lwm_header_len;
207 gboolean lwm_fcf_security;
208 gboolean lwm_fcf_multicast;
212 guint16 lwm_src_addr;
213 guint16 lwm_dst_addr;
214 guint8 lwm_endp_field;
218 proto_tree *lwm_tree = NULL;
219 proto_item *ti_proto = NULL;
223 /*---------------------------------------------------------*/
225 /*Enter name of protocol to info field*/
226 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LwMesh");
227 col_clear(pinfo->cinfo, COL_INFO);
229 /*Set base length of LWM header*/
230 lwm_header_len = LWM_HEADER_BASE_LEN;
232 /*--------------------------------------------------*/
234 /* Create LwMesh dissector tree */
236 /*--------------------------------------------------*/
238 /*Create subtree for the LwMesh*/
239 ti_proto = proto_tree_add_protocol_format(tree, proto_lwm, tvb, 0, -1, "Lightweight Mesh");
240 lwm_tree = proto_item_add_subtree(ti_proto, ett_lwm);
243 col_add_fstr(pinfo->cinfo, COL_INFO, "Lightweight Mesh");
245 /*--------------------------------------------------*/
247 /* Display LwMesh dissector tree */
249 /*--------------------------------------------------*/
251 /*Frame control fields*/
252 lwm_fcf = tvb_get_guint8(tvb, 0);
254 lwm_fcf_security = (lwm_fcf & LWM_FCF_SEC_EN);
255 lwm_fcf_multicast = (lwm_fcf & LWM_FCF_MULTICAST);
258 proto_tree *field_tree;
259 ti = proto_tree_add_uint(lwm_tree, hf_lwm_fcf, tvb, 0, 1, lwm_fcf);
261 field_tree = proto_item_add_subtree(ti, ett_lwm_fcf);
262 proto_tree_add_item(field_tree, hf_lwm_fcf_ack_req, tvb, 0, 1, ENC_NA);
264 proto_tree_add_item(field_tree, hf_lwm_fcf_security, tvb, 0, 1, ENC_NA);
265 proto_tree_add_item(field_tree, hf_lwm_fcf_linklocal, tvb, 0, 1, ENC_NA);
266 proto_tree_add_item(field_tree, hf_lwm_fcf_multicast, tvb, 0, 1, ENC_NA);
267 proto_tree_add_item(field_tree, hf_lwm_fcf_reserved, tvb, 0, 1, ENC_NA);
271 lwm_seq = tvb_get_guint8(tvb, 1);
272 proto_item_append_text(ti_proto, ", Sequence Number: %i", lwm_seq);
273 proto_tree_add_uint(lwm_tree, hf_lwm_seq, tvb, 1, 1, lwm_seq);
275 /*Network addresses*/
277 /*Parse Source address*/
278 lwm_src_addr = tvb_get_letohs(tvb, 2);
280 ti = proto_tree_add_uint(lwm_tree, hf_lwm_src_addr, tvb, 2, 2, lwm_src_addr);
282 if(lwm_src_addr < 0x8000){
283 proto_item_append_text(ti, " (Routing node)");
285 proto_item_append_text(ti, " (Non-routing node)");
288 /*Check value of source address*/
289 if(lwm_src_addr == LWM_BCAST_ADDR){
290 expert_add_info(pinfo, lwm_tree, &ei_lwm_n_src_broad);
293 /*Parse Destination address*/
294 lwm_dst_addr = tvb_get_letohs(tvb, 4);
296 if(lwm_dst_addr == LWM_BCAST_ADDR){
297 proto_tree_add_uint_format_value(lwm_tree, hf_lwm_dst_addr, tvb, 4, 2, lwm_dst_addr,
298 "Broadcast (0x%04x)", lwm_dst_addr);
300 ti = proto_tree_add_uint(lwm_tree, hf_lwm_dst_addr, tvb, 4, 2, lwm_dst_addr);
302 if(lwm_fcf_multicast){
303 proto_item_append_text(ti, " %s", LWM_MULTI_GROUP_STRING);
305 proto_item_append_text(ti, " %s", LWM_MULTI_UNICAST_STRING);
307 if(lwm_dst_addr < 0x8000){
308 proto_item_append_text(ti, " (Routing node)");
310 proto_item_append_text(ti, " (Non-routing node)");
315 /*Enter description to info field*/
316 col_append_fstr(pinfo->cinfo, COL_INFO, ", Nwk_Dst: 0x%04x, Nwk_Src: 0x%04x", lwm_dst_addr, lwm_src_addr);
319 lwm_endp_field = tvb_get_guint8(tvb, 6);
320 lwm_src_endp = (lwm_endp_field & LWM_SRC_ENDP_MASK) >> LWM_SRC_ENDP_OFFSET;
321 lwm_dst_endp = (lwm_endp_field & LWM_DST_ENDP_MASK) >> LWM_DST_ENDP_OFFSET;
323 ti = proto_tree_add_uint(lwm_tree, hf_lwm_src_endp, tvb, 6, 1, lwm_src_endp);
324 if(lwm_src_endp == 0){
325 proto_item_append_text(ti, " (Stack command endpoint)");
328 ti = proto_tree_add_uint(lwm_tree, hf_lwm_dst_endp, tvb, 6, 1, lwm_dst_endp);
329 if(lwm_dst_endp == 0){
330 proto_item_append_text(ti, " (Stack command endpoint)");
333 if( (lwm_src_endp == 0) && (lwm_dst_endp == 0)){
334 /*stack command endpoints*/
337 else if( (lwm_src_endp == 0) || (lwm_dst_endp == 0)){
338 /*If only one endpoint is 0, alert about that*/
340 col_append_str(pinfo->cinfo, COL_INFO, "[Stack command Endpoints mismatch]");
342 expert_add_info(pinfo, lwm_tree, &ei_lwm_mismatch_endp);
346 if( (lwm_fcf_multicast) ){
348 lwm_header_len += LWM_MULTI_HEADER_LEN;
351 proto_tree *multi_tree;
352 guint16 lwm_multi_header;
354 lwm_multi_header = tvb_get_letohs(tvb, 7);
355 ti = proto_tree_add_text(lwm_tree, tvb, 7, 2, "Multicast Header");
356 multi_tree = proto_item_add_subtree(ti, ett_lwm_multi_tree);
358 proto_tree_add_uint(multi_tree, hf_lwm_multi_nmrad, tvb, 7, 2,
359 (lwm_multi_header & LWM_MULTI_NON_MEM_RAD_MASK) >> LWM_MULTI_NON_MEM_RAD_OFFSET);
360 proto_tree_add_uint(multi_tree, hf_lwm_multi_mnmrad, tvb, 7, 2,
361 (lwm_multi_header & LWM_MULTI_MAX_NON_MEM_RAD_MASK) >> LWM_MULTI_MAX_NON_MEM_RAD_OFFSET);
362 proto_tree_add_uint(multi_tree, hf_lwm_multi_mrad, tvb, 7, 2,
363 (lwm_multi_header & LWM_MULTI_MEM_RAD_MASK) >> LWM_MULTI_MEM_RAD_OFFSET);
364 proto_tree_add_uint(multi_tree, hf_lwm_multi_mmrad, tvb, 7, 2,
365 (lwm_multi_header & LWM_MULTI_MAX_MEM_RAD_MASK) >> LWM_MULTI_MAX_MEM_RAD_OFFSET);
370 /*------------------------------*/
372 /* Dissect payload */
374 /*------------------------------*/
376 /*Note: exception will already have occurred if "short header"*/
378 if (tvb_reported_length(tvb) <= lwm_header_len) {
380 expert_add_info(pinfo, lwm_tree, &ei_lwm_empty_payload);
381 col_append_str(pinfo->cinfo, COL_INFO, "[Empty LwMesh Payload]");
383 return tvb_captured_length(tvb);
386 new_tvb = tvb_new_subset_remaining(tvb, lwm_header_len);
389 if(lwm_fcf_security){
394 /*XXX: using -LWM_MIC_LEN for 'start' in the proto_tree_add_item() call fetches */
395 /* the correct bytes from the tvb; however the wrong 4 bytes (before the field) */
396 /* are highlighted in the (GTK) GUI. */
397 rlen = tvb_reported_length(new_tvb);
398 start = (rlen >= LWM_MIC_LEN) ? (rlen-LWM_MIC_LEN) : 0;
399 /*An exception will occur if there are not enough bytes for the MIC */
400 proto_tree_add_item(lwm_tree, hf_lwm_mic, new_tvb, start, LWM_MIC_LEN, ENC_BIG_ENDIAN);
402 col_clear(pinfo->cinfo, COL_INFO); /*XXX: why ?*/
403 col_add_fstr(pinfo->cinfo, COL_INFO,
404 "Encrypted data (%i byte(s)) ",
405 tvb_reported_length(new_tvb) - LWM_MIC_LEN);
406 tvb_set_reported_length(new_tvb, tvb_reported_length(new_tvb) - LWM_MIC_LEN);
407 call_dissector(data_handle, new_tvb, pinfo, lwm_tree);
409 /*stack command endpoint 0 and not secured*/
410 else if( (lwm_src_endp == 0) && (lwm_dst_endp == 0) ){
411 proto_tree *lwm_cmd_tree;
415 /*----------------------------------------------------------------------*/
417 /* Call command dissector (depends on value of first byte of payload) */
419 /*----------------------------------------------------------------------*/
420 lwm_cmd = tvb_get_guint8(new_tvb, 0);
422 col_clear(pinfo->cinfo, COL_INFO); /*XXX: why ?*/
423 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
424 val_to_str(lwm_cmd, lwm_cmd_names, LWM_CMD_UNKNOWN_VAL_STRING));
426 ti = proto_tree_add_text(lwm_tree, new_tvb, 0, -1, "%s",
427 val_to_str(lwm_cmd, lwm_cmd_names, LWM_CMD_UNKNOWN_VAL_STRING));
428 lwm_cmd_tree = proto_item_add_subtree(ti, ett_lwm_cmd_tree);
430 proto_tree_add_uint(lwm_cmd_tree, hf_lwm_cmd, new_tvb, 0, 1, lwm_cmd);
435 len = dissect_lwm_cmd_frame_ack(new_tvb, pinfo, lwm_cmd_tree);
438 case LWM_CMD_ROUTE_ERR:
439 len = dissect_lwm_cmd_frame_route_err(new_tvb, pinfo, lwm_cmd_tree);
442 case LWM_CMD_ROUTE_REQ:
443 len = dissect_lwm_cmd_frame_route_req(new_tvb, pinfo, lwm_cmd_tree);
446 case LWM_CMD_ROUTE_REPLY:
447 len = dissect_lwm_cmd_frame_route_reply(new_tvb, pinfo, lwm_cmd_tree);
452 expert_add_info_format(pinfo, lwm_cmd_tree, &ei_lwm_mal_error, "Unknown command");
453 call_dissector(data_handle, new_tvb, pinfo, lwm_cmd_tree);
454 return tvb_captured_length(tvb);
457 proto_item_set_len(ti, len);
459 /*Here only if additional data after valid 'cmd' data*/
460 /*Note: exception will have already occurred if tvb was missing required bytes for 'cmd'*/
461 /* Report error if additional undissected data*/
462 if (len < tvb_reported_length(new_tvb)) {
463 /*unknown additional data*/
464 expert_add_info_format(pinfo, lwm_cmd_tree, &ei_lwm_mal_error,
465 "Size is %i byte(s), instead of %i bytes", tvb_reported_length(new_tvb), len);
467 new_tvb = tvb_new_subset_remaining(new_tvb, len);
468 call_dissector(data_handle, new_tvb, pinfo, lwm_tree);
473 call_dissector(data_handle, new_tvb, pinfo, lwm_tree);
475 return tvb_captured_length(tvb);
478 /*FUNCTION:------------------------------------------------------
480 * dissect_lwm_cmd_frame_ack
482 * LwMesh command frame - Ack.
485 * tvbuff_t *tvb - pointer to buffer containing raw packet.
486 * packet_info *pinfo - pointer to packet information fields
487 * proto_tree *tree - pointer to data tree wireshark uses to display packet.
489 * int length - amount of data processed
490 *---------------------------------------------------------------
492 static int dissect_lwm_cmd_frame_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *lwm_cmd_tree)
497 lwm_seq = tvb_get_guint8(tvb, 1);
499 col_append_fstr(pinfo->cinfo, COL_INFO, ", Sequence number: %d", lwm_seq);
502 proto_item_append_text(proto_tree_get_parent(lwm_cmd_tree), ", Sequence number: %d", lwm_seq);
503 proto_tree_add_uint(lwm_cmd_tree, hf_lwm_cmd_seq, tvb, 1, 1, lwm_seq);
504 proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_cm, tvb, 2, 1, ENC_NA);
507 return LWM_CMD_FRAME_ACK_LEN;
509 } /* dissect_lwm_cmd_frame_ack*/
511 /*FUNCTION:------------------------------------------------------
513 * dissect_lwm_cmd_frame_route_err
515 * LwMesh command frame - Route error.
518 * tvbuff_t *tvb - pointer to buffer containing raw packet.
519 * packet_info *pinfo - pointer to packet information fields
520 * proto_tree *tree - pointer to data tree wireshark uses to display packet.
522 * int length - amount of data processed
523 *---------------------------------------------------------------
525 static int dissect_lwm_cmd_frame_route_err(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *lwm_cmd_tree)
530 proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_src, tvb, 1, 2, ENC_LITTLE_ENDIAN);
531 ti = proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_dst, tvb, 3, 2, ENC_LITTLE_ENDIAN);
533 if(tvb_get_guint8(tvb, 5) == LWM_CMD_MULTI_ADDR_TRUE){
534 proto_item_append_text(ti, " %s", LWM_MULTI_GROUP_STRING);
536 proto_item_append_text(ti, " %s", LWM_MULTI_UNICAST_STRING);
539 proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_multi, tvb, 5, 1, ENC_NA);
542 return LWM_CMD_FRAME_ROUTE_ERR_LEN;
544 } /* dissect_lwm_cmd_frame_route_err*/
546 /*FUNCTION:------------------------------------------------------
548 * dissect_lwm_cmd_frame_route_req
550 * LwMesh command frame - Route Request.
553 * tvbuff_t *tvb - pointer to buffer containing raw packet.
554 * packet_info *pinfo - pointer to packet information fields
555 * proto_tree *tree - pointer to data tree wireshark uses to display packet.
557 * int length - amount of data processed
558 *---------------------------------------------------------------
560 static int dissect_lwm_cmd_frame_route_req(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *lwm_cmd_tree)
566 proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_src, tvb, 1, 2, ENC_LITTLE_ENDIAN);
567 ti = proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_dst, tvb, 3, 2, ENC_LITTLE_ENDIAN);
569 if(tvb_get_guint8(tvb, 5) == LWM_CMD_MULTI_ADDR_TRUE){
570 proto_item_append_text(ti, " %s", LWM_MULTI_GROUP_STRING);
572 proto_item_append_text(ti, " %s", LWM_MULTI_UNICAST_STRING);
575 proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_multi, tvb, 5, 1, ENC_NA);
577 lwm_linkqual = tvb_get_guint8(tvb, 6);
578 ti = proto_tree_add_uint(lwm_cmd_tree, hf_lwm_cmd_linkquality, tvb, 6, 1, lwm_linkqual);
579 if(lwm_linkqual == 255){
580 proto_item_append_text(ti, " %s", LWM_CMD_LINKQ_STRING);
584 return LWM_CMD_FRAME_ROUTE_REQ_LEN;
586 } /* dissect_lwm_cmd_frame_route_req*/
588 /*FUNCTION:------------------------------------------------------
590 * dissect_lwm_cmd_frame_route_reply
592 * LwMesh command frame - Route Reply.
595 * tvbuff_t *tvb - pointer to buffer containing raw packet.
596 * packet_info *pinfo - pointer to packet information fields
597 * proto_tree *tree - pointer to data tree wireshark uses to display packet.
599 * int length - amount of data processed
600 *---------------------------------------------------------------
602 static int dissect_lwm_cmd_frame_route_reply(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *lwm_cmd_tree)
606 guint8 lwm_revlinkqual;
608 proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_src, tvb, 1, 2, ENC_LITTLE_ENDIAN);
609 ti = proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_dst, tvb, 3, 2, ENC_LITTLE_ENDIAN);
611 if(tvb_get_guint8(tvb, 5) == LWM_CMD_MULTI_ADDR_TRUE){
612 proto_item_append_text(ti, " %s", LWM_MULTI_GROUP_STRING);
614 proto_item_append_text(ti, " %s", LWM_MULTI_UNICAST_STRING);
617 proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_route_multi, tvb, 5, 1, ENC_NA);
618 proto_tree_add_item(lwm_cmd_tree, hf_lwm_cmd_forwlinkquality, tvb, 6, 1, ENC_NA);
620 lwm_revlinkqual = tvb_get_guint8(tvb, 7);
621 ti = proto_tree_add_uint(lwm_cmd_tree, hf_lwm_cmd_revlinkquality, tvb, 7, 1, lwm_revlinkqual);
622 if(lwm_revlinkqual == 255){
623 proto_item_append_text(ti, " %s", LWM_CMD_LINKQ_STRING);
627 return LWM_CMD_FRAME_ROUTE_REPLY_LEN;
629 } /* dissect_lwm_cmd_frame_route_reply*/
631 /*FUNCTION:------------------------------------------------------
635 * IEEE 802.15.4 protocol registration routine.
640 *---------------------------------------------------------------
642 void proto_register_lwm(void)
645 static hf_register_info hf[] = {
647 /*Frame control field*/
649 { "Frame control field", "lwm.fcf", FT_UINT8, BASE_HEX, NULL, 0x0,
650 "Control information for the frame.", HFILL }},
652 { &hf_lwm_fcf_ack_req,
653 { "Acknowledgment Request", "lwm.ack_req", FT_BOOLEAN, 8, NULL, LWM_FCF_ACK_REQUEST,
654 "Specifies whether an acknowledgment is required from the destination node.", HFILL }},
656 { &hf_lwm_fcf_security,
657 { "Security Enabled", "lwm.security", FT_BOOLEAN, 8, NULL, LWM_FCF_SEC_EN,
658 "Specifies whether the frame payload is encrypted.", HFILL }},
660 { &hf_lwm_fcf_linklocal,
661 { "Link Local", "lwm.linklocal", FT_BOOLEAN, 8, NULL, LWM_FCF_LINK_LOCAL,
662 "It may be set to one to prevent neighboring nodes from rebroadcasting a frame.", HFILL }},
664 { &hf_lwm_fcf_multicast,
665 { "Multicast", "lwm.multicast", FT_BOOLEAN, 8, NULL, LWM_FCF_MULTICAST,
666 "If the Multicast subfield is set to one, Multicast Header should be present and the Destination Address is a group address.", HFILL }},
668 { &hf_lwm_fcf_reserved,
669 { "Reserved bits", "lwm.fcf.reserved", FT_UINT8, BASE_HEX, NULL, LWM_FCF_RESERVED,
670 "The 4 bits are reserved.", HFILL }},
674 { "Sequence Number", "lwm.seq", FT_UINT8, BASE_DEC, NULL, 0x0,
675 "Specifies the sequence identifier for the frame.", HFILL }},
678 { "Network Source Address", "lwm.src_addr", FT_UINT16, BASE_HEX, NULL, 0x0,
679 "Specifies the network address of the node originating the frame.", HFILL }},
682 { "Network Destination Address", "lwm.dst_addr", FT_UINT16, BASE_HEX, NULL, 0x0,
683 "Specifies the network address of the destination node or group address for multicast messages.", HFILL }},
686 { "Source Endpoint", "lwm.src_endp", FT_UINT8, BASE_DEC, NULL, 0x0,
687 "Specifies the source endpoint identifier.", HFILL }},
690 { "Destination Endpoint", "lwm.dst_endp", FT_UINT8, BASE_DEC, NULL, 0x0,
691 "Specifies the destination endpoint identifier.", HFILL }},
695 { &hf_lwm_multi_nmrad,
696 { "Non-member Radius", "lwm.multi_nmrad", FT_UINT8, BASE_DEC, NULL, 0x0,
697 "Specifies remaining radius (number of hops) for Non-members of multicast group.", HFILL }},
699 { &hf_lwm_multi_mnmrad,
700 { "Maximum Non-member Radius", "lwm.multi_mnmrad", FT_UINT8, BASE_DEC, NULL, 0x0,
701 "Specifies maximum radius (number of hops) for Non-members of multicast group.", HFILL }},
703 { &hf_lwm_multi_mrad,
704 { "Member Radius", "lwm.multi_mrad", FT_UINT8, BASE_DEC, NULL, 0x0,
705 "Specifies remaining radius (number of hops) for Members of multicast group.", HFILL }},
707 { &hf_lwm_multi_mmrad,
708 { "Maximum Member Radius", "lwm.multi_mmrad", FT_UINT8, BASE_DEC, NULL, 0x0,
709 "Specifies maximum radius (number of hops) for Members of multicast group.", HFILL }},
714 { "Message Integrity Code", "lwm.mic", FT_UINT32, BASE_HEX, NULL, 0x0,
715 "Specifies Message Integrity Code (MIC).", HFILL }},
718 /*----------------------------------*/
720 /* Command Frames Specific Fields */
722 /*----------------------------------*/
725 { "Command ID", "lwm.cmd", FT_UINT8, BASE_HEX, VALS(lwm_cmd_names), 0x0,
726 "It contains Command ID value.", HFILL }},
728 /* Command Frame - Ack */
730 { "Sequence number", "lwm.cmd.seq", FT_UINT8, BASE_DEC, NULL, 0x0,
731 "It contains a network sequence number of a frame that is being acknowledged.", HFILL }},
734 { "Control Message", "lwm.cmd.cm", FT_UINT8, BASE_HEX, NULL, 0x0,
735 "It contains an arbitrary value that can be set on the sending side.", HFILL }},
737 /* Part of Command Frames - Route Request, Route Reply*/
738 { &hf_lwm_cmd_route_src,
739 { "Source address", "lwm.cmd.route_src", FT_UINT16, BASE_HEX, NULL, 0x0,
740 "It contains a source network address from the frame that cannot be routed", HFILL }},
742 { &hf_lwm_cmd_route_dst,
743 { "Destination Address", "lwm.cmd.route_dst", FT_UINT16, BASE_HEX, NULL, 0x0,
744 "It contains a destination network address from the frame that cannot be routed", HFILL }},
746 { &hf_lwm_cmd_route_multi,
747 { "Multicast", "lwm.cmd.multi", FT_UINT8, BASE_HEX, VALS(lwm_cmd_multi_names), 0x0,
748 "If it set to 0, Destination Address field contains a network address. If it set to 1, Destination Address field contains a group ID.", HFILL }},
750 /* Part of Command Frame - Route Request */
751 { &hf_lwm_cmd_linkquality,
752 { "Link Quality", "lwm.cmd.linkq", FT_UINT8, BASE_DEC, NULL, 0x0,
753 "It contains a link quality value of the potential route accumulated over all hops towards the destination.", HFILL }},
755 /* Part of Command Frame - Route Reply */
756 { &hf_lwm_cmd_forwlinkquality,
757 { "Forward Link Quality", "lwm.cmd.flinkq", FT_UINT8, BASE_DEC, NULL, 0x0,
758 "It contains a value of the Link Quality field from the corresponding Route Request Command Frame.", HFILL }},
760 { &hf_lwm_cmd_revlinkquality,
761 { "Reverse Link Quality", "lwm.cmd.rlinkq", FT_UINT8, BASE_DEC, NULL, 0x0,
762 "It contains a link quality value of the discovered route accumulated over all hops towards the originator.", HFILL }},
768 static gint *ett[] = {
775 static ei_register_info ei[] = {
776 { &ei_lwm_mal_error, { "lwm.malformed_error", PI_MALFORMED, PI_ERROR, "Malformed Packet", EXPFILL }},
777 { &ei_lwm_n_src_broad, { "lwm.not_src_broadcast", PI_COMMENTS_GROUP, PI_NOTE, "Source address can not be broadcast address !", EXPFILL }},
778 { &ei_lwm_mismatch_endp, { "lwm.mismatch_endp", PI_COMMENTS_GROUP, PI_WARN, "Stack command Endpoints mismatch (should be 0, both)!", EXPFILL }},
779 { &ei_lwm_empty_payload, { "lwm.empty_payload", PI_COMMENTS_GROUP, PI_WARN, "Empty LwMesh Payload!", EXPFILL }},
784 expert_module_t* expert_lwm;
786 /* Register protocol name and description. */
787 proto_lwm = proto_register_protocol("Lightweight Mesh (v1.1.1)", "LwMesh", "lwm");
789 /* Register header fields and subtrees. */
790 proto_register_field_array(proto_lwm, hf, array_length(hf));
791 proto_register_subtree_array(ett, array_length(ett));
792 expert_lwm = expert_register_protocol(proto_lwm);
793 expert_register_field_array(expert_lwm, ei, array_length(ei));
795 /* Register dissector with Wireshark. */
796 new_register_dissector("lwm", dissect_lwm, proto_lwm);
798 } /* proto_register_lwm */
800 /*FUNCTION:------------------------------------------------------
802 * proto_reg_handoff_lwm
804 * Registers the lwm dissector with Wireshark.
805 * Will be called during Wireshark startup.
810 *---------------------------------------------------------------
812 void proto_reg_handoff_lwm(void)
814 data_handle = find_dissector("data");
816 /* Register our dissector with IEEE 802.15.4 */
817 dissector_add_handle(IEEE802154_PROTOABBREV_WPAN_PANID, find_dissector("lwm"));
818 heur_dissector_add(IEEE802154_PROTOABBREV_WPAN, dissect_lwm_heur, proto_lwm);
820 } /* proto_reg_handoff_lwm */
828 * indent-tabs-mode: nil
831 * ex: set shiftwidth=4 tabstop=8 expandtab:
832 * :indentSize=4:tabSize=8:noTabs=true: