1. Remove PITEM_FINFO from add_tlv_subtree and add_protocol_subtree (as well as some...
[metze/wireshark/wip.git] / plugins / wimax / mac_hd_generic_decoder.c
1 /* mac_hd_generic_decoder.c
2  * WiMax Generic MAC Header decoder
3  *
4  * Copyright (c) 2007 by Intel Corporation.
5  *
6  * Author: Lu Pan <lu.pan@intel.com>
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1999 Gerald Combs
13  *
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.
18  *
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.
23  *
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.
27  */
28
29 /* TODO:  Add FT_UINT24 and FT_INT24 cases to gtk_widget_get_toplevel()
30  * to prevent having to make all the changes from BASE_DEC to BASE_HEX
31  * made to this file today: 10/20/06.
32  */
33
34 /* Include files */
35
36 #include "config.h"
37
38 /*
39 #define DEBUG
40 */
41
42 #include <string.h>
43 #include <glib.h>
44 #include <epan/packet.h>
45 #include <epan/expert.h>
46 #include <epan/address.h>
47 #include <epan/reassemble.h>
48 #include "crc.h"
49 #include "wimax_utils.h"
50
51 extern gint proto_wimax;
52
53 extern gint seen_a_service_type;
54 extern gboolean first_gmh;                      /* defined in wimax_pdu_decoder.c */
55
56 extern gint8 arq_enabled;                       /* declared in packet-wmx.c */
57 extern gint  scheduling_service_type;           /* declared in packet-wmx.c */
58 extern gint  mac_sdu_length;                    /* declared in packet-wmx.c */
59
60 extern address bs_address;                      /* declared in packet-wmx.c */
61 extern guint max_logical_bands;                 /* declared in wimax_compact_dlmap_ie_decoder.c */
62 extern gboolean is_down_link(packet_info *pinfo);/* declared in packet-wmx.c */
63 extern void init_wimax_globals(void);           /* defined in msg_ulmap.c */
64
65 static dissector_handle_t mac_mgmt_msg_decoder_handle = NULL;
66 static dissector_handle_t mac_ip_handle = NULL;
67
68 /* global variables */
69 gboolean include_cor2_changes = FALSE;
70
71 /* Well-known CIDs */
72 guint cid_initial_ranging  = 0x0000;
73 guint global_cid_max_basic = 320;
74 guint cid_max_primary      = 640;
75 guint cid_aas_ranging      = 0xFeFF;
76 guint cid_normal_multicast = 0xFFFa;
77 guint cid_sleep_multicast  = 0xFFFb;
78 guint cid_idle_multicast   = 0xFFFc;
79 guint cid_frag_broadcast   = 0xFFFd;
80 guint cid_padding          = 0xFFFe;
81 guint cid_broadcast        = 0xFFFF;
82
83 /* Maximum number of CID's */
84 #define MAX_CID 64
85
86 /* forward reference */
87 static gint extended_subheader_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
88 static gint arq_feedback_payload_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *parent_item);
89
90 /* Static variables */
91 static reassembly_table payload_reassembly_table;
92
93 gint proto_mac_header_generic_decoder = -1;
94 static gint ett_mac_header_generic_decoder = -1;
95 /* static gint ett_mac_subheader_decoder = -1; */
96 static gint ett_mac_mesh_subheader_decoder = -1;
97 static gint ett_mac_frag_subheader_decoder = -1;
98 static gint ett_mac_grant_mgmt_subheader_decoder = -1;
99 static gint ett_mac_pkt_subheader_decoder = -1;
100 static gint ett_mac_fast_fb_subheader_decoder = -1;
101 static gint ett_mac_ext_subheader_decoder = -1;
102 static gint ett_mac_ext_subheader_dl_decoder = -1;
103 static gint ett_mac_ext_subheader_ul_decoder = -1;
104 static gint ett_mac_arq_fb_payload_decoder = -1;
105 static gint ett_mac_data_pdu_decoder = -1;
106 static gint hf_mac_header_generic_value_bytes = -1;
107
108 static guint frag_type, frag_len;
109 static guint extended_type, arq_fb_payload, seq_number;
110
111 static guint cid_adjust[MAX_CID];  /* Must not start with 0 */
112 static guint cid_vernier[MAX_CID];
113 static guint cid_adj_array_size = 0;
114 static guint *cid_adj_array = NULL;
115 static guint8 *frag_num_array = NULL;
116
117 static address save_src;
118 static address save_dst;
119
120 #define WIMAX_MAC_HEADER_SIZE      6
121 #define IP_HEADER_BYTE 0x45
122
123 #define EXTENDED_SUB_HEADER_RSV_MASK   0x80
124 #define EXTENDED_SUB_HEADER_TYPE_MASK  0x7F
125
126 /* WIMAX GENERIC MAC HEADER FIELDS (figure 19) */
127 /* 1st to 3rd bytes */
128 #define WIMAX_MAC_HEADER_GENERIC_HT           0x800000
129 #define WIMAX_MAC_HEADER_GENERIC_EC           0x400000
130 #define WIMAX_MAC_HEADER_GENERIC_TYPE_5       0x200000
131 #define WIMAX_MAC_HEADER_GENERIC_TYPE_4       0x100000
132 #define WIMAX_MAC_HEADER_GENERIC_TYPE_3       0x080000
133 #define WIMAX_MAC_HEADER_GENERIC_TYPE_2       0x040000
134 #define WIMAX_MAC_HEADER_GENERIC_TYPE_1       0x020000
135 #define WIMAX_MAC_HEADER_GENERIC_TYPE_0       0x010000
136 #define WIMAX_MAC_HEADER_GENERIC_ESF          0x008000
137 #define WIMAX_MAC_HEADER_GENERIC_CI           0x004000
138 #define WIMAX_MAC_HEADER_GENERIC_EKS          0x003000
139 #define WIMAX_MAC_HEADER_GENERIC_RSV          0x000800
140 #define WIMAX_MAC_HEADER_GENERIC_LEN          0x0007FF
141
142 /* WIMAX GENERIC MAC HEADER 1st byte masks */
143 #define WIMAX_MAC_HEADER_GENERIC_HT_MASK     0x80
144 #define WIMAX_MAC_HEADER_GENERIC_EC_MASK     0x40
145 #define WIMAX_MAC_HEADER_GENERIC_TYPE_MASK   0x3F
146 /* WiMax Generic MAC Header Sub Type Masks */
147 #define GENERIC_SUB_TYPE_0         0x01
148 #define GENERIC_SUB_TYPE_1         0x02
149 #define GENERIC_SUB_TYPE_2         0x04
150 #define GENERIC_SUB_TYPE_3         0x08
151 #define GENERIC_SUB_TYPE_4         0x10
152 #define GENERIC_SUB_TYPE_5         0x20
153
154 /* WIMAX GENERIC MAC HEADER 2nd byte masks */
155 #define WIMAX_MAC_HEADER_GENERIC_ESF_MASK    0x80
156 #define WIMAX_MAC_HEADER_GENERIC_CI_MASK     0x40
157 #define WIMAX_MAC_HEADER_GENERIC_EKS_MASK    0x30
158 #define WIMAX_MAC_HEADER_GENERIC_LEN_MASK    0x07
159
160 static int hf_mac_header_generic_ht = -1;
161 static int hf_mac_header_generic_ec = -1;
162 static int hf_mac_header_generic_type_0 = -1;
163 static int hf_mac_header_generic_type_1 = -1;
164 static int hf_mac_header_generic_type_2 = -1;
165 static int hf_mac_header_generic_type_3 = -1;
166 static int hf_mac_header_generic_type_4 = -1;
167 static int hf_mac_header_generic_type_5 = -1;
168 static int hf_mac_header_generic_esf = -1;
169 static int hf_mac_header_generic_ci = -1;
170 static int hf_mac_header_generic_eks = -1;
171 static int hf_mac_header_generic_rsv = -1;
172 static int hf_mac_header_generic_len = -1;
173 static int hf_mac_header_generic_cid = -1;
174 static int hf_mac_header_generic_hcs = -1;
175 static int hf_mac_header_generic_crc = -1;
176
177 /* MAC Header types */
178 static const value_string ht_msgs[] =
179 {
180         { 0, "Generic" },
181         { 1, "Signaling" },
182         { 0,  NULL}
183 };
184
185 /* Encryption Controls */
186 static const value_string ec_msgs[] =
187 {
188         { 0, "Not encrypted" },
189         { 1, "Encrypted" },
190         { 0,  NULL}
191 };
192
193 /* ESF messages */
194 static const value_string esf_msgs[] =
195 {
196         { 0, "Extended subheader is absent" },
197         { 1, "Extended subheader is present" },
198         { 0,  NULL}
199 };
200
201 /* CRC Indicator messages */
202 static const value_string ci_msgs[] =
203 {
204         { 0, "No CRC is included" },
205         { 1, "CRC is included" },
206         { 0,  NULL}
207 };
208
209 /* Sub-Type message 0 */
210 static const value_string type_msg0[] =
211 {
212         { 0, "Fast-feedback allocation subheader(DL)/Grant management subheader(UL) is absent" },
213         { 1, "Fast-feedback allocation subheader(DL)/Grant management subheader(UL) is present" },
214         { 0,  NULL}
215 };
216
217 /* Sub-Type message 1 */
218 static const value_string type_msg1[] =
219 {
220         { 0, "Packing subheader is absent" },
221         { 1, "Packing Subheader is present" },
222         { 0,  NULL}
223 };
224
225 /* Sub-Type message 2 */
226 static const value_string type_msg2[] =
227 {
228         { 0, "Fragmentation subheader is absent" },
229         { 1, "Fragmentation subheader is present" },
230         { 0,  NULL}
231 };
232
233 /* Sub-Type message 3 */
234 static const value_string type_msg3[] =
235 {
236         { 0, "The subheader is not extended" },
237         { 1, "The subheader is extended" },
238         { 0,  NULL}
239 };
240
241 /* Sub-Type message 4 */
242 static const value_string type_msg4[] =
243 {
244         { 0, "ARQ feedback payload is absent" },
245         { 1, "ARQ feedback payload is present" },
246         { 0,  NULL}
247 };
248
249 /* Sub-Type message 5 */
250 static const value_string type_msg5[] =
251 {
252         { 0, "Mesh subheader is absent" },
253         { 1, "Mesh subheader is present" },
254         { 0,  NULL}
255 };
256
257 /* Fast-Feedback Feedback Types */
258 static const value_string fast_fb_types[] =
259 {
260         { 0, "Fast DL measurement" },
261         { 1, "Fast MIMO Feedback, Antenna #0" },
262         { 2, "Fast MIMO Feedback, Antenna #1" },
263         { 3, "MIMO Mode and Permutation Mode Feedback" },
264         { 0,  NULL}
265 };
266
267 /* Extended sub-headers */
268 /* DL sub-header types */
269 typedef enum
270 {
271 SDU_SN,
272 DL_SLEEP_CONTROL,
273 FEEDBACK_REQ,
274 SN_REQ,
275 PDU_SN_SHORT_DL,
276 PDU_SN_LONG_DL
277 } DL_EXT_SUBHEADER_e;
278
279 static const value_string dl_ext_sub_header_type[] =
280 {
281         {0, "SDU_SN"},
282         {1, "DL Sleep Control"},
283         {2, "Feedback Request"},
284         {3, "SN Request"},
285         {4, "PDU SN (short)"},
286         {5, "PDU SN (long)"},
287         {0,  NULL}
288 };
289
290 /* DL Sleep Control Extended Subheader field masks (table 13e) */
291 #define DL_SLEEP_CONTROL_POWER_SAVING_CLASS_ID_MASK       0xFC0000      /*0x00003F*/
292 #define DL_SLEEP_CONTROL_OPERATION_MASK                   0x020000      /*0x000040*/
293 #define DL_SLEEP_CONTROL_FINAL_SLEEP_WINDOW_EXPONENT_MASK 0x01C000      /*0x000380*/
294 #define DL_SLEEP_CONTROL_FINAL_SLEEP_WINDOW_BASE_MASK     0x003FF0      /*0x0FFC00*/
295 #define DL_SLEEP_CONTROL_RESERVED_MASK                    0x00000F      /*0xF00000*/
296
297 /* Feedback Request Extended Subheader field masks (table 13f) */
298 #define FEEDBACK_REQUEST_UIUC_MASK                        0xF00000      /*0x00000F*/
299 #define FEEDBACK_REQUEST_FEEDBACK_TYPE_MASK               0x0F0000      /*0x0000F0*/
300 #define FEEDBACK_REQUEST_OFDMA_SYMBOL_OFFSET_MASK         0x00FC00      /*0x003F00*/
301 #define FEEDBACK_REQUEST_SUBCHANNEL_OFFSET_MASK           0x0003F0      /*0x0FC000*/
302 #define FEEDBACK_REQUEST_NUMBER_OF_SLOTS_MASK             0x00000E      /*0x700000*/
303 #define FEEDBACK_REQUEST_FRAME_OFFSET_MASK                0x000001      /*0x800000*/
304
305 /* OFDMA UIUC Values ??? */
306 static const value_string uiuc_values[] =
307 {
308         { 0, "Fast-Feedback Channel" },
309         { 1, "Burst Profile 1" },
310         { 2, "Burst Profile 2" },
311         { 3, "Burst Profile 3" },
312         { 4, "Burst Profile 4" },
313         { 5, "Burst Profile 5" },
314         { 6, "Burst Profile 6" },
315         { 7, "Burst Profile 7" },
316         { 8, "Burst Profile 8" },
317         { 9, "Burst Profile 9" },
318         { 10, "Burst Profile 10" },
319         { 11, "Extended UIUC 2 IE" },
320         { 12, "CDMA Bandwidth Request, CDMA Ranging" },
321         { 13, "PAPR Reduction Allocation, Safety Zone" },
322         { 14, "CDMA Allocation IE" },
323         { 15, "Extended UIUC" },
324         { 0,  NULL}
325 };
326
327 /* UL sub-header types */
328 typedef enum
329 {
330 MIMO_MODE_FEEDBACK,
331 UL_TX_POWER_REPORT,
332 MINI_FEEDBACK,
333 PDU_SN_SHORT_UL,
334 PDU_SN_LONG_UL
335 } UL_EXT_SUBHEADER_e;
336
337 static const value_string ul_ext_sub_header_type[] =
338 {
339         {0, "MIMO Mode Feedback"},
340         {1, "UL TX Power Report"},
341         {2, "Mini-feedback"},
342         {3, "PDU SN (short)"},
343         {4, "PDU SN (long)"},
344         {0,  NULL}
345 };
346
347 /* MIMO Mode Feedback Extended Subheader field masks (table 13g) */
348 #define MIMO_FEEDBACK_TYPE_MASK                  0xC0   /*0x03*/
349 #define MIMO_FEEDBACK_CONTENT_MASK               0x3F   /*0xFC*/
350 /* Mimo Feedback Types ??? */
351 static const value_string mimo_fb_types[] =
352 {
353         { 0, "Fast DL measurement" },
354         { 1, "Default Feedback with Antenna Grouping" },
355         { 2, "Antenna Selection and Reduced Codebook" },
356         { 3, "Quantized Precoding Weight Feedback" },
357         { 0,  NULL}
358 };
359
360 /* MNI-Feedback Extended Subheader field masks (table 13i) */
361 #define MINI_FEEDBACK_TYPE_MASK                  0xF000 /*0x000F*/
362 #define MINI_FEEDBACK_CONTENT_MASK               0x0FFF /*0xFFF0*/
363 /* Feedback Types */
364 static const value_string fb_types[] =
365 {
366         { 0, "CQI and MIMO Feedback" },
367         { 1, "DL average CINR" },
368         { 2, "MIMO Coefficients Feedback" },
369         { 3, "Preferred DL Channel DIUC Feedback" },
370         { 4, "UL Transmission Power" },
371         { 5, "PHY Channel Feedback" },
372         { 6, "AMC Band Indication Bitmap" },
373         { 7, "Life Span of Short-term Precoding Feedback" },
374         { 8, "Multiple Types of Feedback" },
375         { 9, "Long-term Precoding Feedback" },
376         { 10, "Combined DL Average CINR of Active BSs" },
377         { 11, "MIMO Channel Feedback" },
378         { 12, "CINR Feedback" },
379         { 13, "Close-loop MIMO Feedback" },
380         { 14, "Reserved" },
381         { 15, "Reserved" },
382         { 0,  NULL}
383 };
384
385 /* common fields */
386 static gint hf_mac_header_generic_ext_subheader_rsv = -1;
387 /* DL sub-header */
388 static gint hf_mac_header_generic_ext_subheader_type_dl = -1;
389 static gint hf_mac_header_generic_ext_subheader_sdu_sn = -1;
390 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_pscid = -1;
391 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_op = -1;
392 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_fswe = -1;
393 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_fswb = -1;
394 static gint hf_mac_header_generic_ext_subheader_dl_sleep_control_rsv = -1;
395 static gint hf_mac_header_generic_ext_subheader_fb_req_uiuc = -1;
396 static gint hf_mac_header_generic_ext_subheader_fb_req_fb_type = -1;
397 static gint hf_mac_header_generic_ext_subheader_fb_req_ofdma_symbol_offset = -1;
398 static gint hf_mac_header_generic_ext_subheader_fb_req_subchannel_offset = -1;
399 static gint hf_mac_header_generic_ext_subheader_fb_req_slots = -1;
400 static gint hf_mac_header_generic_ext_subheader_fb_req_frame_offset = -1;
401
402 /* DL Sleep Control Operations */
403 static const value_string dl_sleep_control_ops[] =
404 {
405         { 0, "De-activate Power Saving Class" },
406         { 1, "Activate Power Saving Class" },
407         { 0,  NULL}
408 };
409
410 /* UL sub-header */
411 static gint hf_mac_header_generic_ext_subheader_type_ul = -1;
412 static gint hf_mac_header_generic_ext_subheader_mimo_mode_fb_type = -1;
413 static gint hf_mac_header_generic_ext_subheader_mimo_fb_content = -1;
414 static gint hf_mac_header_generic_ext_subheader_ul_tx_pwr_rep = -1;
415 static gint hf_mac_header_generic_ext_subheader_mini_fb_type = -1;
416 static gint hf_mac_header_generic_ext_subheader_mini_fb_content = -1;
417 /* common fields */
418 static gint hf_mac_header_generic_ext_subheader_pdu_sn_short = -1;
419 static gint hf_mac_header_generic_ext_subheader_pdu_sn_long = -1;
420
421 /* SN Request subheader */
422 #define SN_REQUEST_SUBHEADER_SN_REPORT_INDICATION_1_MASK 0x01
423 #define SN_REQUEST_SUBHEADER_SN_REPORT_INDICATION_2_MASK 0x02
424 #define SN_REQUEST_SUBHEADER_RESERVED_MASK               0xFC
425
426 static gint hf_mac_header_generic_ext_subheader_sn_req_rep_ind_1 = -1;
427 static gint hf_mac_header_generic_ext_subheader_sn_req_rep_ind_2 = -1;
428 static gint hf_mac_header_generic_ext_subheader_sn_req_rsv = -1;
429 /* SN Report Indication message */
430 static const value_string sn_rep_msg[] =
431 {
432         { 0, "" },
433         { 1, "request transmission" },
434         { 0,  NULL}
435 };
436
437 /* Mesh Subheader */
438 static gint hf_mac_header_generic_mesh_subheader = -1;
439
440 /* Fragmentation Subheader (table 8) */
441 #define FRAGMENTATION_SUBHEADER_FC_MASK         0xC000  /*0x0003*/
442 #define FRAGMENTATION_SUBHEADER_BSN_MASK        0x3FF8  /*0x1FFC*/
443 #define FRAGMENTATION_SUBHEADER_RSV_EXT_MASK    0x0007  /*0xE000*/
444 #define FRAGMENTATION_SUBHEADER_FSN_MASK        0x38    /*0x1C*/
445 #define FRAGMENTATION_SUBHEADER_RSV_MASK        0x07    /*0xE0*/
446 #define FRAGMENT_TYPE_MASK  0xC0
447 #define SEQ_NUMBER_MASK     0x38
448 #define SEQ_NUMBER_MASK_11  0x3FF8
449
450 #define NO_FRAG     0
451 #define LAST_FRAG   1
452 #define FIRST_FRAG  2
453 #define MIDDLE_FRAG 3
454
455 static gint hf_mac_header_generic_frag_subhd_fc = -1;
456 static gint hf_mac_header_generic_frag_subhd_fc_ext = -1;
457 static gint hf_mac_header_generic_frag_subhd_bsn = -1;
458 static gint hf_mac_header_generic_frag_subhd_fsn = -1;
459 static gint hf_mac_header_generic_frag_subhd_fsn_ext = -1;
460 static gint hf_mac_header_generic_frag_subhd_rsv = -1;
461 static gint hf_mac_header_generic_frag_subhd_rsv_ext = -1;
462
463 /* Fragment Types */
464 static const value_string frag_types[] =
465 {
466         { 0, "No fragmentation" },
467         { 1, "Last fragment" },
468         { 2, "First fragment" },
469         { 3, "Continuing (middle) fragment" },
470         { 0,  NULL}
471 };
472
473 /* Packing Subheader (table 11) */
474 #define PACKING_SUBHEADER_FC_MASK           0xC00000
475 #define PACKING_SUBHEADER_BSN_MASK          0x3FF800
476 #define PACKING_SUBHEADER_FSN_MASK          0x38
477 #define PACKING_SUBHEADER_LENGTH_MASK       0x07FF
478 #define PACKING_SUBHEADER_LENGTH_EXT_MASK   0x0007FF
479
480 #define FRAG_LENGTH_MASK    0x0007FF00
481
482 static gint hf_mac_header_generic_packing_subhd_fc = -1;
483 static gint hf_mac_header_generic_packing_subhd_fc_ext = -1;
484 static gint hf_mac_header_generic_packing_subhd_bsn = -1;
485 static gint hf_mac_header_generic_packing_subhd_fsn = -1;
486 static gint hf_mac_header_generic_packing_subhd_fsn_ext = -1;
487 static gint hf_mac_header_generic_packing_subhd_len = -1;
488 static gint hf_mac_header_generic_packing_subhd_len_ext = -1;
489
490 /* Fast-feedback Allocation Subheader (table 13) */
491 #define FAST_FEEDBACK_ALLOCATION_OFFSET_MASK 0xFC       /*0x3F*/
492 #define FAST_FEEDBACK_FEEDBACK_TYPE_MASK     0x03       /*0xC0*/
493
494 static gint hf_mac_header_generic_fast_fb_subhd_alloc_offset = -1;
495 static gint hf_mac_header_generic_fast_fb_subhd_fb_type = -1;
496
497 /* Grant Management Subheader (table 9 & 10) */
498 #define GRANT_MGMT_SUBHEADER_UGS_SI_MASK          0x8000        /*0x0001*/
499 #define GRANT_MGMT_SUBHEADER_UGS_PM_MASK          0x4000        /*0x0002*/
500 #define GRANT_MGMT_SUBHEADER_UGS_FLI_MASK         0x2000        /*0x0004*/
501 #define GRANT_MGMT_SUBHEADER_UGS_FL_MASK          0x1E00        /*0x0078*/
502 #define GRANT_MGMT_SUBHEADER_UGS_RSV_MASK         0x01FF        /*0xFF80*/
503 #define GRANT_MGMT_SUBHEADER_EXT_PBR_MASK         0xFFE0        /*0x07FF*/
504 #define GRANT_MGMT_SUBHEADER_EXT_FLI_MASK         0x0010        /*0x0800*/
505 #define GRANT_MGMT_SUBHEADER_EXT_FL_MASK          0x000F        /*0xF000*/
506
507 typedef enum
508 {
509         SCHEDULE_SERVICE_TYPE_RSVD,
510         SCHEDULE_SERVICE_TYPE_UNDEFINED,
511         SCHEDULE_SERVICE_TYPE_BE,
512         SCHEDULE_SERVICE_TYPE_NRTPS,
513         SCHEDULE_SERVICE_TYPE_RTPS,
514         SCHEDULE_SERVICE_TYPE_EXT_RTPS,
515         SCHEDULE_SERVICE_TYPE_UGS
516 } SCHEDULE_SERVICE_TYPE_e;
517
518 static gint hf_mac_header_generic_grant_mgmt_ugs_tree           = -1;
519 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_si       = -1;
520 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_pm       = -1;
521 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_fli      = -1;
522 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_fl       = -1;
523 static gint hf_mac_header_generic_grant_mgmt_subhd_ugs_rsv      = -1;
524 static gint hf_mac_header_generic_grant_mgmt_ext_rtps_tree      = -1;
525 static gint hf_mac_header_generic_grant_mgmt_subhd_ext_pbr      = -1;
526 static gint hf_mac_header_generic_grant_mgmt_subhd_ext_fli      = -1;
527 static gint hf_mac_header_generic_grant_mgmt_subhd_ext_fl       = -1;
528 static gint hf_mac_header_generic_grant_mgmt_ext_pbr_tree       = -1;
529 static gint hf_mac_header_generic_grant_mgmt_subhd_pbr          = -1;
530
531 /* Slip Indicators */
532 static const value_string si_msgs[] =
533 {
534         { 0, "No action" },
535         { 1, "A slip of UL grants relative to the UL queue depth" },
536         { 0,  NULL}
537 };
538
539 /* Poll-Me Messages */
540 static const value_string pm_msgs[] =
541 {
542         { 0, "No action" },
543         { 1, "Request a bandwidth poll" },
544         { 0,  NULL}
545 };
546
547 /* Frame Latency Indications */
548 static const value_string fli_msgs[] =
549 {
550         { 0, "Frame latency field disabled" },
551         { 1, "Frame latency field enabled" },
552         { 0,  NULL}
553 };
554
555 /* ARQ Feedback Payload */
556
557 /* ARQ Feedback IE bit masks (table 111) */
558 #define ARQ_FB_IE_LAST_BIT_MASK      0x8000     /*0x0001*/
559 #define ARQ_FB_IE_ACK_TYPE_MASK      0x6000     /*0x0006*/
560 #define ARQ_FB_IE_BSN_MASK           0x1FFC     /*0x3FF8*/
561 #define ARQ_FB_IE_NUM_MAPS_MASK      0x0003     /*0xC000*/
562 #define ARQ_FB_IE_SEQ_FORMAT_MASK    0x8000     /*0x0001*/
563 #define ARQ_FB_IE_SEQ_ACK_MAP_MASK   0x7000     /*0x000E*/
564 #define ARQ_FB_IE_SEQ1_LENGTH_MASK   0x0F00     /*0x00F0*/
565 #define ARQ_FB_IE_SEQ2_LENGTH_MASK   0x00F0     /*0x0F00*/
566 #define ARQ_FB_IE_SEQ3_LENGTH_MASK   0x000F     /*0xF000*/
567 #define ARQ_FB_IE_SEQ_ACK_MAP_2_MASK 0x6000     /*0x0006*/
568 #define ARQ_FB_IE_SEQ1_LENGTH_6_MASK 0x1F80     /*0x01F8*/
569 #define ARQ_FB_IE_SEQ2_LENGTH_6_MASK 0x007E     /*0x7E00*/
570 #define ARQ_FB_IE_RSV_MASK           0x0001     /*0x8000*/
571
572 static gint hf_mac_header_generic_arq_fb_ie_cid = -1;
573 static gint hf_mac_header_generic_arq_fb_ie_last = -1;
574 static gint hf_mac_header_generic_arq_fb_ie_ack_type = -1;
575 static gint hf_mac_header_generic_arq_fb_ie_bsn = -1;
576 static gint hf_mac_header_generic_arq_fb_ie_num_maps = -1;
577 static gint hf_ack_type_reserved = -1;
578 static gint hf_mac_header_generic_arq_fb_ie_sel_ack_map = -1;
579 static gint hf_mac_header_generic_arq_fb_ie_seq_format = -1;
580 static gint hf_mac_header_generic_arq_fb_ie_seq_ack_map = -1;
581 static gint hf_mac_header_generic_arq_fb_ie_seq1_length = -1;
582 static gint hf_mac_header_generic_arq_fb_ie_seq2_length = -1;
583 static gint hf_mac_header_generic_arq_fb_ie_seq3_length = -1;
584 static gint hf_mac_header_generic_arq_fb_ie_seq_ack_map_2 = -1;
585 static gint hf_mac_header_generic_arq_fb_ie_seq1_length_6 = -1;
586 static gint hf_mac_header_generic_arq_fb_ie_seq2_length_6 = -1;
587 static gint hf_mac_header_generic_arq_fb_ie_rsv = -1;
588
589 static expert_field ei_mac_crc_malformed = EI_INIT;
590 static expert_field ei_mac_crc_missing = EI_INIT;
591
592 /* Last IE Indicators */
593 static const value_string last_ie_msgs[] =
594 {
595         { 0, "No" },
596         { 1, "Yes" },
597         { 0,  NULL}
598 };
599
600 /* Register Wimax defrag table init routine. */
601 void wimax_defragment_init(void)
602 {
603         gint i;
604
605         reassembly_table_init(&payload_reassembly_table,
606             &addresses_reassembly_table_functions);
607
608         /* Init fragmentation variables. */
609         for (i = 0; i < MAX_CID; i++)
610         {
611                 cid_adjust[i] = 1;      /* Must not start with 0 */
612                 cid_vernier[i] = 0;
613         }
614         cid_adj_array_size = 0;
615         /* Free the array memory. */
616         if (cid_adj_array) {
617                 g_free(cid_adj_array);
618         }
619         cid_adj_array = NULL;
620         if (frag_num_array) {
621                 g_free(frag_num_array);
622         }
623         frag_num_array = NULL;
624
625         /* Initialize to make sure bs_address gets set in FCH decoder. */
626         bs_address.len = 0;
627
628         /* Initialize the Scheduling Service Type flag */
629         seen_a_service_type = 0;
630
631         max_logical_bands = 12;
632
633         /* Initialize UL_MAP globals. */
634         init_wimax_globals();
635 }
636
637 static guint decode_packing_subheader(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree, guint payload_length _U_, guint payload_offset, proto_item *parent_item)
638 {
639         proto_item *generic_item = NULL;
640         proto_tree *generic_tree = NULL;
641         guint starting_offset = payload_offset;
642
643         /* update the info column */
644         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Packing subhdr");
645         /* add the Packing subheader info */
646         proto_item_append_text(parent_item, ", Packing Subheader");
647         /* display Packing subheader type */
648         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, payload_tvb, payload_offset, ((arq_enabled|extended_type)?3:2), "Packing subheader (%u bytes)", ((arq_enabled|extended_type)?3:2));
649         /* add Packing subheader subtree */
650         generic_tree = proto_item_add_subtree(generic_item, ett_mac_pkt_subheader_decoder);
651         /* decode and display the Packing subheader */
652         /* Get the fragment type */
653         frag_type = (tvb_get_guint8(payload_tvb, payload_offset) & FRAGMENT_TYPE_MASK) >> 6;
654         /* if ARQ Feedback payload is present */
655         if (arq_fb_payload)
656         {       /* get the frag length */
657                 frag_len = ((tvb_get_ntohl(payload_tvb, payload_offset) & FRAG_LENGTH_MASK) >> 8);
658                 /* get the sequence number */
659                 seq_number = (tvb_get_ntohs(payload_tvb, payload_offset) & SEQ_NUMBER_MASK_11) >> 3;
660                 proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fc_ext, payload_tvb, payload_offset, 3, ENC_BIG_ENDIAN);
661                 proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_bsn, payload_tvb, payload_offset, 3, ENC_BIG_ENDIAN);
662                 proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_len_ext, payload_tvb, payload_offset, 3, ENC_BIG_ENDIAN);
663                 /* update the length and offset */
664                 payload_offset += 3;
665                 frag_len -= 3;
666         }
667         else
668         {
669                 if (extended_type)
670                 {       /* get the frag length */
671                         frag_len = ((tvb_get_ntohl(payload_tvb, payload_offset) & FRAG_LENGTH_MASK) >> 8);
672                         /* get the sequence number */
673                         seq_number = (tvb_get_ntohs(payload_tvb, payload_offset) & SEQ_NUMBER_MASK_11) >> 3;
674                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fc_ext, payload_tvb, payload_offset, 3, ENC_BIG_ENDIAN);
675                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fsn_ext, payload_tvb, payload_offset, 3, ENC_BIG_ENDIAN);
676                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_len_ext, payload_tvb, payload_offset, 3, ENC_BIG_ENDIAN);
677                         /* update the length and offset */
678                         payload_offset += 3;
679                         frag_len -= 3;
680                 }
681                 else
682                 {       /* get the frag length */
683                         frag_len = (tvb_get_ntohs(payload_tvb, payload_offset) & PACKING_SUBHEADER_LENGTH_MASK);
684                         /* get the sequence number */
685                         seq_number = (tvb_get_guint8(payload_tvb, payload_offset) & SEQ_NUMBER_MASK) >> 3;
686                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fc, payload_tvb, payload_offset, 2, ENC_BIG_ENDIAN);
687                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_fsn, payload_tvb, payload_offset, 2, ENC_BIG_ENDIAN);
688                         proto_tree_add_item(generic_tree, hf_mac_header_generic_packing_subhd_len, payload_tvb, payload_offset, 2, ENC_BIG_ENDIAN);
689                         /* update the length and offset */
690                         payload_offset += 2;
691                         frag_len -= 2;
692                 }
693         }
694         /* Prevent a crash! */
695         if ((gint)frag_len < 0)
696                 frag_len = 0;
697         /* Return the number of bytes decoded. */
698         return payload_offset - starting_offset;
699 }
700
701
702 static void dissect_mac_header_generic_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
703 {
704         guint offset = 0;
705         guint payload_offset;
706         guint payload_length = 0;
707
708         static guint8 frag_number[MAX_CID];
709         static guint cid_list[MAX_CID];
710         static guint cid_base;
711         static const char reassem_str[] = "Reassembled Data transport PDU (%u bytes)";
712         static const char data_str[] = "Data transport PDU (%u bytes)";
713         const char *str_ptr;
714         gint length, i, cid_index;
715         guint tvb_len, ret_length, ubyte, new_tvb_len;
716         guint new_payload_len = 0;
717         guint /*mac_ht,*/ mac_ec, mac_esf, mac_ci, /*mac_eks,*/ mac_len, mac_cid, cid;
718         guint ffb_grant_mgmt_subheader, packing_subheader, fragment_subheader;
719         guint mesh_subheader;
720         guint packing_length;
721         guint32 mac_crc, calculated_crc;
722         proto_item *parent_item = NULL;
723         proto_item *generic_item = NULL;
724         proto_tree *generic_tree = NULL;
725         proto_item *child_item = NULL;
726         proto_tree *child_tree = NULL;
727         tvbuff_t *payload_tvb;
728         tvbuff_t *data_pdu_tvb;
729         fragment_head *payload_frag;
730         gboolean first_arq_fb_payload = TRUE;
731
732         proto_mac_header_generic_decoder = proto_wimax;
733
734 #ifdef DEBUG
735         /* update the info column */
736         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "GMH");
737 #endif
738
739         /* Get the frame length */
740         tvb_len =  tvb_reported_length(tvb);
741         if (tvb_len < WIMAX_MAC_HEADER_SIZE)
742         {
743                 /* display the error message */
744                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, tvb_len, "Error: the size of Generic MAC Header tvb is too small! (%u bytes)", tvb_len);
745                 /* add subtree */
746                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_header_generic_decoder);
747                 /* display the Generic MAC Header in Hex */
748                 proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, tvb_len, ENC_NA);
749                 return;
750         }
751         /* get the parent */
752         parent_item = proto_tree_get_parent(tree);
753         /* add the MAC header info */
754         proto_item_append_text(parent_item, " - Generic MAC Header");
755         /* display MAC header message */
756         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, WIMAX_MAC_HEADER_SIZE, "Generic MAC Header (%u bytes)", WIMAX_MAC_HEADER_SIZE);
757         /* add MAC header subtree */
758         generic_tree = proto_item_add_subtree(generic_item, ett_mac_header_generic_decoder);
759         /* Decode and display the MAC header */
760         /* Get the first byte */
761         ubyte = tvb_get_guint8(tvb, offset);
762         /* get the Header Type (HT) */
763         /*mac_ht = ((ubyte & WIMAX_MAC_HEADER_GENERIC_HT_MASK)?1:0); XX: not used ?? */
764         /* get the Encryption Control (EC) */
765         mac_ec = ((ubyte & WIMAX_MAC_HEADER_GENERIC_EC_MASK)?1:0);
766         /* get the sub types */
767         ffb_grant_mgmt_subheader = ((ubyte & GENERIC_SUB_TYPE_0)?1:0);
768         packing_subheader = ((ubyte & GENERIC_SUB_TYPE_1)?1:0);
769         fragment_subheader = ((ubyte & GENERIC_SUB_TYPE_2)?1:0);
770         extended_type = ((ubyte & GENERIC_SUB_TYPE_3)?1:0);
771         arq_fb_payload = ((ubyte & GENERIC_SUB_TYPE_4)?1:0);
772         mesh_subheader = ((ubyte & GENERIC_SUB_TYPE_5)?1:0);
773         /* Get the 2nd byte */
774         ubyte = tvb_get_guint8(tvb, (offset+1));
775         /* get the Extended subheader field (ESF) */
776         mac_esf = ((ubyte & WIMAX_MAC_HEADER_GENERIC_ESF_MASK)?1:0);
777         /* get the CRC indicator (CI) */
778         mac_ci = ((ubyte & WIMAX_MAC_HEADER_GENERIC_CI_MASK)?1:0);
779         /* get the Encryption key sequence (EKS) */
780         /*mac_eks = ((ubyte & WIMAX_MAC_HEADER_GENERIC_EKS_MASK)>>4); XX: not used ?? */
781         /* get the MAC length; this is used even if tree is null */
782         mac_len = (tvb_get_ntohs(tvb, (offset+1)) & WIMAX_MAC_HEADER_GENERIC_LEN);
783         /* get the CID */
784         mac_cid = tvb_get_ntohs(tvb, (offset+3));
785         /* display the Header Type (HT) */
786         proto_tree_add_item(generic_tree, hf_mac_header_generic_ht, tvb, offset, 3, ENC_BIG_ENDIAN);
787         /* display the Encryption Control (EC) */
788         proto_tree_add_item(generic_tree, hf_mac_header_generic_ec, tvb, offset, 3, ENC_BIG_ENDIAN);
789         /* display the sub-types (Type) */
790         proto_tree_add_item(generic_tree, hf_mac_header_generic_type_5, tvb, offset, 3, ENC_BIG_ENDIAN);
791         proto_tree_add_item(generic_tree, hf_mac_header_generic_type_4, tvb, offset, 3, ENC_BIG_ENDIAN);
792         proto_tree_add_item(generic_tree, hf_mac_header_generic_type_3, tvb, offset, 3, ENC_BIG_ENDIAN);
793         proto_tree_add_item(generic_tree, hf_mac_header_generic_type_2, tvb, offset, 3, ENC_BIG_ENDIAN);
794         proto_tree_add_item(generic_tree, hf_mac_header_generic_type_1, tvb, offset, 3, ENC_BIG_ENDIAN);
795         proto_tree_add_item(generic_tree, hf_mac_header_generic_type_0, tvb, offset, 3, ENC_BIG_ENDIAN);
796         /* display the Extended sub-header Field (ESF) */
797         proto_tree_add_item(generic_tree, hf_mac_header_generic_esf, tvb, offset, 3, ENC_BIG_ENDIAN);
798         /* display the CRC Indicator (CI) */
799         proto_tree_add_item(generic_tree, hf_mac_header_generic_ci, tvb, offset, 3, ENC_BIG_ENDIAN);
800         /* display the Encryption Key Sequence (EKS) */
801         proto_tree_add_item(generic_tree, hf_mac_header_generic_eks, tvb, offset, 3, ENC_BIG_ENDIAN);
802         /* display the reserved field */
803         proto_tree_add_item(generic_tree, hf_mac_header_generic_rsv, tvb, offset, 3, ENC_BIG_ENDIAN);
804         /* display the length */
805         proto_tree_add_item(generic_tree, hf_mac_header_generic_len, tvb, offset, 3, ENC_BIG_ENDIAN);
806         /* Decode and display the CID */
807         proto_tree_add_item(generic_tree, hf_mac_header_generic_cid, tvb, (offset+3), 2, ENC_BIG_ENDIAN);
808         /* Decode and display the HCS */
809         proto_tree_add_item(generic_tree, hf_mac_header_generic_hcs, tvb, (offset+5), 1, ENC_BIG_ENDIAN);
810         /* get the frame length without MAC header */
811         length = mac_len - WIMAX_MAC_HEADER_SIZE;
812 #ifdef DEBUG
813         proto_item_append_text(parent_item, "tvb length=%u, mac length=%u, frame length=%u,", tvb_len, mac_len, length);
814 #endif
815         /* set the offset for the frame */
816         offset += WIMAX_MAC_HEADER_SIZE;
817         /* the processing of the subheaders is order sensitive */
818         /* do not change the order */
819
820         if (mac_ec)
821         {
822                 if (mac_ci)
823                 {
824                         if (length >= (gint)sizeof(mac_crc))
825                         {
826                                 length -= (int)sizeof(mac_crc);
827                         }
828                 }
829                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Encrypted PDU (%u bytes)", length);
830                 /* add payload subtree */
831                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_data_pdu_decoder);
832                 proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, length, ENC_NA);
833                 goto check_crc;
834         }
835
836         /* if Extended subheader is present */
837         if (mac_esf)
838         {       /* add the Extended subheader info */
839                 proto_item_append_text(parent_item, ", Extended Subheader(s)");
840                 ret_length = extended_subheader_decoder(tvb_new_subset_length(tvb, offset, length), pinfo, tree);
841                 /* update the length and offset */
842                 length -= ret_length;
843                 offset += ret_length;
844         }
845         /* if Mesh subheader is present */
846         if (mesh_subheader)
847         {       /* update the info column */
848                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Mesh subhdr");
849                 /* add the Mesh subheader info */
850                 proto_item_append_text(parent_item, ", Mesh Subheader");
851                 /* display Mesh subheader type */
852                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Mesh subheader (2 bytes)");
853                 /* add Mesh subheader subtree */
854                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_mesh_subheader_decoder);
855                 /* decode and display the Mesh subheader */
856                 proto_tree_add_item(generic_tree, hf_mac_header_generic_mesh_subheader, tvb, offset, 2, ENC_BIG_ENDIAN);
857                 /* update the length and offset */
858                 length -= 2;
859                 offset += 2;
860         }
861         /* if Fast-feedback allocation (DL) subheader or Grant management (UL) subheader is present */
862         if (ffb_grant_mgmt_subheader)
863         {       /* check if it is downlink packet */
864                 if (is_down_link(pinfo))
865                 {       /* Fast-feedback allocation (DL) subheader is present */
866                         /* update the info column */
867                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Fast-fb subhdr");
868                         /* add the Fast-feedback subheader info */
869                         proto_item_append_text(parent_item, ", Fast-feedback Subheader");
870                         /* display Fast-feedback allocation subheader type */
871                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Fast-feedback allocation (DL) subheader (%u bytes)", length);
872                         /* add Fast-feedback allocation subheader subtree */
873                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_fast_fb_subheader_decoder);
874                         proto_tree_add_item(generic_tree, hf_mac_header_generic_fast_fb_subhd_alloc_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
875                         proto_tree_add_item(generic_tree, hf_mac_header_generic_fast_fb_subhd_fb_type, tvb, offset, 1, ENC_BIG_ENDIAN);
876                         /* update the length and offset */
877                         length -= 1;
878                         offset += 1;
879                 }
880                 else    /* Grant management (UL) subheader is present */
881                 {       /* update the info column */
882                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Grant mgmt subhdr");
883                         /* add the Grant management subheader info */
884                         proto_item_append_text(parent_item, ", Grant Management Subheader");
885                         /* display Grant management subheader type */
886                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, 2, "Grant management (UL) subheader (2 bytes)");
887                         /* add Grant management subheader subtree */
888                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_grant_mgmt_subheader_decoder);
889                         scheduling_service_type = get_service_type();
890                         switch (scheduling_service_type)
891                         {
892                         case SCHEDULE_SERVICE_TYPE_UGS:
893                                 proto_item_append_text(generic_item, ": It looks like UGS is the correct Scheduling Service Type");
894                         break;
895                         case SCHEDULE_SERVICE_TYPE_EXT_RTPS:
896                                 proto_item_append_text(generic_item, ": It looks like Extended rtPS is the correct Scheduling Service Type");
897                         break;
898                         case -1:
899                                 proto_item_append_text(generic_item, ": Cannot determine the correct Scheduling Service Type");
900                         break;
901                         default:
902                                 proto_item_append_text(generic_item, ": It looks like Piggyback Request is the correct Scheduling Service Type");
903                         break;
904                         }
905                         /* Create tree for Scheduling Service Type (UGS) */
906                         child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ugs_tree, tvb, offset, 2, ENC_BIG_ENDIAN);
907                         child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
908                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_si, tvb, offset, 2, ENC_BIG_ENDIAN);
909                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_pm, tvb, offset, 2, ENC_BIG_ENDIAN);
910                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_fli, tvb, offset, 2, ENC_BIG_ENDIAN);
911                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_fl, tvb, offset, 2, ENC_BIG_ENDIAN);
912                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ugs_rsv, tvb, offset, 2, ENC_BIG_ENDIAN);
913
914                         /* Create tree for Scheduling Service Type (Extended RTPS) */
915                         child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ext_rtps_tree, tvb, offset, 2, ENC_BIG_ENDIAN);
916                         child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
917                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_pbr, tvb, offset, 2, ENC_BIG_ENDIAN);
918                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_fli, tvb, offset, 2, ENC_BIG_ENDIAN);
919                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_ext_fl, tvb, offset, 2, ENC_BIG_ENDIAN);
920
921                         /* Create tree for Scheduling Service Type (Piggyback Request) */
922                         child_item = proto_tree_add_item(generic_tree, hf_mac_header_generic_grant_mgmt_ext_pbr_tree, tvb, offset, 2, ENC_BIG_ENDIAN);
923                         child_tree = proto_item_add_subtree(child_item, ett_mac_grant_mgmt_subheader_decoder);
924                         proto_tree_add_item(child_tree, hf_mac_header_generic_grant_mgmt_subhd_pbr, tvb, offset, 2, ENC_BIG_ENDIAN);
925
926                         /* update the length and offset */
927                         length -= 2;
928                         offset += 2;
929                 }
930         }
931         /* if Fragmentation subheader is present */
932         if (fragment_subheader)
933         {       /* update the info column */
934                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Frag subhdr");
935                 /* add the Fragmentation subheader info */
936                 proto_item_append_text(parent_item, ", Frag Subheader");
937                 /* display Fragmentation subheader type */
938                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, ((arq_enabled|extended_type)?2:1), "Fragmentation subheader (%u bytes)", ((arq_enabled|extended_type)?2:1));
939                 /* add Fragmentation subheader subtree */
940                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_frag_subheader_decoder);
941                 /* Get the fragment type */
942                 frag_type = (tvb_get_guint8(tvb, offset) & FRAGMENT_TYPE_MASK) >> 6;
943                 if (arq_fb_payload)
944                 {       /* get the sequence number */
945                         seq_number = (tvb_get_ntohs(tvb, offset) & SEQ_NUMBER_MASK_11) >> 3;
946                         /* decode and display the header */
947                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc_ext, tvb, offset, 2, ENC_BIG_ENDIAN);
948                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_bsn, tvb, offset, 2, ENC_BIG_ENDIAN);
949                         proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv_ext, tvb, offset, 2, ENC_BIG_ENDIAN);
950                         /* update the length and offset */
951                         length -= 2;
952                         offset += 2;
953                 }
954                 else
955                 {
956                         if (extended_type)
957                         {       /* get the sequence number */
958                                 seq_number = (tvb_get_ntohs(tvb, offset) & SEQ_NUMBER_MASK_11) >> 3;
959                                 /* decode and display the header */
960                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc_ext, tvb, offset, 2, ENC_BIG_ENDIAN);
961                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fsn_ext, tvb, offset, 2, ENC_BIG_ENDIAN);
962                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv_ext, tvb, offset, 2, ENC_BIG_ENDIAN);
963                                 /* update the length and offset */
964                                 length -= 2;
965                                 offset += 2;
966                         }
967                         else
968                         {       /* get the sequence number */
969                                 seq_number = (tvb_get_guint8(tvb, offset) & SEQ_NUMBER_MASK) >> 3;
970                                 /* decode and display the header */
971                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fc, tvb, offset, 1, ENC_BIG_ENDIAN);
972                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_fsn, tvb, offset, 1, ENC_BIG_ENDIAN);
973                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_frag_subhd_rsv, tvb, offset, 1, ENC_BIG_ENDIAN);
974                                 /* update the length and offset */
975                                 length -= 1;
976                                 offset += 1;
977                         }
978                 }
979                 frag_len = length;
980         }
981         else    /* ??? default fragment type: no fragment */
982         {
983                 frag_type = NO_FRAG;
984         }
985         /* Decode the MAC payload if there is any */
986         if (mac_ci)
987         {
988                 if (length < (gint)sizeof(mac_crc))
989                 {       /* display error message */
990                         proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Error - the frame is too short (%u bytes)", length);
991                         return;
992                 }
993                 length -= (int)sizeof(mac_crc);
994         }
995         while (length > 0)
996         {
997                 frag_len = length; /* Can be changed by Packing subhdr */
998                 if (packing_subheader)
999                 {
1000                         packing_length = decode_packing_subheader(tvb, pinfo, tree, length, offset, parent_item);
1001                         length -= packing_length;
1002                         offset += packing_length;
1003                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, frag_len, "Data transport PDU (%u bytes)", frag_len);
1004                         /* add payload subtree */
1005                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_data_pdu_decoder);
1006                         proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, tvb, offset, frag_len, ENC_NA);
1007                 }
1008                 /* defragment first if it is fragmented */
1009                 if (frag_type == NO_FRAG)
1010                 {       /* not fragmented payload */
1011                         payload_tvb =  tvb_new_subset_length(tvb, offset, frag_len);
1012                         payload_length = frag_len;
1013                         new_payload_len = frag_len;
1014                 }
1015                 else    /* fragmented payload */
1016                 {       /* add the fragment */
1017                         /* Make sure cid will not match a previous packet with different data */
1018                         for (i = 0; i < MAX_CID; i++)
1019                         {
1020                                 if (cid_list[i] == mac_cid)
1021                                 {
1022                                         cid_base = i * (0xFFFFFFFF / MAX_CID);
1023                                         break;
1024                                 }
1025                                 if (cid_list[i] == 0)
1026                                 {
1027                                         cid_list[i] = mac_cid;
1028                                         cid_base = i * (0xFFFFFFFF / MAX_CID);
1029                                         break;
1030                                 }
1031                         }
1032                         cid_index = i;
1033                         while (pinfo->fd->num > cid_adj_array_size)
1034                         {
1035                                 cid_adj_array_size += 1024;
1036                                 cid_adj_array = (guint *)g_realloc(cid_adj_array, (int)sizeof(guint) * cid_adj_array_size);
1037                                 frag_num_array = (guint8 *)g_realloc(frag_num_array, (int)sizeof(guint8) * cid_adj_array_size);
1038                                 /* Clear the added memory */
1039                                 memset(&cid_adj_array[cid_adj_array_size - 1024], 0, (int)sizeof(guint) * 1024);
1040                         }
1041                         if (first_gmh)
1042                         {
1043                                 /* New cid_adjust for each packet with fragment(s) */
1044                                 cid_adjust[cid_index] += cid_vernier[cid_index];
1045                                 /* cid_vernier must always be 0 at start of packet. */
1046                                 cid_vernier[cid_index] = 0;
1047                         }
1048                         /* Create artificial sequence numbers. */
1049                         frag_number[cid_index]++;
1050                         if (frag_type == FIRST_FRAG)
1051                         {
1052                                 frag_number[cid_index] = 0;
1053                         }
1054                         if (cid_adj_array[pinfo->fd->num])
1055                         {
1056                                 /* We apparently just clicked on the packet again. */
1057                                 cid_adjust[cid_index] = cid_adj_array[pinfo->fd->num];
1058                                 /* Set the frag_number at start of packet. */
1059                                 if (first_gmh)
1060                                 {
1061                                         frag_number[cid_index] = frag_num_array[pinfo->fd->num];
1062                                 }
1063                         } else {
1064                                 /* Save for next time we click on this packet. */
1065                                 cid_adj_array[pinfo->fd->num] = cid_adjust[cid_index];
1066                                 if (first_gmh)
1067                                 {
1068                                         frag_num_array[pinfo->fd->num] = frag_number[cid_index];
1069                                 }
1070                         }
1071                         /* Reset in case we stay in this while() loop to finish the packet. */
1072                         first_gmh = FALSE;
1073                         cid = cid_base + cid_adjust[cid_index] + cid_vernier[cid_index];
1074                         /* Save address pointers. */
1075                         save_src = pinfo->src;
1076                         save_dst = pinfo->dst;
1077                         /* Use dl_src and dl_dst in defragmentation. */
1078                         pinfo->src = pinfo->dl_src;
1079                         pinfo->dst = pinfo->dl_dst;
1080                         payload_frag = fragment_add_seq(&payload_reassembly_table, tvb, offset, pinfo, cid, NULL, frag_number[cid_index], frag_len, ((frag_type==LAST_FRAG)?0:1), 0);
1081                         /* Restore address pointers. */
1082                         pinfo->src = save_src;
1083                         pinfo->dst = save_dst;
1084                         if (frag_type == LAST_FRAG)
1085                         {
1086                                 /* Make sure fragment_add_seq() sees next one as a new frame. */
1087                                 cid_vernier[cid_index]++;
1088                         }
1089                         /* Don't show reassembled packet until last fragment. */
1090                         proto_tree_add_text(tree, tvb, offset, frag_len, "Payload Fragment (%d bytes)", frag_len);
1091
1092                         if (payload_frag && frag_type == LAST_FRAG)
1093                         {       /* defragmented completely */
1094                                 payload_length = payload_frag->len;
1095                                 /* create the new tvb for defragmented frame */
1096                                 payload_tvb = tvb_new_chain(tvb, payload_frag->tvb_data);
1097                                 /* add the defragmented data to the data source list */
1098                                 add_new_data_source(pinfo, payload_tvb, "Reassembled WiMax MAC payload");
1099                                 /* save the tvb langth */
1100                                 new_payload_len = payload_length;
1101                         }
1102                         else /* error or defragment is not complete */
1103                         {
1104                                 payload_tvb = NULL;
1105 #ifdef DEBUG    /* for debug only */
1106 /*                              if (frag_type == LAST_FRAG)*/
1107                                 {       /* error */
1108                                         /* update the info column */
1109                                         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Dropped the incomplete frame");
1110                                 }
1111 #endif
1112 #if 0
1113                                 if (frag_type == FIRST_FRAG)
1114                                 {       /* Set up to decode the first fragment (even though next fragment not read yet) */
1115                                         payload_tvb =  tvb_new_subset_length(tvb, offset, length);
1116                                         payload_length = length;
1117                                         frag_len = length;
1118                                 }
1119 #endif
1120                         }
1121                 }
1122                 /* process the defragmented payload */
1123                 if (payload_tvb)
1124                 {       /* reset the payload_offset */
1125                         payload_offset = 0;
1126                         /* process the payload */
1127                         if (payload_length > 0)
1128                         {
1129                                 if (!new_payload_len)
1130                                         continue;
1131                                 /* if ARQ Feedback payload is present, it should be the first SDU */
1132                                 if (first_arq_fb_payload && arq_fb_payload)
1133                                 {       /* decode and display the ARQ feedback payload */
1134                                         first_arq_fb_payload = FALSE;
1135 #ifndef DEBUG
1136                                         arq_feedback_payload_decoder(tvb_new_subset_length(payload_tvb, payload_offset, new_payload_len), pinfo, generic_tree, parent_item);
1137 #else
1138                                         ret_length = arq_feedback_payload_decoder(tvb_new_subset_length(payload_tvb, payload_offset, new_payload_len), pinfo, generic_tree, parent_item);
1139                                         if (ret_length != new_payload_len)
1140                                         {       /* error */
1141                                                 /* update the info column */
1142                                                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "incorrect ARQ fb payload size");
1143                                         }
1144 #endif
1145                                 }
1146                                 else    /* decode SDUs */
1147                                 {       /* check the payload type */
1148                                         if (mac_cid == cid_padding)
1149                                         {       /* update the info column */
1150                                                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Padding CID");
1151                                                 /* get the parent */
1152                                                 generic_item = proto_tree_get_parent(tree);
1153                                                 /* add the MAC header info */
1154                                                 proto_item_append_text(generic_item, ", Padding CID");
1155                                                 /* display padding CID */
1156                                                 generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, payload_tvb, payload_offset, new_payload_len, "Padding CID (%u bytes)", new_payload_len);
1157                                                 /* add payload subtree */
1158                                                 generic_tree = proto_item_add_subtree(generic_item, ett_mac_header_generic_decoder);
1159                                                 /* display the Padding CID payload  in Hex */
1160                                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, payload_tvb, payload_offset, new_payload_len, ENC_NA);
1161                                         }
1162                                         else if ((mac_cid <= (2 * global_cid_max_basic)) || (mac_cid == cid_aas_ranging)
1163                                                 || (mac_cid >= cid_normal_multicast))
1164                                         {       /* MAC management message */
1165                                                 call_dissector(mac_mgmt_msg_decoder_handle, tvb_new_subset_length(payload_tvb, payload_offset, new_payload_len), pinfo, tree);
1166                                         }
1167                                         else /* data transport PDU */
1168                                         {       /* update the info column */
1169                                                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Data");
1170                                                 /* add the MAC payload info */
1171                                                 proto_item_append_text(parent_item, ", Data");
1172                                                 /* display payload info */
1173                                                 if ((new_payload_len + payload_offset) > payload_length)
1174                                                 {
1175                                                         new_tvb_len = new_payload_len - payload_offset;
1176                                                 }
1177                                                 else
1178                                                 {
1179                                                         new_tvb_len = new_payload_len;
1180                                                 }
1181                                                 if (frag_type == LAST_FRAG || frag_type == NO_FRAG)
1182                                                 {
1183                                                         if (frag_type == NO_FRAG)
1184                                                         {
1185                                                                 str_ptr = data_str;
1186                                                                 new_payload_len = frag_len;
1187                                                         }
1188                                                         else
1189                                                         {
1190                                                                 str_ptr = reassem_str;
1191                                                         }
1192                                                         data_pdu_tvb = tvb_new_subset_length(payload_tvb, payload_offset, new_tvb_len);
1193                                                         generic_item = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, data_pdu_tvb, payload_offset, new_payload_len, str_ptr, new_payload_len);
1194                                                         /* add payload subtree */
1195                                                         generic_tree = proto_item_add_subtree(generic_item, ett_mac_data_pdu_decoder);
1196                                                         /* check the data type */
1197                                                         if (tvb_get_guint8(payload_tvb, payload_offset) == IP_HEADER_BYTE)
1198                                                         {
1199                                                                 if (mac_ip_handle)
1200                                                                         call_dissector(mac_ip_handle, tvb_new_subset_length(payload_tvb, payload_offset, new_tvb_len), pinfo, generic_tree);
1201                                                                 else    /* display the Generic MAC Header in Hex */
1202                                                                         proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, payload_tvb, payload_offset, new_tvb_len, ENC_NA);
1203                                                         }
1204                                                         else    /* display the Generic MAC Header in Hex */
1205                                                                 proto_tree_add_item(generic_tree, hf_mac_header_generic_value_bytes, payload_tvb, payload_offset, new_tvb_len, ENC_NA);
1206                                                 }
1207                                         }
1208                                 }
1209                                 payload_length -= new_payload_len;
1210                         }       /* end of while loop */
1211                 }       /* end of payload processing */
1212                 length -= frag_len;
1213                 offset += frag_len;
1214         } /* end of payload decoding */
1215
1216 check_crc:
1217         /* Decode and display the CRC if it is present */
1218         if (mac_ci)
1219         {
1220                 /* add the CRC info */
1221                 proto_item_append_text(parent_item, ", CRC");
1222                 /* check the length */
1223                 if (MIN(tvb_len, tvb_reported_length(tvb)) >= mac_len)
1224                 {       /* get the CRC */
1225                         mac_crc = tvb_get_ntohl(tvb, mac_len - (int)sizeof(mac_crc));
1226                         /* calculate the CRC */
1227                         calculated_crc = wimax_mac_calc_crc32(tvb_get_ptr(tvb, 0, mac_len - (int)sizeof(mac_crc)), mac_len - (int)sizeof(mac_crc));
1228                         /* display the CRC */
1229                         generic_item = proto_tree_add_item(tree, hf_mac_header_generic_crc, tvb, mac_len - (int)sizeof(mac_crc), (int)sizeof(mac_crc), ENC_BIG_ENDIAN);
1230                         if (mac_crc != calculated_crc)
1231                         {
1232                                 proto_item_append_text(generic_item, " - incorrect! (should be: 0x%x)", calculated_crc);
1233                         }
1234                 }
1235                 else
1236                 {       /* display error message */
1237                         expert_add_info_format(pinfo, tree, &ei_mac_crc_malformed, "CRC missing - the frame is too short (%u bytes)", tvb_len);
1238                 }
1239         }
1240         else    /* CRC is not included */
1241         {       /* add the CRC info */
1242                 proto_item_append_text(parent_item, ", No CRC");
1243                 /* display message */
1244                 expert_add_info(pinfo, tree, &ei_mac_crc_missing);
1245         }
1246 }
1247
1248 static gint extended_subheader_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1249 {
1250         gint offset = 0;
1251         gint length, ext_length, ubyte, i;
1252         proto_item *ti = NULL;
1253         proto_tree *sub_tree = NULL;
1254         proto_tree *ti_tree = NULL;
1255
1256         /* update the info column */
1257         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Ext subhdrs");
1258
1259         /* Get the tvb reported length */
1260         length =  tvb_reported_length(tvb);
1261         if (!length)
1262         {       /* display the error message */
1263                 proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Error: extended subheader tvb is empty ! (%u bytes)", length);
1264                 return length;
1265         }
1266
1267         /* Get the length of the extended subheader group */
1268         ext_length = tvb_get_guint8(tvb, offset);
1269         /* display subheader type */
1270         ti = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Extended subheader group (%u bytes)", ext_length);
1271         /* add extended subheader subtree */
1272         sub_tree = proto_item_add_subtree(ti, ett_mac_ext_subheader_decoder);
1273         /* decode and display the extended subheaders */
1274         for (i=1; i<ext_length;)
1275         {       /* Get the extended subheader type */
1276                 ubyte = (tvb_get_guint8(tvb, (offset+i)) & EXTENDED_SUB_HEADER_TYPE_MASK);
1277                 /* decode and display the extended subheader type (MSB) */
1278                 proto_tree_add_item(sub_tree, hf_mac_header_generic_ext_subheader_rsv, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1279                 /* for downlink */
1280                 if (is_down_link(pinfo)) /* for downlink */
1281                 {       /* decode and display the extended subheader type */
1282                         ti = proto_tree_add_item(sub_tree, hf_mac_header_generic_ext_subheader_type_dl, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1283                         /* add subtree */
1284                         ti_tree = proto_item_add_subtree(ti, ett_mac_ext_subheader_dl_decoder);
1285                         i++;
1286                         switch (ubyte)
1287                         {
1288                         case SDU_SN:
1289                                 /* decode and display the extended sdu sn subheader */
1290                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_sdu_sn, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1291                                 i++;
1292                         break;
1293                         case DL_SLEEP_CONTROL:
1294                                 /* decode and display the extended dl sleep control subheader */
1295                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_pscid, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1296                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_op, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1297                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_fswe, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1298                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_fswb, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1299                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_dl_sleep_control_rsv, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1300                                 i += 3;
1301                         break;
1302                         case FEEDBACK_REQ:
1303                                 /* decode and display the extended feedback request subheader */
1304                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_uiuc, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1305                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_fb_type,  tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1306                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_ofdma_symbol_offset, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1307                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_subchannel_offset, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1308                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_slots, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1309                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_fb_req_frame_offset, tvb, (offset+i), 3, ENC_BIG_ENDIAN);
1310                                 i += 3;
1311                         break;
1312                         case SN_REQ:
1313                                 /* decode and display the extended SN request subheader */
1314                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_sn_req_rep_ind_1, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1315                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_sn_req_rep_ind_2, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1316                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_sn_req_rsv, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1317                                 i++;
1318                         break;
1319                         case PDU_SN_SHORT_DL:
1320                                 /* decode and display the extended pdu sn (short) subheader */
1321                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_pdu_sn_short, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1322                                 i++;
1323                         break;
1324                         case PDU_SN_LONG_DL:
1325                                 /* decode and display the extended pdu sn (long) subheader */
1326                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_pdu_sn_long, tvb, (offset+i), 2, ENC_BIG_ENDIAN);
1327                                 i += 2;
1328                         break;
1329                         default: /* reserved */
1330                         break;
1331                         }
1332                 }
1333                 else /* for uplink */
1334                 {       /* decode and display the extended subheader type */
1335                         ti = proto_tree_add_item(sub_tree, hf_mac_header_generic_ext_subheader_type_ul, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1336                         /* add subtree */
1337                         ti_tree = proto_item_add_subtree(ti, ett_mac_ext_subheader_ul_decoder);
1338                         i++;
1339                         switch (ubyte)
1340                         {
1341                         case MIMO_MODE_FEEDBACK:
1342                                 /* decode and display the extended MIMO Mode Feedback subheader */
1343                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_mimo_mode_fb_type, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1344                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_mimo_fb_content, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1345                                 i++;
1346                         break;
1347                         case UL_TX_POWER_REPORT:
1348                                 /* decode and display the extended ul tx power report subheader */
1349                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_ul_tx_pwr_rep, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1350                                 i++;
1351                         break;
1352                         case MINI_FEEDBACK:
1353                                 /* decode and display the extended MINI Feedback subheader */
1354                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_mini_fb_type, tvb, (offset+i), 2, ENC_BIG_ENDIAN);
1355                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_mini_fb_content, tvb, (offset+i), 2, ENC_BIG_ENDIAN);
1356                                 i += 2;
1357                         break;
1358                         case PDU_SN_SHORT_UL:
1359                                 /* decode and display the extended pdu sn (short) subheader */
1360                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_pdu_sn_short, tvb, (offset+i), 1, ENC_BIG_ENDIAN);
1361                                 i++;
1362                         break;
1363                         case PDU_SN_LONG_UL:
1364                                 /* decode and display the extended pdu sn (long) subheader */
1365                                 proto_tree_add_item(ti_tree, hf_mac_header_generic_ext_subheader_pdu_sn_long, tvb, (offset+i), 2, ENC_BIG_ENDIAN);
1366                                 i += 2;
1367                         break;
1368                         default: /* reserved */
1369                         break;
1370                         }
1371                 }
1372         }
1373         /* return the extended subheader length */
1374         return ext_length;
1375 }
1376
1377 static gint arq_feedback_payload_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *parent_item)
1378 {
1379         gint length, i;
1380         gint offset;
1381         gint last_ie = 0;
1382         gint ack_type, num_maps, seq_format;
1383         gint word2, word3;
1384         proto_item *ti = NULL;
1385         proto_item *sub_ti = NULL;
1386         proto_tree *sub_tree = NULL;
1387
1388         /* update the info column */
1389         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "ARQ feedback payld");
1390
1391         /* add the MAC header info */
1392         proto_item_append_text(parent_item, ", ARQ feedback payload");
1393
1394         /* reset the offset */
1395         offset = 0;
1396
1397         /* Get the tvb reported length */
1398         length =  tvb_reported_length(tvb);
1399         if (!length)
1400         {       /* display the error message */
1401                 proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "Error: ARQ feedback payload tvb is empty ! (%u bytes)", length);
1402                 return length;
1403         }
1404
1405         /* display subheader type */
1406         ti = proto_tree_add_protocol_format(tree, proto_mac_header_generic_decoder, tvb, offset, length, "ARQ feedback payload ");
1407         /* add extended subheader subtree */
1408         sub_tree = proto_item_add_subtree(ti, ett_mac_arq_fb_payload_decoder);
1409         /* decode and display the ARQ Feedback IEs */
1410         while (!last_ie)
1411         {       /* decode and display CID */
1412                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_cid, tvb, offset, 2, ENC_BIG_ENDIAN);
1413                 /* move to next 16-bit word */
1414                 offset += 2;
1415                 /* Get the 2nd 16-bit */
1416                 word2 = tvb_get_ntohs(tvb, offset);
1417                 /* get the last bit */
1418                 last_ie = (word2 & ARQ_FB_IE_LAST_BIT_MASK);
1419                 /* get the ACK type */
1420                 ack_type = ((word2 & ARQ_FB_IE_ACK_TYPE_MASK) >> 13);
1421                 /* get the number of ACK maps */
1422                 num_maps = (word2 & ARQ_FB_IE_NUM_MAPS_MASK) + 1;
1423                 /* decode and display the 2nd word */
1424                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_last, tvb, offset, 2, ENC_BIG_ENDIAN);
1425                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_ack_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1426                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_bsn, tvb, offset, 2, ENC_BIG_ENDIAN);
1427                 /* decode and display the 3rd word */
1428                 if (ack_type != 1)
1429                 {
1430                         sub_ti = proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_num_maps, tvb, offset, 2, ENC_BIG_ENDIAN);
1431                         /* move to next 16-bit word */
1432                         offset += 2;
1433                         proto_item_append_text(sub_ti, " (%d map(s))", num_maps);
1434                         for (i = 0; i < num_maps; i++)
1435                         {
1436                                 if (ack_type != 3)
1437                                 {
1438                                         proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_sel_ack_map, tvb, offset, 2, ENC_BIG_ENDIAN);
1439                                 }
1440                                 else
1441                                 {       /* Get the next 16-bit */
1442                                         word3 = tvb_get_ntohs(tvb, offset);
1443                                         /* get the sequence format */
1444                                         seq_format = (word3 & ARQ_FB_IE_SEQ_FORMAT_MASK);
1445                                         /* decode and display the sequence format */
1446                                         proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq_format, tvb, offset, 2, ENC_BIG_ENDIAN);
1447                                         if (!seq_format)
1448                                         {
1449                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq_ack_map_2, tvb, offset, 2, ENC_BIG_ENDIAN);
1450                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq1_length_6, tvb, offset, 2, ENC_BIG_ENDIAN);
1451                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq2_length_6, tvb, offset, 2, ENC_BIG_ENDIAN);
1452                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_rsv, tvb, offset, 2, ENC_BIG_ENDIAN);
1453                                         }
1454                                         else
1455                                         {
1456                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq_ack_map, tvb, offset, 2, ENC_BIG_ENDIAN);
1457                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq1_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1458                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq2_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1459                                                 proto_tree_add_item(sub_tree, hf_mac_header_generic_arq_fb_ie_seq3_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1460                                         }
1461                                 }
1462                                 /* move to next 16-bit word */
1463                                 offset += 2;
1464                         }
1465                 }
1466                 else
1467                 {
1468                         /* Number of ACK Maps bits are reserved when ACK TYPE == 1 */
1469                         proto_tree_add_item(sub_tree, hf_ack_type_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
1470                         /* move to next 16-bit word */
1471                         offset += 2;
1472                 }
1473         }
1474         /* append text */
1475         proto_item_append_text(ti,"(%u bytes)", offset);
1476         /* return the offset */
1477         return offset;
1478 }
1479
1480 /* Register Wimax Generic Mac Header Protocol and Dissector */
1481 void proto_register_mac_header_generic(void)
1482 {
1483         /* Generic MAC header display */
1484         static hf_register_info hf[] =
1485         {
1486                 {
1487                         &hf_mac_header_generic_value_bytes,
1488                         {
1489                                 "Values", "wmx.genericValueBytes",
1490                                 FT_BYTES, BASE_NONE, NULL, 0x0,
1491                                 NULL, HFILL
1492                         }
1493                 },
1494                 {
1495                         &hf_mac_header_generic_ht,
1496                         {
1497                                 "MAC Header Type", "wmx.genericHt",
1498                                 FT_UINT24, BASE_HEX, VALS(ht_msgs), WIMAX_MAC_HEADER_GENERIC_HT,
1499                                 NULL, HFILL
1500                         }
1501                 },
1502                 {
1503                         &hf_mac_header_generic_ec,
1504                         {
1505                                 "MAC Encryption Control", "wmx.genericEc",
1506                                 FT_UINT24, BASE_HEX, VALS(ec_msgs), WIMAX_MAC_HEADER_GENERIC_EC,
1507                                 NULL, HFILL
1508                         }
1509                 },
1510                 {
1511                         &hf_mac_header_generic_type_0,
1512                         {
1513                                 "MAC Sub-type Bit 0", "wmx.genericType0",
1514                                 FT_UINT24, BASE_HEX, VALS(type_msg0), WIMAX_MAC_HEADER_GENERIC_TYPE_0,
1515                                 NULL, HFILL
1516                         }
1517                 },
1518                 {
1519                         &hf_mac_header_generic_type_1,
1520                         {
1521                                 "MAC Sub-type Bit 1", "wmx.genericType1",
1522                                 FT_UINT24, BASE_HEX, VALS(type_msg1), WIMAX_MAC_HEADER_GENERIC_TYPE_1,
1523                                 NULL, HFILL
1524                         }
1525                 },
1526                 {
1527                         &hf_mac_header_generic_type_2,
1528                         {
1529                                 "MAC Sub-type Bit 2", "wmx.genericType2",
1530                                 FT_UINT24, BASE_HEX, VALS(type_msg2), WIMAX_MAC_HEADER_GENERIC_TYPE_2,
1531                                 NULL, HFILL
1532                         }
1533                 },
1534                 {
1535                         &hf_mac_header_generic_type_3,
1536                         {
1537                                 "MAC Sub-type Bit 3", "wmx.genericType3",
1538                                 FT_UINT24, BASE_HEX, VALS(type_msg3), WIMAX_MAC_HEADER_GENERIC_TYPE_3,
1539                                 NULL, HFILL
1540                         }
1541                 },
1542                 {
1543                         &hf_mac_header_generic_type_4,
1544                         {
1545                                 "MAC Sub-type Bit 4", "wmx.genericType4",
1546                                 FT_UINT24, BASE_HEX, VALS(type_msg4), WIMAX_MAC_HEADER_GENERIC_TYPE_4,
1547                                 NULL, HFILL
1548                         }
1549                 },
1550                 {
1551                         &hf_mac_header_generic_type_5,
1552                         {
1553                                 "MAC Sub-type Bit 5", "wmx.genericType5",
1554                                 FT_UINT24, BASE_HEX, VALS(type_msg5), WIMAX_MAC_HEADER_GENERIC_TYPE_5,
1555                                 NULL, HFILL
1556                         }
1557                 },
1558                 {
1559                         &hf_mac_header_generic_esf,
1560                         {
1561                                 "Extended Sub-header Field", "wmx.genericEsf",
1562                                 FT_UINT24, BASE_HEX, VALS(esf_msgs), WIMAX_MAC_HEADER_GENERIC_ESF,
1563                                 NULL, HFILL
1564                         }
1565                 },
1566                 {
1567                         &hf_mac_header_generic_ci,
1568                         {
1569                                 "CRC Indicator", "wmx.genericCi",
1570                                 FT_UINT24, BASE_HEX, VALS(ci_msgs), WIMAX_MAC_HEADER_GENERIC_CI,
1571                                 NULL, HFILL
1572                         }
1573                 },
1574                 {
1575                         &hf_mac_header_generic_eks,
1576                         {
1577                                 "Encryption Key Sequence", "wmx.genericEks",
1578                                 FT_UINT24, BASE_HEX, NULL, WIMAX_MAC_HEADER_GENERIC_EKS,
1579                                 NULL, HFILL
1580                         }
1581                 },
1582                 {
1583                         &hf_mac_header_generic_rsv,
1584                         {
1585                                 "Reserved", "wmx.genericRsv",
1586                                 FT_UINT24, BASE_DEC, NULL, WIMAX_MAC_HEADER_GENERIC_RSV,
1587                                 NULL, HFILL
1588                         }
1589                 },
1590                 {
1591                         &hf_mac_header_generic_len,
1592                         {
1593                                 "Length", "wmx.genericLen",
1594                                 FT_UINT24, BASE_DEC, NULL, WIMAX_MAC_HEADER_GENERIC_LEN,
1595                                 NULL, HFILL
1596                         }
1597                 },
1598                 {
1599                         &hf_mac_header_generic_cid,
1600                         {
1601                                 "Connection ID", "wmx.genericCid",
1602                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1603                                 NULL, HFILL
1604                         }
1605                 },
1606                 {
1607                         &hf_mac_header_generic_hcs,
1608                         {
1609                                 "Header Check Sequence", "wmx.genericHcs",
1610                                 FT_UINT8, BASE_HEX, NULL, 0x0,
1611                                 NULL, HFILL
1612                         }
1613                 },
1614                 {
1615                         &hf_mac_header_generic_crc,
1616                         {
1617                                 "CRC", "wmx.genericCrc",
1618                                 FT_UINT32, BASE_HEX, NULL, 0x0,
1619                                 NULL, HFILL
1620                         }
1621                 }
1622         };
1623
1624         /* Extended Subheader display */
1625         static hf_register_info hf_ext[] =
1626         {
1627                 {
1628                         &hf_mac_header_generic_ext_subheader_rsv,
1629                         {
1630                                 "Reserved", "wmx.genericExtSubhd.Rsv",
1631                                 FT_UINT8, BASE_DEC, NULL, EXTENDED_SUB_HEADER_RSV_MASK,
1632                                 NULL, HFILL
1633                         }
1634                 },
1635                 {
1636                         &hf_mac_header_generic_ext_subheader_type_dl,
1637                         {
1638                                 "DL Extended Subheader Type", "wmx.genericExtSubhd.Dl",
1639                                 FT_UINT8, BASE_DEC, VALS(dl_ext_sub_header_type), EXTENDED_SUB_HEADER_TYPE_MASK,
1640                                 NULL, HFILL
1641                         }
1642                 },
1643                 {
1644                         &hf_mac_header_generic_ext_subheader_type_ul,
1645                         {
1646                                 "UL Extended Subheader Type", "wmx.genericExtSubhd.Ul",
1647                                 FT_UINT8, BASE_DEC, VALS(ul_ext_sub_header_type), EXTENDED_SUB_HEADER_TYPE_MASK,
1648                                 NULL, HFILL
1649                         }
1650                 },
1651                 {
1652                         &hf_mac_header_generic_ext_subheader_sdu_sn,
1653                         {
1654                                 "SDU Sequence Number", "wmx.genericExtSubhd.SduSn",
1655                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1656                                 NULL, HFILL
1657                         }
1658                 },
1659                 {
1660                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_pscid,
1661                         {
1662                                 "Power Saving Class ID", "wmx.genericExtSubhd.DlSleepCtrlPSCID",
1663                                 FT_UINT24, BASE_DEC, NULL, DL_SLEEP_CONTROL_POWER_SAVING_CLASS_ID_MASK,
1664                                 NULL, HFILL
1665                         }
1666                 },
1667                 {
1668                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_op,
1669                         {
1670                                 "Operation", "wmx.genericExtSubhd.DlSleepCtrlOP",
1671                                 FT_UINT24, BASE_HEX, VALS(dl_sleep_control_ops), DL_SLEEP_CONTROL_OPERATION_MASK,
1672                                 NULL, HFILL
1673                         }
1674                 },
1675                 {
1676                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_fswe,
1677                         {
1678                                 "Final Sleep Window Exponent", "wmx.genericExtSubhd.DlSleepCtrlFSWE",
1679                                 FT_UINT24, BASE_DEC, NULL, DL_SLEEP_CONTROL_FINAL_SLEEP_WINDOW_EXPONENT_MASK,
1680                                 NULL, HFILL
1681                         }
1682                 },
1683                 {
1684                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_fswb,
1685                         {
1686                                 "Final Sleep Window Base", "wmx.genericExtSubhd.DlSleepCtrlFSWB",
1687                                 FT_UINT24, BASE_DEC, NULL, DL_SLEEP_CONTROL_FINAL_SLEEP_WINDOW_BASE_MASK,
1688                                 NULL, HFILL
1689                         }
1690                 },
1691                 {
1692                         &hf_mac_header_generic_ext_subheader_dl_sleep_control_rsv,
1693                         {
1694                                 "Reserved", "wmx.genericExtSubhd.DlSleepCtrlRsv",
1695                                 FT_UINT24, BASE_DEC, NULL, DL_SLEEP_CONTROL_RESERVED_MASK,
1696                                 NULL, HFILL
1697                         }
1698                 },
1699                 {
1700                         &hf_mac_header_generic_ext_subheader_fb_req_uiuc,
1701                         {
1702                                 "UIUC", "wmx.genericExtSubhd.FbReqUIUC",
1703                                 FT_UINT24, BASE_HEX, VALS(uiuc_values), FEEDBACK_REQUEST_UIUC_MASK,
1704                                 NULL, HFILL
1705                         }
1706                 },
1707                 {
1708                         &hf_mac_header_generic_ext_subheader_fb_req_fb_type,
1709                         {
1710                                 "Feedback Type", "wmx.genericExtSubhd.FbReqFbType",
1711                                 FT_UINT24, BASE_HEX, VALS(fb_types), FEEDBACK_REQUEST_FEEDBACK_TYPE_MASK,
1712                                 NULL, HFILL
1713                         }
1714                 },
1715                 {
1716                         &hf_mac_header_generic_ext_subheader_fb_req_ofdma_symbol_offset,
1717                         {
1718                                 "OFDMA Symbol Offset", "wmx.genericExtSubhd.FbReqOfdmaSymbolOffset",
1719                                 FT_UINT24, BASE_HEX, NULL, FEEDBACK_REQUEST_OFDMA_SYMBOL_OFFSET_MASK,
1720                                 NULL, HFILL
1721                         }
1722                 },
1723                 {
1724                         &hf_mac_header_generic_ext_subheader_fb_req_subchannel_offset,
1725                         {
1726                                 "Subchannel Offset", "wmx.genericExtSubhd.FbReqSubchannelOffset",
1727                                 FT_UINT24, BASE_HEX, NULL, FEEDBACK_REQUEST_SUBCHANNEL_OFFSET_MASK,
1728                                 NULL, HFILL
1729                         }
1730                 },
1731                 {
1732                         &hf_mac_header_generic_ext_subheader_fb_req_slots,
1733                         {
1734                                 "Number of Slots", "wmx.genericExtSubhd.FbReqSlots",
1735                                 FT_UINT24, BASE_HEX, NULL, FEEDBACK_REQUEST_NUMBER_OF_SLOTS_MASK,
1736                                 NULL, HFILL
1737                         }
1738                 },
1739                 {
1740                         &hf_mac_header_generic_ext_subheader_fb_req_frame_offset,
1741                         {
1742                                 "Frame Offset", "wmx.genericExtSubhd.FbReqFrameOffset",
1743                                 FT_UINT24, BASE_HEX, NULL, FEEDBACK_REQUEST_FRAME_OFFSET_MASK,
1744                                 NULL, HFILL
1745                         }
1746                 },
1747                 {
1748                         &hf_mac_header_generic_ext_subheader_sn_req_rep_ind_1,
1749                         {
1750                                 "First SN Report Indication", "wmx.genericExtSubhd.SnReqRepInd1",
1751                                 FT_UINT8, BASE_DEC, VALS(sn_rep_msg), SN_REQUEST_SUBHEADER_SN_REPORT_INDICATION_1_MASK,
1752                                 NULL, HFILL
1753                         }
1754                 },
1755                 {
1756                         &hf_mac_header_generic_ext_subheader_sn_req_rep_ind_2,
1757                         {
1758                                 "Second SN Report Indication", "wmx.genericExtSubhd.SnReqRepInd2",
1759                                 FT_UINT8, BASE_DEC, VALS(sn_rep_msg), SN_REQUEST_SUBHEADER_SN_REPORT_INDICATION_2_MASK,
1760                                 NULL, HFILL
1761                         }
1762                 },
1763                 {
1764                         &hf_mac_header_generic_ext_subheader_sn_req_rsv,
1765                         {
1766                                 "Reserved", "wmx.genericExtSubhd.SnReqRsv",
1767                                 FT_UINT8, BASE_DEC, NULL, SN_REQUEST_SUBHEADER_RESERVED_MASK,
1768                                 NULL, HFILL
1769                         }
1770                 },
1771                 {
1772                         &hf_mac_header_generic_ext_subheader_mimo_mode_fb_type,
1773                         {
1774                                 "Feedback Type", "wmx.genericExtSubhd.MimoFbType",
1775                                 FT_UINT8, BASE_DEC, VALS(mimo_fb_types), MIMO_FEEDBACK_TYPE_MASK,
1776                                 NULL, HFILL
1777                         }
1778                 },
1779                 {
1780                         &hf_mac_header_generic_ext_subheader_mimo_fb_content,
1781                         {
1782                                 "Feedback Content", "wmx.genericExtSubhd.MimoFbContent",
1783                                 FT_UINT8, BASE_DEC, NULL, MIMO_FEEDBACK_CONTENT_MASK,
1784                                 NULL, HFILL
1785                         }
1786                 },
1787                 {
1788                         &hf_mac_header_generic_ext_subheader_ul_tx_pwr_rep,
1789                         {
1790                                 "UL TX Power", "wmx.genericExtSubhd.UlTxPwr",
1791                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1792                                 NULL, HFILL
1793                         }
1794                 },
1795                 {
1796                         &hf_mac_header_generic_ext_subheader_mini_fb_type,
1797                         {
1798                                 "Feedback Type", "wmx.genericExtSubhd.MiniFbType",
1799                                 FT_UINT16, BASE_DEC, VALS(fb_types), MINI_FEEDBACK_TYPE_MASK,
1800                                 NULL, HFILL
1801                         }
1802                 },
1803                 {
1804                         &hf_mac_header_generic_ext_subheader_mini_fb_content,
1805                         {
1806                                 "Feedback Content", "wmx.genericExtSubhd.MiniFbContent",
1807                                 FT_UINT16, BASE_DEC, NULL, MINI_FEEDBACK_CONTENT_MASK,
1808                                 NULL, HFILL
1809                         }
1810                 },
1811                 {
1812                         &hf_mac_header_generic_ext_subheader_pdu_sn_short,
1813                         {
1814                                 "PDU Sequence Number", "wmx.genericExtSubhd.PduSnShort",
1815                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1816                                 NULL, HFILL
1817                         }
1818                 },
1819                 {
1820                         &hf_mac_header_generic_ext_subheader_pdu_sn_long,
1821                         {
1822                                 "PDU Sequence Number", "wmx.genericExtSubhd.PduSnLong",
1823                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1824                                 NULL, HFILL
1825                         }
1826                 }
1827         };
1828
1829         /* Mesh Subheader display */
1830         static hf_register_info hf_mesh[] =
1831         {
1832                 {
1833                         &hf_mac_header_generic_mesh_subheader,
1834                         {
1835                                 "Xmt Node Id", "wmx.genericMeshSubhd",
1836                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1837                                 NULL, HFILL
1838                         }
1839                 }
1840         };
1841
1842         /* Fragmentation Subheader display */
1843         static hf_register_info hf_frag[] =
1844         {
1845                 {
1846                         &hf_mac_header_generic_frag_subhd_fc,
1847                         {
1848                                 "Fragment Type", "wmx.genericFragSubhd.Fc",
1849                                 FT_UINT8, BASE_DEC, VALS(frag_types), FRAGMENTATION_SUBHEADER_FC_MASK,
1850                                 NULL, HFILL
1851                         }
1852                 },
1853                 {
1854                         &hf_mac_header_generic_frag_subhd_fc_ext,
1855                         {
1856                                 "Fragment Type", "wmx.genericFragSubhd.FcExt",
1857                                 FT_UINT16, BASE_DEC, VALS(frag_types), FRAGMENTATION_SUBHEADER_FC_MASK,
1858                                 NULL, HFILL
1859                         }
1860                 },
1861                 {
1862                         &hf_mac_header_generic_frag_subhd_bsn,
1863                         {
1864                                 "Block Sequence Number (BSN)", "wmx.genericFragSubhd.Bsn",
1865                                 FT_UINT16, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_BSN_MASK,
1866                                 NULL, HFILL
1867                         }
1868                 },
1869                 {
1870                         &hf_mac_header_generic_frag_subhd_fsn,
1871                         {
1872                                 "Fragment Sequence Number (FSN)", "wmx.genericFragSubhd.Fsn",
1873                                 FT_UINT8, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_FSN_MASK,
1874                                 NULL, HFILL
1875                         }
1876                 },
1877                 {
1878                         &hf_mac_header_generic_frag_subhd_fsn_ext,
1879                         {
1880                                 "Fragment Sequence Number (FSN)", "wmx.genericFragSubhd.FsnExt",
1881                                 FT_UINT16, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_BSN_MASK,
1882                                 NULL, HFILL
1883                         }
1884                 },
1885                 {
1886                         &hf_mac_header_generic_frag_subhd_rsv,
1887                         {
1888                                 "Reserved", "wmx.genericFragSubhd.Rsv",
1889                                 FT_UINT8, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_RSV_MASK,
1890                                 NULL, HFILL
1891                         }
1892                 },
1893                 {
1894                         &hf_mac_header_generic_frag_subhd_rsv_ext,
1895                         {
1896                                 "Reserved", "wmx.genericFragSubhd.RsvExt",
1897                                 FT_UINT16, BASE_DEC, NULL, FRAGMENTATION_SUBHEADER_RSV_EXT_MASK,
1898                                 NULL, HFILL
1899                         }
1900                 }
1901         };
1902
1903         /* Packing Subheader display */
1904         static hf_register_info hf_pack[] =
1905         {
1906                 {
1907                         &hf_mac_header_generic_packing_subhd_fc,
1908                         {
1909                                 "Fragment Type", "wmx.genericPackSubhd.Fc",
1910                                 FT_UINT16, BASE_DEC, VALS(frag_types), PACKING_SUBHEADER_FC_MASK,
1911                                 NULL, HFILL
1912                         }
1913                 },
1914                 {
1915                         &hf_mac_header_generic_packing_subhd_fc_ext,
1916                         {
1917                                 "Fragment Type", "wmx.genericPackSubhd.FcExt",
1918                                 FT_UINT24, BASE_HEX, VALS(frag_types), PACKING_SUBHEADER_FC_MASK,
1919                                 NULL, HFILL
1920                         }
1921                 },
1922                 {
1923                         &hf_mac_header_generic_packing_subhd_bsn,
1924                         {
1925                                 "First Block Sequence Number", "wmx.genericPackSubhd.Bsn",
1926                                 FT_UINT24, BASE_DEC, NULL, PACKING_SUBHEADER_BSN_MASK,
1927                                 NULL, HFILL
1928                         }
1929                 },
1930                 {
1931                         &hf_mac_header_generic_packing_subhd_fsn,
1932                         {
1933                                 "Fragment Number", "wmx.genericPackSubhd.Fsn",
1934                                 FT_UINT16, BASE_DEC, NULL, PACKING_SUBHEADER_FSN_MASK,
1935                                 NULL, HFILL
1936                         }
1937                 },
1938                 {
1939                         &hf_mac_header_generic_packing_subhd_fsn_ext,
1940                         {
1941                                 "Fragment Number", "wmx.genericPackSubhd.FsnExt",
1942                                 FT_UINT24, BASE_DEC, NULL, PACKING_SUBHEADER_BSN_MASK,
1943                                 NULL, HFILL
1944                         }
1945                 },
1946                 {
1947                         &hf_mac_header_generic_packing_subhd_len,
1948                         {
1949                                 "Length", "wmx.genericPackSubhd.Len",
1950                                 FT_UINT16, BASE_DEC, NULL, PACKING_SUBHEADER_LENGTH_MASK,
1951                                 NULL, HFILL
1952                         }
1953                 },
1954                 {
1955                         &hf_mac_header_generic_packing_subhd_len_ext,
1956                         {
1957                                 "Length", "wmx.genericPackSubhd.LenExt",
1958                                 FT_UINT24, BASE_DEC, NULL, PACKING_SUBHEADER_LENGTH_EXT_MASK,
1959                                 NULL, HFILL
1960                         }
1961                 }
1962         };
1963
1964         /* Fast-feedback Allocation Subheader display */
1965         static hf_register_info hf_fast[] =
1966         {
1967                 {
1968                         &hf_mac_header_generic_fast_fb_subhd_alloc_offset,
1969                         {
1970                                 "Allocation Offset", "wmx.genericFastFbSubhd.AllocOffset",
1971                                 FT_UINT8, BASE_DEC, NULL, FAST_FEEDBACK_ALLOCATION_OFFSET_MASK,
1972                                 NULL, HFILL
1973                         }
1974                 },
1975                 {
1976                         &hf_mac_header_generic_fast_fb_subhd_fb_type,
1977                         {
1978                                 "Feedback Type", "wmx.genericFastFbSubhd.FbType",
1979                                 FT_UINT8, BASE_DEC, VALS(fast_fb_types), FAST_FEEDBACK_FEEDBACK_TYPE_MASK,
1980                                 NULL, HFILL
1981                         }
1982                 }
1983         };
1984
1985         /* Grant Management Subheader display */
1986         static hf_register_info hf_grant[] =
1987         {
1988                 {
1989                         &hf_mac_header_generic_grant_mgmt_ext_pbr_tree,
1990                         {
1991                                 "Scheduling Service Type (Default)",
1992                                 "wimax.genericGrantSubhd.Default",
1993                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1994                                 NULL, HFILL
1995                         }
1996                 },
1997                 {
1998                         &hf_mac_header_generic_grant_mgmt_subhd_pbr,
1999                         {
2000                                 "PiggyBack Request", "wmx.genericGrantSubhd.Pbr",
2001                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2002                                 NULL, HFILL
2003                         }
2004                 },
2005                 {
2006                         &hf_mac_header_generic_grant_mgmt_ugs_tree,
2007                         {
2008                                 "Scheduling Service Type (UGS)", "wmx.genericGrantSubhd.UGS",
2009                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2010                                 NULL, HFILL
2011                         }
2012                 },
2013                 {
2014                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_si,
2015                         {
2016                                 "Slip Indicator", "wmx.genericGrantSubhd.Si",
2017                                 FT_UINT16, BASE_DEC, VALS(si_msgs), GRANT_MGMT_SUBHEADER_UGS_SI_MASK,
2018                                 NULL, HFILL
2019                         }
2020                 },
2021                 {
2022                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_pm,
2023                         {
2024                                 "Poll-Me", "wmx.genericGrantSubhd.Pm",
2025                                 FT_UINT16, BASE_DEC, VALS(pm_msgs), GRANT_MGMT_SUBHEADER_UGS_PM_MASK,
2026                                 NULL, HFILL
2027                         }
2028                 },
2029                 {
2030                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_fli,
2031                         {
2032                                 "Frame Latency Indication", "wmx.genericGrantSubhd.Fli",
2033                                 FT_UINT16, BASE_DEC, VALS(fli_msgs), GRANT_MGMT_SUBHEADER_UGS_FLI_MASK,
2034                                 NULL, HFILL
2035                         }
2036                 },
2037                 {
2038                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_fl,
2039                         {
2040                                 "Frame Latency", "wmx.genericGrantSubhd.Fl",
2041                                 FT_UINT16, BASE_DEC, NULL, GRANT_MGMT_SUBHEADER_UGS_FL_MASK,
2042                                 NULL, HFILL
2043                         }
2044                 },
2045                 {
2046                         &hf_mac_header_generic_grant_mgmt_subhd_ugs_rsv,
2047                         {
2048                                 "Reserved", "wmx.genericGrantSubhd.Rsv",
2049                                 FT_UINT16, BASE_DEC, NULL, GRANT_MGMT_SUBHEADER_UGS_RSV_MASK,
2050                                 NULL, HFILL
2051                         }
2052                 },
2053                 {
2054                         &hf_mac_header_generic_grant_mgmt_ext_rtps_tree,
2055                         {
2056                                 "Scheduling Service Type (Extended rtPS)",
2057                                 "wimax.genericGrantSubhd.ExtendedRTPS",
2058                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2059                                 NULL, HFILL
2060                         }
2061                 },
2062                 {
2063                         &hf_mac_header_generic_grant_mgmt_subhd_ext_pbr,
2064                         {
2065                                 "Extended PiggyBack Request", "wmx.genericGrantSubhd.ExtPbr",
2066                                 FT_UINT16, BASE_DEC, NULL, GRANT_MGMT_SUBHEADER_EXT_PBR_MASK,
2067                                 NULL, HFILL
2068                         }
2069                 },
2070                 {
2071                         &hf_mac_header_generic_grant_mgmt_subhd_ext_fli,
2072                         {
2073                                 "Frame Latency Indication", "wmx.genericGrantSubhd.ExtFli",
2074                                 FT_UINT16, BASE_DEC, VALS(fli_msgs), GRANT_MGMT_SUBHEADER_EXT_FLI_MASK,
2075                                 NULL, HFILL
2076                         }
2077                 },
2078                 {
2079                         &hf_mac_header_generic_grant_mgmt_subhd_ext_fl,
2080                         {
2081                                 "Frame Latency", "wmx.genericGrantSubhd.ExtFl",
2082                                 FT_UINT16, BASE_DEC, NULL, GRANT_MGMT_SUBHEADER_EXT_FL_MASK,
2083                                 NULL, HFILL
2084                         }
2085                 }
2086         };
2087
2088         /* ARQ Feedback Payload display */
2089         static hf_register_info hf_arq[] =
2090         {
2091                 {
2092                         &hf_mac_header_generic_arq_fb_ie_cid,
2093                         {
2094                                 "CID", "wmx.genericArq.FbIeCid",
2095                                 FT_UINT16, BASE_DEC, NULL, 0x0,
2096                                 NULL, HFILL
2097                         }
2098                 },
2099                 {
2100                         &hf_mac_header_generic_arq_fb_ie_last,
2101                         {
2102                                 "Last IE", "wmx.genericArq.FbIeLast",
2103                                 FT_UINT16, BASE_DEC, VALS(last_ie_msgs), ARQ_FB_IE_LAST_BIT_MASK,
2104                                 NULL, HFILL
2105                         }
2106                 },
2107                 {
2108                         &hf_mac_header_generic_arq_fb_ie_ack_type,
2109                         {
2110                                 "ACK Type", "wmx.genericArq.FbIeAckType",
2111                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_ACK_TYPE_MASK,
2112                                 NULL, HFILL
2113                         }
2114                 },
2115                 {
2116                         &hf_mac_header_generic_arq_fb_ie_bsn,
2117                         {
2118                                 "BSN", "wmx.genericArq.FbIeBsn",
2119                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_BSN_MASK,
2120                                 NULL, HFILL
2121                         }
2122                 },
2123                 {
2124                         &hf_mac_header_generic_arq_fb_ie_num_maps,
2125                         {
2126                                 "Number of ACK Maps", "wmx.genericArq.FbIeMaps",
2127                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_NUM_MAPS_MASK,
2128                                 NULL, HFILL
2129                         }
2130                 },
2131                 {
2132                         &hf_ack_type_reserved,
2133                         {
2134                                 "Reserved", "wmx.genericArq.FbIeRsvd", FT_UINT16, BASE_DEC, NULL, 0x03, NULL, HFILL
2135                         }
2136                 },
2137                 {
2138                         &hf_mac_header_generic_arq_fb_ie_sel_ack_map,
2139                         {
2140                                 "Selective ACK Map", "wmx.genericArq.FbIeSelAckMap",
2141                                 FT_UINT16, BASE_HEX, NULL, 0x0,
2142                                 NULL, HFILL
2143                         }
2144                 },
2145                 {
2146                         &hf_mac_header_generic_arq_fb_ie_seq_format,
2147                         {
2148                                 "Sequence Format", "wmx.genericArq.FbIeSeqFmt",
2149                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ_FORMAT_MASK,
2150                                 NULL, HFILL
2151                         }
2152                 },
2153                 {
2154                         &hf_mac_header_generic_arq_fb_ie_seq_ack_map,
2155                         {
2156                                 "Sequence ACK Map", "wmx.genericArq.FbIeSeqAckMap",
2157                                 FT_UINT16, BASE_HEX, NULL, ARQ_FB_IE_SEQ_ACK_MAP_MASK,
2158                                 NULL, HFILL
2159                         }
2160                 },
2161                 {
2162                         &hf_mac_header_generic_arq_fb_ie_seq1_length,
2163                         {
2164                                 "Sequence 1 Length", "wmx.genericArq.FbIeSeq1Len",
2165                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ1_LENGTH_MASK,
2166                                 NULL, HFILL
2167                         }
2168                 },
2169                 {
2170                         &hf_mac_header_generic_arq_fb_ie_seq2_length,
2171                         {
2172                                 "Sequence 2 Length", "wmx.genericArq.FbIeSeq2Len",
2173                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ2_LENGTH_MASK,
2174                                 NULL, HFILL
2175                         }
2176                 },
2177                 {
2178                         &hf_mac_header_generic_arq_fb_ie_seq3_length,
2179                         {
2180                                 "Sequence 3 Length", "wmx.genericArq.FbIeSeq3Len",
2181                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ3_LENGTH_MASK,
2182                                 NULL, HFILL
2183                         }
2184                 },
2185                 {
2186                         &hf_mac_header_generic_arq_fb_ie_seq_ack_map_2,
2187                         {
2188                                 "Sequence ACK Map", "wmx.genericArq.FbIeSeqAckMap2",
2189                                 FT_UINT16, BASE_HEX, NULL, ARQ_FB_IE_SEQ_ACK_MAP_2_MASK,
2190                                 NULL, HFILL
2191                         }
2192                 },
2193                 {
2194                         &hf_mac_header_generic_arq_fb_ie_seq1_length_6,
2195                         {
2196                                 "Sequence 1 Length", "wmx.genericArq.FbIeSeq1Len",
2197                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ1_LENGTH_6_MASK,
2198                                 NULL, HFILL
2199                         }
2200                 },
2201                 {
2202                         &hf_mac_header_generic_arq_fb_ie_seq2_length_6,
2203                         {
2204                                 "Sequence 2 Length", "wmx.genericArq.FbIeSeq2Len",
2205                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_SEQ2_LENGTH_6_MASK,
2206                                 NULL, HFILL
2207                         }
2208                 },
2209                 {
2210                         &hf_mac_header_generic_arq_fb_ie_rsv,
2211                         {
2212                                 "Reserved", "wmx.genericArq.FbIeRsv",
2213                                 FT_UINT16, BASE_DEC, NULL, ARQ_FB_IE_RSV_MASK,
2214                                 NULL, HFILL
2215                         }
2216                 }
2217         };
2218
2219         /* Setup protocol subtree array */
2220         static gint *ett[] =
2221                 {
2222                         &ett_mac_header_generic_decoder,
2223                         /* &ett_mac_subheader_decoder, */
2224                         &ett_mac_mesh_subheader_decoder,
2225                         &ett_mac_frag_subheader_decoder,
2226                         &ett_mac_grant_mgmt_subheader_decoder,
2227                         &ett_mac_pkt_subheader_decoder,
2228                         &ett_mac_fast_fb_subheader_decoder,
2229                         &ett_mac_ext_subheader_decoder,
2230                         &ett_mac_ext_subheader_dl_decoder,
2231                         &ett_mac_ext_subheader_ul_decoder,
2232                         &ett_mac_arq_fb_payload_decoder,
2233                         &ett_mac_data_pdu_decoder,
2234                 };
2235
2236         static ei_register_info ei[] = {
2237                 { &ei_mac_crc_malformed, { "wmx.genericCrc.missing", PI_MALFORMED, PI_ERROR, "CRC missing - the frame is too short", EXPFILL }},
2238                 { &ei_mac_crc_missing, { "wmx.genericCrc.missing", PI_PROTOCOL, PI_NOTE, "CRC is not included in this frame!", EXPFILL }},
2239         };
2240
2241         expert_module_t* expert_mac_header_generic;
2242
2243         proto_mac_header_generic_decoder = proto_register_protocol (
2244                 "WiMax Generic/Type1/Type2 MAC Header Messages", /* name       */
2245                 "WiMax Generic/Type1/Type2 MAC Header (hdr)",    /* short name */
2246                 "wmx.hdr"                                        /* abbrev     */
2247                 );
2248
2249         /* register the field display messages */
2250         proto_register_field_array(proto_mac_header_generic_decoder, hf,       array_length(hf));
2251         proto_register_field_array(proto_mac_header_generic_decoder, hf_ext,   array_length(hf_ext));
2252         proto_register_field_array(proto_mac_header_generic_decoder, hf_mesh,  array_length(hf_mesh));
2253         proto_register_field_array(proto_mac_header_generic_decoder, hf_frag,  array_length(hf_frag));
2254         proto_register_field_array(proto_mac_header_generic_decoder, hf_pack,  array_length(hf_pack));
2255         proto_register_field_array(proto_mac_header_generic_decoder, hf_fast,  array_length(hf_fast));
2256         proto_register_field_array(proto_mac_header_generic_decoder, hf_grant, array_length(hf_grant));
2257         proto_register_field_array(proto_mac_header_generic_decoder, hf_arq,   array_length(hf_arq));
2258         proto_register_subtree_array(ett, array_length(ett));
2259
2260         expert_mac_header_generic = expert_register_protocol(proto_mac_header_generic_decoder);
2261         expert_register_field_array(expert_mac_header_generic, ei, array_length(ei));
2262
2263         /* register the generic mac header dissector */
2264         register_dissector("mac_header_generic_handler", dissect_mac_header_generic_decoder, proto_mac_header_generic_decoder);
2265
2266         /* Register the payload fragment table init routine */
2267         register_init_routine(wimax_defragment_init);
2268 }
2269
2270 void
2271 proto_reg_handoff_mac_header_generic(void)
2272 {
2273         mac_mgmt_msg_decoder_handle = find_dissector("wmx_mac_mgmt_msg_decoder");
2274     mac_ip_handle = find_dissector("ip");
2275 }