3 * Routines for WiMAX ASN Control Plane packet dissection dissection
5 * Copyright 2007, Mobile Metrics - http://mobilemetrics.net/
7 * Author: Stephen Croll <croll@mobilemetrics.net>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
41 #include <epan/packet.h>
42 #include <epan/prefs.h>
43 #include <epan/sminmpec.h>
44 #include <epan/addr_resolv.h>
45 #include <epan/ipproto.h>
46 #include <epan/expert.h>
47 #include <epan/filesystem.h>
48 #include <epan/report_err.h>
51 #include "wimaxasncp_dict.h"
53 /* Forward declarations we need below */
54 void proto_register_wimaxasncp(void);
55 void proto_reg_handoff_wimaxasncp(void);
57 /* Initialize the protocol and registered fields */
58 static int proto_wimaxasncp = -1;
59 static int hf_wimaxasncp_version = -1;
60 static int hf_wimaxasncp_flags = -1;
61 static int hf_wimaxasncp_function_type = -1;
62 static int hf_wimaxasncp_op_id = -1;
63 static int hf_wimaxasncp_message_type = -1;
64 static int hf_wimaxasncp_qos_msg = -1;
65 static int hf_wimaxasncp_ho_control_msg = -1;
66 static int hf_wimaxasncp_data_path_control_msg = -1;
67 static int hf_wimaxasncp_context_delivery_msg = -1;
68 static int hf_wimaxasncp_r3_mobility_msg = -1;
69 static int hf_wimaxasncp_paging_msg = -1;
70 static int hf_wimaxasncp_rrm_msg = -1;
71 static int hf_wimaxasncp_authentication_msg = -1;
72 static int hf_wimaxasncp_ms_state_msg = -1;
73 static int hf_wimaxasncp_reauthentication_msg = -1;
74 static int hf_wimaxasncp_session_msg = -1;
75 static int hf_wimaxasncp_length = -1;
76 static int hf_wimaxasncp_msid = -1;
77 static int hf_wimaxasncp_reserved1 = -1;
78 static int hf_wimaxasncp_transaction_id = -1;
79 static int hf_wimaxasncp_reserved2 = -1;
80 static int hf_wimaxasncp_tlv = -1;
81 static int hf_wimaxasncp_tlv_type = -1;
82 static int hf_wimaxasncp_tlv_length = -1;
83 static int hf_wimaxasncp_tlv_value_bytes = -1;
84 static int hf_wimaxasncp_tlv_value_bitflags8 = -1;
85 static int hf_wimaxasncp_tlv_value_bitflags16 = -1;
86 static int hf_wimaxasncp_tlv_value_bitflags32 = -1;
87 static int hf_wimaxasncp_tlv_value_protocol = -1;
88 static int hf_wimaxasncp_tlv_value_vendor_id = -1;
91 static gboolean show_transaction_id_d_bit = FALSE;
92 static gboolean debug_enabled = FALSE;
94 /* Default WiMAX ASN control protocol port */
95 #define WIMAXASNCP_DEF_UDP_PORT 2231
96 static guint global_wimaxasncp_udp_port = WIMAXASNCP_DEF_UDP_PORT;
99 /* Initialize the subtree pointers */
100 static gint ett_wimaxasncp = -1;
101 static gint ett_wimaxasncp_flags = -1;
102 static gint ett_wimaxasncp_tlv = -1;
103 static gint ett_wimaxasncp_tlv_value_bitflags8 = -1;
104 static gint ett_wimaxasncp_tlv_value_bitflags16 = -1;
105 static gint ett_wimaxasncp_tlv_value_bitflags32 = -1;
106 static gint ett_wimaxasncp_tlv_protocol_list = -1;
107 static gint ett_wimaxasncp_tlv_port_range_list = -1;
108 static gint ett_wimaxasncp_tlv_ip_address_mask_list = -1;
109 static gint ett_wimaxasncp_tlv_ip_address_mask = -1;
110 static gint ett_wimaxasncp_tlv_eap = -1;
111 static gint ett_wimaxasncp_tlv_vendor_specific_information_field = -1;
113 /* Header size, up to, but not including, the TLV fields. */
114 #define WIMAXASNCP_HEADER_SIZE 20
116 /* Offset to end of the length field in the headder. */
117 #define WIMAXASNCP_HEADER_LENGTH_END 6
119 #define WIMAXASNCP_BIT32(n) (1 << (31 - (n)))
120 #define WIMAXASNCP_BIT16(n) (1 << (15 - (n)))
121 #define WIMAXASNCP_BIT8(n) (1 << ( 7 - (n)))
123 #define WIMAXASNCP_FLAGS_T WIMAXASNCP_BIT8(6)
124 #define WIMAXASNCP_FLAGS_R WIMAXASNCP_BIT8(7)
129 } wimaxasncp_build_dict_t;
131 static wimaxasncp_dict_t *wimaxasncp_dict = NULL;
133 wimaxasncp_build_dict_t wimaxasncp_build_dict;
135 static wimaxasncp_dict_tlv_t wimaxasncp_tlv_not_found =
137 0, "Unknown", NULL, WIMAXASNCP_TLV_UNKNOWN, 0,
138 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
142 static dissector_handle_t eap_handle;
144 /* ------------------------------------------------------------------------- */
146 static const value_string wimaxasncp_flag_vals[] =
148 { WIMAXASNCP_BIT8(0), "Reserved" },
149 { WIMAXASNCP_BIT8(1), "Reserved" },
150 { WIMAXASNCP_BIT8(2), "Reserved" },
151 { WIMAXASNCP_BIT8(3), "Reserved" },
152 { WIMAXASNCP_BIT8(4), "Reserved" },
153 { WIMAXASNCP_BIT8(5), "Reserved" },
154 { WIMAXASNCP_FLAGS_T, "T - Source and Destination Identifier TLVs"},
155 { WIMAXASNCP_FLAGS_R, "R - Reset Next Expected Transaction ID"},
159 /* ------------------------------------------------------------------------- */
161 static const value_string wimaxasncp_op_id_vals[] =
164 { 1, "Request/Initiation"},
174 /* ------------------------------------------------------------------------- */
176 #define WIMAXASNCP_FT_QOS 1
177 #define WIMAXASNCP_FT_HO_CONTROL 2
178 #define WIMAXASNCP_FT_DATA_PATH_CONTROL 3
179 #define WIMAXASNCP_FT_CONTEXT_TRANSFER 4
180 #define WIMAXASNCP_FT_R3_MOBILITY 5
181 #define WIMAXASNCP_FT_PAGING 6
182 #define WIMAXASNCP_FT_RRM 7
183 #define WIMAXASNCP_FT_AUTHENTICATION 8
184 #define WIMAXASNCP_FT_MS_STATE 9
185 #define WIMAXASNCP_FT_REAUTHENTICATION 10
186 /* since NWG R1 V1.2.0 */
187 #define WIMAXASNCP_FT_IM_OPERATIONS 10
188 /* since NWG R1 V1.2.1 */
189 #define WIMAXASNCP_FT_ACCOUNTING 11
191 /* ------------------------------------------------------------------------- */
193 /* struct to hold a value_string tuple, per version */
194 typedef struct _ver_value_string
200 static const ver_value_string wimaxasncp_function_type_vals[] =
202 {0, { WIMAXASNCP_FT_QOS, "QoS"}},
203 {0, { WIMAXASNCP_FT_HO_CONTROL, "HO Control"}},
204 {0, { WIMAXASNCP_FT_DATA_PATH_CONTROL, "Data Path Control"}},
205 {0, { WIMAXASNCP_FT_CONTEXT_TRANSFER, "Context Transfer"}},
206 {0, { WIMAXASNCP_FT_R3_MOBILITY, "R3 Mobility"}},
207 {0, { WIMAXASNCP_FT_PAGING, "Paging"}},
208 {0, { WIMAXASNCP_FT_RRM, "RRM"}},
209 {0, { WIMAXASNCP_FT_AUTHENTICATION, "Authentication Relay"}},
210 {0, { WIMAXASNCP_FT_MS_STATE, "MS State"}},
211 {0, { WIMAXASNCP_FT_REAUTHENTICATION, "Re-Authentication"}},
212 {WIMAXASNCP_NWGVER_R10_V120, {WIMAXASNCP_FT_IM_OPERATIONS, "IM Operations"}},
213 {WIMAXASNCP_NWGVER_R10_V121, { WIMAXASNCP_FT_ACCOUNTING, "Accounting"}},
217 /* ------------------------------------------------------------------------- */
219 static const ver_value_string wimaxasncp_qos_msg_vals[] =
227 /* ------------------------------------------------------------------------- */
229 static const ver_value_string wimaxasncp_ho_control_msg_vals[] =
232 {0, { 2, "HO_Complete"}},
236 {WIMAXASNCP_NWGVER_R10_V120, { 1, "HO_Req"}},
237 {WIMAXASNCP_NWGVER_R10_V120, { 2, "HO_Rsp"}},
238 {WIMAXASNCP_NWGVER_R10_V120, { 3, "HO_Ack"}},
239 {WIMAXASNCP_NWGVER_R10_V120, { 4, "HO_Cnf"}},
240 {WIMAXASNCP_NWGVER_R10_V120, { 5, "HO_Complete"}},
241 {WIMAXASNCP_NWGVER_R10_V120, { 6, "HO_Directive"}},
242 {WIMAXASNCP_NWGVER_R10_V120, { 7, "HO_Directive_Rsp"}},
246 /* ------------------------------------------------------------------------- */
248 static const ver_value_string wimaxasncp_data_path_control_msg_vals[] =
250 {0, { 1, "Path_Dereg_Ack"}},
251 {0, { 2, "Path_Dereg_Req"}},
252 {0, { 3, "Path_Dereg_Rsp"}},
253 {0, { 4, "Path_Modification_Ack"}},
254 {0, { 5, "Path_Modification_Req"}},
255 {0, { 6, "Path_Modification_Rsp"}},
256 {0, { 7, "Path_Prereg_Ack"}},
257 {0, { 8, "Path_Prereg_Req"}},
258 {0, { 9, "Path_Prereg_Rsp"}},
259 {0, { 10, "Path_Reg_Ack"}},
260 {0, { 11, "Path_Reg_Req"}},
261 {0, { 12, "Path_Reg_Rsp"}},
262 {0, { 13, "MS_Attachment_Req"}},
263 {0, { 14, "MS_Attachment_Rsp"}},
264 {0, { 15, "MS_Attachment_Ack"}},
265 {0, { 16, "Key_Change_Directive"}},
269 static const ver_value_string wimaxasncp_data_path_control_msg_vals_r1v120[] =
271 {WIMAXASNCP_NWGVER_R10_V120, { 1, "Path_Dereg_Req"}},
272 {WIMAXASNCP_NWGVER_R10_V120, { 2, "Path_Dereg_Rsp"}},
273 {WIMAXASNCP_NWGVER_R10_V120, { 3, "Path_Dereg_Ack"}},
274 {WIMAXASNCP_NWGVER_R10_V120, { 4, "Path_Modification_Req"}},
275 {WIMAXASNCP_NWGVER_R10_V120, { 5, "Path_Modification_Rsp"}},
276 {WIMAXASNCP_NWGVER_R10_V120, { 6, "Path_Modification_Ack"}},
277 {WIMAXASNCP_NWGVER_R10_V120, { 7, "Path_Prereg_Req"}},
278 {WIMAXASNCP_NWGVER_R10_V120, { 8, "Path_Prereg_Rsp"}},
279 {WIMAXASNCP_NWGVER_R10_V120, { 9, "Path_Prereg_Ack"}},
280 {WIMAXASNCP_NWGVER_R10_V120, { 10, "Path_Reg_Req"}},
281 {WIMAXASNCP_NWGVER_R10_V120, { 11, "Path_Reg_Rsp"}},
282 {WIMAXASNCP_NWGVER_R10_V120, { 12, "Path_Reg_Ack"}},
283 {WIMAXASNCP_NWGVER_R10_V120, { 13, "Obsolete"}},
284 {WIMAXASNCP_NWGVER_R10_V120, { 14, "Obsolete"}},
285 {WIMAXASNCP_NWGVER_R10_V120, { 15, "Obsolete"}},
286 {WIMAXASNCP_NWGVER_R10_V120, { 16, "Obsolete"}},
290 /* ------------------------------------------------------------------------- */
292 static const ver_value_string wimaxasncp_context_transfer_msg_vals[] =
294 {0, { 1, "Context_Rpt"}},
295 {0, { 2, "Context_Req"}},
296 {0, { 3, "Context_Ack"}},
297 {WIMAXASNCP_NWGVER_R10_V120, { 1, "Context_Req"}},
298 {WIMAXASNCP_NWGVER_R10_V120, { 2, "Context_Rpt"}},
299 {WIMAXASNCP_NWGVER_R10_V120, { 4, "CMAC_Key_Count_Update"}},
300 {WIMAXASNCP_NWGVER_R10_V120, { 5, "CMAC_Key_Count_Update_ACK"}},
301 {WIMAXASNCP_NWGVER_R10_V120, { 6, "CMAC_Key_Count_Req"}},
302 {WIMAXASNCP_NWGVER_R10_V120, { 7, "CMAC_Key_Count_Rsp"}},
303 {WIMAXASNCP_NWGVER_R10_V120, { 8, "Prepaid Request"}},
304 {WIMAXASNCP_NWGVER_R10_V120, { 9, "Prepaid Notify"}},
305 {WIMAXASNCP_NWGVER_R10_V121, { 6, "VOID"}},
306 {WIMAXASNCP_NWGVER_R10_V121, { 7, "VOID"}},
307 {WIMAXASNCP_NWGVER_R10_V121, { 0, NULL}}
310 /* ------------------------------------------------------------------------- */
312 static const ver_value_string wimaxasncp_r3_mobility_msg_vals[] =
314 {0, { 1, "Anchor_DPF_HO_Req"}},
315 {0, { 2, "Anchor_DPF_HO_Trigger"}},
316 {0, { 3, "Anchor_DPF_HO_Rsp"}},
317 {0, { 4, "Anchor_DPF_Relocate_Req"}},
318 {0, { 5, "FA_Register_Req"}},
319 {0, { 6, "FA_Register_Rsp"}},
320 {0, { 7, "Anchor_DPF_Relocate_Rsp"}},
321 {0, { 8, "FA_Revoke_Req"}},
322 {0, { 9, "FA_Revoke_Rsp"}},
323 {WIMAXASNCP_NWGVER_R10_V120, { 5, "Anchor_DPF_Relocate_Rsp"}},
324 {WIMAXASNCP_NWGVER_R10_V120, { 6, "FA_Register_Req"}},
325 {WIMAXASNCP_NWGVER_R10_V120, { 7, "FA_Register_Rsp"}},
326 {WIMAXASNCP_NWGVER_R10_V120, { 10, "Anchor_DPF_Release_Req"}},
327 {WIMAXASNCP_NWGVER_R10_V120, { 11, "Relocation_Ready_Req"}},
328 {WIMAXASNCP_NWGVER_R10_V120, { 12, "Relocation_Ready_Rsp"}},
332 /* ------------------------------------------------------------------------- */
334 static const ver_value_string wimaxasncp_paging_msg_vals[] =
336 {0, { 1, "Initiate_Paging_Req"}},
337 {0, { 2, "Initiate_Paging_Rsp"}},
341 {0, { 6, "Paging_Announce"}},
342 {0, { 7, "CMAC_Key_Count_Req"}},
343 {0, { 8, "CMAC_Key_Count_Rsp"}},
344 {WIMAXASNCP_NWGVER_R10_V120, { 1, "Paging_Announce"}},
345 {WIMAXASNCP_NWGVER_R10_V120, { 2, "Delete_MS_Entry_Req"}},
346 {WIMAXASNCP_NWGVER_R10_V120, { 3, "PC_Relocation_Ind"}},
347 {WIMAXASNCP_NWGVER_R10_V120, { 4, "PC_Relocation_Ack"}},
348 {WIMAXASNCP_NWGVER_R10_V120, { 5, "Obsolete"}},
349 {WIMAXASNCP_NWGVER_R10_V120, { 6, "Obsolete"}},
350 {WIMAXASNCP_NWGVER_R10_V120, { 7, "Obsolete"}},
351 {WIMAXASNCP_NWGVER_R10_V120, { 8, "Obsolete"}},
355 /* ------------------------------------------------------------------------- */
357 static const ver_value_string wimaxasncp_rrm_msg_vals[] =
359 {0, { 1, "R6 PHY_Parameters_Req"}},
360 {0, { 2, "R6 PHY_Parameters_Rpt"}},
361 {0, { 3, "R4/R6 Spare_Capacity_Req"}},
362 {0, { 4, "R4/R6 Spare_Capacity_Rpt"}},
363 {0, { 5, "R6 Neighbor_BS_Resource_Status_Update"}},
364 {0, { 6, "R4/R6 Radio_Config_Update_Req"}},
365 {0, { 7, "R4/R6 Radio_Config_Update_Rpt"}},
366 {WIMAXASNCP_NWGVER_R10_V120, { 8, "R4/R6 Radio_Config_Update_Ack"}},
370 /* ------------------------------------------------------------------------- */
372 static const ver_value_string wimaxasncp_authentication_msg_vals[] =
374 {0, { 1, "AR_Authenticated_Eap_Start"}},
375 {0, { 2, "AR_Authenticated_EAP_Transfer"}},
376 {0, { 3, "AR_Eap_Start"}},
377 {0, { 4, "AR_EAP_Transfer"}},
378 {0, { 5, "AR_EAP_Complete"}},
379 {WIMAXASNCP_NWGVER_R10_V120, { 1, "AR_EAP_Start"}},
380 {WIMAXASNCP_NWGVER_R10_V120, { 2, "AR_EAP_Transfer"}},
381 {WIMAXASNCP_NWGVER_R10_V120, { 3, "Bulk_Interim_Update"}},
382 {WIMAXASNCP_NWGVER_R10_V120, { 4, "Bulk_Interim_Update_Ack"}},
383 {WIMAXASNCP_NWGVER_R10_V120, { 5, "Obsolete"}},
387 /* ------------------------------------------------------------------------- */
389 static const ver_value_string wimaxasncp_ms_state_msg_vals[] =
391 {0, { 1, "IM_Entry_State_Change_Req"}},
392 {0, { 2, "IM_Entry_State_Change_Rsp"}},
393 {0, { 3, "IM_Exit_State_Change_Req"}},
394 {0, { 4, "IM_Exit_State_Change_Rsp"}},
395 {0, { 5, "NW_ReEntry_State_Change_Directive"}},
396 {0, { 6, "MS_PreAttachment_Req"}},
397 {0, { 7, "MS_PreAttachment_Rsp"}},
398 {0, { 8, "MS_PreAttachment_Ack"}},
399 {WIMAXASNCP_NWGVER_R10_V120, { 1, "MS_PreAttachment_Req"}},
400 {WIMAXASNCP_NWGVER_R10_V120, { 2, "MS_PreAttachment_Rsp"}},
401 {WIMAXASNCP_NWGVER_R10_V120, { 3, "MS_PreAttachment_Ack"}},
402 {WIMAXASNCP_NWGVER_R10_V120, { 4, "MS_Attachment_Req"}},
403 {WIMAXASNCP_NWGVER_R10_V120, { 5, "MS_Attachment_Rsp"}},
404 {WIMAXASNCP_NWGVER_R10_V120, { 6, "MS_Attachment_Ack"}},
405 {WIMAXASNCP_NWGVER_R10_V120, { 7, "Key_Change_Directive"}},
406 {WIMAXASNCP_NWGVER_R10_V120, { 8, "Key_Change_Cnf"}},
407 {WIMAXASNCP_NWGVER_R10_V120, { 9, "Key_Change_Ack"}},
408 {WIMAXASNCP_NWGVER_R10_V120, { 10, "Relocation_Conplete_Req"}},
409 {WIMAXASNCP_NWGVER_R10_V120, { 11, "Relocation_Conplete_Rsp"}},
410 {WIMAXASNCP_NWGVER_R10_V120, { 12, "Relocation_Conplete_Ack"}},
411 {WIMAXASNCP_NWGVER_R10_V120, { 13, "Relocation_Notify"}},
412 {WIMAXASNCP_NWGVER_R10_V120, { 14, "Relocation_Req"}},
413 {WIMAXASNCP_NWGVER_R10_V120, { 15, "Relocation_Rsp"}},
414 {WIMAXASNCP_NWGVER_R10_V120, { 16, "NetExit_MS_State_Change_Req"}},
415 {WIMAXASNCP_NWGVER_R10_V120, { 17, "NetExit_MS_State_Change_Rsp"}},
419 /* ------------------------------------------------------------------------- */
421 /* note - function type 10-im_operation, was once used for re-authrntication */
422 static const ver_value_string wimaxasncp_im_operations_msg_vals[] =
424 {0, { 1, "AR_EAP_Start"}},
425 {0, { 2, "Key_Change_Directive"}},
426 {0, { 3, "Key_Change_Cnf"}},
427 {0, { 4, "Relocation_Cnf"}},
428 {0, { 5, "Relocation_Confirm_Ack"}},
429 {0, { 6, "Relocation_Notify"}},
430 {0, { 7, "Relocation_Notify_Ack"}},
431 {0, { 8, "Relocation_Req"}},
432 {0, { 9, "Relocation_Rsp"}},
433 {WIMAXASNCP_NWGVER_R10_V120, { 1, "IM_Entry_State_Change_Req"}},
434 {WIMAXASNCP_NWGVER_R10_V120, { 2, "IM_Entry_State_Change_Rsp"}},
435 {WIMAXASNCP_NWGVER_R10_V120, { 3, "IM_Entry_State_Change_Ack"}},
436 {WIMAXASNCP_NWGVER_R10_V120, { 4, "IM_Exit_State_Change_Req"}},
437 {WIMAXASNCP_NWGVER_R10_V120, { 5, "IM_Exit_State_Change_Rsp"}},
438 {WIMAXASNCP_NWGVER_R10_V120, { 6, "Initiate_Paging_Req"}},
439 {WIMAXASNCP_NWGVER_R10_V120, { 7, "Initiate_Paging_Rsp"}},
440 {WIMAXASNCP_NWGVER_R10_V120, { 8, "LU_Req"}},
441 {WIMAXASNCP_NWGVER_R10_V120, { 9, "LU_Rsp"}},
442 {WIMAXASNCP_NWGVER_R10_V120, { 10, "LU_Cnf"}},
446 /* ------------------------------------------------------------------------- */
448 static const ver_value_string wimaxasncp_accounting_msg_vals_r1v121[] =
450 {WIMAXASNCP_NWGVER_R10_V121, { 1, "Hot_lining_Req"}},
451 {WIMAXASNCP_NWGVER_R10_V121, { 2, "Hot_lining_Rsp"}},
455 /* ------------------------------------------------------------------------- */
457 /* supported NWG versions */
458 static const enum_val_t wimaxasncp_nwg_versions[] = {
459 { "Release 1.0, Version 1.0.0" , "R1.0 v1.0.0" , WIMAXASNCP_NWGVER_R10_V100 },
460 { "Release 1.0, Version 1.2.0" , "R1.0 v1.2.0" , WIMAXASNCP_NWGVER_R10_V120 },
461 { "Release 1.0, Version 1.2.1" , "R1.0 v1.2.1" , WIMAXASNCP_NWGVER_R10_V121 },
465 /* ------------------------------------------------------------------------- */
468 #define WIMAXASNCP_DEF_NWGVER WIMAXASNCP_NWGVER_R10_V121
469 static guint global_wimaxasncp_nwg_ver = WIMAXASNCP_DEF_NWGVER;
471 /* ========================================================================= */
474 guint8 function_type;
475 const ver_value_string *vals;
476 } wimaxasncp_func_msg_t;
478 /* ------------------------------------------------------------------------ */
480 static const wimaxasncp_func_msg_t wimaxasncp_func_to_msg_vals_map[] =
482 { WIMAXASNCP_FT_QOS, wimaxasncp_qos_msg_vals },
483 { WIMAXASNCP_FT_HO_CONTROL, wimaxasncp_ho_control_msg_vals },
484 { WIMAXASNCP_FT_DATA_PATH_CONTROL, wimaxasncp_data_path_control_msg_vals },
485 { WIMAXASNCP_FT_CONTEXT_TRANSFER, wimaxasncp_context_transfer_msg_vals },
486 { WIMAXASNCP_FT_R3_MOBILITY, wimaxasncp_r3_mobility_msg_vals },
487 { WIMAXASNCP_FT_PAGING, wimaxasncp_paging_msg_vals },
488 { WIMAXASNCP_FT_RRM, wimaxasncp_rrm_msg_vals },
489 { WIMAXASNCP_FT_AUTHENTICATION, wimaxasncp_authentication_msg_vals },
490 { WIMAXASNCP_FT_MS_STATE, wimaxasncp_ms_state_msg_vals },
491 { WIMAXASNCP_FT_IM_OPERATIONS, wimaxasncp_im_operations_msg_vals },
492 { WIMAXASNCP_FT_ACCOUNTING, wimaxasncp_accounting_msg_vals_r1v121 }
495 /* ========================================================================= */
497 static const wimaxasncp_dict_tlv_t *wimaxasncp_get_tlv_info(
500 wimaxasncp_dict_tlv_t *res = NULL;
504 wimaxasncp_dict_tlv_t *tlv;
506 for (tlv = wimaxasncp_dict->tlvs; tlv; tlv = tlv->next)
508 if (tlv->type == type)
510 /* if the TLV is defined for current NWG version */
511 if (tlv->since<= global_wimaxasncp_nwg_ver)
513 /* if the current TLV is newer then last found TLV, save it */
514 if(!res || (tlv->since > res->since))
523 if (debug_enabled && !res)
525 g_print("fix-me: unknown TLV type: %u\n", type);
528 return res? res:&wimaxasncp_tlv_not_found;
531 /* ========================================================================= */
533 static const gchar *wimaxasncp_get_enum_name(
534 const wimaxasncp_dict_tlv_t *tlv_info,
537 if (tlv_info->enum_vs)
539 return val_to_str(code, tlv_info->enum_vs, "Unknown");
547 /* ========================================================================= */
549 static const value_string wimaxasncp_decode_type_vals[] =
551 { WIMAXASNCP_TLV_UNKNOWN, "WIMAXASNCP_TLV_UNKNOWN"},
552 { WIMAXASNCP_TLV_TBD, "WIMAXASNCP_TLV_TBD"},
553 { WIMAXASNCP_TLV_COMPOUND, "WIMAXASNCP_TLV_COMPOUND"},
554 { WIMAXASNCP_TLV_BYTES, "WIMAXASNCP_TLV_BYTES"},
555 { WIMAXASNCP_TLV_ENUM8, "WIMAXASNCP_TLV_ENUM8"},
556 { WIMAXASNCP_TLV_ENUM16, "WIMAXASNCP_TLV_ENUM16"},
557 { WIMAXASNCP_TLV_ENUM32, "WIMAXASNCP_TLV_ENUM32"},
558 { WIMAXASNCP_TLV_ETHER, "WIMAXASNCP_TLV_ETHER"},
559 { WIMAXASNCP_TLV_ASCII_STRING, "WIMAXASNCP_TLV_ASCII_STRING"},
560 { WIMAXASNCP_TLV_FLAG0, "WIMAXASNCP_TLV_FLAG0"},
561 { WIMAXASNCP_TLV_BITFLAGS8, "WIMAXASNCP_TLV_BITFLAGS8"},
562 { WIMAXASNCP_TLV_BITFLAGS16, "WIMAXASNCP_TLV_BITFLAGS16"},
563 { WIMAXASNCP_TLV_BITFLAGS32, "WIMAXASNCP_TLV_BITFLAGS32"},
564 { WIMAXASNCP_TLV_ID, "WIMAXASNCP_TLV_ID"},
565 { WIMAXASNCP_TLV_HEX8, "WIMAXASNCP_TLV_HEX8"},
566 { WIMAXASNCP_TLV_HEX16, "WIMAXASNCP_TLV_HEX16"},
567 { WIMAXASNCP_TLV_HEX32, "WIMAXASNCP_TLV_HEX32"},
568 { WIMAXASNCP_TLV_DEC8, "WIMAXASNCP_TLV_DEC8"},
569 { WIMAXASNCP_TLV_DEC16, "WIMAXASNCP_TLV_DEC16"},
570 { WIMAXASNCP_TLV_DEC32, "WIMAXASNCP_TLV_DEC32"},
571 { WIMAXASNCP_TLV_IP_ADDRESS, "WIMAXASNCP_TLV_IP_ADDRESS"},
572 { WIMAXASNCP_TLV_IPV4_ADDRESS, "WIMAXASNCP_TLV_IPV4_ADDRESS"},
573 { WIMAXASNCP_TLV_PROTOCOL_LIST, "WIMAXASNCP_TLV_PROTOCOL_LIST"},
574 { WIMAXASNCP_TLV_PORT_RANGE_LIST, "WIMAXASNCP_TLV_PORT_RANGE_LIST"},
575 { WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST,"WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST"},
576 { WIMAXASNCP_TLV_VENDOR_SPECIFIC, "WIMAXASNCP_TLV_VENDOR_SPECIFIC"},
580 /* ========================================================================= */
582 static void wimaxasncp_proto_tree_add_tlv_ipv4_value(
585 proto_item *tlv_item,
587 const wimaxasncp_dict_tlv_t *tlv_info)
591 const gchar *hostname;
594 if (tlv_info->hf_ipv4 != -1)
596 hf_value = tlv_info->hf_ipv4;
600 hf_value = tlv_info->hf_value;
603 ip = tvb_get_ipv4(tvb, offset);
604 hostname = get_hostname(ip);
605 ip_str = ip_to_str((guint8 *)&ip);
607 proto_tree_add_ipv4_format(
610 "Value: %s (%s)", hostname, ip_str);
612 proto_item_append_text(
613 tlv_item, " - %s (%s)",
617 /* ========================================================================= */
619 static void wimaxasncp_proto_tree_add_tlv_ipv6_value(
622 proto_item *tlv_item,
624 const wimaxasncp_dict_tlv_t *tlv_info)
627 struct e_in6_addr ip;
628 const gchar *hostname;
631 if (tlv_info->hf_ipv4 != -1)
633 hf_value = tlv_info->hf_ipv6;
637 hf_value = tlv_info->hf_value;
640 tvb_get_ipv6(tvb, offset, &ip);
641 hostname = get_hostname6(&ip);
642 ip_str = ip6_to_str(&ip);
644 proto_tree_add_ipv6_format(
646 tvb, offset, 16, (guint8 *)&ip,
647 "Value: %s (%s)", hostname, ip_str);
649 proto_item_append_text(
650 tlv_item, " - %s (%s)",
654 /* ========================================================================= */
656 static void wimaxasncp_proto_tree_add_ether_value(
659 proto_item *tlv_item,
662 const wimaxasncp_dict_tlv_t *tlv_info)
666 const gchar *ether_name;
667 const gchar *ether_str;
669 if (tlv_info->hf_bsid != -1)
671 hf_value = tlv_info->hf_bsid;
675 hf_value = tlv_info->hf_value;
678 p = tvb_get_ptr(tvb, offset, length);
679 ether_name = get_ether_name(p);
680 ether_str = ether_to_str(p);
682 proto_tree_add_ether_format(
684 tvb, offset, length, p,
686 ether_name, ether_str);
688 proto_item_append_text(
689 tlv_item, " - %s (%s)",
690 ether_name, ether_str);
693 /* ========================================================================= */
695 static void wimaxasncp_dissect_tlv_value(
697 packet_info *pinfo _U_,
699 proto_item *tlv_item,
700 const wimaxasncp_dict_tlv_t *tlv_info)
704 const guint max_show_bytes = 24; /* arbitrary */
705 const gchar *hex_note = "[hex]";
707 length = tvb_reported_length(tvb);
709 switch(tlv_info->decoder)
711 case WIMAXASNCP_TLV_ENUM8:
719 if (tlv_info->enums == NULL)
723 g_print("fix-me: enum values missing for TLV %s (%u)\n",
724 tlv_info->name, tlv_info->type);
733 value = tvb_get_guint8(tvb, offset);
735 s = wimaxasncp_get_enum_name(tlv_info, value);
737 proto_tree_add_uint_format(
738 tree, tlv_info->hf_value,
739 tvb, offset, length, value,
740 "Value: %s (%u)", s, value);
742 proto_item_append_text(tlv_item, " - %s", s);
747 case WIMAXASNCP_TLV_ENUM16:
755 if (tlv_info->enums == NULL)
759 g_print("fix-me: enum values missing for TLV %s (%u)\n",
760 tlv_info->name, tlv_info->type);
769 value = tvb_get_ntohs(tvb, offset);
771 s = wimaxasncp_get_enum_name(tlv_info, value);
773 proto_tree_add_uint_format(
774 tree, tlv_info->hf_value,
775 tvb, offset, length, value,
776 "Value: %s (%u)", s, value);
778 proto_item_append_text(tlv_item, " - %s", s);
783 case WIMAXASNCP_TLV_ENUM32:
791 if (tlv_info->enums == NULL)
795 g_print("fix-me: enum values missing for TLV %s (%u)\n",
796 tlv_info->name, tlv_info->type);
805 value = tvb_get_ntohl(tvb, offset);
807 s = wimaxasncp_get_enum_name(tlv_info, value);
809 proto_tree_add_uint_format(
810 tree, tlv_info->hf_value,
811 tvb, offset, length, value,
812 "Value: %s (%u)", s, value);
814 proto_item_append_text(tlv_item, " - %s", s);
819 case WIMAXASNCP_TLV_ETHER:
829 wimaxasncp_proto_tree_add_ether_value(
830 tvb, tree, tlv_item, offset, length, tlv_info);
835 case WIMAXASNCP_TLV_ASCII_STRING:
840 const gchar *s = tvb_get_ephemeral_string(tvb, offset, length);
842 p = tvb_get_ptr(tvb, offset, length);
844 proto_tree_add_string_format(
845 tree, tlv_info->hf_value,
846 tvb, offset, length, p,
849 proto_item_append_text(
850 tlv_item, " - %s", s);
855 case WIMAXASNCP_TLV_FLAG0:
865 case WIMAXASNCP_TLV_BITFLAGS8:
873 if (tlv_info->enums == NULL)
875 /* enum values missing */
880 proto_tree *flags_tree;
885 value = tvb_get_guint8(tvb, offset);
887 item = proto_tree_add_uint_format(
888 tree, tlv_info->hf_value,
889 tvb, offset, length, value,
891 decode_numeric_bitfield(value, 0xff, 8, "0x%02x"));
893 proto_item_append_text(tlv_item, " - 0x%02x", value);
897 flags_tree = proto_item_add_subtree(
898 item, ett_wimaxasncp_tlv_value_bitflags8);
900 for (i = 0; i < 8; ++i)
909 s = wimaxasncp_get_enum_name(tlv_info, value & mask);
911 proto_tree_add_uint_format(
912 flags_tree, hf_wimaxasncp_tlv_value_bitflags8,
913 tvb, offset, length, value,
914 "Bit #%u is set: %s", i, s);
922 case WIMAXASNCP_TLV_BITFLAGS16:
930 if (tlv_info->enums == NULL)
932 /* enum values missing */
937 proto_tree *flags_tree;
942 value = tvb_get_ntohs(tvb, offset);
944 item = proto_tree_add_uint_format(
945 tree, tlv_info->hf_value,
946 tvb, offset, length, value,
948 decode_numeric_bitfield(value, 0xffff, 16, "0x%04x"));
950 proto_item_append_text(tlv_item, " - 0x%04x", value);
954 flags_tree = proto_item_add_subtree(
955 item, ett_wimaxasncp_tlv_value_bitflags16);
957 for (i = 0; i < 16; ++i)
960 mask = 1 << (15 - i);
966 s = wimaxasncp_get_enum_name(tlv_info, value & mask);
968 proto_tree_add_uint_format(
969 flags_tree, hf_wimaxasncp_tlv_value_bitflags16,
970 tvb, offset, length, value,
971 "Bit #%u is set: %s", i, s);
979 case WIMAXASNCP_TLV_BITFLAGS32:
987 if (tlv_info->enums == NULL)
989 /* enum values missing */
994 proto_tree *flags_tree;
999 value = tvb_get_ntohl(tvb, offset);
1001 item = proto_tree_add_uint_format(
1002 tree, tlv_info->hf_value,
1003 tvb, offset, length, value,
1005 decode_numeric_bitfield(value, 0xffffffff, 32, "0x%08x"));
1007 proto_item_append_text(tlv_item, " - 0x%08x", value);
1011 flags_tree = proto_item_add_subtree(
1012 item, ett_wimaxasncp_tlv_value_bitflags32);
1014 for (i = 0; i < 32; ++i)
1017 mask = 1 << (31 - i);
1022 s = wimaxasncp_get_enum_name(tlv_info, value & mask);
1024 proto_tree_add_uint_format(
1025 flags_tree, hf_wimaxasncp_tlv_value_bitflags32,
1026 tvb, offset, length, value,
1027 "Bit #%u is set: %s", i, s);
1035 case WIMAXASNCP_TLV_ID:
1041 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1042 tvb, tree, tlv_item, offset, tlv_info);
1047 else if (length == 6)
1051 wimaxasncp_proto_tree_add_ether_value(
1052 tvb, tree, tlv_item, offset, length, tlv_info);
1057 else if (length == 16)
1061 wimaxasncp_proto_tree_add_tlv_ipv6_value(
1062 tvb, tree, tlv_item, offset, tlv_info);
1069 /* encoding error */
1073 case WIMAXASNCP_TLV_BYTES:
1077 const gchar *format1;
1078 const gchar *format2;
1079 const guint8 *p = tvb_get_ptr(tvb, offset, length);
1081 bytestring_to_str(p, MIN(length, max_show_bytes), 0);
1083 if (length <= max_show_bytes)
1085 format1 = "Value: %s";
1090 format1 = "Value: %s...";
1091 format2 = " - %s...";
1094 proto_tree_add_bytes_format(
1095 tree, tlv_info->hf_value,
1096 tvb, offset, length, p,
1099 proto_item_append_text(
1100 tlv_item, format2, s);
1105 case WIMAXASNCP_TLV_HEX8:
1109 /* encoding error */
1117 value = tvb_get_guint8(tvb, offset);
1119 proto_tree_add_uint_format(
1120 tree, tlv_info->hf_value,
1121 tvb, offset, length, value,
1122 "Value: 0x%02x", value);
1124 proto_item_append_text(tlv_item, " - 0x%02x", value);
1129 case WIMAXASNCP_TLV_HEX16:
1133 /* encoding error */
1141 value = tvb_get_ntohs(tvb, offset);
1143 proto_tree_add_uint_format(
1144 tree, tlv_info->hf_value,
1145 tvb, offset, length, value,
1146 "Value: 0x%04x", value);
1148 proto_item_append_text(tlv_item, " - 0x%04x", value);
1153 case WIMAXASNCP_TLV_HEX32:
1157 /* encoding error */
1165 value = tvb_get_ntohl(tvb, offset);
1167 proto_tree_add_uint_format(
1168 tree, tlv_info->hf_value,
1169 tvb, offset, length, value,
1170 "Value: 0x%08x", value);
1172 proto_item_append_text(tlv_item, " - 0x%08x", value);
1177 case WIMAXASNCP_TLV_DEC8:
1181 /* encoding error */
1189 value = tvb_get_guint8(tvb, offset);
1191 proto_tree_add_uint_format(
1192 tree, tlv_info->hf_value,
1193 tvb, offset, length, value,
1194 "Value: %u", value);
1196 proto_item_append_text(tlv_item, " - %u", value);
1201 case WIMAXASNCP_TLV_DEC16:
1205 /* encoding error */
1213 value = tvb_get_ntohs(tvb, offset);
1215 proto_tree_add_uint_format(
1216 tree, tlv_info->hf_value,
1217 tvb, offset, length, value,
1218 "Value: %u", value);
1220 proto_item_append_text(tlv_item, " - %u", value);
1225 case WIMAXASNCP_TLV_DEC32:
1229 /* encoding error */
1237 value = tvb_get_ntohl(tvb, offset);
1239 proto_tree_add_uint_format(
1240 tree, tlv_info->hf_value,
1241 tvb, offset, length, value,
1242 "Value: %u", value);
1244 proto_item_append_text(tlv_item, " - %u", value);
1249 case WIMAXASNCP_TLV_TBD:
1254 "fix-me: TBD: TLV %s (%u)\n", tlv_info->name, tlv_info->type);
1259 const gchar *format;
1260 const guint8 *p = tvb_get_ptr(tvb, offset, length);
1262 bytestring_to_str(p, MIN(length, max_show_bytes), 0);
1264 if (length <= max_show_bytes)
1266 format = "Value: %s %s";
1270 format = "Value: %s %s...";
1273 proto_tree_add_bytes_format(
1274 tree, tlv_info->hf_value,
1275 tvb, offset, length, p,
1276 format, hex_note, s);
1278 proto_item_append_text(tlv_item, " - TBD");
1283 case WIMAXASNCP_TLV_IP_ADDRESS:
1289 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1290 tvb, tree, tlv_item, offset, tlv_info);
1295 else if (length == 16)
1299 wimaxasncp_proto_tree_add_tlv_ipv6_value(
1300 tvb, tree, tlv_item, offset, tlv_info);
1307 /* encoding error */
1311 case WIMAXASNCP_TLV_IPV4_ADDRESS:
1315 /* encoding error */
1321 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1322 tvb, tree, tlv_item, offset, tlv_info);
1327 case WIMAXASNCP_TLV_PROTOCOL_LIST:
1329 if (length % 2 != 0)
1331 /* encoding error */
1335 if (tree && length > 0)
1337 proto_tree *protocol_list_tree;
1339 const guint max_protocols_in_tlv_item = 8; /* arbitrary */
1341 item = proto_tree_add_text(
1342 tree, tvb, offset, length,
1345 protocol_list_tree = proto_item_add_subtree(
1346 item, ett_wimaxasncp_tlv_protocol_list);
1348 /* hidden item for filtering */
1349 item = proto_tree_add_item(
1350 protocol_list_tree, tlv_info->hf_value,
1351 tvb, offset, length, FALSE);
1353 PROTO_ITEM_SET_HIDDEN(item);
1355 while (offset < tvb_length(tvb))
1358 const gchar *protocol_name;
1360 protocol = tvb_get_ntohs(tvb, offset);
1361 protocol_name = ipprotostr(protocol);
1363 proto_tree_add_uint_format(
1364 protocol_list_tree, tlv_info->hf_protocol,
1365 tvb, offset, 2, protocol,
1366 "Protocol: %s (%u)", protocol_name, protocol);
1370 proto_item_append_text(tlv_item, " - %s", protocol_name);
1372 else if (offset < 2 * max_protocols_in_tlv_item)
1374 proto_item_append_text(tlv_item, ", %s", protocol_name);
1376 else if (offset == 2 * max_protocols_in_tlv_item)
1378 proto_item_append_text(tlv_item, ", ...");
1387 case WIMAXASNCP_TLV_PORT_RANGE_LIST:
1389 if (length % 4 != 0)
1391 /* encoding error */
1395 if (tree && length > 0)
1397 proto_tree *port_range_list_tree;
1399 const guint max_port_ranges_in_tlv_item = 3; /* arbitrary */
1401 item = proto_tree_add_text(
1402 tree, tvb, offset, length,
1405 port_range_list_tree = proto_item_add_subtree(
1406 item, ett_wimaxasncp_tlv_port_range_list);
1408 /* hidden item for filtering */
1409 item = proto_tree_add_item(
1410 port_range_list_tree, tlv_info->hf_value,
1411 tvb, offset, length, FALSE);
1413 PROTO_ITEM_SET_HIDDEN(item);
1415 while (offset < tvb_length(tvb))
1420 portLow = tvb_get_ntohs(tvb, offset);
1421 portHigh = tvb_get_ntohs(tvb, offset + 2);
1423 proto_tree_add_text(
1424 port_range_list_tree, tvb, offset, 4,
1425 "Port Range: %u-%u", portLow, portHigh);
1427 /* hidden items are for filtering */
1429 item = proto_tree_add_item(
1430 port_range_list_tree, tlv_info->hf_port_low,
1431 tvb, offset, 2, FALSE);
1433 PROTO_ITEM_SET_HIDDEN(item);
1435 item = proto_tree_add_item(
1436 port_range_list_tree, tlv_info->hf_port_high,
1437 tvb, offset + 2, 2, FALSE);
1439 PROTO_ITEM_SET_HIDDEN(item);
1443 proto_item_append_text(
1444 tlv_item, " - %u-%u", portLow, portHigh);
1446 else if (offset < 4 * max_port_ranges_in_tlv_item)
1448 proto_item_append_text(
1449 tlv_item, ", %u-%u", portLow, portHigh);
1451 else if (offset == 4 * max_port_ranges_in_tlv_item)
1453 proto_item_append_text(tlv_item, ", ...");
1462 case WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST:
1464 /* --------------------------------------------------------------------
1465 * The definion of these TLVs are ambiguous. The length in octets is
1466 * described as Nx8 (IPv4) or Nx32 (IPv6), but this function cannot
1467 * always differentiate between IPv4 and IPv6. For example, if length
1468 * = 32, then is it IPv4 where N=4 (4x8) or IPv6 where N=1 (1x32)?
1470 * For now, we presume lengths that *can* indicate an IPv6 address and
1471 * mask list *do* denote an IPv6 address and mask list.
1472 * --------------------------------------------------------------------
1475 if (length % 8 != 0)
1477 /* encoding error */
1481 if (tree && length > 0)
1483 proto_tree *ip_address_mask_list_tree;
1486 item = proto_tree_add_text(
1487 tree, tvb, offset, length,
1490 ip_address_mask_list_tree = proto_item_add_subtree(
1491 item, ett_wimaxasncp_tlv_ip_address_mask_list);
1493 /* hidden item for filtering */
1494 item = proto_tree_add_item(
1495 ip_address_mask_list_tree, tlv_info->hf_value,
1496 tvb, offset, length, FALSE);
1498 PROTO_ITEM_SET_HIDDEN(item);
1500 if (length % 32 == 0)
1502 /* ------------------------------------------------------------
1504 * ------------------------------------------------------------
1507 while (offset < tvb_length(tvb))
1509 proto_tree *ip_address_mask_tree;
1510 struct e_in6_addr ip;
1513 item = proto_tree_add_text(
1514 ip_address_mask_list_tree, tvb, offset, 32,
1515 "IPv6 Address and Mask");
1517 ip_address_mask_tree = proto_item_add_subtree(
1518 item, ett_wimaxasncp_tlv_ip_address_mask);
1520 /* --------------------------------------------------------
1522 * --------------------------------------------------------
1525 tvb_get_ipv6(tvb, offset, &ip);
1527 proto_tree_add_item(
1528 ip_address_mask_tree,
1530 tvb, offset, 16, FALSE);
1532 /* too long to display ?
1533 proto_item_append_text(
1535 get_hostname6(&ip), ip6_to_str(&ip));
1540 /* --------------------------------------------------------
1542 * --------------------------------------------------------
1545 tvb_get_ipv6(tvb, offset, &ip);
1547 s = ip6_to_str(&ip);
1549 proto_tree_add_ipv6_format_value(
1550 ip_address_mask_tree,
1551 tlv_info->hf_ipv6_mask,
1552 tvb, offset, 16, (const guint8*)&ip,
1555 /* too long to display ?
1556 proto_item_append_text(
1565 /* ------------------------------------------------------------
1567 * ------------------------------------------------------------
1570 while (offset < tvb_length(tvb))
1572 proto_tree *ip_address_mask_tree;
1576 item = proto_tree_add_text(
1577 ip_address_mask_list_tree, tvb, offset, 8,
1578 "IPv4 Address and Mask");
1580 ip_address_mask_tree = proto_item_add_subtree(
1581 item, ett_wimaxasncp_tlv_ip_address_mask);
1583 /* --------------------------------------------------------
1585 * --------------------------------------------------------
1588 ip = tvb_get_ipv4(tvb, offset);
1590 proto_tree_add_item(
1591 ip_address_mask_tree,
1593 tvb, offset, 4, FALSE);
1595 proto_item_append_text(
1597 get_hostname(ip), ip_to_str((guint8 *)&ip));
1601 /* --------------------------------------------------------
1603 * --------------------------------------------------------
1606 ip = tvb_get_ipv4(tvb, offset);
1608 s = ip_to_str((guint8 *)&ip);
1610 proto_tree_add_ipv4_format_value(
1611 ip_address_mask_tree,
1612 tlv_info->hf_ipv4_mask,
1616 proto_item_append_text(
1626 case WIMAXASNCP_TLV_EAP:
1629 * EAP payload, call eap dissector to dissect eap payload
1632 guint8 eap_type = 0;
1635 eap_code = tvb_get_guint8(tvb, offset);
1636 if (eap_code == EAP_REQUEST || eap_code == EAP_RESPONSE)
1639 eap_type = tvb_get_guint8(tvb, offset + 4);
1642 /* Add code and type to info column */
1643 col_append_str(pinfo->cinfo, COL_INFO, " [");
1644 col_append_str(pinfo->cinfo, COL_INFO,
1645 val_to_str(eap_code, eap_code_vals, "Unknown code (0x%02X)"));
1647 if (eap_code == EAP_REQUEST || eap_code == EAP_RESPONSE)
1649 col_append_str(pinfo->cinfo, COL_INFO, ", ");
1650 col_append_str(pinfo->cinfo, COL_INFO,
1651 val_to_str(eap_type, eap_type_vals, "Unknown type (0x%02X)"));
1654 col_append_str(pinfo->cinfo, COL_INFO, "]");
1658 proto_tree *eap_tree;
1660 gboolean save_writable;
1663 /* Create EAP subtree */
1664 item = proto_tree_add_item(tree, tlv_info->hf_value, tvb,
1665 offset, length, FALSE);
1666 proto_item_set_text(item, "Value");
1667 eap_tree = proto_item_add_subtree(item, ett_wimaxasncp_tlv_eap);
1669 /* Also show high-level details in this root item */
1670 proto_item_append_text(item, " (%s",
1671 val_to_str(eap_code, eap_code_vals,
1672 "Unknown code (0x%02X)"));
1673 if (eap_code == EAP_REQUEST || eap_code == EAP_RESPONSE)
1675 proto_item_append_text(item, ", %s",
1676 val_to_str(eap_type, eap_type_vals,
1677 "Unknown type (0x%02X)"));
1679 proto_item_append_text(item, ")");
1682 /* Extract remaining bytes into new tvb */
1683 eap_tvb = tvb_new_subset(tvb, offset, length,
1684 tvb_length_remaining(tvb, offset));
1686 /* Disable writing to info column while calling eap dissector */
1687 save_writable = col_get_writable(pinfo->cinfo);
1688 col_set_writable(pinfo->cinfo, FALSE);
1690 /* Call the EAP dissector. */
1691 call_dissector(eap_handle, eap_tvb, pinfo, eap_tree);
1693 /* Restore previous writable state of info column */
1694 col_set_writable(pinfo->cinfo, save_writable);
1700 case WIMAXASNCP_TLV_VENDOR_SPECIFIC:
1702 /* --------------------------------------------------------------------
1703 * The format of the vendor specific information field (VSIF) is not
1704 * clearly defined. It appears to be compound as the spec states
1705 * that the vendor ID field shall be the first TLV embedded inside
1706 * the VSIF. However, the vendor ID is shown as a 24-bit value. Does
1707 * this mean the field is 24-bits? If so, how is alignment/padding
1710 * For now, we decode the vendor ID as a non-padded 24-bit value and
1711 * dump the rest as hex.
1712 * --------------------------------------------------------------------
1717 /* encoding error */
1723 proto_tree *vsif_tree;
1726 const gchar *vendorName;
1728 item = proto_tree_add_text(
1729 tree, tvb, offset, length,
1732 vsif_tree = proto_item_add_subtree(
1733 item, ett_wimaxasncp_tlv_vendor_specific_information_field);
1735 /* hidden item for filtering */
1736 item = proto_tree_add_item(
1737 vsif_tree, tlv_info->hf_value,
1738 tvb, offset, length, FALSE);
1740 PROTO_ITEM_SET_HIDDEN(item);
1742 /* ----------------------------------------------------------------
1743 * vendor ID (24-bit)
1744 * ----------------------------------------------------------------
1747 vendorId = tvb_get_ntoh24(tvb, offset);
1749 vendorName = val_to_str_ext_const(vendorId, &sminmpec_values_ext, "Unknown");
1750 proto_tree_add_uint_format(
1751 vsif_tree, tlv_info->hf_vendor_id,
1752 tvb, offset, 3, vendorId,
1753 "Vendor ID: %s (%u)", vendorName, vendorId);
1755 proto_item_append_text(tlv_item, " - %s", vendorName);
1759 /* ----------------------------------------------------------------
1761 * ----------------------------------------------------------------
1764 if (offset < tvb_length(tvb))
1766 proto_tree_add_item(
1767 vsif_tree, tlv_info->hf_vendor_rest_of_info,
1768 tvb, offset, length - offset, FALSE);
1774 case WIMAXASNCP_TLV_UNKNOWN:
1778 const gchar *format1;
1779 const gchar *format2;
1780 const guint8 *p = tvb_get_ptr(tvb, offset, length);
1782 bytestring_to_str(p, MIN(length, max_show_bytes), 0);
1784 if (length <= max_show_bytes)
1786 format1 = "Value: %s %s";
1787 format2 = " - %s %s";
1791 format1 = "Value: %s %s...";
1792 format2 = " - %s %s...";
1795 proto_tree_add_bytes_format(
1796 tree, tlv_info->hf_value,
1797 tvb, offset, length, p,
1798 format1, hex_note, s);
1800 proto_item_append_text(
1801 tlv_item, format2, hex_note, s);
1811 "fix-me: unknown decoder: %d\n", tlv_info->decoder);
1816 /* default is hex dump */
1820 const gchar *format;
1821 const guint8 *p = tvb_get_ptr(tvb, offset, length);
1822 const gchar *s = bytestring_to_str(p, MIN(length, max_show_bytes), 0);
1824 if (length <= max_show_bytes)
1826 format = "Value: %s %s";
1830 format = "Value: %s %s...";
1833 proto_tree_add_bytes_format(
1834 tree, hf_wimaxasncp_tlv_value_bytes,
1835 tvb, offset, length, p,
1836 format, hex_note, s);
1840 /* ========================================================================= */
1842 static guint dissect_wimaxasncp_tlvs(
1850 while (offset < tvb_reported_length(tvb))
1852 proto_tree *tlv_tree = NULL;
1853 proto_item *tlv_item = NULL;
1854 const wimaxasncp_dict_tlv_t *tlv_info;
1860 /* --------------------------------------------------------------------
1862 * --------------------------------------------------------------------
1865 type = tvb_get_ntohs(tvb, offset);
1866 tlv_info = wimaxasncp_get_tlv_info(type);
1868 length = tvb_get_ntohs(tvb, offset + 2);
1869 /* Commented out padding; As there is no mention of padding in
1870 the Latest specification
1871 pad = 4 - (length % 4);
1880 proto_item *type_item;
1882 gint tree_length = MIN(
1883 (gint)(4 + length + pad), tvb_length_remaining(tvb, offset));
1885 tlv_item = proto_tree_add_item(
1886 tree, tlv_info->hf_root,
1887 tvb, offset, tree_length, FALSE);
1889 /* Set label for tlv item */
1890 proto_item_set_text(tlv_item, "TLV: %s", tlv_info->name);
1892 /* Show code number if unknown */
1893 if (tlv_info->decoder == WIMAXASNCP_TLV_UNKNOWN)
1895 proto_item_append_text(tlv_item, " (%u)", type);
1898 /* Indicate if a compound tlv */
1899 if (tlv_info->decoder == WIMAXASNCP_TLV_COMPOUND)
1901 proto_item_append_text(tlv_item, " [Compound]");
1904 /* Create TLV subtree */
1905 tlv_tree = proto_item_add_subtree(
1906 tlv_item, ett_wimaxasncp_tlv);
1908 /* Type (expert item if unknown) */
1909 type_item = proto_tree_add_uint_format(
1910 tlv_tree, hf_wimaxasncp_tlv_type,
1911 tvb, offset, 2, type,
1912 "Type: %s (%u)", tlv_info->name, type);
1914 if (tlv_info->decoder == WIMAXASNCP_TLV_UNKNOWN)
1916 expert_add_info_format(pinfo, type_item,
1917 PI_UNDECODED, PI_WARN,
1918 "Unknown TLV type (%u)",
1923 proto_tree_add_uint(
1924 tlv_tree, hf_wimaxasncp_tlv_length,
1925 tvb, offset + 2, 2, length);
1931 /* --------------------------------------------------------------------
1933 * --------------------------------------------------------------------
1936 if (tlv_info->decoder == WIMAXASNCP_TLV_COMPOUND)
1940 /* error? compound, but no TLVs inside */
1942 else if (tvb_length_remaining(tvb, offset) > 0)
1946 /* N.B. Not padding out tvb length */
1947 tlv_tvb = tvb_new_subset(
1949 MIN(length, tvb_length_remaining(tvb, offset)),
1952 /* N.B. This is a recursive call... */
1953 dissect_wimaxasncp_tlvs(tlv_tvb, pinfo, tlv_tree);
1957 /* this should throw */
1958 tvb_ensure_bytes_exist(tvb, offset, length + pad);
1965 tvb_ensure_bytes_exist(tvb, offset, length + pad);
1967 tlv_tvb = tvb_new_subset(
1969 MIN(length, tvb_length_remaining(tvb, offset)),
1972 wimaxasncp_dissect_tlv_value(
1973 tlv_tvb, pinfo, tlv_tree, tlv_item, tlv_info);
1976 offset += length + pad;
1982 /* ========================================================================= */
1984 static guint dissect_wimaxasncp_backend(
1992 guint8 *pmsid = NULL;
1997 /* ------------------------------------------------------------------------
1999 * ------------------------------------------------------------------------
2004 proto_tree_add_item(
2005 tree, hf_wimaxasncp_msid,
2006 tvb, offset, 6, ENC_NA);
2008 pmsid = tvb_ether_to_str(tvb, offset);
2012 /* ------------------------------------------------------------------------
2014 * ------------------------------------------------------------------------
2017 ui32 = tvb_get_ntohl(tvb, offset);
2021 proto_tree_add_uint(
2022 tree, hf_wimaxasncp_reserved1,
2023 tvb, offset, 4, ui32);
2028 /* ------------------------------------------------------------------------
2030 * ------------------------------------------------------------------------
2034 ui16 = tvb_get_ntohs(tvb, offset);
2036 if (show_transaction_id_d_bit)
2038 const guint16 mask = 0x7fff;
2042 proto_tree_add_uint_format(
2043 tree, hf_wimaxasncp_transaction_id,
2044 tvb, offset, 2, ui16,
2045 "Transaction ID: D + 0x%04x (0x%04x)", mask & ui16, ui16);
2052 proto_tree_add_uint_format(
2053 tree, hf_wimaxasncp_transaction_id,
2054 tvb, offset, 2, ui16,
2055 "Transaction ID: 0x%04x", ui16);
2062 proto_tree_add_uint(
2063 tree, hf_wimaxasncp_transaction_id,
2064 tvb, offset, 2, ui16);
2071 /* ------------------------------------------------------------------------
2073 * ------------------------------------------------------------------------
2076 ui16 = tvb_get_ntohs(tvb, offset);
2080 proto_tree_add_uint(
2081 tree, hf_wimaxasncp_reserved2,
2082 tvb, offset, 2, ui16);
2087 /* ------------------------------------------------------------------------
2089 * ------------------------------------------------------------------------
2092 if (offset < tvb_length(tvb))
2096 tlv_tvb = tvb_new_subset(
2098 tvb_length(tvb) - offset,
2099 tvb_length(tvb) - offset);
2101 offset += dissect_wimaxasncp_tlvs(tlv_tvb, pinfo, tree);
2104 col_append_fstr(pinfo->cinfo, COL_INFO, " - MSID:%s", pmsid);
2107 col_append_fstr(pinfo->cinfo, COL_INFO, ", TID:D+0x%04x", tid);
2111 col_append_fstr(pinfo->cinfo, COL_INFO, ", TID:0x%04x", tid);
2117 /* ========================================================================= */
2121 match_ver_value_string(
2123 const ver_value_string* const strings,
2124 const guint32 max_ver)
2126 const ver_value_string* vvs;
2127 const ver_value_string* res = NULL;
2129 /* loop on the levels, from max to 0 */
2130 for(vvs=strings; vvs->vs.strptr; vvs++)
2132 if((vvs->vs.value == val) && (vvs->since <= max_ver))
2134 if(!res || vvs->since > res->since)
2141 return res? res->vs.strptr : NULL;
2144 static void register_wimaxasncp_fields(const char*);
2153 const gchar *unknown = "Unknown";
2155 /* Set up structures needed to add the protocol subtree and manage it */
2156 proto_item *packet_item = NULL;
2157 proto_item *item = NULL;
2158 proto_tree *wimaxasncp_tree = NULL;
2164 guint8 function_type;
2165 const gchar *function_type_name;
2166 proto_item *function_type_item;
2169 const gchar *message_name;
2170 const wimaxasncp_func_msg_t *p = NULL;
2173 /* ------------------------------------------------------------------------
2174 * First, we do some heuristics to check if the packet cannot be our
2176 * ------------------------------------------------------------------------
2179 /* Should we check a minimum size? If so, uncomment out the following
2182 if (tvb_reported_length(tvb) < WIMAXASNCP_HEADER_SIZE)
2188 /* We currently only support version 1. */
2189 if (tvb_bytes_exist(tvb, 0, 1) && tvb_get_guint8(tvb, 0) != 1)
2194 /* ------------------------------------------------------------------------
2195 * Initialize the protocol and info column.
2196 * ------------------------------------------------------------------------
2199 /* Make entries in Protocol column and Info column on summary display */
2200 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WiMAX");
2202 /* We'll fill in the "Info" column after fetch data, so we clear the
2203 column first in case calls to fetch data from the packet throw an
2205 col_clear(pinfo->cinfo, COL_INFO);
2207 /* ========================================================================
2208 * Disesction starts here
2209 * ========================================================================
2212 /* ------------------------------------------------------------------------
2213 * total packet, we'll adjust after we read the length field
2214 * ------------------------------------------------------------------------
2219 /* Register protocol fields, etc if haven't done yet. */
2220 if (wimaxasncp_dict == NULL)
2222 register_wimaxasncp_fields(NULL);
2227 packet_item = proto_tree_add_item(
2228 tree, proto_wimaxasncp,
2229 tvb, 0, MIN(WIMAXASNCP_HEADER_LENGTH_END, tvb_length(tvb)), ENC_NA);
2231 wimaxasncp_tree = proto_item_add_subtree(
2232 packet_item, ett_wimaxasncp);
2235 /* ------------------------------------------------------------------------
2237 * ------------------------------------------------------------------------
2242 proto_tree_add_item(
2243 wimaxasncp_tree, hf_wimaxasncp_version,
2244 tvb, offset, 1, ENC_BIG_ENDIAN);
2249 /* ------------------------------------------------------------------------
2251 * ------------------------------------------------------------------------
2254 ui8 = tvb_get_guint8(tvb, offset);
2258 proto_tree *flags_tree;
2262 proto_tree_add_uint_format(
2263 wimaxasncp_tree, hf_wimaxasncp_flags,
2264 tvb, offset, 1, ui8,
2265 "Flags: 0x%02x", ui8);
2270 item = proto_tree_add_uint_format(
2271 wimaxasncp_tree, hf_wimaxasncp_flags,
2272 tvb, offset, 1, ui8,
2275 if (ui8 & (WIMAXASNCP_FLAGS_T | WIMAXASNCP_FLAGS_R))
2277 if (ui8 & WIMAXASNCP_FLAGS_T)
2279 proto_item_append_text(item, "T");
2282 if (ui8 & WIMAXASNCP_FLAGS_R)
2284 proto_item_append_text(item, "R");
2287 proto_item_append_text(item, " - ");
2290 proto_item_append_text(
2291 item, "%s", decode_numeric_bitfield(ui8, 0xff, 8, "0x%02x"));
2293 flags_tree = proto_item_add_subtree(
2294 item, ett_wimaxasncp_flags);
2296 for (j = 0; j < 8; ++j)
2299 mask = 1 << (7 - j);
2301 /* Only add flags that are set */
2304 proto_tree_add_uint_format(
2305 flags_tree, hf_wimaxasncp_flags,
2306 tvb, offset, 1, ui8,
2307 "Bit #%u is set: %s",
2310 ui8 & mask, wimaxasncp_flag_vals, "Unknown"));
2318 /* ------------------------------------------------------------------------
2320 * ------------------------------------------------------------------------
2323 function_type = tvb_get_guint8(tvb, offset);
2325 function_type_name = match_ver_value_string(function_type,
2326 wimaxasncp_function_type_vals,
2327 global_wimaxasncp_nwg_ver);
2329 if( function_type_name )
2331 /* add the item to the tree */
2332 proto_tree_add_uint_format(
2333 wimaxasncp_tree, hf_wimaxasncp_function_type,
2334 tvb, offset, 1, function_type,
2335 "%s (%u)", function_type_name, function_type);
2339 /* if not matched, add the item and append expert item */
2340 function_type_item = proto_tree_add_uint_format(
2341 wimaxasncp_tree, hf_wimaxasncp_function_type,
2342 tvb, offset, 1, function_type,
2343 "Unknown (%u)", function_type);
2345 expert_add_info_format(pinfo, function_type_item,
2346 PI_UNDECODED, PI_WARN,
2347 "Unknown function type (%u)",
2353 /* ------------------------------------------------------------------------
2354 * OP ID and message type
2355 * ------------------------------------------------------------------------
2358 ui8 = tvb_get_guint8(tvb, offset);
2361 /* --------------------------------------------------------------------
2363 * --------------------------------------------------------------------
2366 item = proto_tree_add_uint_format(
2367 wimaxasncp_tree, hf_wimaxasncp_op_id,
2368 tvb, offset, 1, ui8,
2369 "OP ID: %s", val_to_str(ui8 >> 5, wimaxasncp_op_id_vals, unknown));
2371 proto_item_append_text(
2372 item, " (%s)", decode_numeric_bitfield(ui8, 0xe0, 8, "%u"));
2375 /* use the function type to find the message vals */
2376 for (i = 0; i < array_length(wimaxasncp_func_to_msg_vals_map); ++i)
2378 p = &wimaxasncp_func_to_msg_vals_map[i];
2380 if (function_type == p->function_type)
2386 /* --------------------------------------------------------------------
2388 * --------------------------------------------------------------------
2391 message_name = p ? match_ver_value_string(0x1f & ui8, p->vals, global_wimaxasncp_nwg_ver) : unknown;
2392 if(message_name == NULL)
2394 message_name = unknown;
2397 item = proto_tree_add_uint_format(
2398 wimaxasncp_tree, hf_wimaxasncp_op_id,
2399 tvb, offset, 1, ui8,
2400 "Message Type: %s", message_name);
2402 proto_item_append_text(
2403 item, " (%s)", decode_numeric_bitfield(ui8, 0x1f, 8, "%u"));
2405 /* Add expert item if not matched */
2406 if (strcmp(message_name, unknown) == 0)
2408 expert_add_info_format(pinfo, item,
2409 PI_UNDECODED, PI_WARN,
2410 "Unknown message op (%u)",
2414 col_add_str(pinfo->cinfo, COL_INFO, message_name);
2418 /* ------------------------------------------------------------------------
2420 * ------------------------------------------------------------------------
2423 length = tvb_get_ntohs(tvb, offset);
2428 packet_item, MAX(WIMAXASNCP_HEADER_LENGTH_END, length));
2430 item = proto_tree_add_uint(
2431 wimaxasncp_tree, hf_wimaxasncp_length,
2432 tvb, offset, 2, length);
2437 if (length < WIMAXASNCP_HEADER_SIZE)
2439 expert_add_info_format(
2440 pinfo, item, PI_MALFORMED, PI_ERROR, "Bad length");
2444 proto_item_append_text(
2445 item, " [error: specified length less than header size (20)]");
2448 if (length <= WIMAXASNCP_HEADER_LENGTH_END)
2454 /* ------------------------------------------------------------------------
2455 * remaining header fields and TLVs
2456 * ------------------------------------------------------------------------
2459 subtree = tvb_new_subset(
2461 MIN(length, tvb_length(tvb) - offset),
2462 length - WIMAXASNCP_HEADER_LENGTH_END);
2464 offset += dissect_wimaxasncp_backend(
2465 subtree, pinfo, wimaxasncp_tree);
2467 /* ------------------------------------------------------------------------
2468 * done, return the amount of data this dissector was able to dissect
2469 * ------------------------------------------------------------------------
2475 /* ========================================================================= */
2476 /* Modify the given string to make a suitable display filter */
2477 static char *alnumerize(
2480 char *r = name; /* read pointer */
2481 char *w = name; /* write pointer */
2484 for ( ; (c = *r); ++r)
2486 if (isalnum((unsigned char)c) || c == '_' || c == '.')
2488 /* These characters are fine - copy them */
2491 else if (c == ' ' || c == '-' || c == '/')
2493 /* Skip these others if haven't written any characters out yet */
2499 /* Skip if we would produce multiple adjacent '_'s */
2500 if (*(w - 1) == '_')
2505 /* OK, replace with underscore */
2509 /* Other undesirable characters are just skipped */
2512 /* Terminate and return modified string */
2517 /* ========================================================================= */
2519 static void add_reg_info(
2527 hf_register_info hf = {
2528 hf_ptr, { name, abbrev, type, display, NULL, 0x0, blurb, HFILL } };
2530 g_array_append_val(wimaxasncp_build_dict.hf, hf);
2533 /* ========================================================================= */
2535 static void add_tlv_reg_info(
2536 wimaxasncp_dict_tlv_t *tlv)
2542 /* ------------------------------------------------------------------------
2544 * ------------------------------------------------------------------------
2547 name = g_strdup(tlv->name);
2548 abbrev = alnumerize(g_strdup_printf("wimaxasncp.tlv.%s", tlv->name));
2550 switch (tlv->decoder)
2552 case WIMAXASNCP_TLV_UNKNOWN:
2553 blurb = "type=Unknown";
2555 case WIMAXASNCP_TLV_TBD:
2556 blurb = g_strdup_printf("type=%u, TBD", tlv->type);
2558 case WIMAXASNCP_TLV_COMPOUND:
2559 blurb = g_strdup_printf("type=%u, Compound", tlv->type);
2561 case WIMAXASNCP_TLV_FLAG0:
2562 blurb = g_strdup_printf("type=%u, Value = Null", tlv->type);
2565 blurb = g_strdup_printf("type=%u", tlv->type);
2570 &tlv->hf_root, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2572 /* ------------------------------------------------------------------------
2573 * add value(s) reg info
2574 * ------------------------------------------------------------------------
2577 name = g_strdup("Value");
2578 abbrev = alnumerize(g_strdup_printf("wimaxasncp.tlv.%s.value", tlv->name));
2579 blurb = g_strdup_printf("value for type=%u", tlv->type);
2581 switch (tlv->decoder)
2583 case WIMAXASNCP_TLV_UNKNOWN:
2587 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE,
2588 "value for unknown type");
2591 case WIMAXASNCP_TLV_TBD:
2593 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2596 case WIMAXASNCP_TLV_COMPOUND:
2597 case WIMAXASNCP_TLV_FLAG0:
2603 case WIMAXASNCP_TLV_BYTES:
2605 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2608 case WIMAXASNCP_TLV_ENUM8:
2610 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_DEC, blurb);
2613 case WIMAXASNCP_TLV_ENUM16:
2615 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2618 case WIMAXASNCP_TLV_ENUM32:
2620 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_DEC, blurb);
2623 case WIMAXASNCP_TLV_ETHER:
2625 &tlv->hf_value, name, abbrev, FT_ETHER, BASE_NONE, blurb);
2628 case WIMAXASNCP_TLV_ASCII_STRING:
2630 &tlv->hf_value, name, abbrev, FT_STRING, BASE_NONE, blurb);
2633 case WIMAXASNCP_TLV_BITFLAGS8:
2635 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_HEX, blurb);
2638 case WIMAXASNCP_TLV_BITFLAGS16:
2640 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_HEX, blurb);
2643 case WIMAXASNCP_TLV_BITFLAGS32:
2645 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_HEX, blurb);
2648 case WIMAXASNCP_TLV_ID:
2652 name = "IPv4 Address";
2654 abbrev = alnumerize(
2655 g_strdup_printf("wimaxasncp.tlv.%s.ipv4_value", tlv->name));
2658 &tlv->hf_ipv4, name, abbrev, FT_IPv4, BASE_NONE, blurb);
2660 name = "IPv6 Address";
2662 abbrev = alnumerize(
2663 g_strdup_printf("wimaxasncp.tlv.%s.ipv6_value", tlv->name));
2666 &tlv->hf_ipv6, name, abbrev, FT_IPv6, BASE_NONE, blurb);
2670 abbrev = alnumerize(
2671 g_strdup_printf("wimaxasncp.tlv.%s.bsid_value", tlv->name));
2674 &tlv->hf_bsid, name, abbrev, FT_ETHER, BASE_NONE, blurb);
2678 case WIMAXASNCP_TLV_HEX8:
2680 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_HEX, blurb);
2683 case WIMAXASNCP_TLV_HEX16:
2685 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_HEX, blurb);
2688 case WIMAXASNCP_TLV_HEX32:
2690 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_HEX, blurb);
2693 case WIMAXASNCP_TLV_DEC8:
2695 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_DEC, blurb);
2698 case WIMAXASNCP_TLV_DEC16:
2700 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2703 case WIMAXASNCP_TLV_DEC32:
2705 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_DEC, blurb);
2708 case WIMAXASNCP_TLV_IP_ADDRESS:
2712 name = "IPv4 Address";
2714 abbrev = alnumerize(
2715 g_strdup_printf("wimaxasncp.tlv.%s.ipv4_value", tlv->name));
2718 &tlv->hf_ipv4, name, abbrev, FT_IPv4, BASE_NONE, blurb);
2720 name = "IPv6 Address";
2722 abbrev = alnumerize(
2723 g_strdup_printf("wimaxasncp.tlv.%s.ipv6_value", tlv->name));
2726 &tlv->hf_ipv6, name, abbrev, FT_IPv6, BASE_NONE, blurb);
2730 case WIMAXASNCP_TLV_IPV4_ADDRESS:
2732 &tlv->hf_value, name, abbrev, FT_IPv4, BASE_NONE, blurb);
2735 case WIMAXASNCP_TLV_PROTOCOL_LIST:
2737 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2739 blurb = g_strdup_printf("value component for type=%u", tlv->type);
2743 abbrev = alnumerize(
2744 g_strdup_printf("wimaxasncp.tlv.%s.value.protocol", tlv->name));
2747 &tlv->hf_protocol, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2751 case WIMAXASNCP_TLV_PORT_RANGE_LIST:
2753 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2755 blurb = g_strdup_printf("value component for type=%u", tlv->type);
2759 abbrev = alnumerize(
2760 g_strdup_printf("wimaxasncp.tlv.%s.value.port_low", tlv->name));
2763 &tlv->hf_port_low, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2767 abbrev = alnumerize(
2768 g_strdup_printf("wimaxasncp.tlv.%s.value.port_high", tlv->name));
2771 &tlv->hf_port_high, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2775 case WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST:
2777 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2779 blurb = g_strdup_printf("value component for type=%u", tlv->type);
2781 name = "IPv4 Address";
2783 abbrev = alnumerize(
2784 g_strdup_printf("wimaxasncp.tlv.%s.value.ipv4", tlv->name));
2787 &tlv->hf_ipv4, name, abbrev, FT_IPv4, BASE_NONE, blurb);
2791 abbrev = alnumerize(
2792 g_strdup_printf("wimaxasncp.tlv.%s.value.ipv4_mask", tlv->name));
2795 &tlv->hf_ipv4_mask, name, abbrev, FT_IPv4, BASE_NONE, blurb);
2797 name = "IPv6 Address";
2799 abbrev = alnumerize(
2800 g_strdup_printf("wimaxasncp.tlv.%s.value.ipv6", tlv->name));
2803 &tlv->hf_ipv6, name, abbrev, FT_IPv6, BASE_NONE, blurb);
2807 abbrev = alnumerize(
2808 g_strdup_printf("wimaxasncp.tlv.%s.value.ipv6_mask", tlv->name));
2811 &tlv->hf_ipv6_mask, name, abbrev, FT_IPv6, BASE_NONE, blurb);
2815 case WIMAXASNCP_TLV_VENDOR_SPECIFIC:
2817 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2819 blurb = g_strdup_printf("value component for type=%u", tlv->type);
2823 abbrev = alnumerize(
2824 g_strdup_printf("wimaxasncp.tlv.%s.value.vendor_id", tlv->name));
2827 &tlv->hf_vendor_id, name, abbrev, FT_UINT24, BASE_DEC, blurb);
2829 name = "Rest of Info";
2831 abbrev = alnumerize(
2833 "wimaxasncp.tlv.%s.value.vendor_rest_of_info", tlv->name));
2836 &tlv->hf_vendor_rest_of_info, name, abbrev, FT_BYTES, BASE_NONE,
2841 case WIMAXASNCP_TLV_EAP:
2842 blurb = g_strdup_printf("EAP payload embedded in %s", name);
2845 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2851 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2856 "fix-me: unknown decoder: %d\n", tlv->decoder);
2863 /* ========================================================================= */
2864 /* Register the protocol fields and subtrees with Wireshark */
2866 register_wimaxasncp_fields(const char* unused _U_)
2868 gboolean debug_parser;
2873 /* ------------------------------------------------------------------------
2874 * List of header fields
2875 * ------------------------------------------------------------------------
2878 static hf_register_info hf_base[] = {
2880 &hf_wimaxasncp_version, /* ID */
2882 "Version", /* FIELDNAME */
2883 "wimaxasncp.version", /* PROTOABBREV.FIELDABBRE */
2884 FT_UINT8, /* FIELDTYPE */
2885 BASE_DEC, /* FIELDBASE */
2886 NULL, /* FIELDCONVERT */
2888 NULL, /* FIELDDESCR */
2893 &hf_wimaxasncp_flags,
2906 &hf_wimaxasncp_function_type,
2909 "wimaxasncp.function_type",
2919 &hf_wimaxasncp_op_id,
2925 VALS(wimaxasncp_op_id_vals),
2932 &hf_wimaxasncp_message_type,
2935 "wimaxasncp.message_type",
2945 &hf_wimaxasncp_qos_msg,
2948 "wimaxasncp.qos_msg",
2958 &hf_wimaxasncp_ho_control_msg,
2961 "wimaxasncp.ho_control_msg",
2971 &hf_wimaxasncp_data_path_control_msg,
2974 "wimaxasncp.data_path_control_msg",
2984 &hf_wimaxasncp_context_delivery_msg,
2987 "wimaxasncp.context_delivery_msg",
2997 &hf_wimaxasncp_r3_mobility_msg,
3000 "wimaxasncp.r3_mobility_msg",
3010 &hf_wimaxasncp_paging_msg,
3013 "wimaxasncp.paging_msg",
3023 &hf_wimaxasncp_rrm_msg,
3026 "wimaxasncp.rrm_msg",
3036 &hf_wimaxasncp_authentication_msg,
3039 "wimaxasncp.authentication_msg",
3049 &hf_wimaxasncp_ms_state_msg,
3052 "wimaxasncp.ms_state_msg",
3062 &hf_wimaxasncp_reauthentication_msg,
3065 "wimaxasncp.reauthentication_msg",
3075 &hf_wimaxasncp_session_msg,
3078 "wimaxasncp.session_msg",
3088 &hf_wimaxasncp_length,
3091 "wimaxasncp.length",
3101 &hf_wimaxasncp_msid,
3114 &hf_wimaxasncp_reserved1,
3117 "wimaxasncp.reserved1",
3127 &hf_wimaxasncp_transaction_id,
3130 "wimaxasncp.transaction_id",
3140 &hf_wimaxasncp_reserved2,
3143 "wimaxasncp.reserved2",
3166 &hf_wimaxasncp_tlv_type,
3169 "wimaxasncp.tlv.type",
3179 &hf_wimaxasncp_tlv_length,
3182 "wimaxasncp.tlv.length",
3192 &hf_wimaxasncp_tlv_value_bytes,
3195 "wimaxasncp.tlv_value_bytes",
3205 &hf_wimaxasncp_tlv_value_bitflags8,
3208 "wimaxasncp.tlv_value_bitflags8",
3218 &hf_wimaxasncp_tlv_value_bitflags16,
3221 "wimaxasncp.tlv_value_bitflags16",
3231 &hf_wimaxasncp_tlv_value_bitflags32,
3234 "wimaxasncp.tlv_value_bitflags32",
3244 &hf_wimaxasncp_tlv_value_protocol,
3247 "wimaxasncp.tlv_value_protocol",
3257 &hf_wimaxasncp_tlv_value_vendor_id,
3260 "wimaxasncp.tlv_value_vendor_id",
3271 /* ------------------------------------------------------------------------
3272 * Protocol subtree array
3273 * ------------------------------------------------------------------------
3276 static gint *ett_base[] = {
3278 &ett_wimaxasncp_flags,
3279 &ett_wimaxasncp_tlv,
3280 &ett_wimaxasncp_tlv_value_bitflags8,
3281 &ett_wimaxasncp_tlv_value_bitflags16,
3282 &ett_wimaxasncp_tlv_value_bitflags32,
3283 &ett_wimaxasncp_tlv_protocol_list,
3284 &ett_wimaxasncp_tlv_port_range_list,
3285 &ett_wimaxasncp_tlv_ip_address_mask_list,
3286 &ett_wimaxasncp_tlv_ip_address_mask,
3287 &ett_wimaxasncp_tlv_eap,
3288 &ett_wimaxasncp_tlv_vendor_specific_information_field
3291 /* ------------------------------------------------------------------------
3292 * load the XML dictionary
3293 * ------------------------------------------------------------------------
3296 debug_parser = getenv("WIRESHARK_DEBUG_WIMAXASNCP_DICT_PARSER") != NULL;
3297 dump_dict = getenv("WIRESHARK_DUMP_WIMAXASNCP_DICT") != NULL;
3299 dir = ep_strdup_printf(
3300 "%s" G_DIR_SEPARATOR_S "wimaxasncp",
3301 get_datafile_dir());
3304 wimaxasncp_dict_scan(dir, "dictionary.xml", debug_parser, &dict_error);
3308 report_failure("wimaxasncp - %s", dict_error);
3312 if (wimaxasncp_dict && dump_dict)
3314 wimaxasncp_dict_print(stdout, wimaxasncp_dict);
3317 /* ------------------------------------------------------------------------
3318 * build the hf and ett dictionary entries
3319 * ------------------------------------------------------------------------
3322 wimaxasncp_build_dict.hf =
3323 g_array_new(FALSE, TRUE, sizeof(hf_register_info));
3325 g_array_append_vals(
3326 wimaxasncp_build_dict.hf, hf_base, array_length(hf_base));
3328 wimaxasncp_build_dict.ett =
3329 g_array_new(FALSE, TRUE, sizeof(gint*));
3331 g_array_append_vals(
3332 wimaxasncp_build_dict.ett, ett_base, array_length(ett_base));
3334 if (wimaxasncp_dict)
3336 wimaxasncp_dict_tlv_t *tlv;
3338 /* For each TLV found in XML file */
3339 for (tlv = wimaxasncp_dict->tlvs; tlv; tlv = tlv->next)
3343 /* Create array for enums */
3344 wimaxasncp_dict_enum_t *e;
3345 GArray* array = g_array_new(TRUE, TRUE, sizeof(value_string));
3347 /* Copy each entry into value_string array */
3348 for (e = tlv->enums; e; e = e->next)
3350 value_string item = { e->code, e->name };
3351 g_array_append_val(array, item);
3354 /* Set enums to use with this TLV */
3355 tlv->enum_vs = (value_string*)(void*)array->data;
3358 add_tlv_reg_info(tlv);
3362 /* add an entry for unknown TLVs */
3363 add_tlv_reg_info(&wimaxasncp_tlv_not_found);
3365 /* The following debug will only be printed if the debug_enabled variable
3366 * is set programmatically. Setting the value via preferences will not
3367 * work as it will be set too late to affect this code path.
3371 if (wimaxasncp_dict)
3373 wimaxasncp_dict_tlv_t *tlv;
3375 for (tlv = wimaxasncp_dict->tlvs; tlv; tlv = tlv->next)
3380 " description = %s\n"
3387 " hf_protocol = %d\n"
3388 " hf_port_low = %d\n"
3389 " hf_port_high = %d\n"
3390 " hf_ipv4_mask = %d\n"
3391 " hf_ipv6_mask = %d\n"
3392 " hf_vendor_id = %d\n"
3393 " hf_vendor_rest_of_info = %d\n",
3398 tlv->decoder, wimaxasncp_decode_type_vals, "Unknown"),
3410 tlv->hf_vendor_rest_of_info);
3415 /* Required function calls to register the header fields and subtrees
3417 proto_register_field_array(
3419 (hf_register_info*)(void *)wimaxasncp_build_dict.hf->data,
3420 wimaxasncp_build_dict.hf->len);
3422 proto_register_subtree_array(
3423 (gint**)(void *)wimaxasncp_build_dict.ett->data,
3424 wimaxasncp_build_dict.ett->len);
3430 /* ========================================================================= */
3431 /* Register the protocol with Wireshark */
3433 /* this format is require because a script is used to build the C function
3434 that calls all the protocol registration.
3438 proto_register_wimaxasncp(void)
3440 module_t *wimaxasncp_module;
3442 /* ------------------------------------------------------------------------
3443 * complete registration
3444 * ------------------------------------------------------------------------
3447 /* Register the protocol name and description */
3448 proto_wimaxasncp = proto_register_protocol(
3449 "WiMAX ASN Control Plane Protocol",
3454 /* Register this dissector by name */
3455 new_register_dissector("wimaxasncp", dissect_wimaxasncp, proto_wimaxasncp);
3457 /* Register preferences module (See Section 2.6 for more on
3459 wimaxasncp_module = prefs_register_protocol(
3461 proto_reg_handoff_wimaxasncp);
3463 /* Register preferences */
3464 prefs_register_bool_preference(
3466 "show_transaction_id_d_bit",
3467 "Show transaction ID direction bit",
3468 "Show transaction ID direction bit separately from the rest of "
3469 "the transaction ID field.",
3470 &show_transaction_id_d_bit);
3472 prefs_register_bool_preference(
3475 "Enable debug output",
3476 "Print debug output to the console.",
3479 prefs_register_uint_preference(
3482 "UDP Port for WiMAX ASN Control Plane Protocol",
3483 "Set UDP port for WiMAX ASN Control Plane Protocol",
3484 10, &global_wimaxasncp_udp_port);
3486 prefs_register_enum_preference(
3490 "Version of the NWG that the R6 protocol complies with",
3491 &global_wimaxasncp_nwg_ver,
3492 wimaxasncp_nwg_versions,
3495 proto_register_prefix("wimaxasncp", register_wimaxasncp_fields);
3498 /* ========================================================================= */
3499 /* If this dissector uses sub-dissector registration add a registration
3500 routine. This exact format is required because a script is used to find
3501 these routines and create the code that calls these routines.
3503 This function is also called by preferences whenever "Apply" is pressed
3504 (see prefs_register_protocol above) so it should accommodate being called
3508 proto_reg_handoff_wimaxasncp(void)
3510 static gboolean inited = FALSE;
3511 static dissector_handle_t wimaxasncp_handle;
3512 static int currentPort = -1;
3517 /* Use new_create_dissector_handle() to indicate that
3518 * dissect_wimaxasncp() returns the number of bytes it dissected (or
3519 * 0 if it thinks the packet does not belong to WiMAX ASN Control
3522 wimaxasncp_handle = new_create_dissector_handle(
3530 if (currentPort != -1)
3532 /* Remove any previous registered port */
3533 dissector_delete_uint("udp.port", currentPort, wimaxasncp_handle);
3536 /* Add the new one from preferences */
3537 currentPort = global_wimaxasncp_udp_port;
3538 dissector_add_uint("udp.port", currentPort, wimaxasncp_handle);
3540 /* Find the EAP dissector */
3541 eap_handle = find_dissector("eap");