Bug Summary

File:builds/wireshark/wireshark/plugins/epan/wimaxasncp/packet-wimaxasncp.c
Warning:line 2224, column 5
Value stored to 'item' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-wimaxasncp.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-18/lib/clang/18 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/libxml2 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D PLUGIN_VERSION="0.0.1" -D WS_DEBUG -D WS_DEBUG_UTF_8 -D wimaxasncp_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/plugins/epan/wimaxasncp -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -dwarf-debug-flags /usr/lib/llvm-18/bin/clang -### --analyze -x c -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D PLUGIN_VERSION="0.0.1" -D WS_DEBUG -D WS_DEBUG_UTF_8 -D wimaxasncp_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/plugins/epan/wimaxasncp -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /usr/include/libxml2 -fvisibility=hidden -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -Wno-pointer-sign -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=gnu11 -fPIC /builds/wireshark/wireshark/plugins/epan/wimaxasncp/packet-wimaxasncp.c -o /builds/wireshark/wireshark/sbout/2025-06-26-100304-3847-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-06-26-100304-3847-1 -x c /builds/wireshark/wireshark/plugins/epan/wimaxasncp/packet-wimaxasncp.c
1/* packet-wimaxasncp.c
2 *
3 * Routines for WiMAX ASN Control Plane packet dissection dissection
4 *
5 * Copyright 2007, Mobile Metrics - http://www.mobilemetrics.net
6 *
7 * Author: Stephen Croll <croll@mobilemetrics.net>
8 *
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16
17#include "config.h"
18
19#include <stdio.h>
20#include <stdlib.h>
21
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
30#include <wsutil/filesystem.h>
31#include <wsutil/report_message.h>
32#include <wsutil/ws_padding_to.h>
33#include <wsutil/strtoi.h>
34#include <libxml/tree.h>
35#include <libxml/parser.h>
36#include <libxml/xpath.h>
37
38
39/* Forward declarations we need below */
40void proto_register_wimaxasncp(void);
41void proto_reg_handoff_wimaxasncp(void);
42
43/* Initialize the protocol and registered fields */
44static int proto_wimaxasncp;
45static int hf_wimaxasncp_version;
46static int hf_wimaxasncp_flags;
47static int hf_wimaxasncp_flags_r;
48static int hf_wimaxasncp_flags_t;
49static int hf_wimaxasncp_flags_reserved;
50static int hf_wimaxasncp_function_type;
51static int hf_wimaxasncp_op_id;
52static int hf_wimaxasncp_message_type;
53static int hf_wimaxasncp_length;
54static int hf_wimaxasncp_msid;
55static int hf_wimaxasncp_reserved1;
56static int hf_wimaxasncp_transaction_id;
57static int hf_wimaxasncp_reserved2;
58/* static int hf_wimaxasncp_tlv; */
59static int hf_wimaxasncp_tlv_type;
60static int hf_wimaxasncp_tlv_length;
61static int hf_wimaxasncp_tlv_value_bytes;
62static int hf_wimaxasncp_tlv_value_bitflags8;
63static int hf_wimaxasncp_tlv_value_bitflags16;
64static int hf_wimaxasncp_tlv_value_bitflags32;
65
66/* Preferences */
67static bool_Bool show_transaction_id_d_bit;
68
69/* Default WiMAX ASN control protocol port */
70#define WIMAXASNCP_DEF_UDP_PORT2231 2231
71
72
73/* Initialize the subtree pointers */
74static int ett_wimaxasncp;
75static int ett_wimaxasncp_flags;
76static int ett_wimaxasncp_tlv;
77static int ett_wimaxasncp_tlv_value_bitflags8;
78static int ett_wimaxasncp_tlv_value_bitflags16;
79static int ett_wimaxasncp_tlv_value_bitflags32;
80static int ett_wimaxasncp_tlv_protocol_list;
81static int ett_wimaxasncp_tlv_port_range_list;
82static int ett_wimaxasncp_tlv_ip_address_mask_list;
83static int ett_wimaxasncp_tlv_ip_address_mask;
84static int ett_wimaxasncp_tlv_eap;
85static int ett_wimaxasncp_tlv_vendor_specific_information_field;
86static int ett_wimaxasncp_port_range;
87
88static expert_field ei_wimaxasncp_tlv_type;
89static expert_field ei_wimaxasncp_function_type;
90static expert_field ei_wimaxasncp_op_id;
91static expert_field ei_wimaxasncp_decoder;
92static expert_field ei_wimaxasncp_message_type;
93static expert_field ei_wimaxasncp_length_bad;
94
95/* Header size, up to, but not including, the TLV fields. */
96#define WIMAXASNCP_HEADER_SIZE20 20
97
98/* Offset to end of the length field in the header. */
99#define WIMAXASNCP_HEADER_LENGTH_END6 6
100
101typedef struct {
102 wmem_array_t* hf;
103 wmem_array_t* ett;
104} wimaxasncp_build_dict_t;
105
106typedef struct _wimaxasncp_tlv_new_t {
107 uint16_t type;
108 char* name;
109 char* description;
110 int decoder;
111 unsigned since;
112 int hf_root;
113 int hf_value;
114 int hf_ipv4;
115 int hf_ipv6;
116 int hf_bsid;
117 int hf_protocol;
118 int hf_port_low;
119 int hf_port_high;
120 int hf_ipv4_mask;
121 int hf_ipv6_mask;
122 int hf_vendor_id;
123 int hf_vendor_rest_of_info;
124 value_string* enum_vs;
125} wimaxasncp_tlv_new_t;
126
127wmem_list_t* wimaxasncp_tlvs = NULL((void*)0);
128
129wimaxasncp_build_dict_t wimaxasncp_build_dict;
130
131static dissector_handle_t wimaxasncp_handle;
132static dissector_handle_t eap_handle;
133
134/* -------------------------------------------------------------------------
135 * NWG versions
136 * ------------------------------------------------------------------------- */
137
138#define WIMAXASNCP_NWGVER_R10_V1000 0
139#define WIMAXASNCP_NWGVER_R10_V1201 1
140#define WIMAXASNCP_NWGVER_R10_V1212 2
141#define WIMAXASNCP_NWGVER_NUM3 3
142
143 /* -------------------------------------------------------------------------
144 * decode types
145 * ------------------------------------------------------------------------- */
146
147enum
148{
149 WIMAXASNCP_TLV_UNKNOWN,
150 WIMAXASNCP_TLV_TBD,
151 WIMAXASNCP_TLV_COMPOUND,
152 WIMAXASNCP_TLV_BYTES,
153 WIMAXASNCP_TLV_ENUM8,
154 WIMAXASNCP_TLV_ENUM16,
155 WIMAXASNCP_TLV_ENUM32,
156 WIMAXASNCP_TLV_ETHER,
157 WIMAXASNCP_TLV_ASCII_STRING,
158 WIMAXASNCP_TLV_FLAG0,
159 WIMAXASNCP_TLV_BITFLAGS8,
160 WIMAXASNCP_TLV_BITFLAGS16,
161 WIMAXASNCP_TLV_BITFLAGS32,
162 WIMAXASNCP_TLV_ID,
163 WIMAXASNCP_TLV_HEX8,
164 WIMAXASNCP_TLV_HEX16,
165 WIMAXASNCP_TLV_HEX32,
166 WIMAXASNCP_TLV_DEC8,
167 WIMAXASNCP_TLV_DEC16,
168 WIMAXASNCP_TLV_DEC32,
169 WIMAXASNCP_TLV_IP_ADDRESS, /* Note: IPv4 or IPv6, determined by length */
170 WIMAXASNCP_TLV_IPV4_ADDRESS,
171 WIMAXASNCP_TLV_PROTOCOL_LIST,
172 WIMAXASNCP_TLV_PORT_RANGE_LIST,
173 WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST,
174 WIMAXASNCP_TLV_EAP,
175 WIMAXASNCP_TLV_VENDOR_SPECIFIC
176};
177
178static int* const hf_wimaxasncp_flag_fields[] = {
179 &hf_wimaxasncp_flags_r,
180 &hf_wimaxasncp_flags_t,
181 &hf_wimaxasncp_flags_reserved,
182 NULL((void*)0),
183};
184
185
186/* ------------------------------------------------------------------------- */
187
188static const value_string wimaxasncp_op_id_vals[] =
189{
190 { 0, "Invalid"},
191 { 1, "Request/Initiation"},
192 { 2, "Response"},
193 { 3, "Ack"},
194 { 4, "Indication"},
195 { 5, "Reserved"},
196 { 6, "Reserved"},
197 { 7, "Reserved"},
198 { 0, NULL((void*)0)}
199};
200
201/* ------------------------------------------------------------------------- */
202
203#define WIMAXASNCP_FT_QOS1 1
204#define WIMAXASNCP_FT_HO_CONTROL2 2
205#define WIMAXASNCP_FT_DATA_PATH_CONTROL3 3
206#define WIMAXASNCP_FT_CONTEXT_TRANSFER4 4
207#define WIMAXASNCP_FT_R3_MOBILITY5 5
208#define WIMAXASNCP_FT_PAGING6 6
209#define WIMAXASNCP_FT_RRM7 7
210#define WIMAXASNCP_FT_AUTHENTICATION8 8
211#define WIMAXASNCP_FT_MS_STATE9 9
212#define WIMAXASNCP_FT_REAUTHENTICATION10 10
213/* since NWG R1 V1.2.0 */
214#define WIMAXASNCP_FT_IM_OPERATIONS10 10
215/* since NWG R1 V1.2.1 */
216#define WIMAXASNCP_FT_ACCOUNTING11 11
217
218/* ------------------------------------------------------------------------- */
219
220/* struct to hold a value_string tuple, per version */
221typedef struct _ver_value_string
222{
223 uint32_t since;
224 value_string vs;
225} ver_value_string;
226
227static const ver_value_string wimaxasncp_function_type_vals[] =
228{
229 {0, { WIMAXASNCP_FT_QOS1, "QoS"}},
230 {0, { WIMAXASNCP_FT_HO_CONTROL2, "HO Control"}},
231 {0, { WIMAXASNCP_FT_DATA_PATH_CONTROL3, "Data Path Control"}},
232 {0, { WIMAXASNCP_FT_CONTEXT_TRANSFER4, "Context Transfer"}},
233 {0, { WIMAXASNCP_FT_R3_MOBILITY5, "R3 Mobility"}},
234 {0, { WIMAXASNCP_FT_PAGING6, "Paging"}},
235 {0, { WIMAXASNCP_FT_RRM7, "RRM"}},
236 {0, { WIMAXASNCP_FT_AUTHENTICATION8, "Authentication Relay"}},
237 {0, { WIMAXASNCP_FT_MS_STATE9, "MS State"}},
238 {0, { WIMAXASNCP_FT_REAUTHENTICATION10, "Re-Authentication"}},
239 {WIMAXASNCP_NWGVER_R10_V1201, {WIMAXASNCP_FT_IM_OPERATIONS10, "IM Operations"}},
240 {WIMAXASNCP_NWGVER_R10_V1212, { WIMAXASNCP_FT_ACCOUNTING11, "Accounting"}},
241 {0, { 0, NULL((void*)0)}}
242};
243
244/* ------------------------------------------------------------------------- */
245
246static const ver_value_string wimaxasncp_qos_msg_vals[] =
247{
248 {0,{ 1, "RR_Req"}},
249 {0,{ 2, "RR_Rsp"}},
250 {0,{ 3, "RR_Ack"}},
251 {0,{ 0, NULL((void*)0)}}
252};
253
254/* ------------------------------------------------------------------------- */
255
256static const ver_value_string wimaxasncp_ho_control_msg_vals[] =
257{
258 {0, { 1, "HO_Ack"}},
259 {0, { 2, "HO_Complete"}},
260 {0, { 3, "HO_Cnf"}},
261 {0, { 4, "HO_Req"}},
262 {0, { 5, "HO_Rsp"}},
263 {WIMAXASNCP_NWGVER_R10_V1201, { 1, "HO_Req"}},
264 {WIMAXASNCP_NWGVER_R10_V1201, { 2, "HO_Rsp"}},
265 {WIMAXASNCP_NWGVER_R10_V1201, { 3, "HO_Ack"}},
266 {WIMAXASNCP_NWGVER_R10_V1201, { 4, "HO_Cnf"}},
267 {WIMAXASNCP_NWGVER_R10_V1201, { 5, "HO_Complete"}},
268 {WIMAXASNCP_NWGVER_R10_V1201, { 6, "HO_Directive"}},
269 {WIMAXASNCP_NWGVER_R10_V1201, { 7, "HO_Directive_Rsp"}},
270 {0, { 0, NULL((void*)0)}}
271};
272
273/* ------------------------------------------------------------------------- */
274
275static const ver_value_string wimaxasncp_data_path_control_msg_vals[] =
276{
277 {0, { 1, "Path_Dereg_Ack"}},
278 {0, { 2, "Path_Dereg_Req"}},
279 {0, { 3, "Path_Dereg_Rsp"}},
280 {0, { 4, "Path_Modification_Ack"}},
281 {0, { 5, "Path_Modification_Req"}},
282 {0, { 6, "Path_Modification_Rsp"}},
283 {0, { 7, "Path_Prereg_Ack"}},
284 {0, { 8, "Path_Prereg_Req"}},
285 {0, { 9, "Path_Prereg_Rsp"}},
286 {0, { 10, "Path_Reg_Ack"}},
287 {0, { 11, "Path_Reg_Req"}},
288 {0, { 12, "Path_Reg_Rsp"}},
289 {0, { 13, "MS_Attachment_Req"}},
290 {0, { 14, "MS_Attachment_Rsp"}},
291 {0, { 15, "MS_Attachment_Ack"}},
292 {0, { 16, "Key_Change_Directive"}},
293 {WIMAXASNCP_NWGVER_R10_V1201, { 1, "Path_Dereg_Req"}},
294 {WIMAXASNCP_NWGVER_R10_V1201, { 2, "Path_Dereg_Rsp"}},
295 {WIMAXASNCP_NWGVER_R10_V1201, { 3, "Path_Dereg_Ack"}},
296 {WIMAXASNCP_NWGVER_R10_V1201, { 4, "Path_Modification_Req"}},
297 {WIMAXASNCP_NWGVER_R10_V1201, { 5, "Path_Modification_Rsp"}},
298 {WIMAXASNCP_NWGVER_R10_V1201, { 6, "Path_Modification_Ack"}},
299 {WIMAXASNCP_NWGVER_R10_V1201, { 7, "Path_Prereg_Req"}},
300 {WIMAXASNCP_NWGVER_R10_V1201, { 8, "Path_Prereg_Rsp"}},
301 {WIMAXASNCP_NWGVER_R10_V1201, { 9, "Path_Prereg_Ack"}},
302 {WIMAXASNCP_NWGVER_R10_V1201, { 10, "Path_Reg_Req"}},
303 {WIMAXASNCP_NWGVER_R10_V1201, { 11, "Path_Reg_Rsp"}},
304 {WIMAXASNCP_NWGVER_R10_V1201, { 12, "Path_Reg_Ack"}},
305 {WIMAXASNCP_NWGVER_R10_V1201, { 13, "Obsolete"}},
306 {WIMAXASNCP_NWGVER_R10_V1201, { 14, "Obsolete"}},
307 {WIMAXASNCP_NWGVER_R10_V1201, { 15, "Obsolete"}},
308 {WIMAXASNCP_NWGVER_R10_V1201, { 16, "Obsolete"}},
309 {0, { 0, NULL((void*)0)}}
310};
311
312/* ------------------------------------------------------------------------- */
313
314static const ver_value_string wimaxasncp_context_transfer_msg_vals[] =
315{
316 {0, { 1, "Context_Rpt"}},
317 {0, { 2, "Context_Req"}},
318 {0, { 3, "Context_Ack"}},
319 {WIMAXASNCP_NWGVER_R10_V1201, { 1, "Context_Req"}},
320 {WIMAXASNCP_NWGVER_R10_V1201, { 2, "Context_Rpt"}},
321 {WIMAXASNCP_NWGVER_R10_V1201, { 4, "CMAC_Key_Count_Update"}},
322 {WIMAXASNCP_NWGVER_R10_V1201, { 5, "CMAC_Key_Count_Update_ACK"}},
323 {WIMAXASNCP_NWGVER_R10_V1201, { 6, "CMAC_Key_Count_Req"}},
324 {WIMAXASNCP_NWGVER_R10_V1201, { 7, "CMAC_Key_Count_Rsp"}},
325 {WIMAXASNCP_NWGVER_R10_V1201, { 8, "Prepaid Request"}},
326 {WIMAXASNCP_NWGVER_R10_V1201, { 9, "Prepaid Notify"}},
327 {WIMAXASNCP_NWGVER_R10_V1212, { 6, "VOID"}},
328 {WIMAXASNCP_NWGVER_R10_V1212, { 7, "VOID"}},
329 {WIMAXASNCP_NWGVER_R10_V1212, { 0, NULL((void*)0)}}
330};
331
332/* ------------------------------------------------------------------------- */
333
334static const ver_value_string wimaxasncp_r3_mobility_msg_vals[] =
335{
336 {0, { 1, "Anchor_DPF_HO_Req"}},
337 {0, { 2, "Anchor_DPF_HO_Trigger"}},
338 {0, { 3, "Anchor_DPF_HO_Rsp"}},
339 {0, { 4, "Anchor_DPF_Relocate_Req"}},
340 {0, { 5, "FA_Register_Req"}},
341 {0, { 6, "FA_Register_Rsp"}},
342 {0, { 7, "Anchor_DPF_Relocate_Rsp"}},
343 {0, { 8, "FA_Revoke_Req"}},
344 {0, { 9, "FA_Revoke_Rsp"}},
345 {WIMAXASNCP_NWGVER_R10_V1201, { 5, "Anchor_DPF_Relocate_Rsp"}},
346 {WIMAXASNCP_NWGVER_R10_V1201, { 6, "FA_Register_Req"}},
347 {WIMAXASNCP_NWGVER_R10_V1201, { 7, "FA_Register_Rsp"}},
348 {WIMAXASNCP_NWGVER_R10_V1201, { 10, "Anchor_DPF_Release_Req"}},
349 {WIMAXASNCP_NWGVER_R10_V1201, { 11, "Relocation_Ready_Req"}},
350 {WIMAXASNCP_NWGVER_R10_V1201, { 12, "Relocation_Ready_Rsp"}},
351 {0, { 0, NULL((void*)0)}}
352};
353
354/* ------------------------------------------------------------------------- */
355
356static const ver_value_string wimaxasncp_paging_msg_vals[] =
357{
358 {0, { 1, "Initiate_Paging_Req"}},
359 {0, { 2, "Initiate_Paging_Rsp"}},
360 {0, { 3, "LU_Cnf"}},
361 {0, { 4, "LU_Req"}},
362 {0, { 5, "LU_Rsp"}},
363 {0, { 6, "Paging_Announce"}},
364 {0, { 7, "CMAC_Key_Count_Req"}},
365 {0, { 8, "CMAC_Key_Count_Rsp"}},
366 {WIMAXASNCP_NWGVER_R10_V1201, { 1, "Paging_Announce"}},
367 {WIMAXASNCP_NWGVER_R10_V1201, { 2, "Delete_MS_Entry_Req"}},
368 {WIMAXASNCP_NWGVER_R10_V1201, { 3, "PC_Relocation_Ind"}},
369 {WIMAXASNCP_NWGVER_R10_V1201, { 4, "PC_Relocation_Ack"}},
370 {WIMAXASNCP_NWGVER_R10_V1201, { 5, "Obsolete"}},
371 {WIMAXASNCP_NWGVER_R10_V1201, { 6, "Obsolete"}},
372 {WIMAXASNCP_NWGVER_R10_V1201, { 7, "Obsolete"}},
373 {WIMAXASNCP_NWGVER_R10_V1201, { 8, "Obsolete"}},
374 {0, { 0, NULL((void*)0)}}
375};
376
377/* ------------------------------------------------------------------------- */
378
379static const ver_value_string wimaxasncp_rrm_msg_vals[] =
380{
381 {0, { 1, "R6 PHY_Parameters_Req"}},
382 {0, { 2, "R6 PHY_Parameters_Rpt"}},
383 {0, { 3, "R4/R6 Spare_Capacity_Req"}},
384 {0, { 4, "R4/R6 Spare_Capacity_Rpt"}},
385 {0, { 5, "R6 Neighbor_BS_Resource_Status_Update"}},
386 {0, { 6, "R4/R6 Radio_Config_Update_Req"}},
387 {0, { 7, "R4/R6 Radio_Config_Update_Rpt"}},
388 {WIMAXASNCP_NWGVER_R10_V1201, { 8, "R4/R6 Radio_Config_Update_Ack"}},
389 {0, { 0, NULL((void*)0)}}
390};
391
392/* ------------------------------------------------------------------------- */
393
394static const ver_value_string wimaxasncp_authentication_msg_vals[] =
395{
396 {0, { 1, "AR_Authenticated_Eap_Start"}},
397 {0, { 2, "AR_Authenticated_EAP_Transfer"}},
398 {0, { 3, "AR_Eap_Start"}},
399 {0, { 4, "AR_EAP_Transfer"}},
400 {0, { 5, "AR_EAP_Complete"}},
401 {WIMAXASNCP_NWGVER_R10_V1201, { 1, "AR_EAP_Start"}},
402 {WIMAXASNCP_NWGVER_R10_V1201, { 2, "AR_EAP_Transfer"}},
403 {WIMAXASNCP_NWGVER_R10_V1201, { 3, "Bulk_Interim_Update"}},
404 {WIMAXASNCP_NWGVER_R10_V1201, { 4, "Bulk_Interim_Update_Ack"}},
405 {WIMAXASNCP_NWGVER_R10_V1201, { 5, "Obsolete"}},
406 {0, { 0, NULL((void*)0)}}
407};
408
409/* ------------------------------------------------------------------------- */
410
411static const ver_value_string wimaxasncp_ms_state_msg_vals[] =
412{
413 {0, { 1, "IM_Entry_State_Change_Req"}},
414 {0, { 2, "IM_Entry_State_Change_Rsp"}},
415 {0, { 3, "IM_Exit_State_Change_Req"}},
416 {0, { 4, "IM_Exit_State_Change_Rsp"}},
417 {0, { 5, "NW_ReEntry_State_Change_Directive"}},
418 {0, { 6, "MS_PreAttachment_Req"}},
419 {0, { 7, "MS_PreAttachment_Rsp"}},
420 {0, { 8, "MS_PreAttachment_Ack"}},
421 {WIMAXASNCP_NWGVER_R10_V1201, { 1, "MS_PreAttachment_Req"}},
422 {WIMAXASNCP_NWGVER_R10_V1201, { 2, "MS_PreAttachment_Rsp"}},
423 {WIMAXASNCP_NWGVER_R10_V1201, { 3, "MS_PreAttachment_Ack"}},
424 {WIMAXASNCP_NWGVER_R10_V1201, { 4, "MS_Attachment_Req"}},
425 {WIMAXASNCP_NWGVER_R10_V1201, { 5, "MS_Attachment_Rsp"}},
426 {WIMAXASNCP_NWGVER_R10_V1201, { 6, "MS_Attachment_Ack"}},
427 {WIMAXASNCP_NWGVER_R10_V1201, { 7, "Key_Change_Directive"}},
428 {WIMAXASNCP_NWGVER_R10_V1201, { 8, "Key_Change_Cnf"}},
429 {WIMAXASNCP_NWGVER_R10_V1201, { 9, "Key_Change_Ack"}},
430 {WIMAXASNCP_NWGVER_R10_V1201, { 10, "Relocation_Complete_Req"}},
431 {WIMAXASNCP_NWGVER_R10_V1201, { 11, "Relocation_Complete_Rsp"}},
432 {WIMAXASNCP_NWGVER_R10_V1201, { 12, "Relocation_Complete_Ack"}},
433 {WIMAXASNCP_NWGVER_R10_V1201, { 13, "Relocation_Notify"}},
434 {WIMAXASNCP_NWGVER_R10_V1201, { 14, "Relocation_Req"}},
435 {WIMAXASNCP_NWGVER_R10_V1201, { 15, "Relocation_Rsp"}},
436 {WIMAXASNCP_NWGVER_R10_V1201, { 16, "NetExit_MS_State_Change_Req"}},
437 {WIMAXASNCP_NWGVER_R10_V1201, { 17, "NetExit_MS_State_Change_Rsp"}},
438 {0, { 0, NULL((void*)0)}}
439};
440
441/* ------------------------------------------------------------------------- */
442
443/* note - function type 10-im_operation, was once used for re-authentication */
444static const ver_value_string wimaxasncp_im_operations_msg_vals[] =
445{
446 {0, { 1, "AR_EAP_Start"}},
447 {0, { 2, "Key_Change_Directive"}},
448 {0, { 3, "Key_Change_Cnf"}},
449 {0, { 4, "Relocation_Cnf"}},
450 {0, { 5, "Relocation_Confirm_Ack"}},
451 {0, { 6, "Relocation_Notify"}},
452 {0, { 7, "Relocation_Notify_Ack"}},
453 {0, { 8, "Relocation_Req"}},
454 {0, { 9, "Relocation_Rsp"}},
455 {WIMAXASNCP_NWGVER_R10_V1201, { 1, "IM_Entry_State_Change_Req"}},
456 {WIMAXASNCP_NWGVER_R10_V1201, { 2, "IM_Entry_State_Change_Rsp"}},
457 {WIMAXASNCP_NWGVER_R10_V1201, { 3, "IM_Entry_State_Change_Ack"}},
458 {WIMAXASNCP_NWGVER_R10_V1201, { 4, "IM_Exit_State_Change_Req"}},
459 {WIMAXASNCP_NWGVER_R10_V1201, { 5, "IM_Exit_State_Change_Rsp"}},
460 {WIMAXASNCP_NWGVER_R10_V1201, { 6, "Initiate_Paging_Req"}},
461 {WIMAXASNCP_NWGVER_R10_V1201, { 7, "Initiate_Paging_Rsp"}},
462 {WIMAXASNCP_NWGVER_R10_V1201, { 8, "LU_Req"}},
463 {WIMAXASNCP_NWGVER_R10_V1201, { 9, "LU_Rsp"}},
464 {WIMAXASNCP_NWGVER_R10_V1201, { 10, "LU_Cnf"}},
465 {0, { 0, NULL((void*)0)}}
466};
467
468/* ------------------------------------------------------------------------- */
469
470static const ver_value_string wimaxasncp_accounting_msg_vals_r1v121[] =
471{
472 {WIMAXASNCP_NWGVER_R10_V1212, { 1, "Hot_lining_Req"}},
473 {WIMAXASNCP_NWGVER_R10_V1212, { 2, "Hot_lining_Rsp"}},
474 {0, { 0, NULL((void*)0)}}
475};
476
477/* ------------------------------------------------------------------------- */
478
479/* supported NWG versions */
480static const enum_val_t wimaxasncp_nwg_versions[] = {
481 { "R1.0_v1.0.0", "Release 1.0, Version 1.0.0", WIMAXASNCP_NWGVER_R10_V1000 },
482 { "R1.0_v1.2.0", "Release 1.0, Version 1.2.0", WIMAXASNCP_NWGVER_R10_V1201 },
483 { "R1.0_v1.2.1", "Release 1.0, Version 1.2.1", WIMAXASNCP_NWGVER_R10_V1212 },
484 { NULL((void*)0), NULL((void*)0), 0 }
485};
486
487/* ------------------------------------------------------------------------- */
488
489/* NWG version */
490#define WIMAXASNCP_DEF_NWGVER2 WIMAXASNCP_NWGVER_R10_V1212
491static unsigned global_wimaxasncp_nwg_ver = WIMAXASNCP_DEF_NWGVER2;
492
493/* ========================================================================= */
494
495typedef struct {
496 uint8_t function_type;
497 const ver_value_string *vals;
498} wimaxasncp_func_msg_t;
499
500/* ------------------------------------------------------------------------ */
501
502static const wimaxasncp_func_msg_t wimaxasncp_func_to_msg_vals_map[] =
503{
504 { WIMAXASNCP_FT_QOS1, wimaxasncp_qos_msg_vals },
505 { WIMAXASNCP_FT_HO_CONTROL2, wimaxasncp_ho_control_msg_vals },
506 { WIMAXASNCP_FT_DATA_PATH_CONTROL3, wimaxasncp_data_path_control_msg_vals },
507 { WIMAXASNCP_FT_CONTEXT_TRANSFER4, wimaxasncp_context_transfer_msg_vals },
508 { WIMAXASNCP_FT_R3_MOBILITY5, wimaxasncp_r3_mobility_msg_vals },
509 { WIMAXASNCP_FT_PAGING6, wimaxasncp_paging_msg_vals },
510 { WIMAXASNCP_FT_RRM7, wimaxasncp_rrm_msg_vals },
511 { WIMAXASNCP_FT_AUTHENTICATION8, wimaxasncp_authentication_msg_vals },
512 { WIMAXASNCP_FT_MS_STATE9, wimaxasncp_ms_state_msg_vals },
513 { WIMAXASNCP_FT_IM_OPERATIONS10, wimaxasncp_im_operations_msg_vals },
514 { WIMAXASNCP_FT_ACCOUNTING11, wimaxasncp_accounting_msg_vals_r1v121 }
515};
516
517/* ========================================================================= */
518
519static wimaxasncp_tlv_new_t wimaxasncp_tlv_not_found =
520{
521 0, "Unknown", NULL((void*)0), WIMAXASNCP_TLV_UNKNOWN, 0,
522 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
523 NULL((void*)0)
524};
525
526
527typedef struct {
528 wimaxasncp_tlv_new_t* res;
529 uint16_t type;
530} wimaxasncp_find_tlv_info_data_t;
531
532static void
533wimaxasncp_find_tlv_info(void* data, void* user_data)
534{
535 wimaxasncp_find_tlv_info_data_t* info_data = (wimaxasncp_find_tlv_info_data_t*)user_data;
536 wimaxasncp_tlv_new_t* tlv = (wimaxasncp_tlv_new_t*)data;
537
538 if (tlv->type == info_data->type)
539 {
540 /* if the TLV is defined for current NWG version */
541 if (tlv->since <= global_wimaxasncp_nwg_ver)
542 {
543 /* if the current TLV is newer then last found TLV, save it */
544 if ((info_data->res == NULL((void*)0)) || (tlv->since > info_data->res->since))
545 {
546 info_data->res = tlv;
547 }
548 }
549 }
550}
551
552static const wimaxasncp_tlv_new_t* wimaxasncp_get_tlv_info(uint16_t type)
553{
554 wimaxasncp_find_tlv_info_data_t data = {NULL((void*)0), type };
555 wmem_list_foreach(wimaxasncp_tlvs, wimaxasncp_find_tlv_info, &data);
556
557 if (data.res)
558 return data.res;
559
560 return &wimaxasncp_tlv_not_found;
561}
562
563/* ========================================================================= */
564
565static const char*
566wimaxasncp_get_enum_name(const wimaxasncp_tlv_new_t* tlv_info, uint32_t code)
567{
568 if (tlv_info->enum_vs)
569 return val_to_str_const(code, tlv_info->enum_vs, "Unknown");
570
571 return "Unknown";
572}
573
574/* ========================================================================= */
575
576static const value_string wimaxasncp_decode_type_vals[] =
577{
578 { WIMAXASNCP_TLV_UNKNOWN, "WIMAXASNCP_TLV_UNKNOWN"},
579 { WIMAXASNCP_TLV_TBD, "WIMAXASNCP_TLV_TBD"},
580 { WIMAXASNCP_TLV_COMPOUND, "WIMAXASNCP_TLV_COMPOUND"},
581 { WIMAXASNCP_TLV_BYTES, "WIMAXASNCP_TLV_BYTES"},
582 { WIMAXASNCP_TLV_ENUM8, "WIMAXASNCP_TLV_ENUM8"},
583 { WIMAXASNCP_TLV_ENUM16, "WIMAXASNCP_TLV_ENUM16"},
584 { WIMAXASNCP_TLV_ENUM32, "WIMAXASNCP_TLV_ENUM32"},
585 { WIMAXASNCP_TLV_ETHER, "WIMAXASNCP_TLV_ETHER"},
586 { WIMAXASNCP_TLV_ASCII_STRING, "WIMAXASNCP_TLV_ASCII_STRING"},
587 { WIMAXASNCP_TLV_FLAG0, "WIMAXASNCP_TLV_FLAG0"},
588 { WIMAXASNCP_TLV_BITFLAGS8, "WIMAXASNCP_TLV_BITFLAGS8"},
589 { WIMAXASNCP_TLV_BITFLAGS16, "WIMAXASNCP_TLV_BITFLAGS16"},
590 { WIMAXASNCP_TLV_BITFLAGS32, "WIMAXASNCP_TLV_BITFLAGS32"},
591 { WIMAXASNCP_TLV_ID, "WIMAXASNCP_TLV_ID"},
592 { WIMAXASNCP_TLV_HEX8, "WIMAXASNCP_TLV_HEX8"},
593 { WIMAXASNCP_TLV_HEX16, "WIMAXASNCP_TLV_HEX16"},
594 { WIMAXASNCP_TLV_HEX32, "WIMAXASNCP_TLV_HEX32"},
595 { WIMAXASNCP_TLV_DEC8, "WIMAXASNCP_TLV_DEC8"},
596 { WIMAXASNCP_TLV_DEC16, "WIMAXASNCP_TLV_DEC16"},
597 { WIMAXASNCP_TLV_DEC32, "WIMAXASNCP_TLV_DEC32"},
598 { WIMAXASNCP_TLV_IP_ADDRESS, "WIMAXASNCP_TLV_IP_ADDRESS"},
599 { WIMAXASNCP_TLV_IPV4_ADDRESS, "WIMAXASNCP_TLV_IPV4_ADDRESS"},
600 { WIMAXASNCP_TLV_PROTOCOL_LIST, "WIMAXASNCP_TLV_PROTOCOL_LIST"},
601 { WIMAXASNCP_TLV_PORT_RANGE_LIST, "WIMAXASNCP_TLV_PORT_RANGE_LIST"},
602 { WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST, "WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST"},
603 { WIMAXASNCP_TLV_EAP, "WIMAXASNCP_TLV_EAP"},
604 { WIMAXASNCP_TLV_VENDOR_SPECIFIC, "WIMAXASNCP_TLV_VENDOR_SPECIFIC"},
605 { 0, NULL((void*)0)}
606};
607
608/* ========================================================================= */
609
610static void wimaxasncp_proto_tree_add_tlv_ipv4_value(
611 packet_info *pinfo,
612 tvbuff_t *tvb,
613 proto_tree *tree,
614 proto_item *tlv_item,
615 unsigned offset,
616 const wimaxasncp_tlv_new_t* tlv_info)
617{
618 int hf_value;
619 uint32_t ip;
620 const char *addr_res;
621
622 if (tlv_info->hf_ipv4 > 0)
623 {
624 hf_value = tlv_info->hf_ipv4;
625 }
626 else
627 {
628 hf_value = tlv_info->hf_value;
629 }
630
631 ip = tvb_get_ipv4(tvb, offset);
632 addr_res = tvb_address_with_resolution_to_str(pinfo->pool, tvb, AT_IPv4, offset);
633
634 proto_tree_add_ipv4_format(
635 tree, hf_value,
636 tvb, offset, 4, ip,
637 "Value: %s", addr_res);
638
639 proto_item_append_text(
640 tlv_item, " - %s", addr_res);
641}
642
643/* ========================================================================= */
644
645static void wimaxasncp_proto_tree_add_tlv_ipv6_value(
646 packet_info *pinfo,
647 tvbuff_t *tvb,
648 proto_tree *tree,
649 proto_item *tlv_item,
650 unsigned offset,
651 const wimaxasncp_tlv_new_t* tlv_info)
652{
653 int hf_value;
654 ws_in6_addr ip;
655 const char *addr_res;
656
657 if (tlv_info->hf_ipv4 > 0)
658 {
659 hf_value = tlv_info->hf_ipv6;
660 }
661 else
662 {
663 hf_value = tlv_info->hf_value;
664 }
665
666 tvb_get_ipv6(tvb, offset, &ip);
667 addr_res = tvb_address_with_resolution_to_str(pinfo->pool, tvb, AT_IPv6, offset);
668
669 proto_tree_add_ipv6_format(
670 tree, hf_value,
671 tvb, offset, 16, &ip,
672 "Value: %s", addr_res);
673
674 proto_item_append_text(
675 tlv_item, " - %s", addr_res);
676}
677
678/* ========================================================================= */
679
680static void wimaxasncp_proto_tree_add_ether_value(
681 packet_info *pinfo,
682 tvbuff_t *tvb,
683 proto_tree *tree,
684 proto_item *tlv_item,
685 unsigned offset,
686 unsigned length,
687 const wimaxasncp_tlv_new_t* tlv_info)
688{
689 int hf_value;
690 const uint8_t *p;
691 const char *ether_name;
692
693 if (tlv_info->hf_bsid > 0)
694 {
695 hf_value = tlv_info->hf_bsid;
696 }
697 else
698 {
699 hf_value = tlv_info->hf_value;
700 }
701
702 p = tvb_get_ptr(tvb, offset, length);
703 ether_name = tvb_address_with_resolution_to_str(pinfo->pool, tvb, AT_ETHER, offset);
704
705 proto_tree_add_ether_format(
706 tree, hf_value,
707 tvb, offset, length, p,
708 "Value: %s",
709 ether_name);
710
711 proto_item_append_text(
712 tlv_item, " - %s",
713 ether_name);
714}
715
716/* ========================================================================= */
717
718static void wimaxasncp_dissect_tlv_value(
719 tvbuff_t *tvb,
720 packet_info *pinfo,
721 proto_tree *tree,
722 proto_item *tlv_item,
723 const wimaxasncp_tlv_new_t* tlv_info)
724{
725 unsigned offset = 0;
726 unsigned length;
727 const unsigned max_show_bytes = 24; /* arbitrary */
728 static const char *hex_note = "[hex]";
729
730 length = tvb_reported_length(tvb);
731
732 switch (tlv_info->decoder)
733 {
734 case WIMAXASNCP_TLV_ENUM8:
735 {
736 if (length != 1)
737 {
738 /* encoding error */
739 break;
740 }
741
742 if (tree)
743 {
744 uint8_t value;
745 const char *s;
746
747 value = tvb_get_uint8(tvb, offset);
748
749 s = wimaxasncp_get_enum_name(tlv_info, value);
750
751 proto_tree_add_uint_format(
752 tree, tlv_info->hf_value,
753 tvb, offset, length, value,
754 "Value: %s (%u)", s, value);
755
756 proto_item_append_text(tlv_item, " - %s", s);
757 }
758
759 return;
760 }
761 case WIMAXASNCP_TLV_ENUM16:
762 {
763 if (length != 2)
764 {
765 /* encoding error */
766 break;
767 }
768
769 if (tree)
770 {
771 uint16_t value;
772 const char *s;
773
774 value = tvb_get_ntohs(tvb, offset);
775
776 s = wimaxasncp_get_enum_name(tlv_info, value);
777
778 proto_tree_add_uint_format(
779 tree, tlv_info->hf_value,
780 tvb, offset, length, value,
781 "Value: %s (%u)", s, value);
782
783 proto_item_append_text(tlv_item, " - %s", s);
784 }
785
786 return;
787 }
788 case WIMAXASNCP_TLV_ENUM32:
789 {
790 if (length != 4)
791 {
792 /* encoding error */
793 break;
794 }
795
796 if (tree)
797 {
798 uint32_t value;
799 const char *s;
800
801 value = tvb_get_ntohl(tvb, offset);
802
803 s = wimaxasncp_get_enum_name(tlv_info, value);
804
805 proto_tree_add_uint_format(
806 tree, tlv_info->hf_value,
807 tvb, offset, length, value,
808 "Value: %s (%u)", s, value);
809
810 proto_item_append_text(tlv_item, " - %s", s);
811 }
812
813 return;
814 }
815 case WIMAXASNCP_TLV_ETHER:
816 {
817 if (length != 6)
818 {
819 /* encoding error */
820 break;
821 }
822
823 if (tree)
824 {
825 wimaxasncp_proto_tree_add_ether_value(
826 pinfo, tvb, tree, tlv_item, offset, length, tlv_info);
827 }
828
829 return;
830 }
831 case WIMAXASNCP_TLV_ASCII_STRING:
832 {
833 if (tree)
834 {
835 const char *s = tvb_get_string_enc(pinfo->pool, tvb, offset, length, ENC_ASCII0x00000000);
836
837 proto_tree_add_string_format(
838 tree, tlv_info->hf_value,
839 tvb, offset, length, s,
840 "Value: %s", s);
841
842 proto_item_append_text(
843 tlv_item, " - %s", s);
844 }
845
846 return;
847 }
848 case WIMAXASNCP_TLV_FLAG0:
849 {
850 if (length != 0)
851 {
852 /* encoding error */
853 break;
854 }
855
856 return;
857 }
858 case WIMAXASNCP_TLV_BITFLAGS8:
859 {
860 if (length != 1)
861 {
862 /* encoding error */
863 break;
864 }
865
866 if (tree)
867 {
868 proto_tree *flags_tree;
869 proto_item *item;
870 uint8_t value;
871 unsigned i;
872
873 value = tvb_get_uint8(tvb, offset);
874
875 item = proto_tree_add_item(
876 tree, tlv_info->hf_value,
877 tvb, offset, 1, ENC_NA0x00000000);
878
879 proto_item_append_text(tlv_item, " - 0x%02x", value);
880
881 if (value != 0)
882 {
883 flags_tree = proto_item_add_subtree(
884 item, ett_wimaxasncp_tlv_value_bitflags8);
885
886 for (i = 0; i < 8; ++i)
887 {
888 uint8_t mask;
889 mask = 1U << (7 - i);
890
891 if (value & mask)
892 {
893 const char *s;
894
895 s = wimaxasncp_get_enum_name(tlv_info, value & mask);
896
897 proto_tree_add_uint_format(
898 flags_tree, hf_wimaxasncp_tlv_value_bitflags8,
899 tvb, offset, length, value,
900 "Bit #%u is set: %s", i, s);
901 }
902 }
903 }
904 }
905
906 return;
907 }
908 case WIMAXASNCP_TLV_BITFLAGS16:
909 {
910 if (length != 2)
911 {
912 /* encoding error */
913 break;
914 }
915
916 if (tree)
917 {
918 proto_tree *flags_tree;
919 proto_item *item;
920 uint16_t value;
921 unsigned i;
922
923 value = tvb_get_ntohs(tvb, offset);
924
925 item = proto_tree_add_item(
926 tree, tlv_info->hf_value,
927 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
928
929 proto_item_append_text(tlv_item, " - 0x%04x", value);
930
931 if (value != 0)
932 {
933 flags_tree = proto_item_add_subtree(
934 item, ett_wimaxasncp_tlv_value_bitflags16);
935
936 for (i = 0; i < 16; ++i)
937 {
938 uint16_t mask;
939 mask = 1U << (15 - i);
940
941 if (value & mask)
942 {
943 const char *s;
944
945 s = wimaxasncp_get_enum_name(tlv_info, value & mask);
946
947 proto_tree_add_uint_format(
948 flags_tree, hf_wimaxasncp_tlv_value_bitflags16,
949 tvb, offset, length, value,
950 "Bit #%u is set: %s", i, s);
951 }
952 }
953 }
954 }
955
956 return;
957 }
958 case WIMAXASNCP_TLV_BITFLAGS32:
959 {
960 if (length != 4)
961 {
962 /* encoding error */
963 break;
964 }
965
966 if (tree)
967 {
968 proto_tree *flags_tree;
969 proto_item *item;
970 uint32_t value;
971 unsigned i;
972
973 value = tvb_get_ntohl(tvb, offset);
974
975 item = proto_tree_add_item(
976 tree, tlv_info->hf_value,
977 tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
978
979 proto_item_append_text(tlv_item, " - 0x%08x", value);
980
981 if (value != 0)
982 {
983 flags_tree = proto_item_add_subtree(
984 item, ett_wimaxasncp_tlv_value_bitflags32);
985
986 for (i = 0; i < 32; ++i)
987 {
988 uint32_t mask;
989 mask = 1U << (31 - i);
990
991 if (value & mask)
992 {
993 const char *s;
994 s = wimaxasncp_get_enum_name(tlv_info, value & mask);
995
996 proto_tree_add_uint_format(
997 flags_tree, hf_wimaxasncp_tlv_value_bitflags32,
998 tvb, offset, length, value,
999 "Bit #%u is set: %s", i, s);
1000 }
1001 }
1002 }
1003 }
1004
1005 return;
1006 }
1007 case WIMAXASNCP_TLV_ID:
1008 {
1009 if (length == 4)
1010 {
1011 if (tree)
1012 {
1013 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1014 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1015 }
1016
1017 return;
1018 }
1019 else if (length == 6)
1020 {
1021 if (tree)
1022 {
1023 wimaxasncp_proto_tree_add_ether_value(
1024 pinfo, tvb, tree, tlv_item, offset, length, tlv_info);
1025 }
1026
1027 return;
1028 }
1029 else if (length == 16)
1030 {
1031 if (tree)
1032 {
1033 wimaxasncp_proto_tree_add_tlv_ipv6_value(
1034 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1035 }
1036
1037 return;
1038 }
1039 else
1040 {
1041 /* encoding error */
1042 break;
1043 }
1044 }
1045 case WIMAXASNCP_TLV_BYTES:
1046 {
1047 if (tree)
1048 {
1049 proto_tree_add_item(
1050 tree, tlv_info->hf_value,
1051 tvb, offset, length, ENC_NA0x00000000);
1052
1053 if (length) {
1054 const char* format;
1055 if (length <= max_show_bytes)
1056 {
1057 format = " - %s";
1058 }
1059 else
1060 {
1061 format = " - %s...";
1062 }
1063 const char* s = tvb_bytes_to_str_punct(
1064 pinfo->pool, tvb, offset, MIN(length, max_show_bytes)(((length) < (max_show_bytes)) ? (length) : (max_show_bytes
))
, 0);
1065
1066 proto_item_append_text(
1067 tlv_item, format, s);
1068 } else {
1069 proto_item_append_text(tlv_item, " - <MISSING>");
1070 }
1071 }
1072
1073 return;
1074 }
1075 case WIMAXASNCP_TLV_HEX8:
1076 {
1077 if (length != 1)
1078 {
1079 /* encoding error */
1080 break;
1081 }
1082
1083 if (tree)
1084 {
1085 uint8_t value;
1086
1087 value = tvb_get_uint8(tvb, offset);
1088
1089 proto_tree_add_uint_format(
1090 tree, tlv_info->hf_value,
1091 tvb, offset, length, value,
1092 "Value: 0x%02x", value);
1093
1094 proto_item_append_text(tlv_item, " - 0x%02x", value);
1095 }
1096
1097 return;
1098 }
1099 case WIMAXASNCP_TLV_HEX16:
1100 {
1101 if (length != 2)
1102 {
1103 /* encoding error */
1104 break;
1105 }
1106
1107 if (tree)
1108 {
1109 uint16_t value;
1110
1111 value = tvb_get_ntohs(tvb, offset);
1112
1113 proto_tree_add_uint_format(
1114 tree, tlv_info->hf_value,
1115 tvb, offset, length, value,
1116 "Value: 0x%04x", value);
1117
1118 proto_item_append_text(tlv_item, " - 0x%04x", value);
1119 }
1120
1121 return;
1122 }
1123 case WIMAXASNCP_TLV_HEX32:
1124 {
1125 if (length != 4)
1126 {
1127 /* encoding error */
1128 break;
1129 }
1130
1131 if (tree)
1132 {
1133 uint32_t value;
1134
1135 value = tvb_get_ntohl(tvb, offset);
1136
1137 proto_tree_add_uint_format(
1138 tree, tlv_info->hf_value,
1139 tvb, offset, length, value,
1140 "Value: 0x%08x", value);
1141
1142 proto_item_append_text(tlv_item, " - 0x%08x", value);
1143 }
1144
1145 return;
1146 }
1147 case WIMAXASNCP_TLV_DEC8:
1148 {
1149 if (length != 1)
1150 {
1151 /* encoding error */
1152 break;
1153 }
1154
1155 if (tree)
1156 {
1157 uint8_t value;
1158
1159 value = tvb_get_uint8(tvb, offset);
1160
1161 proto_tree_add_uint_format(
1162 tree, tlv_info->hf_value,
1163 tvb, offset, length, value,
1164 "Value: %u", value);
1165
1166 proto_item_append_text(tlv_item, " - %u", value);
1167 }
1168
1169 return;
1170 }
1171 case WIMAXASNCP_TLV_DEC16:
1172 {
1173 if (length != 2)
1174 {
1175 /* encoding error */
1176 break;
1177 }
1178
1179 if (tree)
1180 {
1181 uint16_t value;
1182
1183 value = tvb_get_ntohs(tvb, offset);
1184
1185 proto_tree_add_uint_format(
1186 tree, tlv_info->hf_value,
1187 tvb, offset, length, value,
1188 "Value: %u", value);
1189
1190 proto_item_append_text(tlv_item, " - %u", value);
1191 }
1192
1193 return;
1194 }
1195 case WIMAXASNCP_TLV_DEC32:
1196 {
1197 if (length != 4)
1198 {
1199 /* encoding error */
1200 break;
1201 }
1202
1203 if (tree)
1204 {
1205 uint32_t value;
1206
1207 value = tvb_get_ntohl(tvb, offset);
1208
1209 proto_tree_add_uint_format(
1210 tree, tlv_info->hf_value,
1211 tvb, offset, length, value,
1212 "Value: %u", value);
1213
1214 proto_item_append_text(tlv_item, " - %u", value);
1215 }
1216
1217 return;
1218 }
1219 case WIMAXASNCP_TLV_TBD:
1220 {
1221 if (tree)
1222 {
1223 if (length) {
1224 const char *format;
1225 const char *s = tvb_bytes_to_str_punct(
1226 pinfo->pool, tvb, offset, length, 0);
1227
1228 if (length <= max_show_bytes) {
1229 format = "%s %s";
1230 } else {
1231 format = "%s %s...";
1232 }
1233
1234 proto_tree_add_bytes_format_value(
1235 tree, tlv_info->hf_value,
1236 tvb, offset, length, NULL((void*)0), format, hex_note, s);
1237
1238 } else {
1239 proto_tree_add_bytes_format_value(
1240 tree, tlv_info->hf_value,
1241 tvb, offset, length, NULL((void*)0), "%s", "<MISSING>");
1242 }
1243
1244 proto_item_append_text(tlv_item, " - TBD");
1245 }
1246
1247 return;
1248 }
1249 case WIMAXASNCP_TLV_IP_ADDRESS:
1250 {
1251 if (length == 4)
1252 {
1253 if (tree)
1254 {
1255 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1256 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1257 }
1258
1259 return;
1260 }
1261 else if (length == 16)
1262 {
1263 if (tree)
1264 {
1265 wimaxasncp_proto_tree_add_tlv_ipv6_value(
1266 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1267 }
1268
1269 return;
1270 }
1271 else
1272 {
1273 /* encoding error */
1274 break;
1275 }
1276 }
1277 case WIMAXASNCP_TLV_IPV4_ADDRESS:
1278 {
1279 if (length != 4)
1280 {
1281 /* encoding error */
1282 break;
1283 }
1284
1285 if (tree)
1286 {
1287 wimaxasncp_proto_tree_add_tlv_ipv4_value(
1288 pinfo, tvb, tree, tlv_item, offset, tlv_info);
1289 }
1290
1291 return;
1292 }
1293 case WIMAXASNCP_TLV_PROTOCOL_LIST:
1294 {
1295 if (length % 2 != 0)
1296 {
1297 /* encoding error */
1298 break;
1299 }
1300
1301 if (tree && length > 0)
1302 {
1303 proto_tree *protocol_list_tree;
1304 proto_item *item;
1305 const unsigned max_protocols_in_tlv_item = 8; /* arbitrary */
1306
1307 protocol_list_tree = proto_tree_add_subtree(
1308 tree, tvb, offset, length,
1309 ett_wimaxasncp_tlv_protocol_list, NULL((void*)0), "Value");
1310
1311 /* hidden item for filtering */
1312 item = proto_tree_add_item(
1313 protocol_list_tree, tlv_info->hf_value,
1314 tvb, offset, length, ENC_NA0x00000000);
1315
1316 proto_item_set_hidden(item);
1317
1318 while (offset < tvb_reported_length(tvb))
1319 {
1320 uint16_t protocol;
1321 const char *protocol_name;
1322
1323 protocol = tvb_get_ntohs(tvb, offset);
1324 protocol_name = ipprotostr(protocol);
1325
1326 proto_tree_add_uint_format(
1327 protocol_list_tree, tlv_info->hf_protocol,
1328 tvb, offset, 2, protocol,
1329 "Protocol: %s (%u)", protocol_name, protocol);
1330
1331 if (offset == 0)
1332 {
1333 proto_item_append_text(tlv_item, " - %s", protocol_name);
1334 }
1335 else if (offset < 2 * max_protocols_in_tlv_item)
1336 {
1337 proto_item_append_text(tlv_item, ", %s", protocol_name);
1338 }
1339 else if (offset == 2 * max_protocols_in_tlv_item)
1340 {
1341 proto_item_append_text(tlv_item, ", ...");
1342 }
1343
1344 offset += 2;
1345 }
1346 }
1347
1348 return;
1349 }
1350 case WIMAXASNCP_TLV_PORT_RANGE_LIST:
1351 {
1352 if (length % 4 != 0)
1353 {
1354 /* encoding error */
1355 break;
1356 }
1357
1358 if (tree && length > 0)
1359 {
1360 proto_tree *port_range_list_tree;
1361 proto_item *item;
1362 const unsigned max_port_ranges_in_tlv_item = 3; /* arbitrary */
1363
1364 port_range_list_tree = proto_tree_add_subtree(
1365 tree, tvb, offset, length,
1366 ett_wimaxasncp_tlv_port_range_list, NULL((void*)0), "Value");
1367
1368 /* hidden item for filtering */
1369 item = proto_tree_add_item(
1370 port_range_list_tree, tlv_info->hf_value,
1371 tvb, offset, length, ENC_NA0x00000000);
1372
1373 proto_item_set_hidden(item);
1374
1375 while (offset < tvb_reported_length(tvb))
1376 {
1377 uint16_t portLow;
1378 uint16_t portHigh;
1379 proto_tree* range_tree;
1380
1381 portLow = tvb_get_ntohs(tvb, offset);
1382 portHigh = tvb_get_ntohs(tvb, offset + 2);
1383
1384 range_tree = proto_tree_add_subtree_format(
1385 port_range_list_tree, tvb, offset, 4,
1386 ett_wimaxasncp_port_range, NULL((void*)0), "Port Range: %u-%u", portLow, portHigh);
1387
1388 /* hidden items are for filtering */
1389
1390 item = proto_tree_add_item(
1391 range_tree, tlv_info->hf_port_low,
1392 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
1393
1394 proto_item_set_hidden(item);
1395
1396 item = proto_tree_add_item(
1397 range_tree, tlv_info->hf_port_high,
1398 tvb, offset + 2, 2, ENC_BIG_ENDIAN0x00000000);
1399
1400 proto_item_set_hidden(item);
1401
1402 if (offset == 0)
1403 {
1404 proto_item_append_text(
1405 tlv_item, " - %u-%u", portLow, portHigh);
1406 }
1407 else if (offset < 4 * max_port_ranges_in_tlv_item)
1408 {
1409 proto_item_append_text(
1410 tlv_item, ", %u-%u", portLow, portHigh);
1411 }
1412 else if (offset == 4 * max_port_ranges_in_tlv_item)
1413 {
1414 proto_item_append_text(tlv_item, ", ...");
1415 }
1416
1417 offset += 4;
1418 }
1419 }
1420
1421 return;
1422 }
1423 case WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST:
1424 {
1425 /* --------------------------------------------------------------------
1426 * The definion of these TLVs are ambiguous. The length in octets is
1427 * described as Nx8 (IPv4) or Nx32 (IPv6), but this function cannot
1428 * always differentiate between IPv4 and IPv6. For example, if length
1429 * = 32, then is it IPv4 where N=4 (4x8) or IPv6 where N=1 (1x32)?
1430 *
1431 * For now, we presume lengths that *can* indicate an IPv6 address and
1432 * mask list *do* denote an IPv6 address and mask list.
1433 * --------------------------------------------------------------------
1434 */
1435
1436 if (length % 8 != 0)
1437 {
1438 /* encoding error */
1439 break;
1440 }
1441
1442 if (tree && length > 0)
1443 {
1444 proto_tree *ip_address_mask_list_tree;
1445 proto_item *item;
1446
1447 ip_address_mask_list_tree = proto_tree_add_subtree(
1448 tree, tvb, offset, length,
1449 ett_wimaxasncp_tlv_ip_address_mask_list, NULL((void*)0), "Value");
1450
1451 /* hidden item for filtering */
1452 item = proto_tree_add_item(
1453 ip_address_mask_list_tree, tlv_info->hf_value,
1454 tvb, offset, length, ENC_NA0x00000000);
1455
1456 proto_item_set_hidden(item);
1457
1458 if (length % 32 == 0)
1459 {
1460 /* ------------------------------------------------------------
1461 * presume IPv6
1462 * ------------------------------------------------------------
1463 */
1464
1465 while (offset < tvb_reported_length(tvb))
1466 {
1467 proto_tree *ip_address_mask_tree;
1468
1469 ip_address_mask_tree = proto_tree_add_subtree(
1470 ip_address_mask_list_tree, tvb, offset, 32,
1471 ett_wimaxasncp_tlv_ip_address_mask, NULL((void*)0), "IPv6 Address and Mask");
1472
1473 /* --------------------------------------------------------
1474 * address
1475 * --------------------------------------------------------
1476 */
1477
1478 proto_tree_add_item(
1479 ip_address_mask_tree,
1480 tlv_info->hf_ipv6,
1481 tvb, offset, 16, ENC_NA0x00000000);
1482
1483 /* too long to display ?
1484 proto_item_append_text(
1485 item, " - %s (%s)",
1486 get_hostname6(&ip), ip6_to_str(&ip));
1487 */
1488
1489 offset += 16;
1490
1491 /* --------------------------------------------------------
1492 * mask
1493 * --------------------------------------------------------
1494 */
1495 proto_tree_add_item(
1496 ip_address_mask_tree,
1497 tlv_info->hf_ipv6_mask,
1498 tvb, offset, 16, ENC_NA0x00000000);
1499
1500 /* too long to display ?
1501 proto_item_append_text(
1502 item, " / %s", s);
1503 */
1504
1505 offset += 16;
1506 }
1507 }
1508 else
1509 {
1510 /* ------------------------------------------------------------
1511 * IPv4
1512 * ------------------------------------------------------------
1513 */
1514
1515 while (offset < tvb_reported_length(tvb))
1516 {
1517 proto_tree *ip_address_mask_tree;
1518 uint32_t ip;
1519 const char *s;
1520
1521 ip_address_mask_tree = proto_tree_add_subtree(
1522 ip_address_mask_list_tree, tvb, offset, 8,
1523 ett_wimaxasncp_tlv_ip_address_mask, NULL((void*)0), "IPv4 Address and Mask");
1524
1525 /* --------------------------------------------------------
1526 * address
1527 * --------------------------------------------------------
1528 */
1529
1530 ip = tvb_get_ipv4(tvb, offset);
1531
1532 proto_tree_add_item(
1533 ip_address_mask_tree,
1534 tlv_info->hf_ipv4,
1535 tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
1536
1537 proto_item_append_text(
1538 item, " - %s (%s)",
1539 get_hostname(ip), tvb_ip_to_str(pinfo->pool, tvb, offset)tvb_address_to_str(pinfo->pool, tvb, AT_IPv4, offset));
1540
1541 offset += 4;
1542
1543 /* --------------------------------------------------------
1544 * mask
1545 * --------------------------------------------------------
1546 */
1547
1548 s = tvb_ip_to_str(pinfo->pool, tvb, offset)tvb_address_to_str(pinfo->pool, tvb, AT_IPv4, offset);
1549
1550 proto_tree_add_item(
1551 ip_address_mask_tree,
1552 tlv_info->hf_ipv4_mask,
1553 tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
1554
1555 proto_item_append_text(
1556 item, " / %s", s);
1557
1558 offset += 4;
1559 }
1560 }
1561 }
1562
1563 return;
1564 }
1565 case WIMAXASNCP_TLV_EAP:
1566 {
1567 /*
1568 * EAP payload, call eap dissector to dissect eap payload
1569 */
1570 uint8_t eap_code;
1571 uint8_t eap_type = 0;
1572
1573 /* Get code */
1574 eap_code = tvb_get_uint8(tvb, offset);
1575 if (eap_code == EAP_REQUEST1 || eap_code == EAP_RESPONSE2)
1576 {
1577 /* Get type */
1578 eap_type = tvb_get_uint8(tvb, offset + 4);
1579 }
1580
1581 /* Add code and type to info column */
1582 col_append_str(pinfo->cinfo, COL_INFO, " [");
1583 col_append_str(pinfo->cinfo, COL_INFO,
1584 val_to_str(eap_code, eap_code_vals, "Unknown code (0x%02X)"));
1585
1586 if (eap_code == EAP_REQUEST1 || eap_code == EAP_RESPONSE2)
1587 {
1588 col_append_str(pinfo->cinfo, COL_INFO, ", ");
1589 col_append_str(pinfo->cinfo, COL_INFO,
1590 val_to_str_ext(eap_type, &eap_type_vals_ext, "Unknown type (0x%02X)"));
1591 }
1592
1593 col_append_str(pinfo->cinfo, COL_INFO, "]");
1594
1595
1596 {
1597 proto_tree *eap_tree;
1598 proto_item *item;
1599 bool_Bool save_writable;
1600 tvbuff_t *eap_tvb;
1601
1602 /* Create EAP subtree */
1603 item = proto_tree_add_item(tree, tlv_info->hf_value, tvb,
1604 offset, length, ENC_NA0x00000000);
1605 proto_item_set_text(item, "Value");
1606 eap_tree = proto_item_add_subtree(item, ett_wimaxasncp_tlv_eap);
1607
1608 /* Also show high-level details in this root item */
1609 proto_item_append_text(item, " (%s",
1610 val_to_str(eap_code, eap_code_vals,
1611 "Unknown code (0x%02X)"));
1612 if (eap_code == EAP_REQUEST1 || eap_code == EAP_RESPONSE2)
1613 {
1614 proto_item_append_text(item, ", %s",
1615 val_to_str_ext(eap_type, &eap_type_vals_ext,
1616 "Unknown type (0x%02X)"));
1617 }
1618 proto_item_append_text(item, ")");
1619
1620
1621 /* Extract remaining bytes into new tvb */
1622 eap_tvb = tvb_new_subset_remaining(tvb, offset);
1623
1624 /* Disable writing to info column while calling eap dissector */
1625 save_writable = col_get_writable(pinfo->cinfo, -1);
1626 col_set_writable(pinfo->cinfo, -1, false0);
1627
1628 /* Call the EAP dissector. */
1629 call_dissector(eap_handle, eap_tvb, pinfo, eap_tree);
1630
1631 /* Restore previous writable state of info column */
1632 col_set_writable(pinfo->cinfo, -1, save_writable);
1633 }
1634
1635 return;
1636 }
1637
1638 case WIMAXASNCP_TLV_VENDOR_SPECIFIC:
1639 {
1640 /* --------------------------------------------------------------------
1641 * The format of the vendor specific information field (VSIF) is not
1642 * clearly defined. It appears to be compound as the spec states
1643 * that the vendor ID field shall be the first TLV embedded inside
1644 * the VSIF. However, the vendor ID is shown as a 24-bit value. Does
1645 * this mean the field is 24-bits? If so, how is alignment/padding
1646 * handled?
1647 *
1648 * For now, we decode the vendor ID as a non-padded 24-bit value and
1649 * dump the rest as hex.
1650 * --------------------------------------------------------------------
1651 */
1652
1653 if (length < 3)
1654 {
1655 /* encoding error */
1656 break;
1657 }
1658
1659 if (tree)
1660 {
1661 proto_tree *vsif_tree;
1662 proto_item *item;
1663 uint32_t vendorId;
1664 const char *vendorName;
1665
1666 vsif_tree = proto_tree_add_subtree(
1667 tree, tvb, offset, length,
1668 ett_wimaxasncp_tlv_vendor_specific_information_field, NULL((void*)0), "Value");
1669
1670 /* hidden item for filtering */
1671 item = proto_tree_add_item(
1672 vsif_tree, tlv_info->hf_value,
1673 tvb, offset, length, ENC_NA0x00000000);
1674
1675 proto_item_set_hidden(item);
1676
1677 /* ----------------------------------------------------------------
1678 * vendor ID (24-bit)
1679 * ----------------------------------------------------------------
1680 */
1681
1682 vendorId = tvb_get_ntoh24(tvb, offset);
1683
1684 vendorName = enterprises_lookup(vendorId, "Unknown");
1685 proto_tree_add_uint_format(
1686 vsif_tree, tlv_info->hf_vendor_id,
1687 tvb, offset, 3, vendorId,
1688 "Vendor ID: %s (%u)", vendorName, vendorId);
1689
1690 proto_item_append_text(tlv_item, " - %s", vendorName);
1691
1692 offset += 3;
1693
1694 /* ----------------------------------------------------------------
1695 * hex dump the rest
1696 * ----------------------------------------------------------------
1697 */
1698
1699 if (offset < tvb_reported_length(tvb))
1700 {
1701 proto_tree_add_item(
1702 vsif_tree, tlv_info->hf_vendor_rest_of_info,
1703 tvb, offset, length - offset, ENC_NA0x00000000);
1704 }
1705 }
1706
1707 return;
1708 }
1709 case WIMAXASNCP_TLV_UNKNOWN:
1710 {
1711 if (tree)
1712 {
1713 const char* s;
1714 if (length) {
1715 const char* format1;
1716 const char* format2;
1717 if (length <= max_show_bytes)
1718 {
1719 format1 = "%s %s";
1720 format2 = " - %s %s";
1721 }
1722 else
1723 {
1724 format1 = "%s %s...";
1725 format2 = " - %s %s...";
1726 }
1727 s = tvb_bytes_to_str_punct(
1728 pinfo->pool, tvb, offset, MIN(length, max_show_bytes)(((length) < (max_show_bytes)) ? (length) : (max_show_bytes
))
, 0);
1729
1730 proto_tree_add_bytes_format_value(
1731 tree, tlv_info->hf_value,
1732 tvb, offset, length, NULL((void*)0), format1, hex_note, s);
1733
1734 proto_item_append_text(
1735 tlv_item, format2, hex_note, s);
1736 }
1737 else {
1738 proto_tree_add_bytes_format_value(
1739 tree, tlv_info->hf_value,
1740 tvb, offset, length, NULL((void*)0), "%s", "<MISSING>");
1741
1742 proto_item_append_text(tlv_item, " - <MISSING>");
1743 }
1744
1745 }
1746
1747 return;
1748 }
1749 default:
1750 proto_tree_add_expert_format(tree, pinfo, &ei_wimaxasncp_decoder, tvb, offset, length, "Unknown decoder %d", tlv_info->decoder);
1751 break;
1752 }
1753
1754 /* default is hex dump */
1755
1756 if (tree)
1757 {
1758 if (length) {
1759 const char* format;
1760 const char *s = tvb_bytes_to_str_punct(
1761 pinfo->pool, tvb, offset, MIN(length, max_show_bytes)(((length) < (max_show_bytes)) ? (length) : (max_show_bytes
))
, 0);
1762
1763 if (length <= max_show_bytes) {
1764 format = "%s %s";
1765 } else {
1766 format = "%s %s...";
1767 }
1768
1769 proto_tree_add_bytes_format_value(
1770 tree, hf_wimaxasncp_tlv_value_bytes,
1771 tvb, offset, length, NULL((void*)0),
1772 format, hex_note, s);
1773 } else {
1774 proto_tree_add_bytes_format_value(
1775 tree, hf_wimaxasncp_tlv_value_bytes,
1776 tvb, offset, length, NULL((void*)0),
1777 "%s", "<MISSING>");
1778 }
1779 }
1780}
1781
1782/* ========================================================================= */
1783
1784// NOLINTNEXTLINE(misc-no-recursion)
1785static unsigned dissect_wimaxasncp_tlvs(
1786 tvbuff_t *tvb,
1787 packet_info *pinfo,
1788 proto_tree *tree)
1789{
1790 unsigned offset;
1791
1792 offset = 0;
1793 while (offset < tvb_reported_length(tvb))
1794 {
1795 const wimaxasncp_tlv_new_t* tlv_info;
1796
1797 proto_tree *tlv_tree;
1798 proto_item *tlv_item;
1799 uint16_t type;
1800 uint16_t length;
1801 unsigned pad;
1802
1803 /* --------------------------------------------------------------------
1804 * type and length
1805 * --------------------------------------------------------------------
1806 */
1807
1808 type = tvb_get_ntohs(tvb, offset);
1809 tlv_info = wimaxasncp_get_tlv_info(type);
1810
1811 length = tvb_get_ntohs(tvb, offset + 2);
1812#if 0 /* Commented out padding; As there is no mention of padding in
1813 the Latest specification */
1814 pad = WS_PADDING_TO_4(length)((4U - ((length) % 4U)) % 4U);
1815#endif
1816 pad = 0;
1817 {
1818 proto_item *type_item;
1819
1820 int tree_length = MIN(((((int)(4 + length + pad)) < (tvb_captured_length_remaining
(tvb, offset))) ? ((int)(4 + length + pad)) : (tvb_captured_length_remaining
(tvb, offset)))
1821 (int)(4 + length + pad), tvb_captured_length_remaining(tvb, offset))((((int)(4 + length + pad)) < (tvb_captured_length_remaining
(tvb, offset))) ? ((int)(4 + length + pad)) : (tvb_captured_length_remaining
(tvb, offset)))
;
1822
1823 tlv_item = proto_tree_add_item(
1824 tree, tlv_info->hf_root,
1825 tvb, offset, tree_length, ENC_NA0x00000000);
1826
1827 /* Set label for tlv item */
1828 proto_item_set_text(tlv_item, "TLV: %s", tlv_info->name);
1829
1830 /* Show code number if unknown */
1831 if (tlv_info->decoder == WIMAXASNCP_TLV_UNKNOWN)
1832 {
1833 proto_item_append_text(tlv_item, " (%u)", type);
1834 }
1835
1836 /* Indicate if a compound tlv */
1837 if (tlv_info->decoder == WIMAXASNCP_TLV_COMPOUND)
1838 {
1839 proto_item_append_text(tlv_item, " [Compound]");
1840 }
1841
1842 /* Create TLV subtree */
1843 tlv_tree = proto_item_add_subtree(
1844 tlv_item, ett_wimaxasncp_tlv);
1845
1846 /* Type (expert item if unknown) */
1847 type_item = proto_tree_add_uint_format(
1848 tlv_tree, hf_wimaxasncp_tlv_type,
1849 tvb, offset, 2, type,
1850 "Type: %s (%u)", tlv_info->name, type);
1851
1852 if (tlv_info->decoder == WIMAXASNCP_TLV_UNKNOWN)
1853 {
1854 expert_add_info_format(pinfo, type_item, &ei_wimaxasncp_tlv_type,
1855 "Unknown TLV type (%u)",
1856 type);
1857 }
1858
1859 /* Length */
1860 proto_tree_add_uint(
1861 tlv_tree, hf_wimaxasncp_tlv_length,
1862 tvb, offset + 2, 2, length);
1863
1864 }
1865
1866 offset += 4;
1867
1868 /* --------------------------------------------------------------------
1869 * value
1870 * --------------------------------------------------------------------
1871 */
1872
1873 if (tlv_info->decoder == WIMAXASNCP_TLV_COMPOUND)
1874 {
1875 if (length == 0)
1876 {
1877 /* error? compound, but no TLVs inside */
1878 }
1879 else if (tvb_reported_length_remaining(tvb, offset) > 0)
1880 {
1881 tvbuff_t *tlv_tvb;
1882
1883 /* N.B. Not padding out tvb length */
1884 tlv_tvb = tvb_new_subset_length_caplen(
1885 tvb, offset,
1886 MIN(length, tvb_captured_length_remaining(tvb, offset))(((length) < (tvb_captured_length_remaining(tvb, offset)))
? (length) : (tvb_captured_length_remaining(tvb, offset)))
,
1887 length);
1888
1889 increment_dissection_depth(pinfo);
1890 dissect_wimaxasncp_tlvs(tlv_tvb, pinfo, tlv_tree);
1891 decrement_dissection_depth(pinfo);
1892 }
1893 else
1894 {
1895 /* this should throw */
1896 tvb_ensure_bytes_exist(tvb, offset, length + pad);
1897 }
1898 }
1899 else
1900 {
1901 tvbuff_t *tlv_tvb;
1902
1903 tvb_ensure_bytes_exist(tvb, offset, length + pad);
1904
1905 tlv_tvb = tvb_new_subset_length_caplen(
1906 tvb, offset,
1907 MIN(length, tvb_captured_length_remaining(tvb, offset))(((length) < (tvb_captured_length_remaining(tvb, offset)))
? (length) : (tvb_captured_length_remaining(tvb, offset)))
,
1908 length);
1909
1910 wimaxasncp_dissect_tlv_value(
1911 tlv_tvb, pinfo, tlv_tree, tlv_item, tlv_info);
1912 }
1913
1914 offset += length + pad;
1915 }
1916
1917 return offset;
1918}
1919
1920/* ========================================================================= */
1921
1922static unsigned dissect_wimaxasncp_backend(
1923 tvbuff_t *tvb,
1924 packet_info *pinfo,
1925 proto_tree *tree)
1926{
1927 unsigned offset = 0;
1928 uint16_t ui16;
1929 uint32_t ui32;
1930 const uint8_t *pmsid;
1931 uint16_t tid = 0;
1932 bool_Bool dbit_show;
1933
1934
1935 /* ------------------------------------------------------------------------
1936 * MSID
1937 * ------------------------------------------------------------------------
1938 */
1939
1940 if (tree)
1941 {
1942 proto_tree_add_item(
1943 tree, hf_wimaxasncp_msid,
1944 tvb, offset, 6, ENC_NA0x00000000);
1945 }
1946 pmsid = tvb_ether_to_str(pinfo->pool, tvb, offset)tvb_address_to_str(pinfo->pool, tvb, AT_ETHER, offset);
1947
1948 offset += 6;
1949
1950 /* ------------------------------------------------------------------------
1951 * reserved
1952 * ------------------------------------------------------------------------
1953 */
1954
1955 ui32 = tvb_get_ntohl(tvb, offset);
1956
1957 if (tree)
1958 {
1959 proto_tree_add_uint(
1960 tree, hf_wimaxasncp_reserved1,
1961 tvb, offset, 4, ui32);
1962 }
1963
1964 offset += 4;
1965
1966 /* ------------------------------------------------------------------------
1967 * transaction ID
1968 * ------------------------------------------------------------------------
1969 */
1970
1971 dbit_show = false0;
1972 ui16 = tvb_get_ntohs(tvb, offset);
1973
1974 if (show_transaction_id_d_bit)
1975 {
1976 const uint16_t mask = 0x7fff;
1977
1978 if (ui16 & 0x8000)
1979 {
1980 proto_tree_add_uint_format_value(
1981 tree, hf_wimaxasncp_transaction_id,
1982 tvb, offset, 2, ui16,
1983 "D + 0x%04x (0x%04x)", mask & ui16, ui16);
1984
1985 tid = ui16 & mask;
1986 dbit_show = true1;
1987 }
1988 else
1989 {
1990 proto_tree_add_uint(tree, hf_wimaxasncp_transaction_id, tvb, offset, 2, ui16);
1991 tid = ui16;
1992 }
1993 }
1994 else
1995 {
1996 proto_tree_add_uint(
1997 tree, hf_wimaxasncp_transaction_id,
1998 tvb, offset, 2, ui16);
1999
2000 tid = ui16;
2001 }
2002
2003 offset += 2;
2004
2005 /* ------------------------------------------------------------------------
2006 * reserved
2007 * ------------------------------------------------------------------------
2008 */
2009 proto_tree_add_item(tree, hf_wimaxasncp_reserved2, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
2010 offset += 2;
2011
2012 /* ------------------------------------------------------------------------
2013 * TLVs
2014 * ------------------------------------------------------------------------
2015 */
2016
2017 if (tvb_reported_length_remaining(tvb, offset) > 0)
2018 {
2019 tvbuff_t *tlv_tvb;
2020
2021 tlv_tvb = tvb_new_subset_remaining(tvb, offset);
2022
2023 offset += dissect_wimaxasncp_tlvs(tlv_tvb, pinfo, tree);
2024 }
2025
2026 col_append_fstr(pinfo->cinfo, COL_INFO, " - MSID:%s", pmsid);
2027 if (dbit_show)
2028 {
2029 col_append_fstr(pinfo->cinfo, COL_INFO, ", TID:D+0x%04x", tid);
2030 }
2031 else
2032 {
2033 col_append_fstr(pinfo->cinfo, COL_INFO, ", TID:0x%04x", tid);
2034 }
2035
2036 return offset;
2037}
2038
2039/* ========================================================================= */
2040
2041
2042static const char*
2043match_ver_value_string(
2044 const uint32_t val,
2045 const ver_value_string* const strings,
2046 const uint32_t max_ver)
2047{
2048 const ver_value_string* vvs;
2049 const ver_value_string* res = NULL((void*)0);
2050
2051 /* loop on the levels, from max to 0 */
2052 for(vvs=strings; vvs->vs.strptr; vvs++)
2053 {
2054 if ((vvs->vs.value == val) && (vvs->since <= max_ver))
2055 {
2056 if (!res || (vvs->since > res->since))
2057 {
2058 res = vvs;
2059 }
2060 }
2061 }
2062
2063 return res? res->vs.strptr : NULL((void*)0);
2064}
2065
2066static int
2067dissect_wimaxasncp(
2068 tvbuff_t *tvb,
2069 packet_info *pinfo,
2070 proto_tree *tree,
2071 void *data _U___attribute__((unused)))
2072{
2073 static const char unknown[] = "Unknown";
2074
2075 /* Set up structures needed to add the protocol subtree and manage it */
2076 proto_item *packet_item = NULL((void*)0);
2077 proto_item *item = NULL((void*)0);
2078 proto_tree *wimaxasncp_tree = NULL((void*)0);
2079 tvbuff_t *subtree_tvb;
2080
2081 unsigned offset;
2082 uint8_t ui8;
2083
2084 uint8_t function_type;
2085 const char *function_type_name;
2086 proto_item *function_type_item;
2087 uint32_t length;
2088
2089 const wimaxasncp_func_msg_t *p = NULL((void*)0);
2090 const char *message_name;
2091 size_t i;
2092
2093 /* ------------------------------------------------------------------------
2094 * First, we do some heuristics to check if the packet cannot be our
2095 * protocol.
2096 * ------------------------------------------------------------------------
2097 */
2098
2099 /* Should we check a minimum size? If so, uncomment out the following
2100 * code. */
2101#if 0
2102 if (tvb_reported_length(tvb) < WIMAXASNCP_HEADER_SIZE20)
2103 {
2104 return 0;
2105 }
2106#endif
2107
2108 /* We currently only support version 1. */
2109 if (tvb_bytes_exist(tvb, 0, 1) && tvb_get_uint8(tvb, 0) != 1)
2110 {
2111 return 0;
2112 }
2113
2114 /* ------------------------------------------------------------------------
2115 * Initialize the protocol and info column.
2116 * ------------------------------------------------------------------------
2117 */
2118
2119 /* Make entries in Protocol column and Info column on summary display */
2120 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WiMAX");
2121
2122 /* We'll fill in the "Info" column after fetch data, so we clear the
2123 column first in case calls to fetch data from the packet throw an
2124 exception. */
2125 col_clear(pinfo->cinfo, COL_INFO);
2126
2127 /* ========================================================================
2128 * Disesction starts here
2129 * ========================================================================
2130 */
2131
2132 /* ------------------------------------------------------------------------
2133 * total packet, we'll adjust after we read the length field
2134 * ------------------------------------------------------------------------
2135 */
2136
2137 offset = 0;
2138
2139 /* Register protocol fields, etc if haven't done yet. */
2140 if (hf_wimaxasncp_version <= 0)
2141 {
2142 proto_registrar_get_byname("wimaxasncp.version");
2143 }
2144
2145 if (tree)
2146 {
2147 packet_item = proto_tree_add_item(
2148 tree, proto_wimaxasncp,
2149 tvb, 0, MIN(WIMAXASNCP_HEADER_LENGTH_END, tvb_captured_length(tvb))(((6) < (tvb_captured_length(tvb))) ? (6) : (tvb_captured_length
(tvb)))
, ENC_NA0x00000000);
2150
2151 wimaxasncp_tree = proto_item_add_subtree(
2152 packet_item, ett_wimaxasncp);
2153 }
2154
2155 /* ------------------------------------------------------------------------
2156 * version
2157 * ------------------------------------------------------------------------
2158 */
2159
2160 if (tree)
2161 {
2162 proto_tree_add_item(
2163 wimaxasncp_tree, hf_wimaxasncp_version,
2164 tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
2165 }
2166
2167 offset += 1;
2168
2169 /* ------------------------------------------------------------------------
2170 * flags
2171 * ------------------------------------------------------------------------
2172 */
2173 proto_tree_add_bitmask(wimaxasncp_tree, tvb, offset, hf_wimaxasncp_flags, ett_wimaxasncp_flags, hf_wimaxasncp_flag_fields, ENC_NA0x00000000);
2174 offset += 1;
2175
2176 /* ------------------------------------------------------------------------
2177 * function type
2178 * ------------------------------------------------------------------------
2179 */
2180
2181 function_type = tvb_get_uint8(tvb, offset);
2182
2183 function_type_name = match_ver_value_string(function_type,
2184 wimaxasncp_function_type_vals,
2185 global_wimaxasncp_nwg_ver);
2186
2187 if (function_type_name)
2188 {
2189 /* add the item to the tree */
2190 proto_tree_add_uint_format(
2191 wimaxasncp_tree, hf_wimaxasncp_function_type,
2192 tvb, offset, 1, function_type,
2193 "%s (%u)", function_type_name, function_type);
2194 }
2195 else
2196 {
2197 /* if not matched, add the item and append expert item */
2198 function_type_item = proto_tree_add_uint_format(
2199 wimaxasncp_tree, hf_wimaxasncp_function_type,
2200 tvb, offset, 1, function_type,
2201 "Unknown (%u)", function_type);
2202
2203 expert_add_info_format(pinfo, function_type_item,
2204 &ei_wimaxasncp_function_type,
2205 "Unknown function type (%u)",
2206 function_type);
2207 }
2208
2209 offset += 1;
2210
2211 /* ------------------------------------------------------------------------
2212 * OP ID and message type
2213 * ------------------------------------------------------------------------
2214 */
2215
2216 ui8 = tvb_get_uint8(tvb, offset);
2217
2218
2219 /* --------------------------------------------------------------------
2220 * OP ID
2221 * --------------------------------------------------------------------
2222 */
2223
2224 item = proto_tree_add_item(wimaxasncp_tree, hf_wimaxasncp_op_id, tvb, offset, 1, ENC_NA0x00000000);
Value stored to 'item' is never read
2225
2226 /* use the function type to find the message vals */
2227 for (i = 0; i < array_length(wimaxasncp_func_to_msg_vals_map)(sizeof (wimaxasncp_func_to_msg_vals_map) / sizeof (wimaxasncp_func_to_msg_vals_map
)[0])
; ++i)
2228 {
2229 p = &wimaxasncp_func_to_msg_vals_map[i];
2230
2231 if (function_type == p->function_type)
2232 {
2233 break;
2234 }
2235 }
2236
2237 /* --------------------------------------------------------------------
2238 * message type
2239 * --------------------------------------------------------------------
2240 */
2241
2242 message_name = p ? match_ver_value_string(0x1f & ui8, p->vals, global_wimaxasncp_nwg_ver) : unknown;
2243 if (message_name == NULL((void*)0))
2244 {
2245 message_name = unknown;
2246 }
2247
2248 item = proto_tree_add_uint_format_value(
2249 wimaxasncp_tree, hf_wimaxasncp_message_type,
2250 tvb, offset, 1, ui8,
2251 "%s", message_name);
2252
2253 proto_item_append_text(item, " (%u)", ui8 & 0x1F);
2254
2255 /* Add expert item if not matched */
2256 if (strcmp(message_name, unknown) == 0)
2257 {
2258 expert_add_info_format(pinfo, item, &ei_wimaxasncp_message_type,
2259 "Unknown message type (%u)",
2260 0x1f & ui8);
2261 }
2262
2263 col_add_str(pinfo->cinfo, COL_INFO, message_name);
2264 offset += 1;
2265
2266 /* ------------------------------------------------------------------------
2267 * length
2268 * ------------------------------------------------------------------------
2269 */
2270
2271 item = proto_tree_add_item_ret_uint(
2272 wimaxasncp_tree, hf_wimaxasncp_length,
2273 tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &length);
2274
2275 proto_item_set_len(packet_item, MAX(WIMAXASNCP_HEADER_LENGTH_END, length)(((6) > (length)) ? (6) : (length)));
2276 offset += 2;
2277
2278 if (length < WIMAXASNCP_HEADER_SIZE20)
2279 {
2280 expert_add_info_format(pinfo, item, &ei_wimaxasncp_length_bad, "specified length (%u) less than header size (20)", length);
2281 if (length <= WIMAXASNCP_HEADER_LENGTH_END6)
2282 return offset;
2283 }
2284
2285 /* ------------------------------------------------------------------------
2286 * remaining header fields and TLVs
2287 * ------------------------------------------------------------------------
2288 */
2289
2290 subtree_tvb = tvb_new_subset_length_caplen(
2291 tvb, offset,
2292 MIN((int)length, tvb_captured_length_remaining(tvb, offset))((((int)length) < (tvb_captured_length_remaining(tvb, offset
))) ? ((int)length) : (tvb_captured_length_remaining(tvb, offset
)))
,
2293 length - WIMAXASNCP_HEADER_LENGTH_END6);
2294
2295 offset += dissect_wimaxasncp_backend(
2296 subtree_tvb, pinfo, wimaxasncp_tree);
2297
2298 /* ------------------------------------------------------------------------
2299 * done, return the amount of data this dissector was able to dissect
2300 * ------------------------------------------------------------------------
2301 */
2302
2303 return offset;
2304}
2305
2306/* ========================================================================= */
2307/* Modify the given string to make a suitable display filter */
2308static char *alnumerize(
2309 char *name)
2310{
2311 char *r = name; /* read pointer */
2312 char *w = name; /* write pointer */
2313 char c;
2314
2315 for ( ; (c = *r); ++r)
2316 {
2317 if (g_ascii_isalnum(c)((g_ascii_table[(guchar) (c)] & G_ASCII_ALNUM) != 0) || c == '_' || c == '.')
2318 {
2319 /* These characters are fine - copy them */
2320 *(w++) = c;
2321 }
2322 else if (c == ' ' || c == '-' || c == '/')
2323 {
2324 /* Skip these others if haven't written any characters out yet */
2325 if (w == name)
2326 {
2327 continue;
2328 }
2329
2330 /* Skip if we would produce multiple adjacent '_'s */
2331 if (*(w - 1) == '_')
2332 {
2333 continue;
2334 }
2335
2336 /* OK, replace with underscore */
2337 *(w++) = '_';
2338 }
2339
2340 /* Other undesirable characters are just skipped */
2341 }
2342
2343 /* Terminate and return modified string */
2344 *w = '\0';
2345 return name;
2346}
2347
2348/* ========================================================================= */
2349
2350static void add_reg_info(
2351 int *hf_ptr,
2352 const char *name,
2353 const char *abbrev,
2354 enum ftenum type,
2355 int display,
2356 const char *blurb)
2357{
2358 hf_register_info hf = {
2359 hf_ptr, { name, abbrev, type, display, NULL((void*)0), 0x0, blurb, HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } };
2360
2361 wmem_array_append_one(wimaxasncp_build_dict.hf, hf)wmem_array_append((wimaxasncp_build_dict.hf), &(hf), 1);
2362}
2363
2364/* ========================================================================= */
2365
2366static void add_tlv_reg_info(wimaxasncp_tlv_new_t* tlv)
2367{
2368 char *name;
2369 char *abbrev;
2370 const char *root_blurb;
2371 char *blurb;
2372
2373 /* ------------------------------------------------------------------------
2374 * add root reg info
2375 * ------------------------------------------------------------------------
2376 */
2377
2378 name = wmem_strdup(wmem_epan_scope(), tlv->name);
2379 abbrev = alnumerize(wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s", tlv->name));
2380
2381 switch (tlv->decoder)
2382 {
2383 case WIMAXASNCP_TLV_UNKNOWN:
2384 root_blurb = "type=Unknown";
2385 break;
2386 case WIMAXASNCP_TLV_TBD:
2387 root_blurb = wmem_strdup_printf(wmem_epan_scope(), "type=%u, TBD", tlv->type);
2388 break;
2389 case WIMAXASNCP_TLV_COMPOUND:
2390 root_blurb = wmem_strdup_printf(wmem_epan_scope(), "type=%u, Compound", tlv->type);
2391 break;
2392 case WIMAXASNCP_TLV_FLAG0:
2393 root_blurb = wmem_strdup_printf(wmem_epan_scope(), "type=%u, Value = Null", tlv->type);
2394 break;
2395 default:
2396 root_blurb = wmem_strdup_printf(wmem_epan_scope(), "type=%u", tlv->type);
2397 break;
2398 }
2399
2400 add_reg_info(
2401 &tlv->hf_root, name, abbrev, FT_BYTES, BASE_NONE, root_blurb);
2402
2403 /* ------------------------------------------------------------------------
2404 * add value(s) reg info
2405 * ------------------------------------------------------------------------
2406 */
2407
2408 name = wmem_strdup(wmem_epan_scope(), "Value");
2409 abbrev = alnumerize(wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value", tlv->name));
2410 blurb = wmem_strdup_printf(wmem_epan_scope(), "value for type=%u", tlv->type);
2411
2412 switch (tlv->decoder)
2413 {
2414 case WIMAXASNCP_TLV_UNKNOWN:
2415 wmem_free(wmem_epan_scope(), blurb);
2416
2417 add_reg_info(
2418 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE,
2419 "value for unknown type");
2420 break;
2421
2422 case WIMAXASNCP_TLV_TBD:
2423 add_reg_info(
2424 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2425 break;
2426
2427 case WIMAXASNCP_TLV_COMPOUND:
2428 case WIMAXASNCP_TLV_FLAG0:
2429 wmem_free(wmem_epan_scope(), name);
2430 wmem_free(wmem_epan_scope(), abbrev);
2431 wmem_free(wmem_epan_scope(), blurb);
2432 break;
2433
2434 case WIMAXASNCP_TLV_BYTES:
2435 add_reg_info(
2436 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2437 break;
2438
2439 case WIMAXASNCP_TLV_ENUM8:
2440 add_reg_info(
2441 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_DEC, blurb);
2442 break;
2443
2444 case WIMAXASNCP_TLV_ENUM16:
2445 add_reg_info(
2446 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2447 break;
2448
2449 case WIMAXASNCP_TLV_ENUM32:
2450 add_reg_info(
2451 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_DEC, blurb);
2452 break;
2453
2454 case WIMAXASNCP_TLV_ETHER:
2455 add_reg_info(
2456 &tlv->hf_value, name, abbrev, FT_ETHER, BASE_NONE, blurb);
2457 break;
2458
2459 case WIMAXASNCP_TLV_ASCII_STRING:
2460 add_reg_info(
2461 &tlv->hf_value, name, abbrev, FT_STRING, BASE_NONE, blurb);
2462 break;
2463
2464 case WIMAXASNCP_TLV_BITFLAGS8:
2465 add_reg_info(
2466 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_HEX, blurb);
2467 break;
2468
2469 case WIMAXASNCP_TLV_BITFLAGS16:
2470 add_reg_info(
2471 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_HEX, blurb);
2472 break;
2473
2474 case WIMAXASNCP_TLV_BITFLAGS32:
2475 add_reg_info(
2476 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_HEX, blurb);
2477 break;
2478
2479 case WIMAXASNCP_TLV_ID:
2480 wmem_free(wmem_epan_scope(), abbrev);
2481
2482 abbrev = alnumerize(
2483 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.ipv4_value", tlv->name));
2484
2485 add_reg_info(
2486 &tlv->hf_ipv4, "IPv4 Address", abbrev, FT_IPv4, BASE_NONE, blurb);
2487
2488 abbrev = alnumerize(
2489 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.ipv6_value", tlv->name));
2490
2491 add_reg_info(
2492 &tlv->hf_ipv6, "IPv6 Address", abbrev, FT_IPv6, BASE_NONE, blurb);
2493
2494 abbrev = alnumerize(
2495 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.bsid_value", tlv->name));
2496
2497 add_reg_info(
2498 &tlv->hf_bsid, "BS ID", abbrev, FT_ETHER, BASE_NONE, blurb);
2499
2500 break;
2501
2502 case WIMAXASNCP_TLV_HEX8:
2503 add_reg_info(
2504 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_HEX, blurb);
2505 break;
2506
2507 case WIMAXASNCP_TLV_HEX16:
2508 add_reg_info(
2509 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_HEX, blurb);
2510 break;
2511
2512 case WIMAXASNCP_TLV_HEX32:
2513 add_reg_info(
2514 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_HEX, blurb);
2515 break;
2516
2517 case WIMAXASNCP_TLV_DEC8:
2518 add_reg_info(
2519 &tlv->hf_value, name, abbrev, FT_UINT8, BASE_DEC, blurb);
2520 break;
2521
2522 case WIMAXASNCP_TLV_DEC16:
2523 add_reg_info(
2524 &tlv->hf_value, name, abbrev, FT_UINT16, BASE_DEC, blurb);
2525 break;
2526
2527 case WIMAXASNCP_TLV_DEC32:
2528 add_reg_info(
2529 &tlv->hf_value, name, abbrev, FT_UINT32, BASE_DEC, blurb);
2530 break;
2531
2532 case WIMAXASNCP_TLV_IP_ADDRESS:
2533 wmem_free(wmem_epan_scope(), abbrev);
2534
2535 abbrev = alnumerize(
2536 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.ipv4_value", tlv->name));
2537
2538 add_reg_info(
2539 &tlv->hf_ipv4, "IPv4 Address", abbrev, FT_IPv4, BASE_NONE, blurb);
2540
2541 abbrev = alnumerize(
2542 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.ipv6_value", tlv->name));
2543
2544 add_reg_info(
2545 &tlv->hf_ipv6, "IPv6 Address", abbrev, FT_IPv6, BASE_NONE, blurb);
2546
2547 break;
2548
2549 case WIMAXASNCP_TLV_IPV4_ADDRESS:
2550 add_reg_info(
2551 &tlv->hf_value, name, abbrev, FT_IPv4, BASE_NONE, blurb);
2552 break;
2553
2554 case WIMAXASNCP_TLV_PROTOCOL_LIST:
2555 add_reg_info(
2556 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2557
2558 blurb = wmem_strdup_printf(wmem_epan_scope(), "value component for type=%u", tlv->type);
2559
2560 abbrev = alnumerize(
2561 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.protocol", tlv->name));
2562
2563 add_reg_info(
2564 &tlv->hf_protocol, "Protocol", abbrev, FT_UINT16, BASE_DEC, blurb);
2565
2566 break;
2567
2568 case WIMAXASNCP_TLV_PORT_RANGE_LIST:
2569 add_reg_info(
2570 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2571
2572 blurb = wmem_strdup_printf(wmem_epan_scope(), "value component for type=%u", tlv->type);
2573
2574 abbrev = alnumerize(
2575 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.port_low", tlv->name));
2576
2577 add_reg_info(
2578 &tlv->hf_port_low, "Port Low", abbrev, FT_UINT16, BASE_DEC, blurb);
2579
2580 abbrev = alnumerize(
2581 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.port_high", tlv->name));
2582
2583 add_reg_info(
2584 &tlv->hf_port_high, "Port High", abbrev, FT_UINT16, BASE_DEC, blurb);
2585
2586 break;
2587
2588 case WIMAXASNCP_TLV_IP_ADDRESS_MASK_LIST:
2589 add_reg_info(
2590 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2591
2592 blurb = wmem_strdup_printf(wmem_epan_scope(), "value component for type=%u", tlv->type);
2593
2594 abbrev = alnumerize(
2595 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.ipv4", tlv->name));
2596
2597 add_reg_info(
2598 &tlv->hf_ipv4, "IPv4 Address", abbrev, FT_IPv4, BASE_NONE, blurb);
2599
2600 abbrev = alnumerize(
2601 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.ipv4_mask", tlv->name));
2602
2603 add_reg_info(
2604 &tlv->hf_ipv4_mask, "IPv4 Mask", abbrev, FT_IPv4, BASE_NONE, blurb);
2605
2606 abbrev = alnumerize(
2607 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.ipv6", tlv->name));
2608
2609 add_reg_info(
2610 &tlv->hf_ipv6, "IPv6 Address", abbrev, FT_IPv6, BASE_NONE, blurb);
2611
2612 abbrev = alnumerize(
2613 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.ipv6_mask", tlv->name));
2614
2615 add_reg_info(
2616 &tlv->hf_ipv6_mask, "IPv6 Mask", abbrev, FT_IPv6, BASE_NONE, blurb);
2617
2618 break;
2619
2620 case WIMAXASNCP_TLV_VENDOR_SPECIFIC:
2621 add_reg_info(
2622 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2623
2624 blurb = wmem_strdup_printf(wmem_epan_scope(), "value component for type=%u", tlv->type);
2625
2626 abbrev = alnumerize(
2627 wmem_strdup_printf(wmem_epan_scope(), "wimaxasncp.tlv.%s.value.vendor_id", tlv->name));
2628
2629 add_reg_info(
2630 &tlv->hf_vendor_id, "Vendor ID", abbrev, FT_UINT24, BASE_DEC, blurb);
2631
2632 abbrev = alnumerize(
2633 wmem_strdup_printf(wmem_epan_scope(),
2634 "wimaxasncp.tlv.%s.value.vendor_rest_of_info", tlv->name));
2635
2636 add_reg_info(
2637 &tlv->hf_vendor_rest_of_info, "Rest of Info", abbrev, FT_BYTES, BASE_NONE,
2638 blurb);
2639
2640 break;
2641
2642 case WIMAXASNCP_TLV_EAP:
2643 blurb = wmem_strdup_printf(wmem_epan_scope(), "EAP payload embedded in %s", name);
2644
2645 add_reg_info(
2646 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2647 break;
2648
2649
2650 default:
2651 add_reg_info(
2652 &tlv->hf_value, name, abbrev, FT_BYTES, BASE_NONE, blurb);
2653
2654 report_warning("WiMax: unknown decoder: %d\n", tlv->decoder);
2655 break;
2656 }
2657}
2658
2659static int wimaxasncp_decode_type(const char* name)
2660{
2661 size_t i;
2662 for (i = 0; i < array_length(wimaxasncp_decode_type_vals)(sizeof (wimaxasncp_decode_type_vals) / sizeof (wimaxasncp_decode_type_vals
)[0])
- 1; ++i)
2663 {
2664 if (strcmp(name, wimaxasncp_decode_type_vals[i].strptr) == 0)
2665 {
2666 return wimaxasncp_decode_type_vals[i].value;
2667 }
2668 }
2669
2670 /* not found, emit some sort of error here? */
2671
2672 return WIMAXASNCP_TLV_TBD;
2673}
2674
2675typedef struct wimaxasncp_dict_tlv_enum
2676{
2677 xmlChar* name;
2678 unsigned code;
2679
2680} wimaxasncp_dict_tlv_enum_t;
2681
2682typedef struct wimaxasncp_dict_tlv
2683{
2684 xmlChar* name;
2685 xmlChar* description;
2686 uint16_t type;
2687 int decoder;
2688 unsigned since;
2689 GSList* enums;
2690
2691} wimaxasncp_dict_tlv_t;
2692
2693
2694static void
2695wimaxasncp_dict_print_tlv_enum(void* data, void* user_data)
2696{
2697 wimaxasncp_dict_tlv_enum_t* tlv_enum = (wimaxasncp_dict_tlv_enum_t*)data;
2698 FILE* fh = (FILE*)user_data;
2699
2700 fprintf(fh, "\tEnum: %s[%u]\n",
2701 tlv_enum->name ? (char*)tlv_enum->name : "-",
2702 tlv_enum->code);
2703}
2704
2705static void
2706wimaxasncp_dict_print_tlv(void* data, void* user_data)
2707{
2708 wimaxasncp_dict_tlv_t* tlv = (wimaxasncp_dict_tlv_t*)data;
2709 FILE* fh = (FILE*)user_data;
2710
2711 char* str_decoder = val_to_str_wmem(NULL((void*)0), tlv->decoder, wimaxasncp_decode_type_vals, "Unknown");
2712 fprintf(fh, "TLV: %s[%u] %s[%d] %s (since %u)\n",
2713 tlv->name ? (char*)tlv->name : "-",
2714 tlv->type,
2715 str_decoder,
2716 tlv->decoder,
2717 tlv->description ? (char*)tlv->description : "",
2718 tlv->since);
2719 wmem_free(NULL((void*)0), str_decoder);
2720 g_slist_foreach(tlv->enums, wimaxasncp_dict_print_tlv_enum, fh);
2721}
2722
2723void wimaxasncp_dict_print(FILE* fh, GSList* tlvs)
2724{
2725 fprintf(fh, "\n");
2726
2727 g_slist_foreach(tlvs, wimaxasncp_dict_print_tlv, fh);
2728}
2729
2730static void
2731wimaxasncp_print_tlv(void* data, void* user_data)
2732{
2733 wimaxasncp_tlv_new_t* tlv = (wimaxasncp_tlv_new_t*)data;
2734 FILE* fh = (FILE*)user_data;
2735
2736 char* str_decoder = val_to_str_wmem(NULL((void*)0), tlv->decoder, wimaxasncp_decode_type_vals, "Unknown");
2737 fprintf(fh,
2738 "%s\n"
2739 " type = %u\n"
2740 " description = %s\n"
2741 " decoder = %s\n"
2742 " hf_root = %d\n"
2743 " hf_value = %d\n"
2744 " hf_ipv4 = %d\n"
2745 " hf_ipv6 = %d\n"
2746 " hf_bsid = %d\n"
2747 " hf_protocol = %d\n"
2748 " hf_port_low = %d\n"
2749 " hf_port_high = %d\n"
2750 " hf_ipv4_mask = %d\n"
2751 " hf_ipv6_mask = %d\n"
2752 " hf_vendor_id = %d\n"
2753 " hf_vendor_rest_of_info = %d\n",
2754 tlv->name,
2755 tlv->type,
2756 tlv->description,
2757 str_decoder,
2758 tlv->hf_root,
2759 tlv->hf_value,
2760 tlv->hf_ipv4,
2761 tlv->hf_ipv6,
2762 tlv->hf_bsid,
2763 tlv->hf_protocol,
2764 tlv->hf_port_low,
2765 tlv->hf_port_high,
2766 tlv->hf_ipv4_mask,
2767 tlv->hf_ipv6_mask,
2768 tlv->hf_vendor_id,
2769 tlv->hf_vendor_rest_of_info);
2770 wmem_free(NULL((void*)0), str_decoder);
2771}
2772
2773static bool_Bool
2774wimaxasncp_dictionary_process_file(const char* filename, GSList** tlvs)
2775{
2776 xmlDocPtr doc;
2777 xmlNodePtr root_element = NULL((void*)0);
2778 bool_Bool status = true1;
2779
2780 doc = xmlReadFile(filename, NULL((void*)0), XML_PARSE_NOENT);
2781 if (doc == NULL((void*)0))
2782 return false0;
2783
2784 root_element = xmlDocGetRootElement(doc);
2785 if (root_element == NULL((void*)0)) {
2786 status = false0;
2787 goto cleanup;
2788 }
2789
2790 // Iterate through top-level child elements
2791 for (xmlNodePtr current_node = root_element->children; current_node != NULL((void*)0); current_node = current_node->next)
2792 {
2793 if (current_node->type != XML_ELEMENT_NODE)
2794 continue;
2795
2796 // Process <base> element
2797 if (xmlStrcmp(current_node->name, (const xmlChar*)"tlv") == 0)
2798 {
2799 wimaxasncp_dict_tlv_t* element = g_new0(wimaxasncp_dict_tlv_t, 1)((wimaxasncp_dict_tlv_t *) g_malloc0_n ((1), sizeof (wimaxasncp_dict_tlv_t
)))
;
2800 element->name = xmlGetProp(current_node, (const xmlChar*)"name");
2801 element->description = xmlGetProp(current_node, (const xmlChar*)"description");
2802 xmlChar* str_type = xmlGetProp(current_node, (const xmlChar*)"type");
2803 if (str_type != NULL((void*)0))
2804 {
2805 if (g_ascii_strncasecmp(str_type, "0x", 2) == 0)
2806 {
2807 ws_hexstrtou16(str_type, NULL((void*)0), &element->type);
2808 }
2809 else
2810 {
2811 ws_strtou16(str_type, NULL((void*)0), &element->type);
2812 }
2813 xmlFree(str_type);
2814 }
2815 xmlChar* str_since = xmlGetProp(current_node, (const xmlChar*)"since");
2816 if (str_since != NULL((void*)0))
2817 {
2818 ws_strtou32(str_since, NULL((void*)0), &element->since);
2819 xmlFree(str_since);
2820 }
2821 xmlChar* str_decoder = xmlGetProp(current_node, (const xmlChar*)"decoder");
2822 if (str_decoder != NULL((void*)0))
2823 {
2824 element->decoder = wimaxasncp_decode_type(str_decoder);
2825 xmlFree(str_decoder);
2826 }
2827
2828 for (xmlNodePtr tlv_children = current_node->children; tlv_children != NULL((void*)0); tlv_children = tlv_children->next)
2829 {
2830 if (tlv_children->type != XML_ELEMENT_NODE)
2831 continue;
2832
2833 if (xmlStrcmp(tlv_children->name, (const xmlChar*)"enum") == 0)
2834 {
2835 wimaxasncp_dict_tlv_enum_t* tlv_enum = g_new0(wimaxasncp_dict_tlv_enum_t, 1)((wimaxasncp_dict_tlv_enum_t *) g_malloc0_n ((1), sizeof (wimaxasncp_dict_tlv_enum_t
)))
;
2836 tlv_enum->name = xmlGetProp(tlv_children, (const xmlChar*)"name");
2837 xmlChar* str_code = xmlGetProp(tlv_children, (const xmlChar*)"code");
2838 if (str_code != NULL((void*)0))
2839 {
2840 if (g_ascii_strncasecmp(str_code, "0x", 2) == 0)
2841 {
2842 ws_hexstrtou32(str_code, NULL((void*)0), &tlv_enum->code);
2843 }
2844 else if (g_ascii_isdigit(str_code[0])((g_ascii_table[(guchar) (str_code[0])] & G_ASCII_DIGIT) !=
0)
)
2845 {
2846 ws_strtou32(str_code, NULL((void*)0), &tlv_enum->code);
2847 }
2848 else
2849 {
2850 GMatchInfo* match_info;
2851 static GRegex* regex = NULL((void*)0);
2852 if (regex == NULL((void*)0))
2853 {
2854 regex = g_regex_new("^(WIMAXASNCP_BIT)(\\d+)\\((\\d+)\\)$",
2855 G_REGEX_DEFAULT, 0, NULL((void*)0));
2856 }
2857
2858 if (g_regex_match_full(regex, str_code, -1, 0, 0, &match_info, NULL((void*)0)))
2859 {
2860 unsigned bit_value = 0, bit_shift = 0;
2861 gchar* bit_value_str = g_match_info_fetch(match_info, 2);
2862 gchar* parenthesized_value_str = g_match_info_fetch(match_info, 3);
2863
2864 ws_strtou32(bit_value_str, NULL((void*)0), &bit_value);
2865 switch(bit_value)
2866 {
2867 case 8:
2868 if (ws_strtou32(parenthesized_value_str, NULL((void*)0), &bit_shift))
2869 tlv_enum->code = 1 << (7 - bit_shift);
2870 break;
2871 case 16:
2872 if (ws_strtou32(parenthesized_value_str, NULL((void*)0), &bit_shift))
2873 tlv_enum->code = 1 << (15 - bit_shift);
2874 break;
2875 case 32:
2876 if (ws_strtou32(parenthesized_value_str, NULL((void*)0), &bit_shift))
2877 tlv_enum->code = 1 << (31 - bit_shift);
2878 break;
2879 }
2880
2881 }
2882 g_match_info_free(match_info);
2883 }
2884 xmlFree(str_code);
2885 }
2886 element->enums = g_slist_append(element->enums, tlv_enum);
2887 }
2888 }
2889
2890 (*tlvs) = g_slist_append((*tlvs), element);
2891 }
2892 }
2893cleanup:
2894 xmlFreeDoc(doc);
2895
2896 return status;
2897}
2898
2899static void
2900wimaxasncp_dict_enum_process(void* data, void* user_data)
2901{
2902 wimaxasncp_dict_tlv_enum_t* dict_enum = (wimaxasncp_dict_tlv_enum_t*)data;
2903 wmem_array_t* array = (wmem_array_t*)user_data;
2904
2905 value_string item = { dict_enum->code, wmem_strdup(wmem_epan_scope(), dict_enum->name) };
2906 wmem_array_append_one(array, item)wmem_array_append((array), &(item), 1);
2907}
2908
2909static void
2910wimaxasncp_dict_process(void* data, void* user_data)
2911{
2912 wimaxasncp_dict_tlv_t* dict_tlv = (wimaxasncp_dict_tlv_t*)data;
2913 wmem_list_t* tlvs = (wmem_list_t*)user_data;
2914 wimaxasncp_tlv_new_t* tlv = wmem_new0(wmem_epan_scope(), wimaxasncp_tlv_new_t)((wimaxasncp_tlv_new_t*)wmem_alloc0((wmem_epan_scope()), sizeof
(wimaxasncp_tlv_new_t)))
;
2915
2916 tlv->type = dict_tlv->type;
2917 tlv->name = wmem_strdup(wmem_epan_scope(), dict_tlv->name);
2918 tlv->description = wmem_strdup(wmem_epan_scope(), dict_tlv->description);
2919 tlv->decoder = dict_tlv->decoder;
2920 tlv->since = dict_tlv->since;
2921
2922 if (dict_tlv->enums != NULL((void*)0))
2923 {
2924 /* Create array for enums */
2925 wmem_array_t* array = wmem_array_new(wmem_epan_scope(), sizeof(value_string));
2926
2927 /* Copy each entry into value_string array */
2928 g_slist_foreach(dict_tlv->enums, wimaxasncp_dict_enum_process, array);
2929
2930 /* Set enums to use with this TLV */
2931 wmem_array_set_null_terminator(array);
2932 tlv->enum_vs = (value_string*)wmem_array_get_raw(array);
2933 }
2934
2935 add_tlv_reg_info(tlv);
2936
2937 wmem_list_append(tlvs, tlv);
2938}
2939
2940static void
2941wimaxasncp_dict_tlv_enum_clean(void* data, void* user_data _U___attribute__((unused)))
2942{
2943 wimaxasncp_dict_tlv_enum_t* dict_enum = (wimaxasncp_dict_tlv_enum_t*)data;
2944 xmlFree(dict_enum->name);
2945}
2946
2947static void
2948wimaxasncp_dict_clean(void* data, void* user_data)
2949{
2950 wimaxasncp_dict_tlv_t* dict_tlv = (wimaxasncp_dict_tlv_t*)data;
2951
2952 xmlFree(dict_tlv->name);
2953 xmlFree(dict_tlv->description);
2954
2955 g_slist_foreach(dict_tlv->enums, wimaxasncp_dict_tlv_enum_clean, user_data);
2956 g_slist_free(dict_tlv->enums);
2957}
2958
2959/* ========================================================================= */
2960/* Register the protocol fields and subtrees with Wireshark */
2961static void
2962register_wimaxasncp_fields(const char* unused _U___attribute__((unused)))
2963{
2964 bool_Bool dump_dict = getenv("WIRESHARK_DUMP_WIMAXASNCP_DICT") != NULL((void*)0);
2965
2966 /* ------------------------------------------------------------------------
2967 * List of header fields
2968 * ------------------------------------------------------------------------
2969 */
2970
2971 static hf_register_info hf_base[] = {
2972 {
2973 &hf_wimaxasncp_version,
2974 {
2975 "Version",
2976 "wimaxasncp.version",
2977 FT_UINT8,
2978 BASE_DEC,
2979 NULL((void*)0),
2980 0x0,
2981 NULL((void*)0),
2982 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
2983 }
2984 },
2985 {
2986 &hf_wimaxasncp_flags,
2987 {
2988 "Flags",
2989 "wimaxasncp.flags",
2990 FT_UINT8,
2991 BASE_HEX,
2992 NULL((void*)0),
2993 0,
2994 NULL((void*)0),
2995 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
2996 }
2997 },
2998 {
2999 &hf_wimaxasncp_flags_r,
3000 {
3001 "R - Reset Next Expected Transaction ID",
3002 "wimaxasncp.flags.r",
3003 FT_UINT8,
3004 BASE_HEX,
3005 NULL((void*)0),
3006 0x01,
3007 NULL((void*)0),
3008 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3009 }
3010 },
3011 {
3012 &hf_wimaxasncp_flags_t,
3013 {
3014 "T - Source and Destination Identifier TLVs",
3015 "wimaxasncp.flags.t",
3016 FT_UINT8,
3017 BASE_HEX,
3018 NULL((void*)0),
3019 0x02,
3020 NULL((void*)0),
3021 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3022 }
3023 },
3024 {
3025 &hf_wimaxasncp_flags_reserved,
3026 {
3027 "Reserved",
3028 "wimaxasncp.flags.reserved",
3029 FT_UINT8,
3030 BASE_HEX,
3031 NULL((void*)0),
3032 0xFC,
3033 NULL((void*)0),
3034 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3035 }
3036 },
3037 {
3038 &hf_wimaxasncp_function_type,
3039 {
3040 "Function Type",
3041 "wimaxasncp.function_type",
3042 FT_UINT8,
3043 BASE_DEC,
3044 NULL((void*)0),
3045 0x0,
3046 NULL((void*)0),
3047 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3048 }
3049 },
3050 {
3051 &hf_wimaxasncp_op_id,
3052 {
3053 "OP ID",
3054 "wimaxasncp.opid",
3055 FT_UINT8,
3056 BASE_HEX,
3057 VALS(wimaxasncp_op_id_vals)((0 ? (const struct _value_string*)0 : ((wimaxasncp_op_id_vals
))))
,
3058 0xE0,
3059 NULL((void*)0),
3060 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3061 }
3062 },
3063 {
3064 &hf_wimaxasncp_message_type,
3065 {
3066 "Message Type",
3067 "wimaxasncp.message_type",
3068 FT_UINT8,
3069 BASE_HEX,
3070 NULL((void*)0),
3071 0x1F,
3072 NULL((void*)0),
3073 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3074 }
3075 },
3076 {
3077 &hf_wimaxasncp_length,
3078 {
3079 "Length",
3080 "wimaxasncp.length",
3081 FT_UINT16,
3082 BASE_DEC,
3083 NULL((void*)0),
3084 0x0,
3085 NULL((void*)0),
3086 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3087 }
3088 },
3089 {
3090 &hf_wimaxasncp_msid,
3091 {
3092 "MSID",
3093 "wimaxasncp.msid",
3094 FT_ETHER,
3095 BASE_NONE,
3096 NULL((void*)0),
3097 0x0,
3098 NULL((void*)0),
3099 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3100 }
3101 },
3102 {
3103 &hf_wimaxasncp_reserved1,
3104 {
3105 "Reserved",
3106 "wimaxasncp.reserved1",
3107 FT_UINT32,
3108 BASE_HEX,
3109 NULL((void*)0),
3110 0x0,
3111 NULL((void*)0),
3112 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3113 }
3114 },
3115 {
3116 &hf_wimaxasncp_transaction_id,
3117 {
3118 "Transaction ID",
3119 "wimaxasncp.transaction_id",
3120 FT_UINT16,
3121 BASE_HEX,
3122 NULL((void*)0),
3123 0x0,
3124 NULL((void*)0),
3125 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3126 }
3127 },
3128 {
3129 &hf_wimaxasncp_reserved2,
3130 {
3131 "Reserved",
3132 "wimaxasncp.reserved2",
3133 FT_UINT16,
3134 BASE_HEX,
3135 NULL((void*)0),
3136 0x0,
3137 NULL((void*)0),
3138 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3139 }
3140 },
3141#if 0
3142 {
3143 &hf_wimaxasncp_tlv,
3144 {
3145 "TLV",
3146 "wimaxasncp.tlv",
3147 FT_BYTES,
3148 BASE_NONE,
3149 NULL((void*)0),
3150 0x0,
3151 NULL((void*)0),
3152 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3153 }
3154 },
3155#endif
3156 {
3157 &hf_wimaxasncp_tlv_type,
3158 {
3159 "Type",
3160 "wimaxasncp.tlv.type",
3161 FT_UINT16,
3162 BASE_DEC,
3163 NULL((void*)0),
3164 0x0,
3165 NULL((void*)0),
3166 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3167 }
3168 },
3169 {
3170 &hf_wimaxasncp_tlv_length,
3171 {
3172 "Length",
3173 "wimaxasncp.tlv.length",
3174 FT_UINT16,
3175 BASE_DEC,
3176 NULL((void*)0),
3177 0x0,
3178 NULL((void*)0),
3179 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3180 }
3181 },
3182 {
3183 &hf_wimaxasncp_tlv_value_bytes,
3184 {
3185 "Value",
3186 "wimaxasncp.tlv_value_bytes",
3187 FT_BYTES,
3188 BASE_NONE,
3189 NULL((void*)0),
3190 0x0,
3191 NULL((void*)0),
3192 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3193 }
3194 },
3195 {
3196 &hf_wimaxasncp_tlv_value_bitflags8,
3197 {
3198 "Value",
3199 "wimaxasncp.tlv_value_bitflags8",
3200 FT_UINT8,
3201 BASE_HEX,
3202 NULL((void*)0),
3203 0xff,
3204 NULL((void*)0),
3205 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3206 }
3207 },
3208 {
3209 &hf_wimaxasncp_tlv_value_bitflags16,
3210 {
3211 "Value",
3212 "wimaxasncp.tlv_value_bitflags16",
3213 FT_UINT16,
3214 BASE_HEX,
3215 NULL((void*)0),
3216 0xffff,
3217 NULL((void*)0),
3218 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3219 }
3220 },
3221 {
3222 &hf_wimaxasncp_tlv_value_bitflags32,
3223 {
3224 "Value",
3225 "wimaxasncp.tlv_value_bitflags32",
3226 FT_UINT32,
3227 BASE_HEX,
3228 NULL((void*)0),
3229 0xffffffff,
3230 NULL((void*)0),
3231 HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0)
3232 }
3233 },
3234 };
3235
3236 /* ------------------------------------------------------------------------
3237 * Protocol subtree array
3238 * ------------------------------------------------------------------------
3239 */
3240
3241 static int *ett_base[] = {
3242 &ett_wimaxasncp,
3243 &ett_wimaxasncp_flags,
3244 &ett_wimaxasncp_tlv,
3245 &ett_wimaxasncp_tlv_value_bitflags8,
3246 &ett_wimaxasncp_tlv_value_bitflags16,
3247 &ett_wimaxasncp_tlv_value_bitflags32,
3248 &ett_wimaxasncp_tlv_protocol_list,
3249 &ett_wimaxasncp_tlv_port_range_list,
3250 &ett_wimaxasncp_tlv_ip_address_mask_list,
3251 &ett_wimaxasncp_tlv_ip_address_mask,
3252 &ett_wimaxasncp_tlv_eap,
3253 &ett_wimaxasncp_tlv_vendor_specific_information_field,
3254 &ett_wimaxasncp_port_range
3255 };
3256
3257 static ei_register_info ei[] = {
3258 { &ei_wimaxasncp_tlv_type, { "wimaxasncp.tlv.type.unknown", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Unknown tlv", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3259 { &ei_wimaxasncp_function_type, { "wimaxasncp.function_type.unknown", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Unknown function type", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3260 { &ei_wimaxasncp_op_id, { "wimaxasncp.opid.unknown", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Unknown message op", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3261 { &ei_wimaxasncp_decoder, { "wimaxasncp.decoder.unknown", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Unknown decoder", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3262 { &ei_wimaxasncp_message_type, { "wimaxasncp.message_type.unknown", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Unknown message type", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3263 { &ei_wimaxasncp_length_bad, { "wimaxasncp.length.bad", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Bad length", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
3264 };
3265
3266 expert_module_t* expert_wimaxasncp;
3267 GSList* all_tlvs = NULL((void*)0);
3268
3269 /* ------------------------------------------------------------------------
3270 * load the XML dictionary
3271 * ------------------------------------------------------------------------
3272 */
3273 char* dir = ws_strdup_printf("%s" G_DIR_SEPARATOR_S "wimaxasncp" G_DIR_SEPARATOR_S "dictionary.xml", get_datafile_dir())wmem_strdup_printf(((void*)0), "%s" "/" "wimaxasncp" "/" "dictionary.xml"
, get_datafile_dir())
;
3274 bool_Bool success = wimaxasncp_dictionary_process_file(dir, &all_tlvs);
3275 g_free(dir);
3276
3277 if (success && dump_dict)
3278 wimaxasncp_dict_print(stdoutstdout, all_tlvs);
3279
3280 /* ------------------------------------------------------------------------
3281 * build the hf and ett dictionary entries
3282 * ------------------------------------------------------------------------
3283 */
3284
3285 wimaxasncp_build_dict.hf = wmem_array_new(wmem_epan_scope(), sizeof(hf_register_info));
3286 wmem_array_append(wimaxasncp_build_dict.hf, hf_base, array_length(hf_base)(sizeof (hf_base) / sizeof (hf_base)[0]));
3287
3288 wimaxasncp_build_dict.ett = wmem_array_new(wmem_epan_scope(), sizeof(int*));
3289 wmem_array_append(wimaxasncp_build_dict.ett, ett_base, array_length(ett_base)(sizeof (ett_base) / sizeof (ett_base)[0]));
3290
3291 /* Convert the dictionary data to epan scoped data structures */
3292 wimaxasncp_tlvs = wmem_list_new(wmem_epan_scope());
3293 g_slist_foreach(all_tlvs, wimaxasncp_dict_process, wimaxasncp_tlvs);
3294
3295 /* add an entry for unknown TLVs */
3296 add_tlv_reg_info(&wimaxasncp_tlv_not_found);
3297
3298 /* Clean up dictionary data */
3299 g_slist_foreach(all_tlvs, wimaxasncp_dict_clean, NULL((void*)0));
3300
3301 /* Optionally print the hfs created from the dictionary */
3302 if (success && dump_dict)
3303 wmem_list_foreach(wimaxasncp_tlvs, wimaxasncp_print_tlv, stdoutstdout);
3304
3305 /* Required function calls to register the header fields and subtrees
3306 * used */
3307 proto_register_field_array(
3308 proto_wimaxasncp,
3309 (hf_register_info*)wmem_array_get_raw(wimaxasncp_build_dict.hf),
3310 wmem_array_get_count(wimaxasncp_build_dict.hf));
3311
3312 proto_register_subtree_array(
3313 (int**)wmem_array_get_raw(wimaxasncp_build_dict.ett),
3314 wmem_array_get_count(wimaxasncp_build_dict.ett));
3315
3316 expert_wimaxasncp = expert_register_protocol(proto_wimaxasncp);
3317 expert_register_field_array(expert_wimaxasncp, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
3318
3319}
3320
3321
3322
3323
3324/* ========================================================================= */
3325/* Register the protocol with Wireshark */
3326
3327/* this format is require because a script is used to build the C function
3328 that calls all the protocol registration.
3329*/
3330
3331void
3332proto_register_wimaxasncp(void)
3333{
3334 module_t *wimaxasncp_module;
3335
3336 /* ------------------------------------------------------------------------
3337 * complete registration
3338 * ------------------------------------------------------------------------
3339 */
3340
3341 /* Register the protocol name and description */
3342 proto_wimaxasncp = proto_register_protocol("WiMAX ASN Control Plane Protocol", "WiMAX ASN CP", "wimaxasncp");
3343
3344 /* Register this dissector by name */
3345 wimaxasncp_handle = register_dissector("wimaxasncp", dissect_wimaxasncp, proto_wimaxasncp);
3346
3347 wimaxasncp_module = prefs_register_protocol(proto_wimaxasncp, NULL((void*)0));
3348
3349 /* Register preferences */
3350 prefs_register_bool_preference(
3351 wimaxasncp_module,
3352 "show_transaction_id_d_bit",
3353 "Show transaction ID direction bit",
3354 "Show transaction ID direction bit separately from the rest of "
3355 "the transaction ID field.",
3356 &show_transaction_id_d_bit);
3357
3358 prefs_register_enum_preference(
3359 wimaxasncp_module,
3360 "nwg_version",
3361 "NWG Version",
3362 "Version of the NWG that the R6 protocol complies with",
3363 &global_wimaxasncp_nwg_ver,
3364 wimaxasncp_nwg_versions,
3365 false0);
3366
3367 proto_register_prefix("wimaxasncp", register_wimaxasncp_fields);
3368}
3369
3370/* ========================================================================= */
3371/* If this dissector uses sub-dissector registration add a registration
3372 routine. This exact format is required because a script is used to find
3373 these routines and create the code that calls these routines.
3374
3375 This function is also called by preferences whenever "Apply" is pressed
3376 (see prefs_register_protocol above) so it should accommodate being called
3377 more than once.
3378*/
3379void
3380proto_reg_handoff_wimaxasncp(void)
3381{
3382 /* Find the EAP dissector */
3383 eap_handle = find_dissector_add_dependency("eap", proto_wimaxasncp);
3384
3385 dissector_add_uint_with_preference("udp.port", WIMAXASNCP_DEF_UDP_PORT2231, wimaxasncp_handle);
3386}
3387
3388
3389/*
3390 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3391 *
3392 * Local variables:
3393 * c-basic-offset: 4
3394 * tab-width: 8
3395 * indent-tabs-mode: nil
3396 * End:
3397 *
3398 * vi: set shiftwidth=4 tabstop=8 expandtab:
3399 * :indentSize=4:tabSize=8:noTabs=true:
3400 */