1 /* packet-m2m.c
2 * Routines for WiMax MAC to MAC TLV packet disassembly
3 *
4 * Copyright (c) 2007 by Intel Corporation.
5 *
6 * Author: Lu Pan <lu.pan@intel.com>
7 *
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1999 Gerald Combs
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15 /* Include files */
16
17 #include "config.h"
18
19 #include <epan/packet.h>
20 #include <epan/reassemble.h>
21 #include <epan/etypes.h>
22 #include <epan/expert.h>
23 #include "wimax_tlv.h"
24
25 /* forward reference */
26 void proto_reg_handoff_m2m(void);
27 void proto_register_m2m(void);
28 static void fch_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo);
29 static void cdma_code_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo);
30 static void pdu_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo, gint burst_number, gint frag_type, gint frag_number);
31 static void fast_feedback_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo);
32 static void harq_ack_bursts_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo);
33 static void physical_attributes_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo);
34 static void extended_tlv_decoder(packet_info *pinfo);
35 void proto_tree_add_tlv(tlv_info_t *self, tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, gint hf, guint encoding);
36
37 /* Global variables */
38 static dissector_handle_t wimax_cdma_code_burst_handle;
39 static dissector_handle_t wimax_ffb_burst_handle;
40 static dissector_handle_t wimax_fch_burst_handle;
41 static dissector_handle_t wimax_hack_burst_handle;
42 static dissector_handle_t wimax_pdu_burst_handle;
43 static dissector_handle_t wimax_phy_attributes_burst_handle;
44
45 static reassembly_table pdu_reassembly_table;
46
47 static gint proto_m2m = -1;
48
49 static gint ett_m2m = -1;
50 static gint ett_m2m_tlv = -1;
51 static gint ett_m2m_fch = -1;
52 static gint ett_m2m_cdma = -1;
53 static gint ett_m2m_ffb = -1;
54
55 /* TLV types (rev:0.2) */
56 #define TLV_PROTO_VER 1
57 #define TLV_FRAME_NUM 2
58 #define TLV_BURST_NUM 3
59 #define TLV_FRAG_TYPE 4
60 #define TLV_FRAG_NUM 5
61 #define TLV_CDMA_CODE 7
62 #define TLV_FCH_BURST 8
63 #define TLV_PDU_BURST 9
64 #define TLV_FAST_FB 10
65 #define TLV_CRC16_STATUS 11
66 #define TLV_BURST_POWER 12
67 #define TLV_BURST_CINR 13
68 #define TLV_PREAMBLE 14
69 #define TLV_HARQ_ACK_BURST 15
70 #define TLV_PHY_ATTRIBUTES 16
71 #define TLV_EXTENDED_TLV 255
72
73 /* TLV names */
74 static const value_string tlv_name[] =
75 {
76 { TLV_PROTO_VER, "Protocol Version" },
77 { TLV_FRAME_NUM, "Frame Number" },
78 { TLV_BURST_NUM, "Burst Number" },
79 { TLV_FRAG_TYPE, "Fragment Type" },
80 { TLV_FRAG_NUM, "Fragment Number" },
81 { TLV_CDMA_CODE, "CDMA Attribute" },
82 { TLV_FCH_BURST, "FCH Burst" },
83 { TLV_PDU_BURST, "PDU Burst" },
84 { TLV_FAST_FB, "Fast Feedback Burst" },
85 { TLV_CRC16_STATUS, "CRC16 Status" },
86 { TLV_BURST_POWER, " Burst Power" },
87 { TLV_BURST_CINR, "Burst CINR" },
88 { TLV_PREAMBLE, "Preamble" },
89 { TLV_HARQ_ACK_BURST, "HARQ ACK Bursts" },
90 { TLV_PHY_ATTRIBUTES, "PDU Burst Physical Attributes" },
91 { TLV_EXTENDED_TLV, "Extended TLV" },
92 { 0, NULL }
93 };
94
95 /* TLV Fragment types */
96 #define TLV_NO_FRAG 0
97 #define TLV_FIRST_FRAG 1
98 #define TLV_MIDDLE_FRAG 2
99 #define TLV_LAST_FRAG 3
100
101 /* TLV Fragment Type names */
102 static const value_string tlv_frag_type_name[] =
103 {
104 { TLV_NO_FRAG, "No TLV Fragment" },
105 { TLV_FIRST_FRAG, "First TLV Fragment" },
106 { TLV_MIDDLE_FRAG, "Middle TLV Fragment" },
107 { TLV_LAST_FRAG, "Last TLV Fragment" },
108 { 0, NULL }
109 };
110
111 /* TLV CRC16 Status */
112 static const value_string tlv_crc16_status[] =
113 {
114 { 0, "No CRC-16 in burst" },
115 { 1, "Good CRC-16 in burst" },
116 { 2, "Bad CRC-16 in burst" },
117 { 0, NULL }
118 };
119
120 static gint hf_m2m_sequence_number = -1;
121 static gint hf_m2m_frame_number = -1;
122 static gint hf_m2m_tlv_count = -1;
123
124 static gint hf_m2m_type = -1;
125 static gint hf_m2m_len = -1;
126 static gint hf_m2m_len_size = -1;
127 /* static gint hf_m2m_value_bytes = -1; */
128 static gint hf_wimax_invalid_tlv = -1;
129 static gint hf_m2m_value_protocol_vers_uint8 = -1;
130 static gint hf_m2m_value_burst_num_uint8 = -1;
131 static gint hf_m2m_value_frag_type_uint8 = -1;
132 static gint hf_m2m_value_frag_num_uint8 = -1;
133 static gint hf_m2m_value_pdu_burst = -1;
134 static gint hf_m2m_value_fast_fb = -1;
135 static gint hf_m2m_value_fch_burst_uint24 = -1;
136 static gint hf_m2m_value_cdma_code_uint24 = -1;
137 static gint hf_m2m_value_crc16_status_uint8 = -1;
138 static gint hf_m2m_value_burst_power_uint16 = -1;
139 static gint hf_m2m_value_burst_cinr_uint16 = -1;
140 static gint hf_m2m_value_preamble_uint16 = -1;
141 static gint hf_m2m_value_harq_ack_burst_bytes = -1;
142 static gint hf_m2m_phy_attributes = -1;
143
144 static expert_field ei_m2m_unexpected_length = EI_INIT;
145
146
147 /* WiMax MAC to MAC protocol dissector */
dissect_m2m(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)148 static int dissect_m2m(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
149 {
150 proto_item *ti = NULL;
151 proto_item *m2m_item = NULL;
152 proto_tree *m2m_tree = NULL;
153 proto_tree *tlv_tree = NULL;
154 gint burst_number = 0;
155 gint length, offset = 0;
156 gint tlv_count;
157 gint tlv_type, tlv_len, tlv_offset, tlv_value;
158 gint tlv_frag_type = 0;
159 gint tlv_frag_number = 0;
160 tlv_info_t m2m_tlv_info;
161 gint hf;
162 guint encoding;
163 guint frame_number;
164 int expected_len;
165
166 /* display the M2M protocol name */
167 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WiMax");
168
169 /* Clear out stuff in the info column */
170 col_clear(pinfo->cinfo, COL_INFO);
171
172
173 { /* we are being asked for details */
174 m2m_item = proto_tree_add_item(tree, proto_m2m, tvb, 0, -1, ENC_NA);
175 m2m_tree = proto_item_add_subtree(m2m_item, ett_m2m);
176 /* get the tvb reported length */
177 length = tvb_reported_length(tvb);
178 /* add the size info */
179 /*
180 proto_item_append_text(m2m_item, " (%u bytes) - Packet Sequence Number,Number of TLVs", length);
181 */
182 proto_item_append_text(m2m_item, " (%u bytes)", length);
183 /* display the sequence number */
184 proto_tree_add_item(m2m_tree, hf_m2m_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN);
185 offset += 2;
186 /* display the TLV count */
187 proto_tree_add_item(m2m_tree, hf_m2m_tlv_count, tvb, offset, 2, ENC_BIG_ENDIAN);
188 tlv_count = tvb_get_ntohs(tvb, offset);
189 offset += 2;
190 /* parses the TLVs within current packet */
191 while ( tlv_count > 0)
192 { /* init MAC to MAC TLV information */
193 init_tlv_info(&m2m_tlv_info, tvb, offset);
194 /* get the TLV type */
195 tlv_type = get_tlv_type(&m2m_tlv_info);
196 /* get the TLV length */
197 tlv_len = get_tlv_length(&m2m_tlv_info);
198 if(tlv_type == -1 || tlv_len > 64000 || tlv_len < 1)
199 { /* invalid tlv info */
200 col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "M2M TLV error");
201 /* display the invalid TLV in HEX */
202 proto_tree_add_item(m2m_tree, hf_wimax_invalid_tlv, tvb, offset, (length - offset), ENC_NA);
203 break;
204 }
205 /* get the TLV value offset */
206 tlv_offset = get_tlv_value_offset(&m2m_tlv_info);
207 /* display TLV type */
208 ti = proto_tree_add_protocol_format(m2m_tree, proto_m2m, tvb, offset, (tlv_len + tlv_offset), "%s", val_to_str(tlv_type, tlv_name, "Unknown TLV"));
209 /* add TLV subtree */
210 tlv_tree = proto_item_add_subtree(ti, ett_m2m_tlv);
211 /* update the offset */
212 offset += tlv_offset;
213 /* add the size info */
214 /* decode TLV content (TLV value) */
215 expected_len = 0;
216 hf = 0;
217 encoding = ENC_NA;
218 switch (tlv_type)
219 {
220 case TLV_PROTO_VER:
221 /* get the protocol version */
222 tlv_value = tvb_get_guint8( tvb, offset );
223 /* add the description */
224 proto_item_append_text(ti, ": %d", tlv_value);
225 hf = hf_m2m_value_protocol_vers_uint8;
226 encoding = ENC_BIG_ENDIAN;
227 expected_len = 1;
228 break;
229
230 case TLV_BURST_NUM:
231 /* get the burst number */
232 burst_number = tvb_get_guint8( tvb, offset );
233 /* add the description */
234 proto_item_append_text(ti, ": %d", burst_number);
235 hf = hf_m2m_value_burst_num_uint8;
236 encoding = ENC_BIG_ENDIAN;
237 expected_len = 1;
238 break;
239
240 case TLV_FRAG_TYPE:
241 /* add the description */
242 tlv_frag_type = tvb_get_guint8( tvb, offset );
243 proto_item_append_text(ti, ": %s", val_to_str(tlv_frag_type, tlv_frag_type_name, "Unknown"));
244 hf = hf_m2m_value_frag_type_uint8;
245 encoding = ENC_BIG_ENDIAN;
246 expected_len = 1;
247 break;
248
249 case TLV_FRAG_NUM:
250 /* get the fragment number */
251 tlv_frag_number = tvb_get_guint8( tvb, offset );
252 /* add the description */
253 proto_item_append_text(ti, ": %d", tlv_frag_number);
254 hf = hf_m2m_value_frag_num_uint8;
255 encoding = ENC_BIG_ENDIAN;
256 expected_len = 1;
257 break;
258
259 case TLV_PDU_BURST:
260 /* display PDU Burst length info */
261 proto_item_append_text(ti, " (%u bytes)", tlv_len);
262 /* decode and display the PDU Burst */
263 pdu_burst_decoder(tree, tvb, offset, tlv_len, pinfo, burst_number, tlv_frag_type, tlv_frag_number);
264 hf = hf_m2m_value_pdu_burst;
265 encoding = ENC_NA;
266 break;
267
268 case TLV_FAST_FB:
269 /* display the Fast Feedback Burst length info */
270 proto_item_append_text(ti, " (%u bytes)", tlv_len);
271 /* decode and display the Fast Feedback Burst */
272 fast_feedback_burst_decoder(tree, tvb, offset, tlv_len, pinfo);
273 hf = hf_m2m_value_fast_fb;
274 encoding = ENC_NA;
275 break;
276
277 case TLV_FRAME_NUM:
278 /* get the frame number */
279 frame_number = tvb_get_ntoh24( tvb, offset );
280 /* add the description */
281 proto_tree_add_item(tlv_tree, hf_m2m_frame_number, tvb, offset, 3, ENC_BIG_ENDIAN);
282 proto_item_append_text(ti, ": %d", frame_number);
283 break;
284
285 case TLV_FCH_BURST:
286 /* add the description */
287 tlv_value = tvb_get_ntoh24( tvb, offset );
288 proto_item_append_text(ti, ": 0x%X", tlv_value);
289 /* decode and display the TLV FCH burst */
290 fch_burst_decoder(tree, tvb, offset, tlv_len, pinfo);
291 hf = hf_m2m_value_fch_burst_uint24;
292 encoding = ENC_BIG_ENDIAN;
293 expected_len = 3;
294 break;
295
296 case TLV_CDMA_CODE:
297 /* add the description */
298 tlv_value = tvb_get_ntoh24( tvb, offset );
299 proto_item_append_text(ti, ": 0x%X", tlv_value);
300 /* decode and display the CDMA Code */
301 cdma_code_decoder(tree, tvb, offset, tlv_len, pinfo);
302 hf = hf_m2m_value_cdma_code_uint24;
303 encoding = ENC_BIG_ENDIAN;
304 expected_len = 3;
305 break;
306
307 case TLV_CRC16_STATUS:
308 /* add the description */
309 tlv_value = tvb_get_guint8( tvb, offset );
310 proto_item_append_text(ti, ": %s", val_to_str(tlv_value, tlv_crc16_status, "Unknown"));
311 hf = hf_m2m_value_crc16_status_uint8;
312 encoding = ENC_BIG_ENDIAN;
313 expected_len = 1;
314 break;
315
316 case TLV_BURST_POWER:
317 /* add the description */
318 tlv_value = tvb_get_ntohs( tvb, offset );
319 proto_item_append_text(ti, ": %d", tlv_value);
320 hf = hf_m2m_value_burst_power_uint16;
321 encoding = ENC_BIG_ENDIAN;
322 expected_len = 2;
323 break;
324
325 case TLV_BURST_CINR:
326 /* add the description */
327 tlv_value = tvb_get_ntohs( tvb, offset );
328 proto_item_append_text(ti, ": 0x%X", tlv_value);
329 hf = hf_m2m_value_burst_cinr_uint16;
330 encoding = ENC_BIG_ENDIAN;
331 expected_len = 2;
332 break;
333
334 case TLV_PREAMBLE:
335 /* add the description */
336 tlv_value = tvb_get_ntohs( tvb, offset );
337 proto_item_append_text(ti, ": 0x%X", tlv_value);
338 hf = hf_m2m_value_preamble_uint16;
339 encoding = ENC_BIG_ENDIAN;
340 expected_len = 2;
341 break;
342
343 case TLV_HARQ_ACK_BURST:
344 /* display the Burst length info */
345 proto_item_append_text(ti, " (%u bytes)", tlv_len);
346 /* decode and display the HARQ ACK Bursts */
347 harq_ack_bursts_decoder(tree, tvb, offset, tlv_len, pinfo);
348 hf = hf_m2m_value_harq_ack_burst_bytes;
349 encoding = ENC_NA;
350 break;
351
352 case TLV_PHY_ATTRIBUTES:
353 /* display the Burst length info */
354 proto_item_append_text(ti, " (%u bytes)", tlv_len);
355 /* decode and display the PDU Burst Physical Attributes */
356 physical_attributes_decoder(tree, tvb, offset, tlv_len, pinfo);
357 hf = hf_m2m_phy_attributes;
358 encoding = ENC_NA;
359 break;
360
361 case TLV_EXTENDED_TLV:
362 /* display the Burst length info */
363 proto_item_append_text(ti, " (%u bytes)", tlv_len);
364 /* decode and display the Extended TLV */
365 extended_tlv_decoder(pinfo);
366 break;
367
368 default:
369 /* update the info column */
370 col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Unknown TLV Type");
371 break;
372 }
373 /* expand the TLV detail */
374 if (hf) {
375 if (offset - tlv_offset == expected_len) {
376 proto_tree_add_tlv(&m2m_tlv_info, tvb, offset - tlv_offset, pinfo, tlv_tree, hf, encoding);
377 } else {
378 expert_add_info_format(pinfo, NULL, &ei_m2m_unexpected_length, "Expected length %d, got %d.", expected_len, offset - tlv_offset);
379 }
380 }
381 offset += tlv_len;
382 /* update tlv_count */
383 tlv_count--;
384 }
385 }
386 return tvb_captured_length(tvb);
387 }
388
389 /* Decode and display the FCH burst */
fch_burst_decoder(proto_tree * tree,tvbuff_t * tvb,gint offset,gint length,packet_info * pinfo)390 static void fch_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo)
391 {
392 if(wimax_fch_burst_handle)
393 { /* call FCH dissector */
394 call_dissector(wimax_fch_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree);
395 }
396 else /* display FCH info */
397 { /* update the info column */
398 col_append_str(pinfo->cinfo, COL_INFO, "FCH Burst: DL Frame Prefix");
399 }
400 }
401
402 /* Decode and display the CDMA Code Attribute */
cdma_code_decoder(proto_tree * tree,tvbuff_t * tvb,gint offset,gint length,packet_info * pinfo)403 static void cdma_code_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo)
404 {
405 if(wimax_cdma_code_burst_handle)
406 { /* call CDMA dissector */
407 call_dissector(wimax_cdma_code_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree);
408 }
409 else /* display CDMA Code Attribute info */
410 { /* update the info column */
411 col_append_str(pinfo->cinfo, COL_INFO, "CDMA Code Attribute");
412 }
413 }
414
415 /* Decode and display the PDU Burst */
pdu_burst_decoder(proto_tree * tree,tvbuff_t * tvb,gint offset,gint length,packet_info * pinfo,gint burst_number,gint frag_type,gint frag_number)416 static void pdu_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo, gint burst_number, gint frag_type, gint frag_number)
417 {
418 fragment_head *pdu_frag;
419 tvbuff_t *pdu_tvb = NULL;
420
421 /* update the info column */
422 switch (frag_type)
423 {
424 case TLV_FIRST_FRAG:
425 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "First TLV Fragment (%d)", frag_number);
426 break;
427 case TLV_LAST_FRAG:
428 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Last TLV Fragment (%d)", frag_number);
429 break;
430 case TLV_MIDDLE_FRAG:
431 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Middle TLV Fragment %d", frag_number);
432 break;
433 }
434 if(frag_type == TLV_NO_FRAG)
435 { /* not fragmented PDU */
436 pdu_tvb = tvb_new_subset_length(tvb, offset, length);
437 }
438 else /* fragmented PDU */
439 { /* add the fragment */
440 pdu_frag = fragment_add_seq(&pdu_reassembly_table, tvb, offset, pinfo, burst_number, NULL, frag_number - 1, length, ((frag_type==TLV_LAST_FRAG)?0:1), 0);
441 if(pdu_frag && frag_type == TLV_LAST_FRAG)
442 {
443 /* create the new tvb for defragmented frame */
444 pdu_tvb = tvb_new_chain(tvb, pdu_frag->tvb_data);
445 /* add the defragmented data to the data source list */
446 add_new_data_source(pinfo, pdu_tvb, "Reassembled WiMax PDU Frame");
447 }
448 else
449 {
450 pdu_tvb = NULL;
451 if(frag_type == TLV_LAST_FRAG)
452 { /* update the info column */
453 col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Incomplete PDU frame");
454 }
455 }
456 }
457 /* process the defragmented PDU burst */
458 if(pdu_tvb)
459 {
460 if(wimax_pdu_burst_handle)
461 {/* decode and display PDU Burst */
462 call_dissector(wimax_pdu_burst_handle, pdu_tvb, pinfo, tree);
463 }
464 else /* display PDU Burst info */
465 { /* update the info column */
466 col_append_str(pinfo->cinfo, COL_INFO, "PDU Burst");
467 }
468 }
469 }
470
471 /* Decode and display the Fast Feedback Burst */
fast_feedback_burst_decoder(proto_tree * tree,tvbuff_t * tvb,gint offset,gint length,packet_info * pinfo)472 static void fast_feedback_burst_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo)
473 {
474 if(wimax_ffb_burst_handle)
475 { /* display the TLV Fast Feedback Burst dissector info */
476 call_dissector(wimax_ffb_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree);
477 }
478 else /* display the Fast Feedback Burst info */
479 { /* update the info column */
480 col_append_str(pinfo->cinfo, COL_INFO, "Fast Feedback Burst");
481 }
482 }
483
harq_ack_bursts_decoder(proto_tree * tree,tvbuff_t * tvb,gint offset,gint length,packet_info * pinfo)484 static void harq_ack_bursts_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo)
485 {
486 if(wimax_hack_burst_handle)
487 { /* call the TLV HARQ ACK Bursts dissector */
488 call_dissector(wimax_hack_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree);
489 }
490 else /* display the TLV HARQ ACK Bursts info */
491 { /* update the info column */
492 col_append_str(pinfo->cinfo, COL_INFO, "HARQ ACK Bursts");
493 }
494 }
495
physical_attributes_decoder(proto_tree * tree,tvbuff_t * tvb,gint offset,gint length,packet_info * pinfo)496 static void physical_attributes_decoder(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, packet_info *pinfo)
497 {
498 if(wimax_phy_attributes_burst_handle)
499 { /* call the TLV PDU Burst Physical Attributes dissector */
500 call_dissector(wimax_phy_attributes_burst_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree);
501 }
502 else /* display the TLV PDU Burst Physical Attributes info */
503 { /* update the info column */
504 col_append_str(pinfo->cinfo, COL_INFO, "PHY-attr");
505 }
506 }
507
extended_tlv_decoder(packet_info * pinfo)508 static void extended_tlv_decoder(packet_info *pinfo)
509 {
510 /* display the Extended TLV info */
511 /* update the info column */
512 col_append_str(pinfo->cinfo, COL_INFO, "Extended TLV");
513 }
514
515 /* Display the raw WiMax TLV */
proto_tree_add_tlv(tlv_info_t * self,tvbuff_t * tvb,guint offset,packet_info * pinfo,proto_tree * tree,gint hf,guint encoding)516 void proto_tree_add_tlv(tlv_info_t *self, tvbuff_t *tvb, guint offset, packet_info *pinfo, proto_tree *tree, gint hf, guint encoding)
517 {
518 guint tlv_offset;
519 gint tlv_type, tlv_len;
520
521 /* make sure the TLV information is valid */
522 if(!self->valid)
523 { /* invalid TLV info */
524 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Invalid TLV");
525 return;
526 }
527 tlv_offset = offset;
528 /* display TLV type */
529 proto_tree_add_item(tree, hf_m2m_type, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
530 tlv_offset++;
531 /* check the TLV length type */
532 if( self->length_type )
533 { /* multiple bytes TLV length */
534 /* display the length of the TLV length with MSB */
535 proto_tree_add_item(tree, hf_m2m_len_size, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
536 tlv_offset++;
537 if(self->size_of_length)
538 /* display the multiple byte TLV length */
539 proto_tree_add_item(tree, hf_m2m_len, tvb, tlv_offset, self->size_of_length, ENC_BIG_ENDIAN);
540 else
541 return;
542 }
543 else /* display the single byte TLV length */
544 proto_tree_add_item(tree, hf_m2m_len, tvb, tlv_offset, 1, ENC_BIG_ENDIAN);
545
546 tlv_type = get_tlv_type(self);
547 /* Display Frame Number as special case for filter */
548 if ( tlv_type == TLV_FRAME_NUM )
549 {
550 return;
551 }
552
553 /* get the TLV length */
554 tlv_len = get_tlv_length(self);
555 proto_tree_add_item(tree, hf, tvb, (offset + self->value_offset), tlv_len, encoding);
556 }
557
558 /* Register Wimax Mac to Mac Protocol */
proto_register_m2m(void)559 void proto_register_m2m(void)
560 {
561 /* M2M TLV display */
562 static hf_register_info hf[] =
563 {
564 {
565 &hf_m2m_sequence_number,
566 {
567 "Packet Sequence Number", "m2m.seq_number",
568 FT_UINT16, BASE_DEC, NULL, 0x0,
569 NULL, HFILL
570 }
571 },
572 {
573 &hf_m2m_frame_number,
574 {
575 "Value", "m2m.frame_number",
576 FT_UINT24, BASE_DEC, NULL, 0x0,
577 NULL, HFILL
578 }
579 },
580 {
581 &hf_m2m_tlv_count,
582 {
583 "Number of TLVs in the packet", "m2m.tlv_count",
584 FT_UINT16, BASE_DEC, NULL, 0x0,
585 NULL, HFILL
586 }
587 }
588 };
589
590 /* WiMax TLV display */
591 static hf_register_info hf_tlv[] =
592 {
593 {
594 &hf_m2m_type,
595 {
596 "Type", "m2m.tlv_type",
597 FT_UINT8, BASE_DEC, NULL, 0x0,
598 NULL, HFILL
599 }
600 },
601 {
602 &hf_m2m_len,
603 {
604 "Length", "m2m.tlv_len",
605 FT_UINT8, BASE_DEC, NULL, 0x0,
606 NULL, HFILL
607 }
608 },
609 {
610 &hf_m2m_len_size,
611 {
612 "Length Size", "m2m.tlv_len_size",
613 FT_UINT8, BASE_HEX, NULL, 0x0,
614 NULL, HFILL
615 }
616 },
617 #if 0
618 {
619 &hf_m2m_value_bytes,
620 {
621 "Value (hex)", "m2m.multibyte_tlv_value",
622 FT_BYTES, BASE_NONE, NULL, 0x0,
623 NULL, HFILL
624 }
625 },
626 #endif
627 {
628 &hf_m2m_value_protocol_vers_uint8,
629 {
630 "Value", "m2m.protocol_vers_tlv_value",
631 FT_UINT8, BASE_DEC, NULL, 0x0,
632 NULL, HFILL
633 }
634 },
635 {
636 &hf_m2m_value_burst_num_uint8,
637 {
638 "Value", "m2m.burst_num_tlv_value",
639 FT_UINT8, BASE_DEC, NULL, 0x0,
640 NULL, HFILL
641 }
642 },
643 {
644 &hf_m2m_value_frag_type_uint8,
645 {
646 "Value", "m2m.frag_type_tlv_value",
647 FT_UINT8, BASE_DEC, NULL, 0x0,
648 NULL, HFILL
649 }
650 },
651 {
652 &hf_m2m_value_frag_num_uint8,
653 {
654 "Value", "m2m.frag_num_tlv_value",
655 FT_UINT8, BASE_DEC, NULL, 0x0,
656 NULL, HFILL
657 }
658 },
659 {
660 &hf_m2m_value_pdu_burst,
661 {
662 "Value (hex)", "m2m.pdu_burst_tlv_value",
663 FT_BYTES, BASE_NONE, NULL, 0x0,
664 NULL, HFILL
665 }
666 },
667 {
668 &hf_m2m_value_fast_fb,
669 {
670 "Value (hex)", "m2m.fast_fb_tlv_value",
671 FT_BYTES, BASE_NONE, NULL, 0x0,
672 NULL, HFILL
673 }
674 },
675 {
676 &hf_m2m_value_fch_burst_uint24,
677 {
678 "Value", "m2m.fch_burst_tlv_value",
679 FT_UINT24, BASE_DEC, NULL, 0x0,
680 NULL, HFILL
681 }
682 },
683 {
684 &hf_m2m_value_cdma_code_uint24,
685 {
686 "Value", "m2m.cdma_code_tlv_value",
687 FT_UINT24, BASE_DEC, NULL, 0x0,
688 NULL, HFILL
689 }
690 },
691 {
692 &hf_m2m_value_crc16_status_uint8,
693 {
694 "Value", "m2m.crc16_status_tlv_value",
695 FT_UINT8, BASE_DEC, NULL, 0x0,
696 NULL, HFILL
697 }
698 },
699 {
700 &hf_m2m_value_burst_power_uint16,
701 {
702 "Value", "m2m.burst_power_tlv_value",
703 FT_UINT16, BASE_DEC, NULL, 0x0,
704 NULL, HFILL
705 }
706 },
707 {
708 &hf_m2m_value_burst_cinr_uint16,
709 {
710 "Value", "m2m.burst_cinr_tlv_value",
711 FT_UINT16, BASE_DEC, NULL, 0x0,
712 NULL, HFILL
713 }
714 },
715 {
716 &hf_m2m_value_preamble_uint16,
717 {
718 "Value", "m2m.preamble_tlv_value",
719 FT_UINT16, BASE_DEC, NULL, 0x0,
720 NULL, HFILL
721 }
722 },
723 {
724 &hf_m2m_value_harq_ack_burst_bytes,
725 {
726 "Value (hex)", "m2m.harq_ack_burst_tlv_value",
727 FT_BYTES, BASE_NONE, NULL, 0x0,
728 NULL, HFILL
729 }
730 },
731 {
732 &hf_m2m_phy_attributes,
733 {
734 "Value (hex)", "m2m.phy_attributes",
735 FT_BYTES, BASE_NONE, NULL, 0x0,
736 NULL, HFILL
737 }
738 },
739 {
740 &hf_wimax_invalid_tlv,
741 {
742 "Invalid TLV (hex)", "m2m.invalid_tlv",
743 FT_BYTES, BASE_NONE, NULL, 0x0,
744 NULL, HFILL
745 }
746 }
747 };
748
749 static gint *ett[] =
750 {
751 &ett_m2m,
752 &ett_m2m_tlv,
753 &ett_m2m_fch,
754 &ett_m2m_cdma,
755 &ett_m2m_ffb,
756 };
757
758 static ei_register_info ei[] = {
759 { &ei_m2m_unexpected_length, { "m2m.unexpected_length", PI_MALFORMED, PI_ERROR, "Unexpected length", EXPFILL }},
760 };
761
762 expert_module_t* expert_m2m;
763
764 proto_m2m = proto_register_protocol (
765 "WiMax Mac to Mac Packet", /* name */
766 "M2M (m2m)", /* short name */
767 "m2m" /* abbrev */
768 );
769
770 proto_register_field_array(proto_m2m, hf, array_length(hf));
771 proto_register_field_array(proto_m2m, hf_tlv, array_length(hf_tlv));
772 proto_register_subtree_array(ett, array_length(ett));
773 expert_m2m = expert_register_protocol(proto_m2m);
774 expert_register_field_array(expert_m2m, ei, array_length(ei));
775
776 /* Register reassembly table */
777 reassembly_table_register(&pdu_reassembly_table,
778 &addresses_reassembly_table_functions);
779 }
780
781 /* Register Wimax Mac to Mac Protocol handler */
proto_reg_handoff_m2m(void)782 void proto_reg_handoff_m2m(void)
783 {
784 dissector_handle_t m2m_handle;
785
786 m2m_handle = create_dissector_handle(dissect_m2m, proto_m2m);
787 dissector_add_uint("ethertype", ETHERTYPE_WMX_M2M, m2m_handle);
788
789 /* find the wimax handlers */
790 wimax_cdma_code_burst_handle = find_dissector("wimax_cdma_code_burst_handler");
791 wimax_fch_burst_handle = find_dissector("wimax_fch_burst_handler");
792 wimax_ffb_burst_handle = find_dissector("wimax_ffb_burst_handler");
793 wimax_hack_burst_handle = find_dissector("wimax_hack_burst_handler");
794 wimax_pdu_burst_handle = find_dissector("wimax_pdu_burst_handler");
795 wimax_phy_attributes_burst_handle = find_dissector("wimax_phy_attributes_burst_handler");
796 }
797
798 /*
799 * Editor modelines - https://www.wireshark.org/tools/modelines.html
800 *
801 * Local variables:
802 * c-basic-offset: 8
803 * tab-width: 8
804 * indent-tabs-mode: t
805 * End:
806 *
807 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
808 * :indentSize=8:tabSize=8:noTabs=false:
809 */
810