2 * WiMax MAC Management ARQ Feedback, Discard, Reset Message decoders
4 * Copyright (c) 2007 by Intel Corporation.
6 * Author: John R. Underwood <junderx@yahoo.com>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1999 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include "moduleinfo.h"
36 #include <epan/packet.h>
38 #include "wimax_tlv.h"
39 #include "wimax_mac.h"
41 extern gint man_ofdma;
43 /* Forward reference */
44 void dissect_mac_mgmt_msg_arq_feedback_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
45 void dissect_mac_mgmt_msg_arq_discard_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
46 void dissect_mac_mgmt_msg_arq_reset_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
48 static gint proto_mac_mgmt_msg_arq_feedback_decoder = -1;
49 static gint proto_mac_mgmt_msg_arq_discard_decoder = -1;
50 static gint proto_mac_mgmt_msg_arq_reset_decoder = -1;
52 static gint ett_mac_mgmt_msg_arq_decoder = -1;
54 /* Setup protocol subtree array */
57 &ett_mac_mgmt_msg_arq_decoder,
62 static gint hf_arq_cid = -1;
63 static gint hf_arq_last = -1;
64 static gint hf_arq_ack_type = -1;
65 static gint hf_ack_type_reserved = -1;
66 static gint hf_arq_bsn = -1;
67 static gint hf_arq_num_ack_maps = -1;
68 static gint hf_arq_selective_map = -1;
69 static gint hf_arq_seq_format = -1;
70 static gint hf_arq_0seq_ack_map = -1;
71 static gint hf_arq_0seq1_len = -1;
72 static gint hf_arq_0seq2_len = -1;
73 static gint hf_arq_1seq_ack_map = -1;
74 static gint hf_arq_1seq1_len = -1;
75 static gint hf_arq_1seq2_len = -1;
76 static gint hf_arq_1seq3_len = -1;
77 static gint hf_arq_reserved = -1;
79 static gint hf_arq_discard_cid = -1;
80 static gint hf_arq_discard_reserved = -1;
81 static gint hf_arq_discard_bsn = -1;
83 static gint hf_arq_reset_cid = -1;
84 static gint hf_arq_reset_type = -1;
85 static gint hf_arq_reset_direction = -1;
86 static gint hf_arq_reset_reserved = -1;
88 static gint hf_arq_message_type = -1;
90 /* STRING RESOURCES */
92 static const true_false_string tfs_present = {
97 static const true_false_string tfs_rng_req_aas_broadcast = {
98 "SS cannot receive broadcast messages",
99 "SS can receive broadcast messages"
102 static const true_false_string tfs_arq_last = {
103 "Last ARQ feedback IE in the list",
104 "More ARQ feedback IE in the list"
107 static const value_string vals_arq_ack_type[] = {
108 {0, "Selective ACK entry"},
109 {1, "Cumulative ACK entry"},
110 {2, "Cumulative with Selective ACK entry"},
111 {3, "Cumulative ACK with Block Sequence Ack entry"},
115 static const value_string vals_arq_reset_type[] = {
116 {0, "Original message from Initiator"},
117 {1, "Acknowledgment from Responder"},
118 {2, "Confirmation from Initiator"},
123 static const value_string vals_arq_reset_direction[] = {
124 {0, "Uplink or downlink"},
131 /* Register Wimax Mac Payload Protocol and Dissector */
132 void proto_register_mac_mgmt_msg_arq_feedback(void)
134 /* ARQ fields display */
135 static hf_register_info hf[] =
137 /* TODO: Make three separate arq message types */
139 &hf_arq_message_type,
141 "MAC Management Message Type", "wmx.macmgtmsgtype.arq",
142 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
148 "ACK Type", "wmx.arq.ack_type",
149 FT_UINT8, BASE_DEC, VALS(vals_arq_ack_type), 0x60, NULL, HFILL
155 "BSN", "wmx.arq.bsn",
156 FT_UINT16, BASE_DEC, NULL, 0x1FFC, NULL, HFILL
162 "Connection ID", "wmx.arq.cid",
163 FT_UINT16, BASE_DEC, NULL, 0x00, "The ID of the connection being referenced", HFILL
169 "BSN", "wmx.arq.discard_bsn",
170 FT_UINT16, BASE_DEC, NULL, 0x07FF, NULL, HFILL
176 "Connection ID", "wmx.arq.discard_cid",
177 FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL
181 &hf_arq_discard_reserved,
183 "Reserved", "wmx.arq.discard_reserved",
184 FT_UINT8, BASE_DEC, NULL, 0xF8, NULL, HFILL
190 "LAST", "wmx.arq.last",
191 FT_BOOLEAN, 8, TFS(&tfs_arq_last), 0x80, NULL, HFILL
195 &hf_arq_num_ack_maps,
197 "Number of ACK Maps", "wmx.arq.num_maps",
198 FT_UINT8, BASE_DEC, NULL, 0x03, NULL, HFILL
204 "Reserved", "wmx.arq.reserved",
205 FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL
211 "Connection ID", "wmx.arq.reset_cid",
212 FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL
216 &hf_arq_reset_direction,
218 "Direction", "wmx.arq.reset_direction",
219 FT_UINT8, BASE_DEC, VALS(vals_arq_reset_direction), 0x30, NULL, HFILL
223 &hf_arq_reset_reserved,
225 "Reserved", "wmx.arq.reset_reserved",
226 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL
232 "Type", "wmx.arq.reset_type",
233 FT_UINT8, BASE_DEC, VALS(vals_arq_reset_type), 0xC0, NULL, HFILL
237 &hf_arq_selective_map,
239 "Selective ACK Map", "wmx.arq.selective_map",
240 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL
244 &hf_arq_0seq_ack_map,
246 "Sequence ACK Map", "wmx.arq.seq_ack_map",
247 FT_UINT8, BASE_HEX, NULL, 0x60, NULL, HFILL
251 &hf_arq_1seq_ack_map,
253 "Sequence ACK Map", "wmx.arq.seq_ack_map",
254 FT_UINT8, BASE_HEX, NULL, 0x70, NULL, HFILL
260 "Sequence Format", "wmx.arq.seq_format",
261 FT_UINT8, BASE_DEC, NULL, 0x80, NULL, HFILL
267 "Sequence 1 Length", "wmx.arq.seq1_len",
268 FT_UINT16, BASE_DEC, NULL, 0x1F80, NULL, HFILL
274 "Sequence 2 Length", "wmx.arq.seq2_len",
275 FT_UINT16, BASE_DEC, NULL, 0x007E, NULL, HFILL
281 "Sequence 1 Length", "wmx.arq.seq1_len",
282 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL
288 "Sequence 2 Length", "wmx.arq.seq2_len",
289 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL
295 "Sequence 3 Length", "wmx.arq.seq3_len",
296 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL
300 &hf_ack_type_reserved,
302 "Reserved", "wmx.ack_type.reserved",
303 FT_UINT8, BASE_DEC, NULL, 0x03, NULL, HFILL
308 proto_mac_mgmt_msg_arq_feedback_decoder = proto_register_protocol (
309 "WiMax ARQ Feedback/Discard/Reset Messages", /* name */
310 "WiMax ARQ Feedback/Discard/Reset (arq)", /* short name */
311 "wmx.arq" /* abbrev */
314 proto_register_field_array(proto_mac_mgmt_msg_arq_feedback_decoder, hf, array_length(hf));
315 proto_register_subtree_array(ett, array_length(ett));
318 /* Register Wimax Mac Payload Protocol and Dissector */
319 void proto_register_mac_mgmt_msg_arq_discard(void)
321 proto_mac_mgmt_msg_arq_discard_decoder = proto_mac_mgmt_msg_arq_feedback_decoder;
324 /* Register Wimax Mac Payload Protocol and Dissector */
325 void proto_register_mac_mgmt_msg_arq_reset(void)
327 proto_mac_mgmt_msg_arq_reset_decoder = proto_mac_mgmt_msg_arq_feedback_decoder;
330 /* Decode ARQ-Feedback messages. */
331 void dissect_mac_mgmt_msg_arq_feedback_decoder(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
334 guint arq_feedback_ie_count = 0;
336 gboolean arq_last = FALSE;
339 guint arq_num_ack_maps;
340 guint tvb_len, payload_type;
341 proto_item *arq_feedback_item = NULL;
342 proto_tree *arq_feedback_tree = NULL;
343 proto_item *arq_fb_item = NULL;
344 proto_tree *arq_fb_tree = NULL;
345 proto_item *ti = NULL;
348 /* Ensure the right payload type */
349 payload_type = tvb_get_guint8(tvb, offset);
350 if(payload_type != MAC_MGMT_MSG_ARQ_FEEDBACK)
356 { /* we are being asked for details */
358 /* Get the tvb reported length */
359 tvb_len = tvb_reported_length(tvb);
360 /* display MAC payload type ARQ-Feedback */
361 arq_feedback_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_arq_feedback_decoder, tvb, offset, tvb_len, "MAC Management Message, ARQ-Feedback (33)");
362 /* add MAC ARQ Feedback subtree */
363 arq_feedback_tree = proto_item_add_subtree(arq_feedback_item, ett_mac_mgmt_msg_arq_decoder);
364 /* display the Message Type */
365 proto_tree_add_item(arq_feedback_tree, hf_arq_message_type, tvb, offset, 1, ENC_BIG_ENDIAN);
368 while(offset < tvb_len && !arq_last)
370 arq_feedback_ie_count++;
371 arq_cid = tvb_get_ntohs(tvb, offset);
372 arq_last = ((tvb_get_guint8(tvb, offset + 2) & 0x80) != 0);
373 arq_ack_type = (tvb_get_guint8(tvb, offset + 2) & 0x60) >> 5;
374 arq_bsn = (tvb_get_ntohs(tvb, offset + 2) & 0x1FFC) >> 2;
375 arq_num_ack_maps = 1 + (tvb_get_guint8(tvb, offset + 3) & 0x03);
377 arq_fb_item = proto_tree_add_protocol_format(arq_feedback_tree, proto_mac_mgmt_msg_arq_feedback_decoder, tvb, offset, tvb_len, "ARQ_Feedback_IE");
378 proto_item_append_text(arq_fb_item, ", CID: %u, %s ARQ feedback IE, %s, BSN: %u",
379 arq_cid, arq_last ? "Last" : "More", val_to_str(arq_ack_type, vals_arq_ack_type, ""), arq_bsn);
380 if (arq_ack_type != ARQ_CUMULATIVE_ACK_ENTRY) {
381 proto_item_append_text(arq_fb_item, ", %u ACK Map(s)", arq_num_ack_maps);
383 /* add ARQ Feedback IE subtree */
384 arq_fb_tree = proto_item_add_subtree(arq_fb_item, ett_mac_mgmt_msg_arq_decoder);
385 proto_tree_add_item(arq_fb_tree, hf_arq_cid, tvb, offset, 2, ENC_BIG_ENDIAN);
386 proto_tree_add_item(arq_fb_tree, hf_arq_last, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
387 proto_tree_add_item(arq_fb_tree, hf_arq_ack_type, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
388 proto_tree_add_item(arq_fb_tree, hf_arq_bsn, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
389 if (arq_ack_type != ARQ_CUMULATIVE_ACK_ENTRY) {
390 ti = proto_tree_add_item(arq_fb_tree, hf_arq_num_ack_maps, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
391 proto_item_append_text(ti, " (%d map(s))", arq_num_ack_maps);
394 for (i = 0; i < arq_num_ack_maps; i++) {
395 /* Each ACK Map is 16 bits. */
397 if (arq_ack_type != 3) {
398 proto_tree_add_item(arq_fb_tree, hf_arq_selective_map, tvb, offset, 2, ENC_BIG_ENDIAN);
400 proto_tree_add_item(arq_fb_tree, hf_arq_seq_format, tvb, offset, 1, ENC_BIG_ENDIAN);
401 seq_format = (tvb_get_guint8(tvb, offset) & 0x80) >> 7;
402 if (seq_format == 0) {
403 proto_tree_add_item(arq_fb_tree, hf_arq_0seq_ack_map, tvb, offset, 1, ENC_BIG_ENDIAN);
404 proto_tree_add_item(arq_fb_tree, hf_arq_0seq1_len, tvb, offset, 2, ENC_BIG_ENDIAN);
405 proto_tree_add_item(arq_fb_tree, hf_arq_0seq2_len, tvb, offset, 2, ENC_BIG_ENDIAN);
406 proto_tree_add_item(arq_fb_tree, hf_arq_reserved, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
408 proto_tree_add_item(arq_fb_tree, hf_arq_1seq_ack_map, tvb, offset, 1, ENC_BIG_ENDIAN);
409 proto_tree_add_item(arq_fb_tree, hf_arq_1seq1_len, tvb, offset, 1, ENC_BIG_ENDIAN);
410 proto_tree_add_item(arq_fb_tree, hf_arq_1seq2_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
411 proto_tree_add_item(arq_fb_tree, hf_arq_1seq3_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
416 /* Number of ACK Maps bits are reserved when ACK TYPE == 1 */
417 proto_tree_add_item(arq_fb_tree, hf_ack_type_reserved, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
418 /* update the offset */
421 /* update the offset */
424 proto_item_append_text(arq_feedback_item, ", %u ARQ_feedback_IE(s)", arq_feedback_ie_count);
428 /* Decode ARQ-Discard messages. */
429 void dissect_mac_mgmt_msg_arq_discard_decoder(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
431 guint tvb_len, payload_type;
432 proto_item *arq_discard_item = NULL;
433 proto_tree *arq_discard_tree = NULL;
435 /* Ensure the right payload type */
436 payload_type = tvb_get_guint8(tvb, 0);
437 if(payload_type != MAC_MGMT_MSG_ARQ_DISCARD)
443 { /* we are being asked for details */
445 /* Get the tvb reported length */
446 tvb_len = tvb_reported_length(tvb);
447 /* display MAC payload type ARQ-Discard */
448 arq_discard_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_arq_discard_decoder, tvb, 0, tvb_len, "MAC Management Message, ARQ-Discard (34)");
449 /* add MAC ARQ Discard subtree */
450 arq_discard_tree = proto_item_add_subtree(arq_discard_item, ett_mac_mgmt_msg_arq_decoder);
451 /* display the Message Type */
452 proto_tree_add_item(arq_discard_tree, hf_arq_message_type, tvb, 0, 1, ENC_BIG_ENDIAN);
454 proto_tree_add_item(arq_discard_tree, hf_arq_discard_cid, tvb, 1, 2, ENC_BIG_ENDIAN);
455 proto_tree_add_item(arq_discard_tree, hf_arq_discard_reserved, tvb, 3, 1, ENC_BIG_ENDIAN);
456 proto_tree_add_item(arq_discard_tree, hf_arq_discard_bsn, tvb, 3, 2, ENC_BIG_ENDIAN);
460 /* Decode ARQ-Reset messages. */
461 void dissect_mac_mgmt_msg_arq_reset_decoder(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
463 guint tvb_len, payload_type;
464 proto_item *arq_reset_item = NULL;
465 proto_tree *arq_reset_tree = NULL;
467 /* Ensure the right payload type */
468 payload_type = tvb_get_guint8(tvb, 0);
469 if(payload_type != MAC_MGMT_MSG_ARQ_RESET)
475 { /* we are being asked for details */
477 /* Get the tvb reported length */
478 tvb_len = tvb_reported_length(tvb);
479 /* display MAC payload type ARQ-Reset */
480 arq_reset_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_arq_reset_decoder, tvb, 0, tvb_len, "MAC Management Message, ARQ-Reset (35)");
481 /* add MAC ARQ Reset subtree */
482 arq_reset_tree = proto_item_add_subtree(arq_reset_item, ett_mac_mgmt_msg_arq_decoder);
483 /* display the Message Type */
484 proto_tree_add_item(arq_reset_tree, hf_arq_message_type, tvb, 0, 1, ENC_BIG_ENDIAN);
486 proto_tree_add_item(arq_reset_tree, hf_arq_reset_cid, tvb, 1, 2, ENC_BIG_ENDIAN);
487 proto_tree_add_item(arq_reset_tree, hf_arq_reset_type, tvb, 3, 1, ENC_BIG_ENDIAN);
488 proto_tree_add_item(arq_reset_tree, hf_arq_reset_direction, tvb, 3, 1, ENC_BIG_ENDIAN);
489 proto_tree_add_item(arq_reset_tree, hf_arq_reset_reserved, tvb, 3, 1, ENC_BIG_ENDIAN);