Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / plugins / epan / wimaxasncp / packet-wimaxasncp.c
blob156856b3c6a17cb60580d2abceb0d327f73f375b
1 /* packet-wimaxasncp.c
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
17 #include "config.h"
19 #include <stdio.h>
20 #include <stdlib.h>
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>
28 #include <epan/eap.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; */
72 /* Preferences */
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)
114 typedef struct {
115 wmem_array_t* hf;
116 wmem_array_t* ett;
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,
127 NULL, NULL, NULL
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"},
145 { 0, NULL}
148 /* ------------------------------------------------------------------------- */
150 static const value_string wimaxasncp_op_id_vals[] =
152 { 0, "Invalid"},
153 { 1, "Request/Initiation"},
154 { 2, "Response"},
155 { 3, "Ack"},
156 { 4, "Indication"},
157 { 5, "Reserved"},
158 { 6, "Reserved"},
159 { 7, "Reserved"},
160 { 0, NULL}
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
185 uint32_t since;
186 value_string vs;
187 } 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"}},
203 {0, { 0, NULL}}
206 /* ------------------------------------------------------------------------- */
208 static const ver_value_string wimaxasncp_qos_msg_vals[] =
210 {0,{ 1, "RR_Req"}},
211 {0,{ 2, "RR_Rsp"}},
212 {0,{ 3, "RR_Ack"}},
213 {0,{ 0, NULL}}
216 /* ------------------------------------------------------------------------- */
218 static const ver_value_string wimaxasncp_ho_control_msg_vals[] =
220 {0, { 1, "HO_Ack"}},
221 {0, { 2, "HO_Complete"}},
222 {0, { 3, "HO_Cnf"}},
223 {0, { 4, "HO_Req"}},
224 {0, { 5, "HO_Rsp"}},
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"}},
232 {0, { 0, NULL}}
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"}},
271 {0, { 0, NULL}}
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"}},
313 {0, { 0, NULL}}
316 /* ------------------------------------------------------------------------- */
318 static const ver_value_string wimaxasncp_paging_msg_vals[] =
320 {0, { 1, "Initiate_Paging_Req"}},
321 {0, { 2, "Initiate_Paging_Rsp"}},
322 {0, { 3, "LU_Cnf"}},
323 {0, { 4, "LU_Req"}},
324 {0, { 5, "LU_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"}},
336 {0, { 0, NULL}}
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"}},
351 {0, { 0, NULL}}
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"}},
368 {0, { 0, NULL}}
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"}},
400 {0, { 0, NULL}}
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"}},
427 {0, { 0, NULL}}
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"}},
436 {0, { 0, NULL}}
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 },
446 { NULL, NULL, 0 }
449 /* ------------------------------------------------------------------------- */
451 /* NWG version */
452 #define WIMAXASNCP_DEF_NWGVER WIMAXASNCP_NWGVER_R10_V121
453 static unsigned global_wimaxasncp_nwg_ver = WIMAXASNCP_DEF_NWGVER;
455 /* ========================================================================= */
457 typedef struct {
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(
482 uint16_t type)
484 wimaxasncp_dict_tlv_t *res = NULL;
486 if (wimaxasncp_dict)
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))
500 res = tlv;
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,
519 uint32_t code)
521 if (tlv_info->enum_vs)
523 return val_to_str_const(code, tlv_info->enum_vs, "Unknown");
525 else
527 return "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"},
561 { 0, NULL}
564 /* ========================================================================= */
566 static void wimaxasncp_proto_tree_add_tlv_ipv4_value(
567 packet_info *pinfo,
568 tvbuff_t *tvb,
569 proto_tree *tree,
570 proto_item *tlv_item,
571 unsigned offset,
572 const wimaxasncp_dict_tlv_t *tlv_info)
574 int hf_value;
575 uint32_t ip;
576 const char *addr_res;
578 if (tlv_info->hf_ipv4 > 0)
580 hf_value = tlv_info->hf_ipv4;
582 else
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(
591 tree, hf_value,
592 tvb, offset, 4, ip,
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(
602 packet_info *pinfo,
603 tvbuff_t *tvb,
604 proto_tree *tree,
605 proto_item *tlv_item,
606 unsigned offset,
607 const wimaxasncp_dict_tlv_t *tlv_info)
609 int hf_value;
610 ws_in6_addr ip;
611 const char *addr_res;
613 if (tlv_info->hf_ipv4 > 0)
615 hf_value = tlv_info->hf_ipv6;
617 else
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(
626 tree, hf_value,
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(
637 packet_info *pinfo,
638 tvbuff_t *tvb,
639 proto_tree *tree,
640 proto_item *tlv_item,
641 unsigned offset,
642 unsigned length,
643 const wimaxasncp_dict_tlv_t *tlv_info)
645 int hf_value;
646 const uint8_t *p;
647 const char *ether_name;
649 if (tlv_info->hf_bsid > 0)
651 hf_value = tlv_info->hf_bsid;
653 else
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(
662 tree, hf_value,
663 tvb, offset, length, p,
664 "Value: %s",
665 ether_name);
667 proto_item_append_text(
668 tlv_item, " - %s",
669 ether_name);
672 /* ========================================================================= */
674 static void wimaxasncp_dissect_tlv_value(
675 tvbuff_t *tvb,
676 packet_info *pinfo,
677 proto_tree *tree,
678 proto_item *tlv_item,
679 const wimaxasncp_dict_tlv_t *tlv_info)
681 unsigned offset = 0;
682 unsigned length;
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:
692 if (length != 1)
694 /* encoding error */
695 break;
698 if (tlv_info->enums == NULL)
700 if (debug_enabled)
702 g_print("fix-me: enum values missing for TLV %s (%u)\n",
703 tlv_info->name, tlv_info->type);
707 if (tree)
709 uint8_t value;
710 const char *s;
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);
724 return;
726 case WIMAXASNCP_TLV_ENUM16:
728 if (length != 2)
730 /* encoding error */
731 break;
734 if (tlv_info->enums == NULL)
736 if (debug_enabled)
738 g_print("fix-me: enum values missing for TLV %s (%u)\n",
739 tlv_info->name, tlv_info->type);
743 if (tree)
745 uint16_t value;
746 const char *s;
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);
760 return;
762 case WIMAXASNCP_TLV_ENUM32:
764 if (length != 4)
766 /* encoding error */
767 break;
770 if (tlv_info->enums == NULL)
772 if (debug_enabled)
774 g_print("fix-me: enum values missing for TLV %s (%u)\n",
775 tlv_info->name, tlv_info->type);
779 if (tree)
781 uint32_t value;
782 const char *s;
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);
796 return;
798 case WIMAXASNCP_TLV_ETHER:
800 if (length != 6)
802 /* encoding error */
803 break;
806 if (tree)
808 wimaxasncp_proto_tree_add_ether_value(
809 pinfo, tvb, tree, tlv_item, offset, length, tlv_info);
812 return;
814 case WIMAXASNCP_TLV_ASCII_STRING:
816 if (tree)
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,
823 "Value: %s", s);
825 proto_item_append_text(
826 tlv_item, " - %s", s);
829 return;
831 case WIMAXASNCP_TLV_FLAG0:
833 if (length != 0)
835 /* encoding error */
836 break;
839 return;
841 case WIMAXASNCP_TLV_BITFLAGS8:
843 if (length != 1)
845 /* encoding error */
846 break;
849 if (tlv_info->enums == NULL)
851 /* enum values missing */
854 if (tree)
856 proto_tree *flags_tree;
857 proto_item *item;
858 uint8_t value;
859 unsigned i;
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);
869 if (value != 0)
871 flags_tree = proto_item_add_subtree(
872 item, ett_wimaxasncp_tlv_value_bitflags8);
874 for (i = 0; i < 8; ++i)
876 uint8_t mask;
877 mask = 1U << (7 - i);
879 if (value & mask)
881 const char *s;
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);
894 return;
896 case WIMAXASNCP_TLV_BITFLAGS16:
898 if (length != 2)
900 /* encoding error */
901 break;
904 if (tlv_info->enums == NULL)
906 /* enum values missing */
909 if (tree)
911 proto_tree *flags_tree;
912 proto_item *item;
913 uint16_t value;
914 unsigned i;
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);
924 if (value != 0)
926 flags_tree = proto_item_add_subtree(
927 item, ett_wimaxasncp_tlv_value_bitflags16);
929 for (i = 0; i < 16; ++i)
931 uint16_t mask;
932 mask = 1U << (15 - i);
934 if (value & mask)
936 const char *s;
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);
949 return;
951 case WIMAXASNCP_TLV_BITFLAGS32:
953 if (length != 4)
955 /* encoding error */
956 break;
959 if (tlv_info->enums == NULL)
961 /* enum values missing */
964 if (tree)
966 proto_tree *flags_tree;
967 proto_item *item;
968 uint32_t value;
969 unsigned i;
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);
979 if (value != 0)
981 flags_tree = proto_item_add_subtree(
982 item, ett_wimaxasncp_tlv_value_bitflags32);
984 for (i = 0; i < 32; ++i)
986 uint32_t mask;
987 mask = 1U << (31 - i);
989 if (value & mask)
991 const char *s;
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);
1003 return;
1005 case WIMAXASNCP_TLV_ID:
1007 if (length == 4)
1009 if (tree)
1011 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1012 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1015 return;
1017 else if (length == 6)
1019 if (tree)
1021 wimaxasncp_proto_tree_add_ether_value(
1022 pinfo, tvb, tree, tlv_item, offset, length, tlv_info);
1025 return;
1027 else if (length == 16)
1029 if (tree)
1031 wimaxasncp_proto_tree_add_tlv_ipv6_value(
1032 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1035 return;
1037 else
1039 /* encoding error */
1040 break;
1043 case WIMAXASNCP_TLV_BYTES:
1045 if (tree)
1047 proto_tree_add_item(
1048 tree, tlv_info->hf_value,
1049 tvb, offset, length, ENC_NA);
1051 if (length) {
1052 const char* format;
1053 if (length <= max_show_bytes)
1055 format = " - %s";
1057 else
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);
1066 } else {
1067 proto_item_append_text(tlv_item, " - <MISSING>");
1071 return;
1073 case WIMAXASNCP_TLV_HEX8:
1075 if (length != 1)
1077 /* encoding error */
1078 break;
1081 if (tree)
1083 uint8_t value;
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);
1095 return;
1097 case WIMAXASNCP_TLV_HEX16:
1099 if (length != 2)
1101 /* encoding error */
1102 break;
1105 if (tree)
1107 uint16_t value;
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);
1119 return;
1121 case WIMAXASNCP_TLV_HEX32:
1123 if (length != 4)
1125 /* encoding error */
1126 break;
1129 if (tree)
1131 uint32_t value;
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);
1143 return;
1145 case WIMAXASNCP_TLV_DEC8:
1147 if (length != 1)
1149 /* encoding error */
1150 break;
1153 if (tree)
1155 uint8_t value;
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);
1167 return;
1169 case WIMAXASNCP_TLV_DEC16:
1171 if (length != 2)
1173 /* encoding error */
1174 break;
1177 if (tree)
1179 uint16_t value;
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);
1191 return;
1193 case WIMAXASNCP_TLV_DEC32:
1195 if (length != 4)
1197 /* encoding error */
1198 break;
1201 if (tree)
1203 uint32_t value;
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);
1215 return;
1217 case WIMAXASNCP_TLV_TBD:
1219 if (debug_enabled)
1221 g_print(
1222 "fix-me: TBD: TLV %s (%u)\n", tlv_info->name, tlv_info->type);
1225 if (tree)
1227 if (length) {
1228 const char *format;
1229 const char *s = tvb_bytes_to_str_punct(
1230 pinfo->pool, tvb, offset, length, 0);
1232 if (length <= max_show_bytes) {
1233 format = "%s %s";
1234 } else {
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);
1242 } else {
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");
1251 return;
1253 case WIMAXASNCP_TLV_IP_ADDRESS:
1255 if (length == 4)
1257 if (tree)
1259 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1260 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1263 return;
1265 else if (length == 16)
1267 if (tree)
1269 wimaxasncp_proto_tree_add_tlv_ipv6_value(
1270 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1273 return;
1275 else
1277 /* encoding error */
1278 break;
1281 case WIMAXASNCP_TLV_IPV4_ADDRESS:
1283 if (length != 4)
1285 /* encoding error */
1286 break;
1289 if (tree)
1291 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1292 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1295 return;
1297 case WIMAXASNCP_TLV_PROTOCOL_LIST:
1299 if (length % 2 != 0)
1301 /* encoding error */
1302 break;
1305 if (tree && length > 0)
1307 proto_tree *protocol_list_tree;
1308 proto_item *item;
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))
1324 uint16_t protocol;
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);
1335 if (offset == 0)
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, ", ...");
1348 offset += 2;
1352 return;
1354 case WIMAXASNCP_TLV_PORT_RANGE_LIST:
1356 if (length % 4 != 0)
1358 /* encoding error */
1359 break;
1362 if (tree && length > 0)
1364 proto_tree *port_range_list_tree;
1365 proto_item *item;
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))
1381 uint16_t portLow;
1382 uint16_t portHigh;
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);
1406 if (offset == 0)
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, ", ...");
1421 offset += 4;
1425 return;
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 */
1443 break;
1446 if (tree && length > 0)
1448 proto_tree *ip_address_mask_list_tree;
1449 proto_item *item;
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 /* ------------------------------------------------------------
1465 * presume IPv6
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 /* --------------------------------------------------------
1478 * address
1479 * --------------------------------------------------------
1482 proto_tree_add_item(
1483 ip_address_mask_tree,
1484 tlv_info->hf_ipv6,
1485 tvb, offset, 16, ENC_NA);
1487 /* too long to display ?
1488 proto_item_append_text(
1489 item, " - %s (%s)",
1490 get_hostname6(&ip), ip6_to_str(&ip));
1493 offset += 16;
1495 /* --------------------------------------------------------
1496 * mask
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(
1506 item, " / %s", s);
1509 offset += 16;
1512 else
1514 /* ------------------------------------------------------------
1515 * IPv4
1516 * ------------------------------------------------------------
1519 while (offset < tvb_reported_length(tvb))
1521 proto_tree *ip_address_mask_tree;
1522 uint32_t ip;
1523 const char *s;
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 /* --------------------------------------------------------
1530 * address
1531 * --------------------------------------------------------
1534 ip = tvb_get_ipv4(tvb, offset);
1536 proto_tree_add_item(
1537 ip_address_mask_tree,
1538 tlv_info->hf_ipv4,
1539 tvb, offset, 4, ENC_BIG_ENDIAN);
1541 proto_item_append_text(
1542 item, " - %s (%s)",
1543 get_hostname(ip), tvb_ip_to_str(pinfo->pool, tvb, offset));
1545 offset += 4;
1547 /* --------------------------------------------------------
1548 * mask
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(
1560 item, " / %s", s);
1562 offset += 4;
1567 return;
1569 case WIMAXASNCP_TLV_EAP:
1572 * EAP payload, call eap dissector to dissect eap payload
1574 uint8_t eap_code;
1575 uint8_t eap_type = 0;
1577 /* Get code */
1578 eap_code = tvb_get_uint8(tvb, offset);
1579 if (eap_code == EAP_REQUEST || eap_code == EAP_RESPONSE)
1581 /* Get type */
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;
1602 proto_item *item;
1603 bool save_writable;
1604 tvbuff_t *eap_tvb;
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);
1639 return;
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
1650 * handled?
1652 * For now, we decode the vendor ID as a non-padded 24-bit value and
1653 * dump the rest as hex.
1654 * --------------------------------------------------------------------
1657 if (length < 3)
1659 /* encoding error */
1660 break;
1663 if (tree)
1665 proto_tree *vsif_tree;
1666 proto_item *item;
1667 uint32_t vendorId;
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);
1696 offset += 3;
1698 /* ----------------------------------------------------------------
1699 * hex dump the rest
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);
1711 return;
1713 case WIMAXASNCP_TLV_UNKNOWN:
1715 if (tree)
1717 const char* s;
1718 if (length) {
1719 const char* format1;
1720 const char* format2;
1721 if (length <= max_show_bytes)
1723 format1 = "%s %s";
1724 format2 = " - %s %s";
1726 else
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);
1741 else {
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>");
1751 return;
1753 default:
1754 if (debug_enabled)
1756 g_print(
1757 "fix-me: unknown decoder: %d\n", tlv_info->decoder);
1759 break;
1762 /* default is hex dump */
1764 if (tree)
1766 if (length) {
1767 const char* format;
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) {
1772 format = "%s %s";
1773 } else {
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);
1781 } else {
1782 proto_tree_add_bytes_format_value(
1783 tree, hf_wimaxasncp_tlv_value_bytes,
1784 tvb, offset, length, NULL,
1785 "%s", "<MISSING>");
1790 /* ========================================================================= */
1792 // NOLINTNEXTLINE(misc-no-recursion)
1793 static unsigned dissect_wimaxasncp_tlvs(
1794 tvbuff_t *tvb,
1795 packet_info *pinfo,
1796 proto_tree *tree)
1798 unsigned offset;
1800 offset = 0;
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;
1807 uint16_t type;
1808 uint16_t length;
1809 unsigned pad;
1811 /* --------------------------------------------------------------------
1812 * type and length
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);
1823 if (pad == 4)
1825 pad = 0;
1827 #endif
1828 pad = 0;
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)",
1868 type);
1871 /* Length */
1872 proto_tree_add_uint(
1873 tlv_tree, hf_wimaxasncp_tlv_length,
1874 tvb, offset + 2, 2, length);
1878 offset += 4;
1880 /* --------------------------------------------------------------------
1881 * value
1882 * --------------------------------------------------------------------
1885 if (tlv_info->decoder == WIMAXASNCP_TLV_COMPOUND)
1887 if (length == 0)
1889 /* error? compound, but no TLVs inside */
1891 else if (tvb_reported_length_remaining(tvb, offset) > 0)
1893 tvbuff_t *tlv_tvb;
1895 /* N.B. Not padding out tvb length */
1896 tlv_tvb = tvb_new_subset_length_caplen(
1897 tvb, offset,
1898 MIN(length, tvb_captured_length_remaining(tvb, offset)),
1899 length);
1901 increment_dissection_depth(pinfo);
1902 dissect_wimaxasncp_tlvs(tlv_tvb, pinfo, tlv_tree);
1903 decrement_dissection_depth(pinfo);
1905 else
1907 /* this should throw */
1908 tvb_ensure_bytes_exist(tvb, offset, length + pad);
1911 else
1913 tvbuff_t *tlv_tvb;
1915 tvb_ensure_bytes_exist(tvb, offset, length + pad);
1917 tlv_tvb = tvb_new_subset_length_caplen(
1918 tvb, offset,
1919 MIN(length, tvb_captured_length_remaining(tvb, offset)),
1920 length);
1922 wimaxasncp_dissect_tlv_value(
1923 tlv_tvb, pinfo, tlv_tree, tlv_item, tlv_info);
1926 offset += length + pad;
1929 return offset;
1932 /* ========================================================================= */
1934 static unsigned dissect_wimaxasncp_backend(
1935 tvbuff_t *tvb,
1936 packet_info *pinfo,
1937 proto_tree *tree)
1939 unsigned offset = 0;
1940 uint16_t ui16;
1941 uint32_t ui32;
1942 const uint8_t *pmsid;
1943 uint16_t tid = 0;
1944 bool dbit_show;
1947 /* ------------------------------------------------------------------------
1948 * MSID
1949 * ------------------------------------------------------------------------
1952 if (tree)
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);
1960 offset += 6;
1962 /* ------------------------------------------------------------------------
1963 * reserved
1964 * ------------------------------------------------------------------------
1967 ui32 = tvb_get_ntohl(tvb, offset);
1969 if (tree)
1971 proto_tree_add_uint(
1972 tree, hf_wimaxasncp_reserved1,
1973 tvb, offset, 4, ui32);
1976 offset += 4;
1978 /* ------------------------------------------------------------------------
1979 * transaction ID
1980 * ------------------------------------------------------------------------
1983 dbit_show = false;
1984 ui16 = tvb_get_ntohs(tvb, offset);
1986 if (show_transaction_id_d_bit)
1988 const uint16_t mask = 0x7fff;
1990 if (ui16 & 0x8000)
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);
1997 tid = ui16 & mask;
1998 dbit_show = true;
2000 else
2002 proto_tree_add_uint_format(
2003 tree, hf_wimaxasncp_transaction_id,
2004 tvb, offset, 2, ui16,
2005 "Transaction ID: 0x%04x", ui16);
2007 tid = ui16;
2010 else
2012 proto_tree_add_uint(
2013 tree, hf_wimaxasncp_transaction_id,
2014 tvb, offset, 2, ui16);
2016 tid = ui16;
2019 offset += 2;
2021 /* ------------------------------------------------------------------------
2022 * reserved
2023 * ------------------------------------------------------------------------
2026 ui16 = tvb_get_ntohs(tvb, offset);
2028 if (tree)
2030 proto_tree_add_uint(
2031 tree, hf_wimaxasncp_reserved2,
2032 tvb, offset, 2, ui16);
2035 offset += 2;
2037 /* ------------------------------------------------------------------------
2038 * TLVs
2039 * ------------------------------------------------------------------------
2042 if (tvb_reported_length_remaining(tvb, offset) > 0)
2044 tvbuff_t *tlv_tvb;
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);
2052 if (dbit_show)
2054 col_append_fstr(pinfo->cinfo, COL_INFO, ", TID:D+0x%04x", tid);
2056 else
2058 col_append_fstr(pinfo->cinfo, COL_INFO, ", TID:0x%04x", tid);
2061 return offset;
2064 /* ========================================================================= */
2067 static const char*
2068 match_ver_value_string(
2069 const uint32_t val,
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))
2083 res = vvs;
2088 return res? res->vs.strptr : NULL;
2091 static int
2092 dissect_wimaxasncp(
2093 tvbuff_t *tvb,
2094 packet_info *pinfo,
2095 proto_tree *tree,
2096 void *data _U_)
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;
2104 tvbuff_t *subtree;
2106 unsigned offset;
2107 uint8_t ui8;
2109 uint8_t function_type;
2110 const char *function_type_name;
2111 proto_item *function_type_item;
2112 uint16_t length;
2114 const wimaxasncp_func_msg_t *p = NULL;
2115 const char *message_name;
2116 size_t i;
2118 /* ------------------------------------------------------------------------
2119 * First, we do some heuristics to check if the packet cannot be our
2120 * protocol.
2121 * ------------------------------------------------------------------------
2124 /* Should we check a minimum size? If so, uncomment out the following
2125 * code. */
2126 #if 0
2127 if (tvb_reported_length(tvb) < WIMAXASNCP_HEADER_SIZE)
2129 return 0;
2131 #endif
2133 /* We currently only support version 1. */
2134 if (tvb_bytes_exist(tvb, 0, 1) && tvb_get_uint8(tvb, 0) != 1)
2136 return 0;
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
2149 exception. */
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 * ------------------------------------------------------------------------
2162 offset = 0;
2164 /* Register protocol fields, etc if haven't done yet. */
2165 if (hf_wimaxasncp_version <= 0)
2167 proto_registrar_get_byname("wimaxasncp.version");
2170 if (tree)
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 /* ------------------------------------------------------------------------
2181 * version
2182 * ------------------------------------------------------------------------
2185 if (tree)
2187 proto_tree_add_item(
2188 wimaxasncp_tree, hf_wimaxasncp_version,
2189 tvb, offset, 1, ENC_BIG_ENDIAN);
2192 offset += 1;
2194 /* ------------------------------------------------------------------------
2195 * flags
2196 * ------------------------------------------------------------------------
2199 ui8 = tvb_get_uint8(tvb, offset);
2201 if (tree)
2203 proto_tree *flags_tree;
2205 if (ui8 == 0)
2207 proto_tree_add_uint_format(
2208 wimaxasncp_tree, hf_wimaxasncp_flags,
2209 tvb, offset, 1, ui8,
2210 "Flags: 0x%02x", ui8);
2212 else
2214 unsigned j;
2215 item = proto_tree_add_uint_format(
2216 wimaxasncp_tree, hf_wimaxasncp_flags,
2217 tvb, offset, 1, ui8,
2218 "Flags: ");
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)
2242 uint8_t mask;
2243 mask = 1U << (7 - j);
2245 /* Only add flags that are set */
2246 if (ui8 & mask)
2248 proto_tree_add_uint_format(
2249 flags_tree, hf_wimaxasncp_flags,
2250 tvb, offset, 1, ui8,
2251 "Bit #%u is set: %s",
2253 val_to_str(
2254 ui8 & mask, wimaxasncp_flag_vals, "Unknown"));
2260 offset += 1;
2262 /* ------------------------------------------------------------------------
2263 * function type
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);
2281 else
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)",
2292 function_type);
2295 offset += 1;
2297 /* ------------------------------------------------------------------------
2298 * OP ID and message type
2299 * ------------------------------------------------------------------------
2302 ui8 = tvb_get_uint8(tvb, offset);
2305 /* --------------------------------------------------------------------
2306 * OP ID
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)
2325 break;
2329 /* --------------------------------------------------------------------
2330 * message type
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)",
2352 0x1f & ui8);
2355 col_add_str(pinfo->cinfo, COL_INFO, message_name);
2357 offset += 1;
2359 /* ------------------------------------------------------------------------
2360 * length
2361 * ------------------------------------------------------------------------
2364 length = tvb_get_ntohs(tvb, offset);
2366 if (tree)
2368 proto_item_set_len(
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);
2376 offset += 2;
2378 if (length < WIMAXASNCP_HEADER_SIZE)
2380 expert_add_info(pinfo, item, &ei_wimaxasncp_length_bad);
2382 if (tree)
2384 proto_item_append_text(
2385 item, " [error: specified length less than header size (20)]");
2388 if (length <= WIMAXASNCP_HEADER_LENGTH_END)
2390 return offset;
2394 /* ------------------------------------------------------------------------
2395 * remaining header fields and TLVs
2396 * ------------------------------------------------------------------------
2399 subtree = tvb_new_subset_length_caplen(
2400 tvb, offset,
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 * ------------------------------------------------------------------------
2412 return offset;
2415 /* ========================================================================= */
2416 /* Modify the given string to make a suitable display filter */
2417 static char *alnumerize(
2418 char *name)
2420 char *r = name; /* read pointer */
2421 char *w = name; /* write pointer */
2422 char c;
2424 for ( ; (c = *r); ++r)
2426 if (g_ascii_isalnum(c) || c == '_' || c == '.')
2428 /* These characters are fine - copy them */
2429 *(w++) = c;
2431 else if (c == ' ' || c == '-' || c == '/')
2433 /* Skip these others if haven't written any characters out yet */
2434 if (w == name)
2436 continue;
2439 /* Skip if we would produce multiple adjacent '_'s */
2440 if (*(w - 1) == '_')
2442 continue;
2445 /* OK, replace with underscore */
2446 *(w++) = '_';
2449 /* Other undesirable characters are just skipped */
2452 /* Terminate and return modified string */
2453 *w = '\0';
2454 return name;
2457 /* ========================================================================= */
2459 static void add_reg_info(
2460 int *hf_ptr,
2461 const char *name,
2462 const char *abbrev,
2463 enum ftenum type,
2464 int display,
2465 const char *blurb)
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)
2478 char *name;
2479 char *abbrev;
2480 const char *root_blurb;
2481 char *blurb;
2483 /* ------------------------------------------------------------------------
2484 * add root reg info
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";
2495 break;
2496 case WIMAXASNCP_TLV_TBD:
2497 root_blurb = wmem_strdup_printf(wmem_epan_scope(), "type=%u, TBD", tlv->type);
2498 break;
2499 case WIMAXASNCP_TLV_COMPOUND:
2500 root_blurb = wmem_strdup_printf(wmem_epan_scope(), "type=%u, Compound", tlv->type);
2501 break;
2502 case WIMAXASNCP_TLV_FLAG0:
2503 root_blurb = wmem_strdup_printf(wmem_epan_scope(), "type=%u, Value = Null", tlv->type);
2504 break;
2505 default:
2506 root_blurb = wmem_strdup_printf(wmem_epan_scope(), "type=%u", tlv->type);
2507 break;
2510 add_reg_info(
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);
2527 add_reg_info(
2528 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE,
2529 "value for unknown type");
2530 break;
2532 case WIMAXASNCP_TLV_TBD:
2533 add_reg_info(
2534 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2535 break;
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);
2542 break;
2544 case WIMAXASNCP_TLV_BYTES:
2545 add_reg_info(
2546 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2547 break;
2549 case WIMAXASNCP_TLV_ENUM8:
2550 add_reg_info(
2551 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_DEC, blurb);
2552 break;
2554 case WIMAXASNCP_TLV_ENUM16:
2555 add_reg_info(
2556 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2557 break;
2559 case WIMAXASNCP_TLV_ENUM32:
2560 add_reg_info(
2561 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_DEC, blurb);
2562 break;
2564 case WIMAXASNCP_TLV_ETHER:
2565 add_reg_info(
2566 &tlv->hf_value, name, abbrev, FT_ETHER, BASE_NONE, blurb);
2567 break;
2569 case WIMAXASNCP_TLV_ASCII_STRING:
2570 add_reg_info(
2571 &tlv->hf_value, name, abbrev, FT_STRING, BASE_NONE, blurb);
2572 break;
2574 case WIMAXASNCP_TLV_BITFLAGS8:
2575 add_reg_info(
2576 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_HEX, blurb);
2577 break;
2579 case WIMAXASNCP_TLV_BITFLAGS16:
2580 add_reg_info(
2581 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_HEX, blurb);
2582 break;
2584 case WIMAXASNCP_TLV_BITFLAGS32:
2585 add_reg_info(
2586 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_HEX, blurb);
2587 break;
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));
2595 add_reg_info(
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));
2601 add_reg_info(
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));
2607 add_reg_info(
2608 &tlv->hf_bsid, "BS ID", abbrev, FT_ETHER, BASE_NONE, blurb);
2610 break;
2612 case WIMAXASNCP_TLV_HEX8:
2613 add_reg_info(
2614 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_HEX, blurb);
2615 break;
2617 case WIMAXASNCP_TLV_HEX16:
2618 add_reg_info(
2619 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_HEX, blurb);
2620 break;
2622 case WIMAXASNCP_TLV_HEX32:
2623 add_reg_info(
2624 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_HEX, blurb);
2625 break;
2627 case WIMAXASNCP_TLV_DEC8:
2628 add_reg_info(
2629 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_DEC, blurb);
2630 break;
2632 case WIMAXASNCP_TLV_DEC16:
2633 add_reg_info(
2634 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2635 break;
2637 case WIMAXASNCP_TLV_DEC32:
2638 add_reg_info(
2639 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_DEC, blurb);
2640 break;
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));
2648 add_reg_info(
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));
2654 add_reg_info(
2655 &tlv->hf_ipv6, "IPv6 Address", abbrev, FT_IPv6, BASE_NONE, blurb);
2657 break;
2659 case WIMAXASNCP_TLV_IPV4_ADDRESS:
2660 add_reg_info(
2661 &tlv->hf_value, name, abbrev, FT_IPv4, BASE_NONE, blurb);
2662 break;
2664 case WIMAXASNCP_TLV_PROTOCOL_LIST:
2665 add_reg_info(
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));
2673 add_reg_info(
2674 &tlv->hf_protocol, "Protocol", abbrev, FT_UINT16, BASE_DEC, blurb);
2676 break;
2678 case WIMAXASNCP_TLV_PORT_RANGE_LIST:
2679 add_reg_info(
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));
2687 add_reg_info(
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));
2693 add_reg_info(
2694 &tlv->hf_port_high, "Port High", abbrev, FT_UINT16, BASE_DEC, blurb);
2696 break;
2698 case WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST:
2699 add_reg_info(
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));
2707 add_reg_info(
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));
2713 add_reg_info(
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));
2719 add_reg_info(
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));
2725 add_reg_info(
2726 &tlv->hf_ipv6_mask, "IPv6 Mask", abbrev, FT_IPv6, BASE_NONE, blurb);
2728 break;
2730 case WIMAXASNCP_TLV_VENDOR_SPECIFIC:
2731 add_reg_info(
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));
2739 add_reg_info(
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));
2746 add_reg_info(
2747 &tlv->hf_vendor_rest_of_info, "Rest of Info", abbrev, FT_BYTES, BASE_NONE,
2748 blurb);
2750 break;
2752 case WIMAXASNCP_TLV_EAP:
2753 blurb = wmem_strdup_printf(wmem_epan_scope(), "EAP payload embedded in %s", name);
2755 add_reg_info(
2756 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2757 break;
2760 default:
2761 add_reg_info(
2762 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2764 if (debug_enabled)
2766 g_print(
2767 "fix-me: unknown decoder: %d\n", tlv->decoder);
2770 break;
2774 /* ========================================================================= */
2775 /* Register the protocol fields and subtrees with Wireshark */
2776 static void
2777 register_wimaxasncp_fields(const char* unused _U_)
2779 bool debug_parser;
2780 bool dump_dict;
2781 char *dir;
2782 char* dict_error;
2784 /* ------------------------------------------------------------------------
2785 * List of header fields
2786 * ------------------------------------------------------------------------
2789 static hf_register_info hf_base[] = {
2791 &hf_wimaxasncp_version,
2793 "Version",
2794 "wimaxasncp.version",
2795 FT_UINT8,
2796 BASE_DEC,
2797 NULL,
2798 0x0,
2799 NULL,
2800 HFILL
2804 &hf_wimaxasncp_flags,
2806 "Flags",
2807 "wimaxasncp.flags",
2808 FT_UINT8,
2809 BASE_HEX,
2810 NULL,
2811 0xff,
2812 NULL,
2813 HFILL
2817 &hf_wimaxasncp_function_type,
2819 "Function Type",
2820 "wimaxasncp.function_type",
2821 FT_UINT8,
2822 BASE_DEC,
2823 NULL,
2824 0x0,
2825 NULL,
2826 HFILL
2830 &hf_wimaxasncp_op_id,
2832 "OP ID",
2833 "wimaxasncp.opid",
2834 FT_UINT8,
2835 BASE_HEX,
2836 VALS(wimaxasncp_op_id_vals),
2837 0xE0,
2838 NULL,
2839 HFILL
2843 &hf_wimaxasncp_message_type,
2845 "Message Type",
2846 "wimaxasncp.message_type",
2847 FT_UINT8,
2848 BASE_HEX,
2849 NULL,
2850 0x1F,
2851 NULL,
2852 HFILL
2855 #if 0
2857 &hf_wimaxasncp_qos_msg,
2859 "Message Type",
2860 "wimaxasncp.qos_msg",
2861 FT_UINT8,
2862 BASE_HEX,
2863 NULL,
2864 0x1F,
2865 NULL,
2866 HFILL
2869 #endif
2870 #if 0
2872 &hf_wimaxasncp_ho_control_msg,
2874 "Message Type",
2875 "wimaxasncp.ho_control_msg",
2876 FT_UINT8,
2877 BASE_HEX,
2878 NULL,
2879 0x1F,
2880 NULL,
2881 HFILL
2884 #endif
2885 #if 0
2887 &hf_wimaxasncp_data_path_control_msg,
2889 "Message Type",
2890 "wimaxasncp.data_path_control_msg",
2891 FT_UINT8,
2892 BASE_HEX,
2893 NULL,
2894 0x1F,
2895 NULL,
2896 HFILL
2899 #endif
2900 #if 0
2902 &hf_wimaxasncp_context_delivery_msg,
2904 "Message Type",
2905 "wimaxasncp.context_delivery_msg",
2906 FT_UINT8,
2907 BASE_HEX,
2908 NULL,
2909 0x1F,
2910 NULL,
2911 HFILL
2914 #endif
2915 #if 0
2917 &hf_wimaxasncp_r3_mobility_msg,
2919 "Message Type",
2920 "wimaxasncp.r3_mobility_msg",
2921 FT_UINT8,
2922 BASE_HEX,
2923 NULL,
2924 0x1F,
2925 NULL,
2926 HFILL
2929 #endif
2930 #if 0
2932 &hf_wimaxasncp_paging_msg,
2934 "Message Type",
2935 "wimaxasncp.paging_msg",
2936 FT_UINT8,
2937 BASE_HEX,
2938 NULL,
2939 0x1F,
2940 NULL,
2941 HFILL
2944 #endif
2945 #if 0
2947 &hf_wimaxasncp_rrm_msg,
2949 "Message Type",
2950 "wimaxasncp.rrm_msg",
2951 FT_UINT8,
2952 BASE_HEX,
2953 NULL,
2954 0x1F,
2955 NULL,
2956 HFILL
2959 #endif
2960 #if 0
2962 &hf_wimaxasncp_authentication_msg,
2964 "Message Type",
2965 "wimaxasncp.authentication_msg",
2966 FT_UINT8,
2967 BASE_HEX,
2968 NULL,
2969 0x1F,
2970 NULL,
2971 HFILL
2974 #endif
2975 #if 0
2977 &hf_wimaxasncp_ms_state_msg,
2979 "Message Type",
2980 "wimaxasncp.ms_state_msg",
2981 FT_UINT8,
2982 BASE_HEX,
2983 NULL,
2984 0x1F,
2985 NULL,
2986 HFILL
2989 #endif
2990 #if 0
2992 &hf_wimaxasncp_reauthentication_msg,
2994 "Message Type",
2995 "wimaxasncp.reauthentication_msg",
2996 FT_UINT8,
2997 BASE_HEX,
2998 NULL,
2999 0x1F,
3000 NULL,
3001 HFILL
3004 #endif
3005 #if 0
3007 &hf_wimaxasncp_session_msg,
3009 "Message Type",
3010 "wimaxasncp.session_msg",
3011 FT_UINT8,
3012 BASE_HEX,
3013 NULL,
3014 0x1F,
3015 NULL,
3016 HFILL
3019 #endif
3021 &hf_wimaxasncp_length,
3023 "Length",
3024 "wimaxasncp.length",
3025 FT_UINT16,
3026 BASE_DEC,
3027 NULL,
3028 0x0,
3029 NULL,
3030 HFILL
3034 &hf_wimaxasncp_msid,
3036 "MSID",
3037 "wimaxasncp.msid",
3038 FT_ETHER,
3039 BASE_NONE,
3040 NULL,
3041 0x0,
3042 NULL,
3043 HFILL
3047 &hf_wimaxasncp_reserved1,
3049 "Reserved",
3050 "wimaxasncp.reserved1",
3051 FT_UINT32,
3052 BASE_HEX,
3053 NULL,
3054 0x0,
3055 NULL,
3056 HFILL
3060 &hf_wimaxasncp_transaction_id,
3062 "Transaction ID",
3063 "wimaxasncp.transaction_id",
3064 FT_UINT16,
3065 BASE_HEX,
3066 NULL,
3067 0x0,
3068 NULL,
3069 HFILL
3073 &hf_wimaxasncp_reserved2,
3075 "Reserved",
3076 "wimaxasncp.reserved2",
3077 FT_UINT16,
3078 BASE_HEX,
3079 NULL,
3080 0x0,
3081 NULL,
3082 HFILL
3085 #if 0
3087 &hf_wimaxasncp_tlv,
3089 "TLV",
3090 "wimaxasncp.tlv",
3091 FT_BYTES,
3092 BASE_NONE,
3093 NULL,
3094 0x0,
3095 NULL,
3096 HFILL
3099 #endif
3101 &hf_wimaxasncp_tlv_type,
3103 "Type",
3104 "wimaxasncp.tlv.type",
3105 FT_UINT16,
3106 BASE_DEC,
3107 NULL,
3108 0x0,
3109 NULL,
3110 HFILL
3114 &hf_wimaxasncp_tlv_length,
3116 "Length",
3117 "wimaxasncp.tlv.length",
3118 FT_UINT16,
3119 BASE_DEC,
3120 NULL,
3121 0x0,
3122 NULL,
3123 HFILL
3127 &hf_wimaxasncp_tlv_value_bytes,
3129 "Value",
3130 "wimaxasncp.tlv_value_bytes",
3131 FT_BYTES,
3132 BASE_NONE,
3133 NULL,
3134 0x0,
3135 NULL,
3136 HFILL
3140 &hf_wimaxasncp_tlv_value_bitflags8,
3142 "Value",
3143 "wimaxasncp.tlv_value_bitflags8",
3144 FT_UINT8,
3145 BASE_HEX,
3146 NULL,
3147 0xff,
3148 NULL,
3149 HFILL
3153 &hf_wimaxasncp_tlv_value_bitflags16,
3155 "Value",
3156 "wimaxasncp.tlv_value_bitflags16",
3157 FT_UINT16,
3158 BASE_HEX,
3159 NULL,
3160 0xffff,
3161 NULL,
3162 HFILL
3166 &hf_wimaxasncp_tlv_value_bitflags32,
3168 "Value",
3169 "wimaxasncp.tlv_value_bitflags32",
3170 FT_UINT32,
3171 BASE_HEX,
3172 NULL,
3173 0xffffffff,
3174 NULL,
3175 HFILL
3178 #if 0
3180 &hf_wimaxasncp_tlv_value_protocol,
3182 "Value",
3183 "wimaxasncp.tlv_value_protocol",
3184 FT_UINT16,
3185 BASE_DEC,
3186 NULL,
3187 0x0,
3188 NULL,
3189 HFILL
3192 #endif
3193 #if 0
3195 &hf_wimaxasncp_tlv_value_vendor_id,
3197 "Vendor ID",
3198 "wimaxasncp.tlv_value_vendor_id",
3199 FT_UINT24,
3200 BASE_DEC,
3201 NULL,
3202 0x0,
3203 NULL,
3204 HFILL
3207 #endif
3210 /* ------------------------------------------------------------------------
3211 * Protocol subtree array
3212 * ------------------------------------------------------------------------
3215 static int *ett_base[] = {
3216 &ett_wimaxasncp,
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());
3253 wimaxasncp_dict =
3254 wimaxasncp_dict_scan(dir, "dictionary.xml", debug_parser, &dict_error);
3256 g_free(dir);
3258 if (dict_error)
3260 report_failure("wimaxasncp - %s", dict_error);
3261 g_free(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));
3277 wmem_array_append(
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*));
3283 wmem_array_append(
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)
3293 if (tlv->enums)
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.
3322 if (debug_enabled)
3324 if (wimaxasncp_dict)
3326 wimaxasncp_dict_tlv_t *tlv;
3328 for (tlv = wimaxasncp_dict->tlvs; tlv; tlv = tlv->next)
3330 ws_debug_printf(
3331 "%s\n"
3332 " type = %u\n"
3333 " description = %s\n"
3334 " decoder = %s\n"
3335 " hf_root = %d\n"
3336 " hf_value = %d\n"
3337 " hf_ipv4 = %d\n"
3338 " hf_ipv6 = %d\n"
3339 " hf_bsid = %d\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",
3347 tlv->name,
3348 tlv->type,
3349 tlv->description,
3350 val_to_str(
3351 tlv->decoder, wimaxasncp_decode_type_vals, "Unknown"),
3352 tlv->hf_root,
3353 tlv->hf_value,
3354 tlv->hf_ipv4,
3355 tlv->hf_ipv6,
3356 tlv->hf_bsid,
3357 tlv->hf_protocol,
3358 tlv->hf_port_low,
3359 tlv->hf_port_high,
3360 tlv->hf_ipv4_mask,
3361 tlv->hf_ipv6_mask,
3362 tlv->hf_vendor_id,
3363 tlv->hf_vendor_rest_of_info);
3368 /* Required function calls to register the header fields and subtrees
3369 * used */
3370 proto_register_field_array(
3371 proto_wimaxasncp,
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.
3394 void
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(
3414 wimaxasncp_module,
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(
3422 wimaxasncp_module,
3423 "debug_enabled",
3424 "Enable debug output",
3425 "Print debug output to the console.",
3426 &debug_enabled);
3428 prefs_register_enum_preference(
3429 wimaxasncp_module,
3430 "nwg_version",
3431 "NWG Version",
3432 "Version of the NWG that the R6 protocol complies with",
3433 &global_wimaxasncp_nwg_ver,
3434 wimaxasncp_nwg_versions,
3435 false);
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
3447 more than once.
3449 void
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
3462 * Local variables:
3463 * c-basic-offset: 4
3464 * tab-width: 8
3465 * indent-tabs-mode: nil
3466 * End:
3468 * vi: set shiftwidth=4 tabstop=8 expandtab:
3469 * :indentSize=4:tabSize=8:noTabs=true: