3 * Routines for WiMAX ASN Control Plane packet dissection dissection
5 * Copyright 2007, Mobile Metrics - http://www.mobilemetrics.net
7 * Author: Stephen Croll <croll@mobilemetrics.net>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/sminmpec.h>
25 #include <epan/addr_resolv.h>
26 #include <epan/ipproto.h>
27 #include <epan/expert.h>
29 #include <wsutil/filesystem.h>
30 #include <wsutil/report_message.h>
31 #include <epan/ws_printf.h>
33 #include "wimaxasncp_dict.h"
35 /* Forward declarations we need below */
36 void proto_register_wimaxasncp(void);
37 void proto_reg_handoff_wimaxasncp(void);
39 /* Initialize the protocol and registered fields */
40 static int proto_wimaxasncp
;
41 static int hf_wimaxasncp_version
;
42 static int hf_wimaxasncp_flags
;
43 static int hf_wimaxasncp_function_type
;
44 static int hf_wimaxasncp_op_id
;
45 static int hf_wimaxasncp_message_type
;
46 /* static int hf_wimaxasncp_qos_msg; */
47 /* static int hf_wimaxasncp_ho_control_msg; */
48 /* static int hf_wimaxasncp_data_path_control_msg; */
49 /* static int hf_wimaxasncp_context_delivery_msg; */
50 /* static int hf_wimaxasncp_r3_mobility_msg; */
51 /* static int hf_wimaxasncp_paging_msg; */
52 /* static int hf_wimaxasncp_rrm_msg; */
53 /* static int hf_wimaxasncp_authentication_msg; */
54 /* static int hf_wimaxasncp_ms_state_msg; */
55 /* static int hf_wimaxasncp_reauthentication_msg; */
56 /* static int hf_wimaxasncp_session_msg; */
57 static int hf_wimaxasncp_length
;
58 static int hf_wimaxasncp_msid
;
59 static int hf_wimaxasncp_reserved1
;
60 static int hf_wimaxasncp_transaction_id
;
61 static int hf_wimaxasncp_reserved2
;
62 /* static int hf_wimaxasncp_tlv; */
63 static int hf_wimaxasncp_tlv_type
;
64 static int hf_wimaxasncp_tlv_length
;
65 static int hf_wimaxasncp_tlv_value_bytes
;
66 static int hf_wimaxasncp_tlv_value_bitflags8
;
67 static int hf_wimaxasncp_tlv_value_bitflags16
;
68 static int hf_wimaxasncp_tlv_value_bitflags32
;
69 /* static int hf_wimaxasncp_tlv_value_protocol; */
70 /* static int hf_wimaxasncp_tlv_value_vendor_id; */
73 static bool show_transaction_id_d_bit
;
74 static bool debug_enabled
;
76 /* Default WiMAX ASN control protocol port */
77 #define WIMAXASNCP_DEF_UDP_PORT 2231
80 /* Initialize the subtree pointers */
81 static int ett_wimaxasncp
;
82 static int ett_wimaxasncp_flags
;
83 static int ett_wimaxasncp_tlv
;
84 static int ett_wimaxasncp_tlv_value_bitflags8
;
85 static int ett_wimaxasncp_tlv_value_bitflags16
;
86 static int ett_wimaxasncp_tlv_value_bitflags32
;
87 static int ett_wimaxasncp_tlv_protocol_list
;
88 static int ett_wimaxasncp_tlv_port_range_list
;
89 static int ett_wimaxasncp_tlv_ip_address_mask_list
;
90 static int ett_wimaxasncp_tlv_ip_address_mask
;
91 static int ett_wimaxasncp_tlv_eap
;
92 static int ett_wimaxasncp_tlv_vendor_specific_information_field
;
93 static int ett_wimaxasncp_port_range
;
95 static expert_field ei_wimaxasncp_tlv_type
;
96 static expert_field ei_wimaxasncp_function_type
;
97 static expert_field ei_wimaxasncp_op_id
;
98 static expert_field ei_wimaxasncp_message_type
;
99 static expert_field ei_wimaxasncp_length_bad
;
101 /* Header size, up to, but not including, the TLV fields. */
102 #define WIMAXASNCP_HEADER_SIZE 20
104 /* Offset to end of the length field in the header. */
105 #define WIMAXASNCP_HEADER_LENGTH_END 6
107 #define WIMAXASNCP_BIT32(n) (1U << (31 - (n)))
108 #define WIMAXASNCP_BIT16(n) (1U << (15 - (n)))
109 #define WIMAXASNCP_BIT8(n) (1U << ( 7 - (n)))
111 #define WIMAXASNCP_FLAGS_T WIMAXASNCP_BIT8(6)
112 #define WIMAXASNCP_FLAGS_R WIMAXASNCP_BIT8(7)
117 } wimaxasncp_build_dict_t
;
119 static wimaxasncp_dict_t
*wimaxasncp_dict
;
121 wimaxasncp_build_dict_t wimaxasncp_build_dict
;
123 static wimaxasncp_dict_tlv_t wimaxasncp_tlv_not_found
=
125 0, "Unknown", NULL
, WIMAXASNCP_TLV_UNKNOWN
, 0,
126 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
130 static dissector_handle_t wimaxasncp_handle
;
131 static dissector_handle_t eap_handle
;
133 /* ------------------------------------------------------------------------- */
135 static const value_string wimaxasncp_flag_vals
[] =
137 { WIMAXASNCP_BIT8(0), "Reserved" },
138 { WIMAXASNCP_BIT8(1), "Reserved" },
139 { WIMAXASNCP_BIT8(2), "Reserved" },
140 { WIMAXASNCP_BIT8(3), "Reserved" },
141 { WIMAXASNCP_BIT8(4), "Reserved" },
142 { WIMAXASNCP_BIT8(5), "Reserved" },
143 { WIMAXASNCP_FLAGS_T
, "T - Source and Destination Identifier TLVs"},
144 { WIMAXASNCP_FLAGS_R
, "R - Reset Next Expected Transaction ID"},
148 /* ------------------------------------------------------------------------- */
150 static const value_string wimaxasncp_op_id_vals
[] =
153 { 1, "Request/Initiation"},
163 /* ------------------------------------------------------------------------- */
165 #define WIMAXASNCP_FT_QOS 1
166 #define WIMAXASNCP_FT_HO_CONTROL 2
167 #define WIMAXASNCP_FT_DATA_PATH_CONTROL 3
168 #define WIMAXASNCP_FT_CONTEXT_TRANSFER 4
169 #define WIMAXASNCP_FT_R3_MOBILITY 5
170 #define WIMAXASNCP_FT_PAGING 6
171 #define WIMAXASNCP_FT_RRM 7
172 #define WIMAXASNCP_FT_AUTHENTICATION 8
173 #define WIMAXASNCP_FT_MS_STATE 9
174 #define WIMAXASNCP_FT_REAUTHENTICATION 10
175 /* since NWG R1 V1.2.0 */
176 #define WIMAXASNCP_FT_IM_OPERATIONS 10
177 /* since NWG R1 V1.2.1 */
178 #define WIMAXASNCP_FT_ACCOUNTING 11
180 /* ------------------------------------------------------------------------- */
182 /* struct to hold a value_string tuple, per version */
183 typedef struct _ver_value_string
189 static const ver_value_string wimaxasncp_function_type_vals
[] =
191 {0, { WIMAXASNCP_FT_QOS
, "QoS"}},
192 {0, { WIMAXASNCP_FT_HO_CONTROL
, "HO Control"}},
193 {0, { WIMAXASNCP_FT_DATA_PATH_CONTROL
, "Data Path Control"}},
194 {0, { WIMAXASNCP_FT_CONTEXT_TRANSFER
, "Context Transfer"}},
195 {0, { WIMAXASNCP_FT_R3_MOBILITY
, "R3 Mobility"}},
196 {0, { WIMAXASNCP_FT_PAGING
, "Paging"}},
197 {0, { WIMAXASNCP_FT_RRM
, "RRM"}},
198 {0, { WIMAXASNCP_FT_AUTHENTICATION
, "Authentication Relay"}},
199 {0, { WIMAXASNCP_FT_MS_STATE
, "MS State"}},
200 {0, { WIMAXASNCP_FT_REAUTHENTICATION
, "Re-Authentication"}},
201 {WIMAXASNCP_NWGVER_R10_V120
, {WIMAXASNCP_FT_IM_OPERATIONS
, "IM Operations"}},
202 {WIMAXASNCP_NWGVER_R10_V121
, { WIMAXASNCP_FT_ACCOUNTING
, "Accounting"}},
206 /* ------------------------------------------------------------------------- */
208 static const ver_value_string wimaxasncp_qos_msg_vals
[] =
216 /* ------------------------------------------------------------------------- */
218 static const ver_value_string wimaxasncp_ho_control_msg_vals
[] =
221 {0, { 2, "HO_Complete"}},
225 {WIMAXASNCP_NWGVER_R10_V120
, { 1, "HO_Req"}},
226 {WIMAXASNCP_NWGVER_R10_V120
, { 2, "HO_Rsp"}},
227 {WIMAXASNCP_NWGVER_R10_V120
, { 3, "HO_Ack"}},
228 {WIMAXASNCP_NWGVER_R10_V120
, { 4, "HO_Cnf"}},
229 {WIMAXASNCP_NWGVER_R10_V120
, { 5, "HO_Complete"}},
230 {WIMAXASNCP_NWGVER_R10_V120
, { 6, "HO_Directive"}},
231 {WIMAXASNCP_NWGVER_R10_V120
, { 7, "HO_Directive_Rsp"}},
235 /* ------------------------------------------------------------------------- */
237 static const ver_value_string wimaxasncp_data_path_control_msg_vals
[] =
239 {0, { 1, "Path_Dereg_Ack"}},
240 {0, { 2, "Path_Dereg_Req"}},
241 {0, { 3, "Path_Dereg_Rsp"}},
242 {0, { 4, "Path_Modification_Ack"}},
243 {0, { 5, "Path_Modification_Req"}},
244 {0, { 6, "Path_Modification_Rsp"}},
245 {0, { 7, "Path_Prereg_Ack"}},
246 {0, { 8, "Path_Prereg_Req"}},
247 {0, { 9, "Path_Prereg_Rsp"}},
248 {0, { 10, "Path_Reg_Ack"}},
249 {0, { 11, "Path_Reg_Req"}},
250 {0, { 12, "Path_Reg_Rsp"}},
251 {0, { 13, "MS_Attachment_Req"}},
252 {0, { 14, "MS_Attachment_Rsp"}},
253 {0, { 15, "MS_Attachment_Ack"}},
254 {0, { 16, "Key_Change_Directive"}},
255 {WIMAXASNCP_NWGVER_R10_V120
, { 1, "Path_Dereg_Req"}},
256 {WIMAXASNCP_NWGVER_R10_V120
, { 2, "Path_Dereg_Rsp"}},
257 {WIMAXASNCP_NWGVER_R10_V120
, { 3, "Path_Dereg_Ack"}},
258 {WIMAXASNCP_NWGVER_R10_V120
, { 4, "Path_Modification_Req"}},
259 {WIMAXASNCP_NWGVER_R10_V120
, { 5, "Path_Modification_Rsp"}},
260 {WIMAXASNCP_NWGVER_R10_V120
, { 6, "Path_Modification_Ack"}},
261 {WIMAXASNCP_NWGVER_R10_V120
, { 7, "Path_Prereg_Req"}},
262 {WIMAXASNCP_NWGVER_R10_V120
, { 8, "Path_Prereg_Rsp"}},
263 {WIMAXASNCP_NWGVER_R10_V120
, { 9, "Path_Prereg_Ack"}},
264 {WIMAXASNCP_NWGVER_R10_V120
, { 10, "Path_Reg_Req"}},
265 {WIMAXASNCP_NWGVER_R10_V120
, { 11, "Path_Reg_Rsp"}},
266 {WIMAXASNCP_NWGVER_R10_V120
, { 12, "Path_Reg_Ack"}},
267 {WIMAXASNCP_NWGVER_R10_V120
, { 13, "Obsolete"}},
268 {WIMAXASNCP_NWGVER_R10_V120
, { 14, "Obsolete"}},
269 {WIMAXASNCP_NWGVER_R10_V120
, { 15, "Obsolete"}},
270 {WIMAXASNCP_NWGVER_R10_V120
, { 16, "Obsolete"}},
274 /* ------------------------------------------------------------------------- */
276 static const ver_value_string wimaxasncp_context_transfer_msg_vals
[] =
278 {0, { 1, "Context_Rpt"}},
279 {0, { 2, "Context_Req"}},
280 {0, { 3, "Context_Ack"}},
281 {WIMAXASNCP_NWGVER_R10_V120
, { 1, "Context_Req"}},
282 {WIMAXASNCP_NWGVER_R10_V120
, { 2, "Context_Rpt"}},
283 {WIMAXASNCP_NWGVER_R10_V120
, { 4, "CMAC_Key_Count_Update"}},
284 {WIMAXASNCP_NWGVER_R10_V120
, { 5, "CMAC_Key_Count_Update_ACK"}},
285 {WIMAXASNCP_NWGVER_R10_V120
, { 6, "CMAC_Key_Count_Req"}},
286 {WIMAXASNCP_NWGVER_R10_V120
, { 7, "CMAC_Key_Count_Rsp"}},
287 {WIMAXASNCP_NWGVER_R10_V120
, { 8, "Prepaid Request"}},
288 {WIMAXASNCP_NWGVER_R10_V120
, { 9, "Prepaid Notify"}},
289 {WIMAXASNCP_NWGVER_R10_V121
, { 6, "VOID"}},
290 {WIMAXASNCP_NWGVER_R10_V121
, { 7, "VOID"}},
291 {WIMAXASNCP_NWGVER_R10_V121
, { 0, NULL
}}
294 /* ------------------------------------------------------------------------- */
296 static const ver_value_string wimaxasncp_r3_mobility_msg_vals
[] =
298 {0, { 1, "Anchor_DPF_HO_Req"}},
299 {0, { 2, "Anchor_DPF_HO_Trigger"}},
300 {0, { 3, "Anchor_DPF_HO_Rsp"}},
301 {0, { 4, "Anchor_DPF_Relocate_Req"}},
302 {0, { 5, "FA_Register_Req"}},
303 {0, { 6, "FA_Register_Rsp"}},
304 {0, { 7, "Anchor_DPF_Relocate_Rsp"}},
305 {0, { 8, "FA_Revoke_Req"}},
306 {0, { 9, "FA_Revoke_Rsp"}},
307 {WIMAXASNCP_NWGVER_R10_V120
, { 5, "Anchor_DPF_Relocate_Rsp"}},
308 {WIMAXASNCP_NWGVER_R10_V120
, { 6, "FA_Register_Req"}},
309 {WIMAXASNCP_NWGVER_R10_V120
, { 7, "FA_Register_Rsp"}},
310 {WIMAXASNCP_NWGVER_R10_V120
, { 10, "Anchor_DPF_Release_Req"}},
311 {WIMAXASNCP_NWGVER_R10_V120
, { 11, "Relocation_Ready_Req"}},
312 {WIMAXASNCP_NWGVER_R10_V120
, { 12, "Relocation_Ready_Rsp"}},
316 /* ------------------------------------------------------------------------- */
318 static const ver_value_string wimaxasncp_paging_msg_vals
[] =
320 {0, { 1, "Initiate_Paging_Req"}},
321 {0, { 2, "Initiate_Paging_Rsp"}},
325 {0, { 6, "Paging_Announce"}},
326 {0, { 7, "CMAC_Key_Count_Req"}},
327 {0, { 8, "CMAC_Key_Count_Rsp"}},
328 {WIMAXASNCP_NWGVER_R10_V120
, { 1, "Paging_Announce"}},
329 {WIMAXASNCP_NWGVER_R10_V120
, { 2, "Delete_MS_Entry_Req"}},
330 {WIMAXASNCP_NWGVER_R10_V120
, { 3, "PC_Relocation_Ind"}},
331 {WIMAXASNCP_NWGVER_R10_V120
, { 4, "PC_Relocation_Ack"}},
332 {WIMAXASNCP_NWGVER_R10_V120
, { 5, "Obsolete"}},
333 {WIMAXASNCP_NWGVER_R10_V120
, { 6, "Obsolete"}},
334 {WIMAXASNCP_NWGVER_R10_V120
, { 7, "Obsolete"}},
335 {WIMAXASNCP_NWGVER_R10_V120
, { 8, "Obsolete"}},
339 /* ------------------------------------------------------------------------- */
341 static const ver_value_string wimaxasncp_rrm_msg_vals
[] =
343 {0, { 1, "R6 PHY_Parameters_Req"}},
344 {0, { 2, "R6 PHY_Parameters_Rpt"}},
345 {0, { 3, "R4/R6 Spare_Capacity_Req"}},
346 {0, { 4, "R4/R6 Spare_Capacity_Rpt"}},
347 {0, { 5, "R6 Neighbor_BS_Resource_Status_Update"}},
348 {0, { 6, "R4/R6 Radio_Config_Update_Req"}},
349 {0, { 7, "R4/R6 Radio_Config_Update_Rpt"}},
350 {WIMAXASNCP_NWGVER_R10_V120
, { 8, "R4/R6 Radio_Config_Update_Ack"}},
354 /* ------------------------------------------------------------------------- */
356 static const ver_value_string wimaxasncp_authentication_msg_vals
[] =
358 {0, { 1, "AR_Authenticated_Eap_Start"}},
359 {0, { 2, "AR_Authenticated_EAP_Transfer"}},
360 {0, { 3, "AR_Eap_Start"}},
361 {0, { 4, "AR_EAP_Transfer"}},
362 {0, { 5, "AR_EAP_Complete"}},
363 {WIMAXASNCP_NWGVER_R10_V120
, { 1, "AR_EAP_Start"}},
364 {WIMAXASNCP_NWGVER_R10_V120
, { 2, "AR_EAP_Transfer"}},
365 {WIMAXASNCP_NWGVER_R10_V120
, { 3, "Bulk_Interim_Update"}},
366 {WIMAXASNCP_NWGVER_R10_V120
, { 4, "Bulk_Interim_Update_Ack"}},
367 {WIMAXASNCP_NWGVER_R10_V120
, { 5, "Obsolete"}},
371 /* ------------------------------------------------------------------------- */
373 static const ver_value_string wimaxasncp_ms_state_msg_vals
[] =
375 {0, { 1, "IM_Entry_State_Change_Req"}},
376 {0, { 2, "IM_Entry_State_Change_Rsp"}},
377 {0, { 3, "IM_Exit_State_Change_Req"}},
378 {0, { 4, "IM_Exit_State_Change_Rsp"}},
379 {0, { 5, "NW_ReEntry_State_Change_Directive"}},
380 {0, { 6, "MS_PreAttachment_Req"}},
381 {0, { 7, "MS_PreAttachment_Rsp"}},
382 {0, { 8, "MS_PreAttachment_Ack"}},
383 {WIMAXASNCP_NWGVER_R10_V120
, { 1, "MS_PreAttachment_Req"}},
384 {WIMAXASNCP_NWGVER_R10_V120
, { 2, "MS_PreAttachment_Rsp"}},
385 {WIMAXASNCP_NWGVER_R10_V120
, { 3, "MS_PreAttachment_Ack"}},
386 {WIMAXASNCP_NWGVER_R10_V120
, { 4, "MS_Attachment_Req"}},
387 {WIMAXASNCP_NWGVER_R10_V120
, { 5, "MS_Attachment_Rsp"}},
388 {WIMAXASNCP_NWGVER_R10_V120
, { 6, "MS_Attachment_Ack"}},
389 {WIMAXASNCP_NWGVER_R10_V120
, { 7, "Key_Change_Directive"}},
390 {WIMAXASNCP_NWGVER_R10_V120
, { 8, "Key_Change_Cnf"}},
391 {WIMAXASNCP_NWGVER_R10_V120
, { 9, "Key_Change_Ack"}},
392 {WIMAXASNCP_NWGVER_R10_V120
, { 10, "Relocation_Complete_Req"}},
393 {WIMAXASNCP_NWGVER_R10_V120
, { 11, "Relocation_Complete_Rsp"}},
394 {WIMAXASNCP_NWGVER_R10_V120
, { 12, "Relocation_Complete_Ack"}},
395 {WIMAXASNCP_NWGVER_R10_V120
, { 13, "Relocation_Notify"}},
396 {WIMAXASNCP_NWGVER_R10_V120
, { 14, "Relocation_Req"}},
397 {WIMAXASNCP_NWGVER_R10_V120
, { 15, "Relocation_Rsp"}},
398 {WIMAXASNCP_NWGVER_R10_V120
, { 16, "NetExit_MS_State_Change_Req"}},
399 {WIMAXASNCP_NWGVER_R10_V120
, { 17, "NetExit_MS_State_Change_Rsp"}},
403 /* ------------------------------------------------------------------------- */
405 /* note - function type 10-im_operation, was once used for re-authentication */
406 static const ver_value_string wimaxasncp_im_operations_msg_vals
[] =
408 {0, { 1, "AR_EAP_Start"}},
409 {0, { 2, "Key_Change_Directive"}},
410 {0, { 3, "Key_Change_Cnf"}},
411 {0, { 4, "Relocation_Cnf"}},
412 {0, { 5, "Relocation_Confirm_Ack"}},
413 {0, { 6, "Relocation_Notify"}},
414 {0, { 7, "Relocation_Notify_Ack"}},
415 {0, { 8, "Relocation_Req"}},
416 {0, { 9, "Relocation_Rsp"}},
417 {WIMAXASNCP_NWGVER_R10_V120
, { 1, "IM_Entry_State_Change_Req"}},
418 {WIMAXASNCP_NWGVER_R10_V120
, { 2, "IM_Entry_State_Change_Rsp"}},
419 {WIMAXASNCP_NWGVER_R10_V120
, { 3, "IM_Entry_State_Change_Ack"}},
420 {WIMAXASNCP_NWGVER_R10_V120
, { 4, "IM_Exit_State_Change_Req"}},
421 {WIMAXASNCP_NWGVER_R10_V120
, { 5, "IM_Exit_State_Change_Rsp"}},
422 {WIMAXASNCP_NWGVER_R10_V120
, { 6, "Initiate_Paging_Req"}},
423 {WIMAXASNCP_NWGVER_R10_V120
, { 7, "Initiate_Paging_Rsp"}},
424 {WIMAXASNCP_NWGVER_R10_V120
, { 8, "LU_Req"}},
425 {WIMAXASNCP_NWGVER_R10_V120
, { 9, "LU_Rsp"}},
426 {WIMAXASNCP_NWGVER_R10_V120
, { 10, "LU_Cnf"}},
430 /* ------------------------------------------------------------------------- */
432 static const ver_value_string wimaxasncp_accounting_msg_vals_r1v121
[] =
434 {WIMAXASNCP_NWGVER_R10_V121
, { 1, "Hot_lining_Req"}},
435 {WIMAXASNCP_NWGVER_R10_V121
, { 2, "Hot_lining_Rsp"}},
439 /* ------------------------------------------------------------------------- */
441 /* supported NWG versions */
442 static const enum_val_t wimaxasncp_nwg_versions
[] = {
443 { "R1.0_v1.0.0", "Release 1.0, Version 1.0.0", WIMAXASNCP_NWGVER_R10_V100
},
444 { "R1.0_v1.2.0", "Release 1.0, Version 1.2.0", WIMAXASNCP_NWGVER_R10_V120
},
445 { "R1.0_v1.2.1", "Release 1.0, Version 1.2.1", WIMAXASNCP_NWGVER_R10_V121
},
449 /* ------------------------------------------------------------------------- */
452 #define WIMAXASNCP_DEF_NWGVER WIMAXASNCP_NWGVER_R10_V121
453 static unsigned global_wimaxasncp_nwg_ver
= WIMAXASNCP_DEF_NWGVER
;
455 /* ========================================================================= */
458 uint8_t function_type
;
459 const ver_value_string
*vals
;
460 } wimaxasncp_func_msg_t
;
462 /* ------------------------------------------------------------------------ */
464 static const wimaxasncp_func_msg_t wimaxasncp_func_to_msg_vals_map
[] =
466 { WIMAXASNCP_FT_QOS
, wimaxasncp_qos_msg_vals
},
467 { WIMAXASNCP_FT_HO_CONTROL
, wimaxasncp_ho_control_msg_vals
},
468 { WIMAXASNCP_FT_DATA_PATH_CONTROL
, wimaxasncp_data_path_control_msg_vals
},
469 { WIMAXASNCP_FT_CONTEXT_TRANSFER
, wimaxasncp_context_transfer_msg_vals
},
470 { WIMAXASNCP_FT_R3_MOBILITY
, wimaxasncp_r3_mobility_msg_vals
},
471 { WIMAXASNCP_FT_PAGING
, wimaxasncp_paging_msg_vals
},
472 { WIMAXASNCP_FT_RRM
, wimaxasncp_rrm_msg_vals
},
473 { WIMAXASNCP_FT_AUTHENTICATION
, wimaxasncp_authentication_msg_vals
},
474 { WIMAXASNCP_FT_MS_STATE
, wimaxasncp_ms_state_msg_vals
},
475 { WIMAXASNCP_FT_IM_OPERATIONS
, wimaxasncp_im_operations_msg_vals
},
476 { WIMAXASNCP_FT_ACCOUNTING
, wimaxasncp_accounting_msg_vals_r1v121
}
479 /* ========================================================================= */
481 static const wimaxasncp_dict_tlv_t
*wimaxasncp_get_tlv_info(
484 wimaxasncp_dict_tlv_t
*res
= NULL
;
488 wimaxasncp_dict_tlv_t
*tlv
;
490 for (tlv
= wimaxasncp_dict
->tlvs
; tlv
; tlv
= tlv
->next
)
492 if (tlv
->type
== type
)
494 /* if the TLV is defined for current NWG version */
495 if (tlv
->since
<= global_wimaxasncp_nwg_ver
)
497 /* if the current TLV is newer then last found TLV, save it */
498 if (!res
|| (tlv
->since
> res
->since
))
507 if (debug_enabled
&& !res
)
509 g_print("fix-me: unknown TLV type: %u\n", type
);
512 return res
? res
:&wimaxasncp_tlv_not_found
;
515 /* ========================================================================= */
517 static const char *wimaxasncp_get_enum_name(
518 const wimaxasncp_dict_tlv_t
*tlv_info
,
521 if (tlv_info
->enum_vs
)
523 return val_to_str_const(code
, tlv_info
->enum_vs
, "Unknown");
531 /* ========================================================================= */
533 static const value_string wimaxasncp_decode_type_vals
[] =
535 { WIMAXASNCP_TLV_UNKNOWN
, "WIMAXASNCP_TLV_UNKNOWN"},
536 { WIMAXASNCP_TLV_TBD
, "WIMAXASNCP_TLV_TBD"},
537 { WIMAXASNCP_TLV_COMPOUND
, "WIMAXASNCP_TLV_COMPOUND"},
538 { WIMAXASNCP_TLV_BYTES
, "WIMAXASNCP_TLV_BYTES"},
539 { WIMAXASNCP_TLV_ENUM8
, "WIMAXASNCP_TLV_ENUM8"},
540 { WIMAXASNCP_TLV_ENUM16
, "WIMAXASNCP_TLV_ENUM16"},
541 { WIMAXASNCP_TLV_ENUM32
, "WIMAXASNCP_TLV_ENUM32"},
542 { WIMAXASNCP_TLV_ETHER
, "WIMAXASNCP_TLV_ETHER"},
543 { WIMAXASNCP_TLV_ASCII_STRING
, "WIMAXASNCP_TLV_ASCII_STRING"},
544 { WIMAXASNCP_TLV_FLAG0
, "WIMAXASNCP_TLV_FLAG0"},
545 { WIMAXASNCP_TLV_BITFLAGS8
, "WIMAXASNCP_TLV_BITFLAGS8"},
546 { WIMAXASNCP_TLV_BITFLAGS16
, "WIMAXASNCP_TLV_BITFLAGS16"},
547 { WIMAXASNCP_TLV_BITFLAGS32
, "WIMAXASNCP_TLV_BITFLAGS32"},
548 { WIMAXASNCP_TLV_ID
, "WIMAXASNCP_TLV_ID"},
549 { WIMAXASNCP_TLV_HEX8
, "WIMAXASNCP_TLV_HEX8"},
550 { WIMAXASNCP_TLV_HEX16
, "WIMAXASNCP_TLV_HEX16"},
551 { WIMAXASNCP_TLV_HEX32
, "WIMAXASNCP_TLV_HEX32"},
552 { WIMAXASNCP_TLV_DEC8
, "WIMAXASNCP_TLV_DEC8"},
553 { WIMAXASNCP_TLV_DEC16
, "WIMAXASNCP_TLV_DEC16"},
554 { WIMAXASNCP_TLV_DEC32
, "WIMAXASNCP_TLV_DEC32"},
555 { WIMAXASNCP_TLV_IP_ADDRESS
, "WIMAXASNCP_TLV_IP_ADDRESS"},
556 { WIMAXASNCP_TLV_IPV4_ADDRESS
, "WIMAXASNCP_TLV_IPV4_ADDRESS"},
557 { WIMAXASNCP_TLV_PROTOCOL_LIST
, "WIMAXASNCP_TLV_PROTOCOL_LIST"},
558 { WIMAXASNCP_TLV_PORT_RANGE_LIST
, "WIMAXASNCP_TLV_PORT_RANGE_LIST"},
559 { WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST
, "WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST"},
560 { WIMAXASNCP_TLV_VENDOR_SPECIFIC
, "WIMAXASNCP_TLV_VENDOR_SPECIFIC"},
564 /* ========================================================================= */
566 static void wimaxasncp_proto_tree_add_tlv_ipv4_value(
570 proto_item
*tlv_item
,
572 const wimaxasncp_dict_tlv_t
*tlv_info
)
576 const char *addr_res
;
578 if (tlv_info
->hf_ipv4
> 0)
580 hf_value
= tlv_info
->hf_ipv4
;
584 hf_value
= tlv_info
->hf_value
;
587 ip
= tvb_get_ipv4(tvb
, offset
);
588 addr_res
= tvb_address_with_resolution_to_str(pinfo
->pool
, tvb
, AT_IPv4
, offset
);
590 proto_tree_add_ipv4_format(
593 "Value: %s", addr_res
);
595 proto_item_append_text(
596 tlv_item
, " - %s", addr_res
);
599 /* ========================================================================= */
601 static void wimaxasncp_proto_tree_add_tlv_ipv6_value(
605 proto_item
*tlv_item
,
607 const wimaxasncp_dict_tlv_t
*tlv_info
)
611 const char *addr_res
;
613 if (tlv_info
->hf_ipv4
> 0)
615 hf_value
= tlv_info
->hf_ipv6
;
619 hf_value
= tlv_info
->hf_value
;
622 tvb_get_ipv6(tvb
, offset
, &ip
);
623 addr_res
= tvb_address_with_resolution_to_str(pinfo
->pool
, tvb
, AT_IPv6
, offset
);
625 proto_tree_add_ipv6_format(
627 tvb
, offset
, 16, &ip
,
628 "Value: %s", addr_res
);
630 proto_item_append_text(
631 tlv_item
, " - %s", addr_res
);
634 /* ========================================================================= */
636 static void wimaxasncp_proto_tree_add_ether_value(
640 proto_item
*tlv_item
,
643 const wimaxasncp_dict_tlv_t
*tlv_info
)
647 const char *ether_name
;
649 if (tlv_info
->hf_bsid
> 0)
651 hf_value
= tlv_info
->hf_bsid
;
655 hf_value
= tlv_info
->hf_value
;
658 p
= tvb_get_ptr(tvb
, offset
, length
);
659 ether_name
= tvb_address_with_resolution_to_str(pinfo
->pool
, tvb
, AT_ETHER
, offset
);
661 proto_tree_add_ether_format(
663 tvb
, offset
, length
, p
,
667 proto_item_append_text(
672 /* ========================================================================= */
674 static void wimaxasncp_dissect_tlv_value(
678 proto_item
*tlv_item
,
679 const wimaxasncp_dict_tlv_t
*tlv_info
)
683 const unsigned max_show_bytes
= 24; /* arbitrary */
684 static const char *hex_note
= "[hex]";
686 length
= tvb_reported_length(tvb
);
688 switch (tlv_info
->decoder
)
690 case WIMAXASNCP_TLV_ENUM8
:
698 if (tlv_info
->enums
== NULL
)
702 g_print("fix-me: enum values missing for TLV %s (%u)\n",
703 tlv_info
->name
, tlv_info
->type
);
712 value
= tvb_get_uint8(tvb
, offset
);
714 s
= wimaxasncp_get_enum_name(tlv_info
, value
);
716 proto_tree_add_uint_format(
717 tree
, tlv_info
->hf_value
,
718 tvb
, offset
, length
, value
,
719 "Value: %s (%u)", s
, value
);
721 proto_item_append_text(tlv_item
, " - %s", s
);
726 case WIMAXASNCP_TLV_ENUM16
:
734 if (tlv_info
->enums
== NULL
)
738 g_print("fix-me: enum values missing for TLV %s (%u)\n",
739 tlv_info
->name
, tlv_info
->type
);
748 value
= tvb_get_ntohs(tvb
, offset
);
750 s
= wimaxasncp_get_enum_name(tlv_info
, value
);
752 proto_tree_add_uint_format(
753 tree
, tlv_info
->hf_value
,
754 tvb
, offset
, length
, value
,
755 "Value: %s (%u)", s
, value
);
757 proto_item_append_text(tlv_item
, " - %s", s
);
762 case WIMAXASNCP_TLV_ENUM32
:
770 if (tlv_info
->enums
== NULL
)
774 g_print("fix-me: enum values missing for TLV %s (%u)\n",
775 tlv_info
->name
, tlv_info
->type
);
784 value
= tvb_get_ntohl(tvb
, offset
);
786 s
= wimaxasncp_get_enum_name(tlv_info
, value
);
788 proto_tree_add_uint_format(
789 tree
, tlv_info
->hf_value
,
790 tvb
, offset
, length
, value
,
791 "Value: %s (%u)", s
, value
);
793 proto_item_append_text(tlv_item
, " - %s", s
);
798 case WIMAXASNCP_TLV_ETHER
:
808 wimaxasncp_proto_tree_add_ether_value(
809 pinfo
, tvb
, tree
, tlv_item
, offset
, length
, tlv_info
);
814 case WIMAXASNCP_TLV_ASCII_STRING
:
818 const char *s
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, length
, ENC_ASCII
);
820 proto_tree_add_string_format(
821 tree
, tlv_info
->hf_value
,
822 tvb
, offset
, length
, s
,
825 proto_item_append_text(
826 tlv_item
, " - %s", s
);
831 case WIMAXASNCP_TLV_FLAG0
:
841 case WIMAXASNCP_TLV_BITFLAGS8
:
849 if (tlv_info
->enums
== NULL
)
851 /* enum values missing */
856 proto_tree
*flags_tree
;
861 value
= tvb_get_uint8(tvb
, offset
);
863 item
= proto_tree_add_item(
864 tree
, tlv_info
->hf_value
,
865 tvb
, offset
, 1, ENC_NA
);
867 proto_item_append_text(tlv_item
, " - 0x%02x", value
);
871 flags_tree
= proto_item_add_subtree(
872 item
, ett_wimaxasncp_tlv_value_bitflags8
);
874 for (i
= 0; i
< 8; ++i
)
877 mask
= 1U << (7 - i
);
883 s
= wimaxasncp_get_enum_name(tlv_info
, value
& mask
);
885 proto_tree_add_uint_format(
886 flags_tree
, hf_wimaxasncp_tlv_value_bitflags8
,
887 tvb
, offset
, length
, value
,
888 "Bit #%u is set: %s", i
, s
);
896 case WIMAXASNCP_TLV_BITFLAGS16
:
904 if (tlv_info
->enums
== NULL
)
906 /* enum values missing */
911 proto_tree
*flags_tree
;
916 value
= tvb_get_ntohs(tvb
, offset
);
918 item
= proto_tree_add_item(
919 tree
, tlv_info
->hf_value
,
920 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
922 proto_item_append_text(tlv_item
, " - 0x%04x", value
);
926 flags_tree
= proto_item_add_subtree(
927 item
, ett_wimaxasncp_tlv_value_bitflags16
);
929 for (i
= 0; i
< 16; ++i
)
932 mask
= 1U << (15 - i
);
938 s
= wimaxasncp_get_enum_name(tlv_info
, value
& mask
);
940 proto_tree_add_uint_format(
941 flags_tree
, hf_wimaxasncp_tlv_value_bitflags16
,
942 tvb
, offset
, length
, value
,
943 "Bit #%u is set: %s", i
, s
);
951 case WIMAXASNCP_TLV_BITFLAGS32
:
959 if (tlv_info
->enums
== NULL
)
961 /* enum values missing */
966 proto_tree
*flags_tree
;
971 value
= tvb_get_ntohl(tvb
, offset
);
973 item
= proto_tree_add_item(
974 tree
, tlv_info
->hf_value
,
975 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
977 proto_item_append_text(tlv_item
, " - 0x%08x", value
);
981 flags_tree
= proto_item_add_subtree(
982 item
, ett_wimaxasncp_tlv_value_bitflags32
);
984 for (i
= 0; i
< 32; ++i
)
987 mask
= 1U << (31 - i
);
992 s
= wimaxasncp_get_enum_name(tlv_info
, value
& mask
);
994 proto_tree_add_uint_format(
995 flags_tree
, hf_wimaxasncp_tlv_value_bitflags32
,
996 tvb
, offset
, length
, value
,
997 "Bit #%u is set: %s", i
, s
);
1005 case WIMAXASNCP_TLV_ID
:
1011 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1012 pinfo
, tvb
, tree
, tlv_item
, offset
, tlv_info
);
1017 else if (length
== 6)
1021 wimaxasncp_proto_tree_add_ether_value(
1022 pinfo
, tvb
, tree
, tlv_item
, offset
, length
, tlv_info
);
1027 else if (length
== 16)
1031 wimaxasncp_proto_tree_add_tlv_ipv6_value(
1032 pinfo
, tvb
, tree
, tlv_item
, offset
, tlv_info
);
1039 /* encoding error */
1043 case WIMAXASNCP_TLV_BYTES
:
1047 proto_tree_add_item(
1048 tree
, tlv_info
->hf_value
,
1049 tvb
, offset
, length
, ENC_NA
);
1053 if (length
<= max_show_bytes
)
1059 format
= " - %s...";
1061 const char* s
= tvb_bytes_to_str_punct(
1062 pinfo
->pool
, tvb
, offset
, MIN(length
, max_show_bytes
), 0);
1064 proto_item_append_text(
1065 tlv_item
, format
, s
);
1067 proto_item_append_text(tlv_item
, " - <MISSING>");
1073 case WIMAXASNCP_TLV_HEX8
:
1077 /* encoding error */
1085 value
= tvb_get_uint8(tvb
, offset
);
1087 proto_tree_add_uint_format(
1088 tree
, tlv_info
->hf_value
,
1089 tvb
, offset
, length
, value
,
1090 "Value: 0x%02x", value
);
1092 proto_item_append_text(tlv_item
, " - 0x%02x", value
);
1097 case WIMAXASNCP_TLV_HEX16
:
1101 /* encoding error */
1109 value
= tvb_get_ntohs(tvb
, offset
);
1111 proto_tree_add_uint_format(
1112 tree
, tlv_info
->hf_value
,
1113 tvb
, offset
, length
, value
,
1114 "Value: 0x%04x", value
);
1116 proto_item_append_text(tlv_item
, " - 0x%04x", value
);
1121 case WIMAXASNCP_TLV_HEX32
:
1125 /* encoding error */
1133 value
= tvb_get_ntohl(tvb
, offset
);
1135 proto_tree_add_uint_format(
1136 tree
, tlv_info
->hf_value
,
1137 tvb
, offset
, length
, value
,
1138 "Value: 0x%08x", value
);
1140 proto_item_append_text(tlv_item
, " - 0x%08x", value
);
1145 case WIMAXASNCP_TLV_DEC8
:
1149 /* encoding error */
1157 value
= tvb_get_uint8(tvb
, offset
);
1159 proto_tree_add_uint_format(
1160 tree
, tlv_info
->hf_value
,
1161 tvb
, offset
, length
, value
,
1162 "Value: %u", value
);
1164 proto_item_append_text(tlv_item
, " - %u", value
);
1169 case WIMAXASNCP_TLV_DEC16
:
1173 /* encoding error */
1181 value
= tvb_get_ntohs(tvb
, offset
);
1183 proto_tree_add_uint_format(
1184 tree
, tlv_info
->hf_value
,
1185 tvb
, offset
, length
, value
,
1186 "Value: %u", value
);
1188 proto_item_append_text(tlv_item
, " - %u", value
);
1193 case WIMAXASNCP_TLV_DEC32
:
1197 /* encoding error */
1205 value
= tvb_get_ntohl(tvb
, offset
);
1207 proto_tree_add_uint_format(
1208 tree
, tlv_info
->hf_value
,
1209 tvb
, offset
, length
, value
,
1210 "Value: %u", value
);
1212 proto_item_append_text(tlv_item
, " - %u", value
);
1217 case WIMAXASNCP_TLV_TBD
:
1222 "fix-me: TBD: TLV %s (%u)\n", tlv_info
->name
, tlv_info
->type
);
1229 const char *s
= tvb_bytes_to_str_punct(
1230 pinfo
->pool
, tvb
, offset
, length
, 0);
1232 if (length
<= max_show_bytes
) {
1235 format
= "%s %s...";
1238 proto_tree_add_bytes_format_value(
1239 tree
, tlv_info
->hf_value
,
1240 tvb
, offset
, length
, NULL
, format
, hex_note
, s
);
1243 proto_tree_add_bytes_format_value(
1244 tree
, tlv_info
->hf_value
,
1245 tvb
, offset
, length
, NULL
, "%s", "<MISSING>");
1248 proto_item_append_text(tlv_item
, " - TBD");
1253 case WIMAXASNCP_TLV_IP_ADDRESS
:
1259 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1260 pinfo
, tvb
, tree
, tlv_item
, offset
, tlv_info
);
1265 else if (length
== 16)
1269 wimaxasncp_proto_tree_add_tlv_ipv6_value(
1270 pinfo
, tvb
, tree
, tlv_item
, offset
, tlv_info
);
1277 /* encoding error */
1281 case WIMAXASNCP_TLV_IPV4_ADDRESS
:
1285 /* encoding error */
1291 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1292 pinfo
, tvb
, tree
, tlv_item
, offset
, tlv_info
);
1297 case WIMAXASNCP_TLV_PROTOCOL_LIST
:
1299 if (length
% 2 != 0)
1301 /* encoding error */
1305 if (tree
&& length
> 0)
1307 proto_tree
*protocol_list_tree
;
1309 const unsigned max_protocols_in_tlv_item
= 8; /* arbitrary */
1311 protocol_list_tree
= proto_tree_add_subtree(
1312 tree
, tvb
, offset
, length
,
1313 ett_wimaxasncp_tlv_protocol_list
, NULL
, "Value");
1315 /* hidden item for filtering */
1316 item
= proto_tree_add_item(
1317 protocol_list_tree
, tlv_info
->hf_value
,
1318 tvb
, offset
, length
, ENC_NA
);
1320 proto_item_set_hidden(item
);
1322 while (offset
< tvb_reported_length(tvb
))
1325 const char *protocol_name
;
1327 protocol
= tvb_get_ntohs(tvb
, offset
);
1328 protocol_name
= ipprotostr(protocol
);
1330 proto_tree_add_uint_format(
1331 protocol_list_tree
, tlv_info
->hf_protocol
,
1332 tvb
, offset
, 2, protocol
,
1333 "Protocol: %s (%u)", protocol_name
, protocol
);
1337 proto_item_append_text(tlv_item
, " - %s", protocol_name
);
1339 else if (offset
< 2 * max_protocols_in_tlv_item
)
1341 proto_item_append_text(tlv_item
, ", %s", protocol_name
);
1343 else if (offset
== 2 * max_protocols_in_tlv_item
)
1345 proto_item_append_text(tlv_item
, ", ...");
1354 case WIMAXASNCP_TLV_PORT_RANGE_LIST
:
1356 if (length
% 4 != 0)
1358 /* encoding error */
1362 if (tree
&& length
> 0)
1364 proto_tree
*port_range_list_tree
;
1366 const unsigned max_port_ranges_in_tlv_item
= 3; /* arbitrary */
1368 port_range_list_tree
= proto_tree_add_subtree(
1369 tree
, tvb
, offset
, length
,
1370 ett_wimaxasncp_tlv_port_range_list
, NULL
, "Value");
1372 /* hidden item for filtering */
1373 item
= proto_tree_add_item(
1374 port_range_list_tree
, tlv_info
->hf_value
,
1375 tvb
, offset
, length
, ENC_NA
);
1377 proto_item_set_hidden(item
);
1379 while (offset
< tvb_reported_length(tvb
))
1383 proto_tree
* range_tree
;
1385 portLow
= tvb_get_ntohs(tvb
, offset
);
1386 portHigh
= tvb_get_ntohs(tvb
, offset
+ 2);
1388 range_tree
= proto_tree_add_subtree_format(
1389 port_range_list_tree
, tvb
, offset
, 4,
1390 ett_wimaxasncp_port_range
, NULL
, "Port Range: %u-%u", portLow
, portHigh
);
1392 /* hidden items are for filtering */
1394 item
= proto_tree_add_item(
1395 range_tree
, tlv_info
->hf_port_low
,
1396 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1398 proto_item_set_hidden(item
);
1400 item
= proto_tree_add_item(
1401 range_tree
, tlv_info
->hf_port_high
,
1402 tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
1404 proto_item_set_hidden(item
);
1408 proto_item_append_text(
1409 tlv_item
, " - %u-%u", portLow
, portHigh
);
1411 else if (offset
< 4 * max_port_ranges_in_tlv_item
)
1413 proto_item_append_text(
1414 tlv_item
, ", %u-%u", portLow
, portHigh
);
1416 else if (offset
== 4 * max_port_ranges_in_tlv_item
)
1418 proto_item_append_text(tlv_item
, ", ...");
1427 case WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST
:
1429 /* --------------------------------------------------------------------
1430 * The definion of these TLVs are ambiguous. The length in octets is
1431 * described as Nx8 (IPv4) or Nx32 (IPv6), but this function cannot
1432 * always differentiate between IPv4 and IPv6. For example, if length
1433 * = 32, then is it IPv4 where N=4 (4x8) or IPv6 where N=1 (1x32)?
1435 * For now, we presume lengths that *can* indicate an IPv6 address and
1436 * mask list *do* denote an IPv6 address and mask list.
1437 * --------------------------------------------------------------------
1440 if (length
% 8 != 0)
1442 /* encoding error */
1446 if (tree
&& length
> 0)
1448 proto_tree
*ip_address_mask_list_tree
;
1451 ip_address_mask_list_tree
= proto_tree_add_subtree(
1452 tree
, tvb
, offset
, length
,
1453 ett_wimaxasncp_tlv_ip_address_mask_list
, NULL
, "Value");
1455 /* hidden item for filtering */
1456 item
= proto_tree_add_item(
1457 ip_address_mask_list_tree
, tlv_info
->hf_value
,
1458 tvb
, offset
, length
, ENC_NA
);
1460 proto_item_set_hidden(item
);
1462 if (length
% 32 == 0)
1464 /* ------------------------------------------------------------
1466 * ------------------------------------------------------------
1469 while (offset
< tvb_reported_length(tvb
))
1471 proto_tree
*ip_address_mask_tree
;
1473 ip_address_mask_tree
= proto_tree_add_subtree(
1474 ip_address_mask_list_tree
, tvb
, offset
, 32,
1475 ett_wimaxasncp_tlv_ip_address_mask
, NULL
, "IPv6 Address and Mask");
1477 /* --------------------------------------------------------
1479 * --------------------------------------------------------
1482 proto_tree_add_item(
1483 ip_address_mask_tree
,
1485 tvb
, offset
, 16, ENC_NA
);
1487 /* too long to display ?
1488 proto_item_append_text(
1490 get_hostname6(&ip), ip6_to_str(&ip));
1495 /* --------------------------------------------------------
1497 * --------------------------------------------------------
1499 proto_tree_add_item(
1500 ip_address_mask_tree
,
1501 tlv_info
->hf_ipv6_mask
,
1502 tvb
, offset
, 16, ENC_NA
);
1504 /* too long to display ?
1505 proto_item_append_text(
1514 /* ------------------------------------------------------------
1516 * ------------------------------------------------------------
1519 while (offset
< tvb_reported_length(tvb
))
1521 proto_tree
*ip_address_mask_tree
;
1525 ip_address_mask_tree
= proto_tree_add_subtree(
1526 ip_address_mask_list_tree
, tvb
, offset
, 8,
1527 ett_wimaxasncp_tlv_ip_address_mask
, NULL
, "IPv4 Address and Mask");
1529 /* --------------------------------------------------------
1531 * --------------------------------------------------------
1534 ip
= tvb_get_ipv4(tvb
, offset
);
1536 proto_tree_add_item(
1537 ip_address_mask_tree
,
1539 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1541 proto_item_append_text(
1543 get_hostname(ip
), tvb_ip_to_str(pinfo
->pool
, tvb
, offset
));
1547 /* --------------------------------------------------------
1549 * --------------------------------------------------------
1552 s
= tvb_ip_to_str(pinfo
->pool
, tvb
, offset
);
1554 proto_tree_add_item(
1555 ip_address_mask_tree
,
1556 tlv_info
->hf_ipv4_mask
,
1557 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1559 proto_item_append_text(
1569 case WIMAXASNCP_TLV_EAP
:
1572 * EAP payload, call eap dissector to dissect eap payload
1575 uint8_t eap_type
= 0;
1578 eap_code
= tvb_get_uint8(tvb
, offset
);
1579 if (eap_code
== EAP_REQUEST
|| eap_code
== EAP_RESPONSE
)
1582 eap_type
= tvb_get_uint8(tvb
, offset
+ 4);
1585 /* Add code and type to info column */
1586 col_append_str(pinfo
->cinfo
, COL_INFO
, " [");
1587 col_append_str(pinfo
->cinfo
, COL_INFO
,
1588 val_to_str(eap_code
, eap_code_vals
, "Unknown code (0x%02X)"));
1590 if (eap_code
== EAP_REQUEST
|| eap_code
== EAP_RESPONSE
)
1592 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
1593 col_append_str(pinfo
->cinfo
, COL_INFO
,
1594 val_to_str_ext(eap_type
, &eap_type_vals_ext
, "Unknown type (0x%02X)"));
1597 col_append_str(pinfo
->cinfo
, COL_INFO
, "]");
1601 proto_tree
*eap_tree
;
1606 /* Create EAP subtree */
1607 item
= proto_tree_add_item(tree
, tlv_info
->hf_value
, tvb
,
1608 offset
, length
, ENC_NA
);
1609 proto_item_set_text(item
, "Value");
1610 eap_tree
= proto_item_add_subtree(item
, ett_wimaxasncp_tlv_eap
);
1612 /* Also show high-level details in this root item */
1613 proto_item_append_text(item
, " (%s",
1614 val_to_str(eap_code
, eap_code_vals
,
1615 "Unknown code (0x%02X)"));
1616 if (eap_code
== EAP_REQUEST
|| eap_code
== EAP_RESPONSE
)
1618 proto_item_append_text(item
, ", %s",
1619 val_to_str_ext(eap_type
, &eap_type_vals_ext
,
1620 "Unknown type (0x%02X)"));
1622 proto_item_append_text(item
, ")");
1625 /* Extract remaining bytes into new tvb */
1626 eap_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1628 /* Disable writing to info column while calling eap dissector */
1629 save_writable
= col_get_writable(pinfo
->cinfo
, -1);
1630 col_set_writable(pinfo
->cinfo
, -1, false);
1632 /* Call the EAP dissector. */
1633 call_dissector(eap_handle
, eap_tvb
, pinfo
, eap_tree
);
1635 /* Restore previous writable state of info column */
1636 col_set_writable(pinfo
->cinfo
, -1, save_writable
);
1642 case WIMAXASNCP_TLV_VENDOR_SPECIFIC
:
1644 /* --------------------------------------------------------------------
1645 * The format of the vendor specific information field (VSIF) is not
1646 * clearly defined. It appears to be compound as the spec states
1647 * that the vendor ID field shall be the first TLV embedded inside
1648 * the VSIF. However, the vendor ID is shown as a 24-bit value. Does
1649 * this mean the field is 24-bits? If so, how is alignment/padding
1652 * For now, we decode the vendor ID as a non-padded 24-bit value and
1653 * dump the rest as hex.
1654 * --------------------------------------------------------------------
1659 /* encoding error */
1665 proto_tree
*vsif_tree
;
1668 const char *vendorName
;
1670 vsif_tree
= proto_tree_add_subtree(
1671 tree
, tvb
, offset
, length
,
1672 ett_wimaxasncp_tlv_vendor_specific_information_field
, NULL
, "Value");
1674 /* hidden item for filtering */
1675 item
= proto_tree_add_item(
1676 vsif_tree
, tlv_info
->hf_value
,
1677 tvb
, offset
, length
, ENC_NA
);
1679 proto_item_set_hidden(item
);
1681 /* ----------------------------------------------------------------
1682 * vendor ID (24-bit)
1683 * ----------------------------------------------------------------
1686 vendorId
= tvb_get_ntoh24(tvb
, offset
);
1688 vendorName
= enterprises_lookup(vendorId
, "Unknown");
1689 proto_tree_add_uint_format(
1690 vsif_tree
, tlv_info
->hf_vendor_id
,
1691 tvb
, offset
, 3, vendorId
,
1692 "Vendor ID: %s (%u)", vendorName
, vendorId
);
1694 proto_item_append_text(tlv_item
, " - %s", vendorName
);
1698 /* ----------------------------------------------------------------
1700 * ----------------------------------------------------------------
1703 if (offset
< tvb_reported_length(tvb
))
1705 proto_tree_add_item(
1706 vsif_tree
, tlv_info
->hf_vendor_rest_of_info
,
1707 tvb
, offset
, length
- offset
, ENC_NA
);
1713 case WIMAXASNCP_TLV_UNKNOWN
:
1719 const char* format1
;
1720 const char* format2
;
1721 if (length
<= max_show_bytes
)
1724 format2
= " - %s %s";
1728 format1
= "%s %s...";
1729 format2
= " - %s %s...";
1731 s
= tvb_bytes_to_str_punct(
1732 pinfo
->pool
, tvb
, offset
, MIN(length
, max_show_bytes
), 0);
1734 proto_tree_add_bytes_format_value(
1735 tree
, tlv_info
->hf_value
,
1736 tvb
, offset
, length
, NULL
, format1
, hex_note
, s
);
1738 proto_item_append_text(
1739 tlv_item
, format2
, hex_note
, s
);
1742 proto_tree_add_bytes_format_value(
1743 tree
, tlv_info
->hf_value
,
1744 tvb
, offset
, length
, NULL
, "%s", "<MISSING>");
1746 proto_item_append_text(tlv_item
, " - <MISSING>");
1757 "fix-me: unknown decoder: %d\n", tlv_info
->decoder
);
1762 /* default is hex dump */
1768 const char *s
= tvb_bytes_to_str_punct(
1769 pinfo
->pool
, tvb
, offset
, MIN(length
, max_show_bytes
), 0);
1771 if (length
<= max_show_bytes
) {
1774 format
= "%s %s...";
1777 proto_tree_add_bytes_format_value(
1778 tree
, hf_wimaxasncp_tlv_value_bytes
,
1779 tvb
, offset
, length
, NULL
,
1780 format
, hex_note
, s
);
1782 proto_tree_add_bytes_format_value(
1783 tree
, hf_wimaxasncp_tlv_value_bytes
,
1784 tvb
, offset
, length
, NULL
,
1790 /* ========================================================================= */
1792 // NOLINTNEXTLINE(misc-no-recursion)
1793 static unsigned dissect_wimaxasncp_tlvs(
1801 while (offset
< tvb_reported_length(tvb
))
1803 const wimaxasncp_dict_tlv_t
*tlv_info
;
1805 proto_tree
*tlv_tree
;
1806 proto_item
*tlv_item
;
1811 /* --------------------------------------------------------------------
1813 * --------------------------------------------------------------------
1816 type
= tvb_get_ntohs(tvb
, offset
);
1817 tlv_info
= wimaxasncp_get_tlv_info(type
);
1819 length
= tvb_get_ntohs(tvb
, offset
+ 2);
1820 #if 0 /* Commented out padding; As there is no mention of padding in
1821 the Latest specification */
1822 pad
= 4 - (length
% 4);
1830 proto_item
*type_item
;
1832 int tree_length
= MIN(
1833 (int)(4 + length
+ pad
), tvb_captured_length_remaining(tvb
, offset
));
1835 tlv_item
= proto_tree_add_item(
1836 tree
, tlv_info
->hf_root
,
1837 tvb
, offset
, tree_length
, ENC_NA
);
1839 /* Set label for tlv item */
1840 proto_item_set_text(tlv_item
, "TLV: %s", tlv_info
->name
);
1842 /* Show code number if unknown */
1843 if (tlv_info
->decoder
== WIMAXASNCP_TLV_UNKNOWN
)
1845 proto_item_append_text(tlv_item
, " (%u)", type
);
1848 /* Indicate if a compound tlv */
1849 if (tlv_info
->decoder
== WIMAXASNCP_TLV_COMPOUND
)
1851 proto_item_append_text(tlv_item
, " [Compound]");
1854 /* Create TLV subtree */
1855 tlv_tree
= proto_item_add_subtree(
1856 tlv_item
, ett_wimaxasncp_tlv
);
1858 /* Type (expert item if unknown) */
1859 type_item
= proto_tree_add_uint_format(
1860 tlv_tree
, hf_wimaxasncp_tlv_type
,
1861 tvb
, offset
, 2, type
,
1862 "Type: %s (%u)", tlv_info
->name
, type
);
1864 if (tlv_info
->decoder
== WIMAXASNCP_TLV_UNKNOWN
)
1866 expert_add_info_format(pinfo
, type_item
, &ei_wimaxasncp_tlv_type
,
1867 "Unknown TLV type (%u)",
1872 proto_tree_add_uint(
1873 tlv_tree
, hf_wimaxasncp_tlv_length
,
1874 tvb
, offset
+ 2, 2, length
);
1880 /* --------------------------------------------------------------------
1882 * --------------------------------------------------------------------
1885 if (tlv_info
->decoder
== WIMAXASNCP_TLV_COMPOUND
)
1889 /* error? compound, but no TLVs inside */
1891 else if (tvb_reported_length_remaining(tvb
, offset
) > 0)
1895 /* N.B. Not padding out tvb length */
1896 tlv_tvb
= tvb_new_subset_length_caplen(
1898 MIN(length
, tvb_captured_length_remaining(tvb
, offset
)),
1901 increment_dissection_depth(pinfo
);
1902 dissect_wimaxasncp_tlvs(tlv_tvb
, pinfo
, tlv_tree
);
1903 decrement_dissection_depth(pinfo
);
1907 /* this should throw */
1908 tvb_ensure_bytes_exist(tvb
, offset
, length
+ pad
);
1915 tvb_ensure_bytes_exist(tvb
, offset
, length
+ pad
);
1917 tlv_tvb
= tvb_new_subset_length_caplen(
1919 MIN(length
, tvb_captured_length_remaining(tvb
, offset
)),
1922 wimaxasncp_dissect_tlv_value(
1923 tlv_tvb
, pinfo
, tlv_tree
, tlv_item
, tlv_info
);
1926 offset
+= length
+ pad
;
1932 /* ========================================================================= */
1934 static unsigned dissect_wimaxasncp_backend(
1939 unsigned offset
= 0;
1942 const uint8_t *pmsid
;
1947 /* ------------------------------------------------------------------------
1949 * ------------------------------------------------------------------------
1954 proto_tree_add_item(
1955 tree
, hf_wimaxasncp_msid
,
1956 tvb
, offset
, 6, ENC_NA
);
1958 pmsid
= tvb_ether_to_str(pinfo
->pool
, tvb
, offset
);
1962 /* ------------------------------------------------------------------------
1964 * ------------------------------------------------------------------------
1967 ui32
= tvb_get_ntohl(tvb
, offset
);
1971 proto_tree_add_uint(
1972 tree
, hf_wimaxasncp_reserved1
,
1973 tvb
, offset
, 4, ui32
);
1978 /* ------------------------------------------------------------------------
1980 * ------------------------------------------------------------------------
1984 ui16
= tvb_get_ntohs(tvb
, offset
);
1986 if (show_transaction_id_d_bit
)
1988 const uint16_t mask
= 0x7fff;
1992 proto_tree_add_uint_format(
1993 tree
, hf_wimaxasncp_transaction_id
,
1994 tvb
, offset
, 2, ui16
,
1995 "Transaction ID: D + 0x%04x (0x%04x)", mask
& ui16
, ui16
);
2002 proto_tree_add_uint_format(
2003 tree
, hf_wimaxasncp_transaction_id
,
2004 tvb
, offset
, 2, ui16
,
2005 "Transaction ID: 0x%04x", ui16
);
2012 proto_tree_add_uint(
2013 tree
, hf_wimaxasncp_transaction_id
,
2014 tvb
, offset
, 2, ui16
);
2021 /* ------------------------------------------------------------------------
2023 * ------------------------------------------------------------------------
2026 ui16
= tvb_get_ntohs(tvb
, offset
);
2030 proto_tree_add_uint(
2031 tree
, hf_wimaxasncp_reserved2
,
2032 tvb
, offset
, 2, ui16
);
2037 /* ------------------------------------------------------------------------
2039 * ------------------------------------------------------------------------
2042 if (tvb_reported_length_remaining(tvb
, offset
) > 0)
2046 tlv_tvb
= tvb_new_subset_remaining(tvb
, offset
);
2048 offset
+= dissect_wimaxasncp_tlvs(tlv_tvb
, pinfo
, tree
);
2051 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " - MSID:%s", pmsid
);
2054 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", TID:D+0x%04x", tid
);
2058 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", TID:0x%04x", tid
);
2064 /* ========================================================================= */
2068 match_ver_value_string(
2070 const ver_value_string
* const strings
,
2071 const uint32_t max_ver
)
2073 const ver_value_string
* vvs
;
2074 const ver_value_string
* res
= NULL
;
2076 /* loop on the levels, from max to 0 */
2077 for(vvs
=strings
; vvs
->vs
.strptr
; vvs
++)
2079 if ((vvs
->vs
.value
== val
) && (vvs
->since
<= max_ver
))
2081 if (!res
|| (vvs
->since
> res
->since
))
2088 return res
? res
->vs
.strptr
: NULL
;
2098 static const char unknown
[] = "Unknown";
2100 /* Set up structures needed to add the protocol subtree and manage it */
2101 proto_item
*packet_item
= NULL
;
2102 proto_item
*item
= NULL
;
2103 proto_tree
*wimaxasncp_tree
= NULL
;
2109 uint8_t function_type
;
2110 const char *function_type_name
;
2111 proto_item
*function_type_item
;
2114 const wimaxasncp_func_msg_t
*p
= NULL
;
2115 const char *message_name
;
2118 /* ------------------------------------------------------------------------
2119 * First, we do some heuristics to check if the packet cannot be our
2121 * ------------------------------------------------------------------------
2124 /* Should we check a minimum size? If so, uncomment out the following
2127 if (tvb_reported_length(tvb
) < WIMAXASNCP_HEADER_SIZE
)
2133 /* We currently only support version 1. */
2134 if (tvb_bytes_exist(tvb
, 0, 1) && tvb_get_uint8(tvb
, 0) != 1)
2139 /* ------------------------------------------------------------------------
2140 * Initialize the protocol and info column.
2141 * ------------------------------------------------------------------------
2144 /* Make entries in Protocol column and Info column on summary display */
2145 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "WiMAX");
2147 /* We'll fill in the "Info" column after fetch data, so we clear the
2148 column first in case calls to fetch data from the packet throw an
2150 col_clear(pinfo
->cinfo
, COL_INFO
);
2152 /* ========================================================================
2153 * Disesction starts here
2154 * ========================================================================
2157 /* ------------------------------------------------------------------------
2158 * total packet, we'll adjust after we read the length field
2159 * ------------------------------------------------------------------------
2164 /* Register protocol fields, etc if haven't done yet. */
2165 if (hf_wimaxasncp_version
<= 0)
2167 proto_registrar_get_byname("wimaxasncp.version");
2172 packet_item
= proto_tree_add_item(
2173 tree
, proto_wimaxasncp
,
2174 tvb
, 0, MIN(WIMAXASNCP_HEADER_LENGTH_END
, tvb_captured_length(tvb
)), ENC_NA
);
2176 wimaxasncp_tree
= proto_item_add_subtree(
2177 packet_item
, ett_wimaxasncp
);
2180 /* ------------------------------------------------------------------------
2182 * ------------------------------------------------------------------------
2187 proto_tree_add_item(
2188 wimaxasncp_tree
, hf_wimaxasncp_version
,
2189 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2194 /* ------------------------------------------------------------------------
2196 * ------------------------------------------------------------------------
2199 ui8
= tvb_get_uint8(tvb
, offset
);
2203 proto_tree
*flags_tree
;
2207 proto_tree_add_uint_format(
2208 wimaxasncp_tree
, hf_wimaxasncp_flags
,
2209 tvb
, offset
, 1, ui8
,
2210 "Flags: 0x%02x", ui8
);
2215 item
= proto_tree_add_uint_format(
2216 wimaxasncp_tree
, hf_wimaxasncp_flags
,
2217 tvb
, offset
, 1, ui8
,
2220 if (ui8
& (WIMAXASNCP_FLAGS_T
| WIMAXASNCP_FLAGS_R
))
2222 if (ui8
& WIMAXASNCP_FLAGS_T
)
2224 proto_item_append_text(item
, "T");
2227 if (ui8
& WIMAXASNCP_FLAGS_R
)
2229 proto_item_append_text(item
, "R");
2232 proto_item_append_text(item
, " - ");
2235 proto_item_append_text(item
, "0x%02x", ui8
);
2237 flags_tree
= proto_item_add_subtree(
2238 item
, ett_wimaxasncp_flags
);
2240 for (j
= 0; j
< 8; ++j
)
2243 mask
= 1U << (7 - j
);
2245 /* Only add flags that are set */
2248 proto_tree_add_uint_format(
2249 flags_tree
, hf_wimaxasncp_flags
,
2250 tvb
, offset
, 1, ui8
,
2251 "Bit #%u is set: %s",
2254 ui8
& mask
, wimaxasncp_flag_vals
, "Unknown"));
2262 /* ------------------------------------------------------------------------
2264 * ------------------------------------------------------------------------
2267 function_type
= tvb_get_uint8(tvb
, offset
);
2269 function_type_name
= match_ver_value_string(function_type
,
2270 wimaxasncp_function_type_vals
,
2271 global_wimaxasncp_nwg_ver
);
2273 if (function_type_name
)
2275 /* add the item to the tree */
2276 proto_tree_add_uint_format(
2277 wimaxasncp_tree
, hf_wimaxasncp_function_type
,
2278 tvb
, offset
, 1, function_type
,
2279 "%s (%u)", function_type_name
, function_type
);
2283 /* if not matched, add the item and append expert item */
2284 function_type_item
= proto_tree_add_uint_format(
2285 wimaxasncp_tree
, hf_wimaxasncp_function_type
,
2286 tvb
, offset
, 1, function_type
,
2287 "Unknown (%u)", function_type
);
2289 expert_add_info_format(pinfo
, function_type_item
,
2290 &ei_wimaxasncp_function_type
,
2291 "Unknown function type (%u)",
2297 /* ------------------------------------------------------------------------
2298 * OP ID and message type
2299 * ------------------------------------------------------------------------
2302 ui8
= tvb_get_uint8(tvb
, offset
);
2305 /* --------------------------------------------------------------------
2307 * --------------------------------------------------------------------
2310 item
= proto_tree_add_uint_format(
2311 wimaxasncp_tree
, hf_wimaxasncp_op_id
,
2312 tvb
, offset
, 1, ui8
,
2313 "OP ID: %s", val_to_str(ui8
>> 5, wimaxasncp_op_id_vals
, unknown
));
2315 proto_item_append_text(item
, " (%u)", ((ui8
>> 5) & 7));
2318 /* use the function type to find the message vals */
2319 for (i
= 0; i
< array_length(wimaxasncp_func_to_msg_vals_map
); ++i
)
2321 p
= &wimaxasncp_func_to_msg_vals_map
[i
];
2323 if (function_type
== p
->function_type
)
2329 /* --------------------------------------------------------------------
2331 * --------------------------------------------------------------------
2334 message_name
= p
? match_ver_value_string(0x1f & ui8
, p
->vals
, global_wimaxasncp_nwg_ver
) : unknown
;
2335 if (message_name
== NULL
)
2337 message_name
= unknown
;
2340 item
= proto_tree_add_uint_format(
2341 wimaxasncp_tree
, hf_wimaxasncp_message_type
,
2342 tvb
, offset
, 1, ui8
,
2343 "Message Type: %s", message_name
);
2345 proto_item_append_text(item
, " (%u)", ui8
& 0x1F);
2347 /* Add expert item if not matched */
2348 if (strcmp(message_name
, unknown
) == 0)
2350 expert_add_info_format(pinfo
, item
, &ei_wimaxasncp_message_type
,
2351 "Unknown message type (%u)",
2355 col_add_str(pinfo
->cinfo
, COL_INFO
, message_name
);
2359 /* ------------------------------------------------------------------------
2361 * ------------------------------------------------------------------------
2364 length
= tvb_get_ntohs(tvb
, offset
);
2369 packet_item
, MAX(WIMAXASNCP_HEADER_LENGTH_END
, length
));
2371 item
= proto_tree_add_uint(
2372 wimaxasncp_tree
, hf_wimaxasncp_length
,
2373 tvb
, offset
, 2, length
);
2378 if (length
< WIMAXASNCP_HEADER_SIZE
)
2380 expert_add_info(pinfo
, item
, &ei_wimaxasncp_length_bad
);
2384 proto_item_append_text(
2385 item
, " [error: specified length less than header size (20)]");
2388 if (length
<= WIMAXASNCP_HEADER_LENGTH_END
)
2394 /* ------------------------------------------------------------------------
2395 * remaining header fields and TLVs
2396 * ------------------------------------------------------------------------
2399 subtree
= tvb_new_subset_length_caplen(
2401 MIN(length
, tvb_captured_length_remaining(tvb
, offset
)),
2402 length
- WIMAXASNCP_HEADER_LENGTH_END
);
2404 offset
+= dissect_wimaxasncp_backend(
2405 subtree
, pinfo
, wimaxasncp_tree
);
2407 /* ------------------------------------------------------------------------
2408 * done, return the amount of data this dissector was able to dissect
2409 * ------------------------------------------------------------------------
2415 /* ========================================================================= */
2416 /* Modify the given string to make a suitable display filter */
2417 static char *alnumerize(
2420 char *r
= name
; /* read pointer */
2421 char *w
= name
; /* write pointer */
2424 for ( ; (c
= *r
); ++r
)
2426 if (g_ascii_isalnum(c
) || c
== '_' || c
== '.')
2428 /* These characters are fine - copy them */
2431 else if (c
== ' ' || c
== '-' || c
== '/')
2433 /* Skip these others if haven't written any characters out yet */
2439 /* Skip if we would produce multiple adjacent '_'s */
2440 if (*(w
- 1) == '_')
2445 /* OK, replace with underscore */
2449 /* Other undesirable characters are just skipped */
2452 /* Terminate and return modified string */
2457 /* ========================================================================= */
2459 static void add_reg_info(
2467 hf_register_info hf
= {
2468 hf_ptr
, { name
, abbrev
, type
, display
, NULL
, 0x0, blurb
, HFILL
} };
2470 wmem_array_append_one(wimaxasncp_build_dict
.hf
, hf
);
2473 /* ========================================================================= */
2475 static void add_tlv_reg_info(
2476 wimaxasncp_dict_tlv_t
*tlv
)
2480 const char *root_blurb
;
2483 /* ------------------------------------------------------------------------
2485 * ------------------------------------------------------------------------
2488 name
= wmem_strdup(wmem_epan_scope(), tlv
->name
);
2489 abbrev
= alnumerize(wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s", tlv
->name
));
2491 switch (tlv
->decoder
)
2493 case WIMAXASNCP_TLV_UNKNOWN
:
2494 root_blurb
= "type=Unknown";
2496 case WIMAXASNCP_TLV_TBD
:
2497 root_blurb
= wmem_strdup_printf(wmem_epan_scope(), "type=%u, TBD", tlv
->type
);
2499 case WIMAXASNCP_TLV_COMPOUND
:
2500 root_blurb
= wmem_strdup_printf(wmem_epan_scope(), "type=%u, Compound", tlv
->type
);
2502 case WIMAXASNCP_TLV_FLAG0
:
2503 root_blurb
= wmem_strdup_printf(wmem_epan_scope(), "type=%u, Value = Null", tlv
->type
);
2506 root_blurb
= wmem_strdup_printf(wmem_epan_scope(), "type=%u", tlv
->type
);
2511 &tlv
->hf_root
, name
, abbrev
, FT_BYTES
, BASE_NONE
, root_blurb
);
2513 /* ------------------------------------------------------------------------
2514 * add value(s) reg info
2515 * ------------------------------------------------------------------------
2518 name
= wmem_strdup(wmem_epan_scope(), "Value");
2519 abbrev
= alnumerize(wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value", tlv
->name
));
2520 blurb
= wmem_strdup_printf(wmem_epan_scope(), "value for type=%u", tlv
->type
);
2522 switch (tlv
->decoder
)
2524 case WIMAXASNCP_TLV_UNKNOWN
:
2525 wmem_free(wmem_epan_scope(), blurb
);
2528 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
,
2529 "value for unknown type");
2532 case WIMAXASNCP_TLV_TBD
:
2534 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
, blurb
);
2537 case WIMAXASNCP_TLV_COMPOUND
:
2538 case WIMAXASNCP_TLV_FLAG0
:
2539 wmem_free(wmem_epan_scope(), name
);
2540 wmem_free(wmem_epan_scope(), abbrev
);
2541 wmem_free(wmem_epan_scope(), blurb
);
2544 case WIMAXASNCP_TLV_BYTES
:
2546 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
, blurb
);
2549 case WIMAXASNCP_TLV_ENUM8
:
2551 &tlv
->hf_value
, name
, abbrev
, FT_UINT8
, BASE_DEC
, blurb
);
2554 case WIMAXASNCP_TLV_ENUM16
:
2556 &tlv
->hf_value
, name
, abbrev
, FT_UINT16
, BASE_DEC
, blurb
);
2559 case WIMAXASNCP_TLV_ENUM32
:
2561 &tlv
->hf_value
, name
, abbrev
, FT_UINT32
, BASE_DEC
, blurb
);
2564 case WIMAXASNCP_TLV_ETHER
:
2566 &tlv
->hf_value
, name
, abbrev
, FT_ETHER
, BASE_NONE
, blurb
);
2569 case WIMAXASNCP_TLV_ASCII_STRING
:
2571 &tlv
->hf_value
, name
, abbrev
, FT_STRING
, BASE_NONE
, blurb
);
2574 case WIMAXASNCP_TLV_BITFLAGS8
:
2576 &tlv
->hf_value
, name
, abbrev
, FT_UINT8
, BASE_HEX
, blurb
);
2579 case WIMAXASNCP_TLV_BITFLAGS16
:
2581 &tlv
->hf_value
, name
, abbrev
, FT_UINT16
, BASE_HEX
, blurb
);
2584 case WIMAXASNCP_TLV_BITFLAGS32
:
2586 &tlv
->hf_value
, name
, abbrev
, FT_UINT32
, BASE_HEX
, blurb
);
2589 case WIMAXASNCP_TLV_ID
:
2590 wmem_free(wmem_epan_scope(), abbrev
);
2592 abbrev
= alnumerize(
2593 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.ipv4_value", tlv
->name
));
2596 &tlv
->hf_ipv4
, "IPv4 Address", abbrev
, FT_IPv4
, BASE_NONE
, blurb
);
2598 abbrev
= alnumerize(
2599 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.ipv6_value", tlv
->name
));
2602 &tlv
->hf_ipv6
, "IPv6 Address", abbrev
, FT_IPv6
, BASE_NONE
, blurb
);
2604 abbrev
= alnumerize(
2605 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.bsid_value", tlv
->name
));
2608 &tlv
->hf_bsid
, "BS ID", abbrev
, FT_ETHER
, BASE_NONE
, blurb
);
2612 case WIMAXASNCP_TLV_HEX8
:
2614 &tlv
->hf_value
, name
, abbrev
, FT_UINT8
, BASE_HEX
, blurb
);
2617 case WIMAXASNCP_TLV_HEX16
:
2619 &tlv
->hf_value
, name
, abbrev
, FT_UINT16
, BASE_HEX
, blurb
);
2622 case WIMAXASNCP_TLV_HEX32
:
2624 &tlv
->hf_value
, name
, abbrev
, FT_UINT32
, BASE_HEX
, blurb
);
2627 case WIMAXASNCP_TLV_DEC8
:
2629 &tlv
->hf_value
, name
, abbrev
, FT_UINT8
, BASE_DEC
, blurb
);
2632 case WIMAXASNCP_TLV_DEC16
:
2634 &tlv
->hf_value
, name
, abbrev
, FT_UINT16
, BASE_DEC
, blurb
);
2637 case WIMAXASNCP_TLV_DEC32
:
2639 &tlv
->hf_value
, name
, abbrev
, FT_UINT32
, BASE_DEC
, blurb
);
2642 case WIMAXASNCP_TLV_IP_ADDRESS
:
2643 wmem_free(wmem_epan_scope(), abbrev
);
2645 abbrev
= alnumerize(
2646 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.ipv4_value", tlv
->name
));
2649 &tlv
->hf_ipv4
, "IPv4 Address", abbrev
, FT_IPv4
, BASE_NONE
, blurb
);
2651 abbrev
= alnumerize(
2652 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.ipv6_value", tlv
->name
));
2655 &tlv
->hf_ipv6
, "IPv6 Address", abbrev
, FT_IPv6
, BASE_NONE
, blurb
);
2659 case WIMAXASNCP_TLV_IPV4_ADDRESS
:
2661 &tlv
->hf_value
, name
, abbrev
, FT_IPv4
, BASE_NONE
, blurb
);
2664 case WIMAXASNCP_TLV_PROTOCOL_LIST
:
2666 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
, blurb
);
2668 blurb
= wmem_strdup_printf(wmem_epan_scope(), "value component for type=%u", tlv
->type
);
2670 abbrev
= alnumerize(
2671 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.protocol", tlv
->name
));
2674 &tlv
->hf_protocol
, "Protocol", abbrev
, FT_UINT16
, BASE_DEC
, blurb
);
2678 case WIMAXASNCP_TLV_PORT_RANGE_LIST
:
2680 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
, blurb
);
2682 blurb
= wmem_strdup_printf(wmem_epan_scope(), "value component for type=%u", tlv
->type
);
2684 abbrev
= alnumerize(
2685 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.port_low", tlv
->name
));
2688 &tlv
->hf_port_low
, "Port Low", abbrev
, FT_UINT16
, BASE_DEC
, blurb
);
2690 abbrev
= alnumerize(
2691 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.port_high", tlv
->name
));
2694 &tlv
->hf_port_high
, "Port High", abbrev
, FT_UINT16
, BASE_DEC
, blurb
);
2698 case WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST
:
2700 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
, blurb
);
2702 blurb
= wmem_strdup_printf(wmem_epan_scope(), "value component for type=%u", tlv
->type
);
2704 abbrev
= alnumerize(
2705 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.ipv4", tlv
->name
));
2708 &tlv
->hf_ipv4
, "IPv4 Address", abbrev
, FT_IPv4
, BASE_NONE
, blurb
);
2710 abbrev
= alnumerize(
2711 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.ipv4_mask", tlv
->name
));
2714 &tlv
->hf_ipv4_mask
, "IPv4 Mask", abbrev
, FT_IPv4
, BASE_NONE
, blurb
);
2716 abbrev
= alnumerize(
2717 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.ipv6", tlv
->name
));
2720 &tlv
->hf_ipv6
, "IPv6 Address", abbrev
, FT_IPv6
, BASE_NONE
, blurb
);
2722 abbrev
= alnumerize(
2723 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.ipv6_mask", tlv
->name
));
2726 &tlv
->hf_ipv6_mask
, "IPv6 Mask", abbrev
, FT_IPv6
, BASE_NONE
, blurb
);
2730 case WIMAXASNCP_TLV_VENDOR_SPECIFIC
:
2732 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
, blurb
);
2734 blurb
= wmem_strdup_printf(wmem_epan_scope(), "value component for type=%u", tlv
->type
);
2736 abbrev
= alnumerize(
2737 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.vendor_id", tlv
->name
));
2740 &tlv
->hf_vendor_id
, "Vendor ID", abbrev
, FT_UINT24
, BASE_DEC
, blurb
);
2742 abbrev
= alnumerize(
2743 wmem_strdup_printf(wmem_epan_scope(),
2744 "wimaxasncp.tlv.%s.value.vendor_rest_of_info", tlv
->name
));
2747 &tlv
->hf_vendor_rest_of_info
, "Rest of Info", abbrev
, FT_BYTES
, BASE_NONE
,
2752 case WIMAXASNCP_TLV_EAP
:
2753 blurb
= wmem_strdup_printf(wmem_epan_scope(), "EAP payload embedded in %s", name
);
2756 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
, blurb
);
2762 &tlv
->hf_value
, name
, abbrev
, FT_BYTES
, BASE_NONE
, blurb
);
2767 "fix-me: unknown decoder: %d\n", tlv
->decoder
);
2774 /* ========================================================================= */
2775 /* Register the protocol fields and subtrees with Wireshark */
2777 register_wimaxasncp_fields(const char* unused _U_
)
2784 /* ------------------------------------------------------------------------
2785 * List of header fields
2786 * ------------------------------------------------------------------------
2789 static hf_register_info hf_base
[] = {
2791 &hf_wimaxasncp_version
,
2794 "wimaxasncp.version",
2804 &hf_wimaxasncp_flags
,
2817 &hf_wimaxasncp_function_type
,
2820 "wimaxasncp.function_type",
2830 &hf_wimaxasncp_op_id
,
2836 VALS(wimaxasncp_op_id_vals
),
2843 &hf_wimaxasncp_message_type
,
2846 "wimaxasncp.message_type",
2857 &hf_wimaxasncp_qos_msg
,
2860 "wimaxasncp.qos_msg",
2872 &hf_wimaxasncp_ho_control_msg
,
2875 "wimaxasncp.ho_control_msg",
2887 &hf_wimaxasncp_data_path_control_msg
,
2890 "wimaxasncp.data_path_control_msg",
2902 &hf_wimaxasncp_context_delivery_msg
,
2905 "wimaxasncp.context_delivery_msg",
2917 &hf_wimaxasncp_r3_mobility_msg
,
2920 "wimaxasncp.r3_mobility_msg",
2932 &hf_wimaxasncp_paging_msg
,
2935 "wimaxasncp.paging_msg",
2947 &hf_wimaxasncp_rrm_msg
,
2950 "wimaxasncp.rrm_msg",
2962 &hf_wimaxasncp_authentication_msg
,
2965 "wimaxasncp.authentication_msg",
2977 &hf_wimaxasncp_ms_state_msg
,
2980 "wimaxasncp.ms_state_msg",
2992 &hf_wimaxasncp_reauthentication_msg
,
2995 "wimaxasncp.reauthentication_msg",
3007 &hf_wimaxasncp_session_msg
,
3010 "wimaxasncp.session_msg",
3021 &hf_wimaxasncp_length
,
3024 "wimaxasncp.length",
3034 &hf_wimaxasncp_msid
,
3047 &hf_wimaxasncp_reserved1
,
3050 "wimaxasncp.reserved1",
3060 &hf_wimaxasncp_transaction_id
,
3063 "wimaxasncp.transaction_id",
3073 &hf_wimaxasncp_reserved2
,
3076 "wimaxasncp.reserved2",
3101 &hf_wimaxasncp_tlv_type
,
3104 "wimaxasncp.tlv.type",
3114 &hf_wimaxasncp_tlv_length
,
3117 "wimaxasncp.tlv.length",
3127 &hf_wimaxasncp_tlv_value_bytes
,
3130 "wimaxasncp.tlv_value_bytes",
3140 &hf_wimaxasncp_tlv_value_bitflags8
,
3143 "wimaxasncp.tlv_value_bitflags8",
3153 &hf_wimaxasncp_tlv_value_bitflags16
,
3156 "wimaxasncp.tlv_value_bitflags16",
3166 &hf_wimaxasncp_tlv_value_bitflags32
,
3169 "wimaxasncp.tlv_value_bitflags32",
3180 &hf_wimaxasncp_tlv_value_protocol
,
3183 "wimaxasncp.tlv_value_protocol",
3195 &hf_wimaxasncp_tlv_value_vendor_id
,
3198 "wimaxasncp.tlv_value_vendor_id",
3210 /* ------------------------------------------------------------------------
3211 * Protocol subtree array
3212 * ------------------------------------------------------------------------
3215 static int *ett_base
[] = {
3217 &ett_wimaxasncp_flags
,
3218 &ett_wimaxasncp_tlv
,
3219 &ett_wimaxasncp_tlv_value_bitflags8
,
3220 &ett_wimaxasncp_tlv_value_bitflags16
,
3221 &ett_wimaxasncp_tlv_value_bitflags32
,
3222 &ett_wimaxasncp_tlv_protocol_list
,
3223 &ett_wimaxasncp_tlv_port_range_list
,
3224 &ett_wimaxasncp_tlv_ip_address_mask_list
,
3225 &ett_wimaxasncp_tlv_ip_address_mask
,
3226 &ett_wimaxasncp_tlv_eap
,
3227 &ett_wimaxasncp_tlv_vendor_specific_information_field
,
3228 &ett_wimaxasncp_port_range
3231 static ei_register_info ei
[] = {
3232 { &ei_wimaxasncp_tlv_type
, { "wimaxasncp.tlv.type.unknown", PI_UNDECODED
, PI_WARN
, "Unknown tlv", EXPFILL
}},
3233 { &ei_wimaxasncp_function_type
, { "wimaxasncp.function_type.unknown", PI_UNDECODED
, PI_WARN
, "Unknown function type", EXPFILL
}},
3234 { &ei_wimaxasncp_op_id
, { "wimaxasncp.opid.unknown", PI_UNDECODED
, PI_WARN
, "Unknown message op", EXPFILL
}},
3235 { &ei_wimaxasncp_message_type
, { "wimaxasncp.message_type.unknown", PI_UNDECODED
, PI_WARN
, "Unknown message type", EXPFILL
}},
3236 { &ei_wimaxasncp_length_bad
, { "wimaxasncp.length.bad", PI_MALFORMED
, PI_ERROR
, "Bad length", EXPFILL
}},
3239 expert_module_t
* expert_wimaxasncp
;
3241 /* ------------------------------------------------------------------------
3242 * load the XML dictionary
3243 * ------------------------------------------------------------------------
3246 debug_parser
= getenv("WIRESHARK_DEBUG_WIMAXASNCP_DICT_PARSER") != NULL
;
3247 dump_dict
= getenv("WIRESHARK_DUMP_WIMAXASNCP_DICT") != NULL
;
3249 dir
= ws_strdup_printf(
3250 "%s" G_DIR_SEPARATOR_S
"wimaxasncp",
3251 get_datafile_dir());
3254 wimaxasncp_dict_scan(dir
, "dictionary.xml", debug_parser
, &dict_error
);
3260 report_failure("wimaxasncp - %s", dict_error
);
3264 if (wimaxasncp_dict
&& dump_dict
)
3266 wimaxasncp_dict_print(stdout
, wimaxasncp_dict
);
3269 /* ------------------------------------------------------------------------
3270 * build the hf and ett dictionary entries
3271 * ------------------------------------------------------------------------
3274 wimaxasncp_build_dict
.hf
=
3275 wmem_array_new(wmem_epan_scope(), sizeof(hf_register_info
));
3278 wimaxasncp_build_dict
.hf
, hf_base
, array_length(hf_base
));
3280 wimaxasncp_build_dict
.ett
=
3281 wmem_array_new(wmem_epan_scope(), sizeof(int*));
3284 wimaxasncp_build_dict
.ett
, ett_base
, array_length(ett_base
));
3286 if (wimaxasncp_dict
)
3288 wimaxasncp_dict_tlv_t
*tlv
;
3290 /* For each TLV found in XML file */
3291 for (tlv
= wimaxasncp_dict
->tlvs
; tlv
; tlv
= tlv
->next
)
3295 /* Create array for enums */
3296 wimaxasncp_dict_enum_t
*e
;
3297 wmem_array_t
* array
= wmem_array_new(wmem_epan_scope(), sizeof(value_string
));
3299 /* Copy each entry into value_string array */
3300 for (e
= tlv
->enums
; e
; e
= e
->next
)
3302 value_string item
= { e
->code
, e
->name
};
3303 wmem_array_append_one(array
, item
);
3306 /* Set enums to use with this TLV */
3307 wmem_array_set_null_terminator(array
);
3308 tlv
->enum_vs
= (value_string
*)wmem_array_get_raw(array
);
3311 add_tlv_reg_info(tlv
);
3315 /* add an entry for unknown TLVs */
3316 add_tlv_reg_info(&wimaxasncp_tlv_not_found
);
3318 /* The following debug will only be printed if the debug_enabled variable
3319 * is set programmatically. Setting the value via preferences will not
3320 * work as it will be set too late to affect this code path.
3324 if (wimaxasncp_dict
)
3326 wimaxasncp_dict_tlv_t
*tlv
;
3328 for (tlv
= wimaxasncp_dict
->tlvs
; tlv
; tlv
= tlv
->next
)
3333 " description = %s\n"
3340 " hf_protocol = %d\n"
3341 " hf_port_low = %d\n"
3342 " hf_port_high = %d\n"
3343 " hf_ipv4_mask = %d\n"
3344 " hf_ipv6_mask = %d\n"
3345 " hf_vendor_id = %d\n"
3346 " hf_vendor_rest_of_info = %d\n",
3351 tlv
->decoder
, wimaxasncp_decode_type_vals
, "Unknown"),
3363 tlv
->hf_vendor_rest_of_info
);
3368 /* Required function calls to register the header fields and subtrees
3370 proto_register_field_array(
3372 (hf_register_info
*)wmem_array_get_raw(wimaxasncp_build_dict
.hf
),
3373 wmem_array_get_count(wimaxasncp_build_dict
.hf
));
3375 proto_register_subtree_array(
3376 (int**)wmem_array_get_raw(wimaxasncp_build_dict
.ett
),
3377 wmem_array_get_count(wimaxasncp_build_dict
.ett
));
3379 expert_wimaxasncp
= expert_register_protocol(proto_wimaxasncp
);
3380 expert_register_field_array(expert_wimaxasncp
, ei
, array_length(ei
));
3387 /* ========================================================================= */
3388 /* Register the protocol with Wireshark */
3390 /* this format is require because a script is used to build the C function
3391 that calls all the protocol registration.
3395 proto_register_wimaxasncp(void)
3397 module_t
*wimaxasncp_module
;
3399 /* ------------------------------------------------------------------------
3400 * complete registration
3401 * ------------------------------------------------------------------------
3404 /* Register the protocol name and description */
3405 proto_wimaxasncp
= proto_register_protocol("WiMAX ASN Control Plane Protocol", "WiMAX ASN CP", "wimaxasncp");
3407 /* Register this dissector by name */
3408 wimaxasncp_handle
= register_dissector("wimaxasncp", dissect_wimaxasncp
, proto_wimaxasncp
);
3410 wimaxasncp_module
= prefs_register_protocol(proto_wimaxasncp
, NULL
);
3412 /* Register preferences */
3413 prefs_register_bool_preference(
3415 "show_transaction_id_d_bit",
3416 "Show transaction ID direction bit",
3417 "Show transaction ID direction bit separately from the rest of "
3418 "the transaction ID field.",
3419 &show_transaction_id_d_bit
);
3421 prefs_register_bool_preference(
3424 "Enable debug output",
3425 "Print debug output to the console.",
3428 prefs_register_enum_preference(
3432 "Version of the NWG that the R6 protocol complies with",
3433 &global_wimaxasncp_nwg_ver
,
3434 wimaxasncp_nwg_versions
,
3437 proto_register_prefix("wimaxasncp", register_wimaxasncp_fields
);
3440 /* ========================================================================= */
3441 /* If this dissector uses sub-dissector registration add a registration
3442 routine. This exact format is required because a script is used to find
3443 these routines and create the code that calls these routines.
3445 This function is also called by preferences whenever "Apply" is pressed
3446 (see prefs_register_protocol above) so it should accommodate being called
3450 proto_reg_handoff_wimaxasncp(void)
3452 /* Find the EAP dissector */
3453 eap_handle
= find_dissector_add_dependency("eap", proto_wimaxasncp
);
3455 dissector_add_uint_with_preference("udp.port", WIMAXASNCP_DEF_UDP_PORT
, wimaxasncp_handle
);
3460 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3465 * indent-tabs-mode: nil
3468 * vi: set shiftwidth=4 tabstop=8 expandtab:
3469 * :indentSize=4:tabSize=8:noTabs=true: