2 * Routines for ISDN Q.921-User Adaptation Layer dissection
4 * It is hopefully (needs testing) compliant to
5 * https://tools.ietf.org/html/rfc3057
6 * https://tools.ietf.org/html/draft-ietf-sigtran-iua-imp-guide-01
7 * To do: - provide better handling of length parameters
9 * Copyright 2002, Michael Tuexen <tuexen [AT] fh-muenster.de>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * Copied from README.developer
17 * SPDX-License-Identifier: GPL-2.0-or-later
22 #include <epan/packet.h>
23 #include <epan/prefs.h>
24 #include <epan/sctpppids.h>
25 #include <epan/lapd_sapi.h>
26 #include <wsutil/str_util.h>
27 #include <wsutil/ws_roundup.h>
29 void proto_register_iua(void);
30 void proto_reg_handoff_iua(void);
32 static module_t
*iua_module
;
34 static dissector_table_t lapd_gsm_sapi_dissector_table
;
36 /* Whether to use GSM SAPI vals or not */
37 static bool global_iua_gsm_sapis
= true;
39 /* Initialize the protocol and registered fields */
41 static int hf_int_interface_id
;
42 static int hf_text_interface_id
;
43 static int hf_info_string
;
44 static int hf_dlci_zero_bit
;
45 static int hf_dlci_spare_bit
;
46 static int hf_dlci_sapi
;
47 static int hf_dlci_gsm_sapi
;
48 static int hf_dlci_one_bit
;
49 static int hf_dlci_tei
;
50 static int hf_dlci_spare
;
51 static int hf_diag_info
;
52 static int hf_interface_range_start
;
53 static int hf_interface_range_end
;
54 static int hf_heartbeat_data
;
55 static int hf_asp_reason
;
56 static int hf_traffic_mode_type
;
57 static int hf_error_code
;
58 static int hf_error_code_ig
;
59 static int hf_status_type
;
60 static int hf_status_id
;
61 static int hf_release_reason
;
62 static int hf_tei_status
;
64 static int hf_parameter_tag
;
65 static int hf_parameter_tag_ig
;
66 static int hf_parameter_length
;
67 static int hf_parameter_value
;
68 static int hf_parameter_padding
;
69 static int hf_version
;
70 static int hf_reserved
;
71 static int hf_message_class
;
72 static int hf_message_type
;
73 static int hf_message_length
;
75 /* Initialize the subtree pointers */
77 static int ett_iua_parameter
;
79 /* stores the current SAPI value */
80 static uint8_t sapi_val
;
81 static bool sapi_val_assigned
;
83 /* option setable via preferences, default is plain RFC 3057 */
84 static bool support_IG
;
86 static dissector_handle_t q931_handle
;
87 static dissector_handle_t x25_handle
;
88 static dissector_handle_t iua_handle
;
90 #define PARAMETER_TAG_LENGTH 2
91 #define PARAMETER_LENGTH_LENGTH 2
92 #define PARAMETER_HEADER_LENGTH (PARAMETER_TAG_LENGTH + PARAMETER_LENGTH_LENGTH)
94 #define PARAMETER_TAG_OFFSET 0
95 #define PARAMETER_LENGTH_OFFSET (PARAMETER_TAG_OFFSET + PARAMETER_TAG_LENGTH)
96 #define PARAMETER_VALUE_OFFSET (PARAMETER_LENGTH_OFFSET + PARAMETER_LENGTH_LENGTH)
97 #define PARAMETER_HEADER_OFFSET PARAMETER_TAG_OFFSET
99 #define INT_INTERFACE_ID_LENGTH 4
102 dissect_int_interface_identifier_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
104 uint16_t number_of_ids
, id_number
;
107 number_of_ids
= (tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
) - PARAMETER_HEADER_LENGTH
) / INT_INTERFACE_ID_LENGTH
;
108 offset
= PARAMETER_VALUE_OFFSET
;
110 proto_item_append_text(parameter_item
, " (");
111 for (id_number
= 0; id_number
< number_of_ids
; id_number
++) {
112 proto_tree_add_item(parameter_tree
, hf_int_interface_id
, parameter_tvb
, offset
, INT_INTERFACE_ID_LENGTH
, ENC_BIG_ENDIAN
);
113 proto_item_append_text(parameter_item
, (id_number
> 0) ? ", %d" : "%d", tvb_get_ntohl(parameter_tvb
, offset
));
114 offset
+= INT_INTERFACE_ID_LENGTH
;
116 proto_item_append_text(parameter_item
, ")");
119 #define TEXT_INTERFACE_ID_OFFSET PARAMETER_VALUE_OFFSET
122 dissect_text_interface_identifier_parameter(tvbuff_t
*parameter_tvb
, packet_info
*pinfo
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
124 uint16_t interface_id_length
;
126 interface_id_length
= tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
) - PARAMETER_HEADER_LENGTH
;
128 proto_tree_add_item(parameter_tree
, hf_text_interface_id
, parameter_tvb
, TEXT_INTERFACE_ID_OFFSET
, interface_id_length
, ENC_ASCII
);
129 proto_item_append_text(parameter_item
, " (%s)",
130 tvb_format_text(pinfo
->pool
, parameter_tvb
, TEXT_INTERFACE_ID_OFFSET
, interface_id_length
));
133 #define INFO_STRING_OFFSET PARAMETER_VALUE_OFFSET
136 dissect_info_string_parameter(tvbuff_t
*parameter_tvb
, packet_info
*pinfo
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
138 uint16_t info_string_length
;
140 info_string_length
= tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
) - PARAMETER_HEADER_LENGTH
;
141 proto_tree_add_item(parameter_tree
, hf_info_string
, parameter_tvb
, INFO_STRING_OFFSET
, info_string_length
, ENC_ASCII
);
142 proto_item_append_text(parameter_item
, " (%s)",
143 tvb_format_text(pinfo
->pool
, parameter_tvb
, INFO_STRING_OFFSET
, info_string_length
));
146 #define DLCI_SAPI_LENGTH 1
147 #define DLCI_TEI_LENGTH 1
148 #define DLCI_SPARE_LENGTH 2
150 #define DLCI_SAPI_OFFSET PARAMETER_VALUE_OFFSET
151 #define DLCI_TEI_OFFSET (DLCI_SAPI_OFFSET + DLCI_SAPI_LENGTH)
152 #define DLCI_SPARE_OFFSET (DLCI_TEI_OFFSET + DLCI_TEI_LENGTH)
154 #define ZERO_BIT_MASK 0x01
155 #define SPARE_BIT_MASK 0x02
156 #define SAPI_MASK 0xfc
158 #define ONE_BIT_MASK 0x01
159 #define TEI_MASK 0xfe
161 /* SAPI values taken from Q.921 */
162 #define SAPI_VAL_CALL_CONTROL 0
163 #define SAPI_VAL_Q931_PACKET 1
164 #define SAPI_VAL_TELACTION 12
165 #define SAPI_VAL_X25 16
166 #define SAPI_VAL_LAYER_2 63
167 static const value_string sapi_values
[] = {
168 { SAPI_VAL_CALL_CONTROL
, "Call control procedures" },
169 { SAPI_VAL_Q931_PACKET
, "Q.931 packet mode communication" },
170 { SAPI_VAL_TELACTION
, "Teleaction communication" },
171 { SAPI_VAL_X25
, "X.25 packet communication" },
172 { SAPI_VAL_LAYER_2
, "Layer 2 management procedures" },
176 static const value_string gsm_sapi_vals
[] = {
177 { LAPD_GSM_SAPI_RA_SIG_PROC
, "Radio signalling procedures" },
178 { LAPD_GSM_SAPI_NOT_USED_1
, "(Not used in GSM PLMN)" },
179 { LAPD_GSM_SAPI_NOT_USED_16
, "(Not used in GSM PLMN)" },
180 { LAPD_GSM_SAPI_OM_PROC
, "Operation and maintenance procedure" },
181 { LAPD_SAPI_L2
, "Layer 2 management procedures" },
186 dissect_dlci_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
)
188 proto_tree_add_item(parameter_tree
, hf_dlci_zero_bit
, parameter_tvb
, DLCI_SAPI_OFFSET
, DLCI_SAPI_LENGTH
, ENC_BIG_ENDIAN
);
189 proto_tree_add_item(parameter_tree
, hf_dlci_spare_bit
, parameter_tvb
, DLCI_SAPI_OFFSET
, DLCI_SAPI_LENGTH
, ENC_BIG_ENDIAN
);
190 /* Add the SAPI + some explanatory text, store the SAPI value so that we can later how to
191 * dissect the protocol data */
192 if(global_iua_gsm_sapis
) {
193 proto_tree_add_item(parameter_tree
, hf_dlci_gsm_sapi
, parameter_tvb
, DLCI_SAPI_OFFSET
, DLCI_SAPI_LENGTH
, ENC_BIG_ENDIAN
);
195 proto_tree_add_item(parameter_tree
, hf_dlci_sapi
, parameter_tvb
, DLCI_SAPI_OFFSET
, DLCI_SAPI_LENGTH
, ENC_BIG_ENDIAN
);
197 sapi_val
= (tvb_get_uint8(parameter_tvb
, DLCI_SAPI_OFFSET
) & SAPI_MASK
) >> SAPI_SHIFT
;
198 sapi_val_assigned
= true;
200 proto_tree_add_item(parameter_tree
, hf_dlci_one_bit
, parameter_tvb
, DLCI_TEI_OFFSET
, DLCI_TEI_LENGTH
, ENC_BIG_ENDIAN
);
201 proto_tree_add_item(parameter_tree
, hf_dlci_tei
, parameter_tvb
, DLCI_TEI_OFFSET
, DLCI_TEI_LENGTH
, ENC_BIG_ENDIAN
);
202 proto_tree_add_item(parameter_tree
, hf_dlci_spare
, parameter_tvb
, DLCI_SPARE_OFFSET
, DLCI_SPARE_LENGTH
, ENC_BIG_ENDIAN
);
206 dissect_diagnostic_information_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
208 uint16_t diag_info_length
;
210 diag_info_length
= tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
) - PARAMETER_HEADER_LENGTH
;
211 proto_tree_add_item(parameter_tree
, hf_diag_info
, parameter_tvb
, PARAMETER_VALUE_OFFSET
, diag_info_length
, ENC_NA
);
212 proto_item_append_text(parameter_item
, " (%u byte%s)", diag_info_length
, plurality(diag_info_length
, "", "s"));
215 #define START_LENGTH 4
217 #define INTERVAL_LENGTH (START_LENGTH + END_LENGTH)
219 #define START_OFFSET 0
220 #define END_OFFSET (START_OFFSET + START_LENGTH)
223 dissect_integer_range_interface_identifier_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
225 uint16_t number_of_ranges
, range_number
;
228 number_of_ranges
= (tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
) - PARAMETER_HEADER_LENGTH
) / INTERVAL_LENGTH
;
229 offset
= PARAMETER_VALUE_OFFSET
;
230 proto_item_append_text(parameter_item
, " (");
231 for (range_number
= 0; range_number
< number_of_ranges
; range_number
++) {
232 proto_tree_add_item(parameter_tree
, hf_interface_range_start
, parameter_tvb
, offset
+ START_OFFSET
, START_LENGTH
, ENC_BIG_ENDIAN
);
233 proto_tree_add_item(parameter_tree
, hf_interface_range_end
, parameter_tvb
, offset
+ END_OFFSET
, END_LENGTH
, ENC_BIG_ENDIAN
);
234 proto_item_append_text(parameter_item
, (range_number
> 0) ? ", %d-%d" : "%d-%d",
235 tvb_get_ntohl(parameter_tvb
, offset
+ START_OFFSET
), tvb_get_ntohl(parameter_tvb
, offset
+ END_OFFSET
));
236 offset
+= INTERVAL_LENGTH
;
238 proto_item_append_text(parameter_item
, ")");
241 #define HEARTBEAT_DATA_OFFSET PARAMETER_VALUE_OFFSET
244 dissect_heartbeat_data_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
246 uint16_t heartbeat_data_length
;
248 heartbeat_data_length
= tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
) - PARAMETER_HEADER_LENGTH
;
249 proto_tree_add_item(parameter_tree
, hf_heartbeat_data
, parameter_tvb
, HEARTBEAT_DATA_OFFSET
, heartbeat_data_length
, ENC_NA
);
250 proto_item_append_text(parameter_item
, " (%u byte%s)", heartbeat_data_length
, plurality(heartbeat_data_length
, "", "s"));
253 #define ASP_MGMT_REASON 1
255 static const value_string asp_reason_values
[] = {
256 { ASP_MGMT_REASON
, "Management inhibit" },
259 #define ASP_REASON_LENGTH 4
260 #define ASP_REASON_OFFSET PARAMETER_VALUE_OFFSET
263 dissect_asp_reason_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
265 proto_tree_add_item(parameter_tree
, hf_asp_reason
, parameter_tvb
, ASP_REASON_OFFSET
, ASP_REASON_LENGTH
, ENC_BIG_ENDIAN
);
266 proto_item_append_text(parameter_item
, " (%s)", val_to_str_const(tvb_get_ntohl(parameter_tvb
, ASP_REASON_OFFSET
), asp_reason_values
, "unknown"));
269 #define OVER_RIDE_TRAFFIC_MODE_TYPE 1
270 #define LOAD_SHARE_TRAFFIC_MODE_TYPE 2
272 static const value_string traffic_mode_type_values
[] = {
273 { OVER_RIDE_TRAFFIC_MODE_TYPE
, "Over-ride" },
274 { LOAD_SHARE_TRAFFIC_MODE_TYPE
, "Load-share" },
277 #define TRAFFIC_MODE_TYPE_LENGTH 4
278 #define TRAFFIC_MODE_TYPE_OFFSET PARAMETER_VALUE_OFFSET
281 dissect_traffic_mode_type_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
283 proto_tree_add_item(parameter_tree
, hf_traffic_mode_type
, parameter_tvb
, TRAFFIC_MODE_TYPE_OFFSET
, TRAFFIC_MODE_TYPE_LENGTH
, ENC_BIG_ENDIAN
);
284 proto_item_append_text(parameter_item
, " (%s)",
285 val_to_str_const(tvb_get_ntohl(parameter_tvb
, TRAFFIC_MODE_TYPE_OFFSET
), traffic_mode_type_values
, "unknown"));
288 #define INVALID_VERSION_ERROR 0x01
289 #define INVALID_INTERFACE_IDENTIFIER_ERROR 0x02
290 #define UNSUPPORTED_MESSAGE_CLASS_ERROR 0x03
291 #define UNSUPPORTED_MESSAGE_TYPE_ERROR 0x04
292 #define UNSUPPORTED_TRAFFIC_HANDLING_MODE_ERROR 0x05
293 #define UNEXPECTED_MESSAGE_ERROR 0x06
294 #define PROTOCOL_ERROR 0x07
295 #define UNSUPPORTED_INTERFACE_IDENTIFIER_TYPE_ERROR 0x08
296 #define INVALID_STREAM_IDENTIFIER_ERROR 0x09
297 #define UNASSIGNED_TEI_ERROR 0x0a
298 #define UNRECOGNIZED_SAPI_ERROR 0x0b
299 #define INVALID_TEI_SAPI_COMBINATION_ERROR 0x0c
300 #define REFUSED_MANAGEMENT_BLOCKING_ERROR 0x0d
301 #define ASP_IDENTIFIER_REQUIRED_ERROR 0x0e
302 #define INVALID_ASP_IDENTIFIER_ERROR 0x0f
304 static const value_string error_code_values
[] = {
305 { INVALID_VERSION_ERROR
, "Invalid version" },
306 { INVALID_INTERFACE_IDENTIFIER_ERROR
, "Invalid interface identifier" },
307 { UNSUPPORTED_MESSAGE_CLASS_ERROR
, "Unsupported message class" },
308 { UNSUPPORTED_MESSAGE_TYPE_ERROR
, "Unsupported message type" },
309 { UNSUPPORTED_TRAFFIC_HANDLING_MODE_ERROR
, "Unsupported traffic handling mode" },
310 { UNEXPECTED_MESSAGE_ERROR
, "Unexpected message" },
311 { PROTOCOL_ERROR
, "Protocol error" },
312 { UNSUPPORTED_INTERFACE_IDENTIFIER_TYPE_ERROR
, "Unsupported interface identifier type" },
313 { INVALID_STREAM_IDENTIFIER_ERROR
, "Invalid stream identifier" },
314 { UNASSIGNED_TEI_ERROR
, "Unassigned TEI" },
315 { UNRECOGNIZED_SAPI_ERROR
, "Unrecognized SAPI" },
316 { INVALID_TEI_SAPI_COMBINATION_ERROR
, "Invalid TEI/SAPI combination" },
319 static const value_string error_code_ig_values
[] = {
320 { INVALID_VERSION_ERROR
, "Invalid version" },
321 { INVALID_INTERFACE_IDENTIFIER_ERROR
, "Invalid interface identifier" },
322 { UNSUPPORTED_MESSAGE_CLASS_ERROR
, "Unsupported message class" },
323 { UNSUPPORTED_MESSAGE_TYPE_ERROR
, "Unsupported message type" },
324 { UNSUPPORTED_TRAFFIC_HANDLING_MODE_ERROR
, "Unsupported traffic handling mode" },
325 { UNEXPECTED_MESSAGE_ERROR
, "Unexpected message" },
326 { PROTOCOL_ERROR
, "Protocol error" },
327 { UNSUPPORTED_INTERFACE_IDENTIFIER_TYPE_ERROR
, "Unsupported interface identifier type" },
328 { INVALID_STREAM_IDENTIFIER_ERROR
, "Invalid stream identifier" },
329 { UNASSIGNED_TEI_ERROR
, "Unassigned TEI" },
330 { UNRECOGNIZED_SAPI_ERROR
, "Unrecognized SAPI" },
331 { INVALID_TEI_SAPI_COMBINATION_ERROR
, "Invalid TEI/SAPI combination" },
332 { REFUSED_MANAGEMENT_BLOCKING_ERROR
, "Refused - Management blocking" },
333 { ASP_IDENTIFIER_REQUIRED_ERROR
, "ASP identifier required" },
334 { INVALID_ASP_IDENTIFIER_ERROR
, "Invalid ASP identifier" },
337 #define ERROR_CODE_LENGTH 4
338 #define ERROR_CODE_OFFSET PARAMETER_VALUE_OFFSET
341 dissect_error_code_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
343 proto_tree_add_item(parameter_tree
, support_IG
?hf_error_code_ig
:hf_error_code
, parameter_tvb
, ERROR_CODE_OFFSET
, ERROR_CODE_LENGTH
, ENC_BIG_ENDIAN
);
344 proto_item_append_text(parameter_item
, " (%s)",
345 val_to_str_const(tvb_get_ntohl(parameter_tvb
, ERROR_CODE_OFFSET
), support_IG
?error_code_ig_values
:error_code_values
, "unknown"));
348 #define ASP_STATE_CHANGE_STATUS_TYPE 0x01
349 #define OTHER_STATUS_TYPE 0x02
351 static const value_string status_type_values
[] = {
352 { ASP_STATE_CHANGE_STATUS_TYPE
, "Application server state change" },
353 { OTHER_STATUS_TYPE
, "Other" },
356 #define AS_DOWN_STATUS_IDENT 0x01
357 #define AS_INACTIVE_STATUS_IDENT 0x02
358 #define AS_ACTIVE_STATUS_IDENT 0x03
359 #define AS_PENDING_STATUS_IDENT 0x04
361 #define INSUFFICIENT_ASP_RESOURCES_STATUS_IDENT 0x01
362 #define ALTERNATE_ASP_ACTIVE_STATUS_IDENT 0x02
364 static const value_string status_type_id_values
[] = {
365 { ASP_STATE_CHANGE_STATUS_TYPE
* 256 * 256 + AS_DOWN_STATUS_IDENT
, "Application server down" },
366 { ASP_STATE_CHANGE_STATUS_TYPE
* 256 * 256 + AS_INACTIVE_STATUS_IDENT
, "Application server inactive" },
367 { ASP_STATE_CHANGE_STATUS_TYPE
* 256 * 256 + AS_ACTIVE_STATUS_IDENT
, "Application server active" },
368 { ASP_STATE_CHANGE_STATUS_TYPE
* 256 * 256 + AS_PENDING_STATUS_IDENT
, "Application server pending" },
369 { OTHER_STATUS_TYPE
* 256 * 256 + INSUFFICIENT_ASP_RESOURCES_STATUS_IDENT
, "Insufficient ASP resources active in AS" },
370 { OTHER_STATUS_TYPE
* 256 * 256 + ALTERNATE_ASP_ACTIVE_STATUS_IDENT
, "Alternate ASP active" },
373 static const value_string status_type_id_ig_values
[] = {
374 { ASP_STATE_CHANGE_STATUS_TYPE
* 256 * 256 + AS_INACTIVE_STATUS_IDENT
, "Application server inactive" },
375 { ASP_STATE_CHANGE_STATUS_TYPE
* 256 * 256 + AS_ACTIVE_STATUS_IDENT
, "Application server active" },
376 { ASP_STATE_CHANGE_STATUS_TYPE
* 256 * 256 + AS_PENDING_STATUS_IDENT
, "Application server pending" },
377 { OTHER_STATUS_TYPE
* 256 * 256 + INSUFFICIENT_ASP_RESOURCES_STATUS_IDENT
, "Insufficient ASP resources active in AS" },
378 { OTHER_STATUS_TYPE
* 256 * 256 + ALTERNATE_ASP_ACTIVE_STATUS_IDENT
, "Alternate ASP active" },
381 #define STATUS_TYPE_LENGTH 2
382 #define STATUS_IDENT_LENGTH 2
383 #define STATUS_TYPE_OFFSET PARAMETER_VALUE_OFFSET
384 #define STATUS_IDENT_OFFSET (STATUS_TYPE_OFFSET + STATUS_TYPE_LENGTH)
387 dissect_status_type_identification_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
389 uint16_t status_type
, status_id
;
391 status_type
= tvb_get_ntohs(parameter_tvb
, STATUS_TYPE_OFFSET
);
392 status_id
= tvb_get_ntohs(parameter_tvb
, STATUS_IDENT_OFFSET
);
394 proto_tree_add_item(parameter_tree
, hf_status_type
, parameter_tvb
, STATUS_TYPE_OFFSET
, STATUS_TYPE_LENGTH
, ENC_BIG_ENDIAN
);
395 proto_tree_add_uint_format_value(parameter_tree
, hf_status_id
, parameter_tvb
, STATUS_IDENT_OFFSET
, STATUS_IDENT_LENGTH
,
396 status_id
, "%u (%s)", status_id
,
397 val_to_str_const(status_type
* 256 * 256 + status_id
, support_IG
?status_type_id_ig_values
:status_type_id_values
, "unknown"));
399 proto_item_append_text(parameter_item
, " (%s)",
400 val_to_str_const(status_type
* 256 * 256 + status_id
, support_IG
?status_type_id_ig_values
:status_type_id_values
, "unknown status information"));
403 #define PROTOCOL_DATA_OFFSET PARAMETER_VALUE_OFFSET
406 dissect_protocol_data_parameter(tvbuff_t
*parameter_tvb
, proto_item
*parameter_item
, packet_info
*pinfo
, proto_tree
*tree
)
408 uint16_t protocol_data_length
;
409 tvbuff_t
*protocol_data_tvb
;
411 protocol_data_length
= tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
) - PARAMETER_HEADER_LENGTH
;
412 protocol_data_tvb
= tvb_new_subset_length(parameter_tvb
, PROTOCOL_DATA_OFFSET
, protocol_data_length
);
413 proto_item_append_text(parameter_item
, " (%u byte%s)", protocol_data_length
, plurality(protocol_data_length
, "", "s"));
415 if(sapi_val_assigned
== false)
419 if(global_iua_gsm_sapis
) {
420 if (!dissector_try_uint(lapd_gsm_sapi_dissector_table
, sapi_val
, protocol_data_tvb
, pinfo
, tree
))
421 call_data_dissector(protocol_data_tvb
, pinfo
, tree
);
427 case SAPI_VAL_CALL_CONTROL
:
428 case SAPI_VAL_Q931_PACKET
:
429 call_dissector(q931_handle
, protocol_data_tvb
, pinfo
, tree
);
433 call_dissector(x25_handle
, protocol_data_tvb
, pinfo
, tree
);
441 #define RELEASE_MGMT_REASON 0
442 #define RELEASE_PHYS_REASON 1
443 #define RELEASE_DM_REASON 2
444 #define RELEASE_OTHER_REASON 3
446 static const value_string release_reason_values
[] = {
447 { RELEASE_MGMT_REASON
, "Management layer generated release" },
448 { RELEASE_PHYS_REASON
, "Physical layer alarm generated release" },
449 { RELEASE_DM_REASON
, "Layer 2 should release" },
450 { RELEASE_OTHER_REASON
, "Other reason" },
453 #define RELEASE_REASON_OFFSET PARAMETER_VALUE_OFFSET
454 #define RELEASE_REASON_LENGTH 4
457 dissect_release_reason_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
459 proto_tree_add_item(parameter_tree
, hf_release_reason
, parameter_tvb
, RELEASE_REASON_OFFSET
, RELEASE_REASON_LENGTH
, ENC_BIG_ENDIAN
);
460 proto_item_append_text(parameter_item
, " (%s)",
461 val_to_str_const(tvb_get_ntohl(parameter_tvb
, RELEASE_REASON_OFFSET
), release_reason_values
, "unknown"));
464 #define TEI_STATUS_ASSIGNED 0
465 #define TEI_STATUS_UNASSIGNED 1
467 static const value_string tei_status_values
[] = {
468 { TEI_STATUS_ASSIGNED
, "TEI is considered assigned by Q.921" },
469 { TEI_STATUS_UNASSIGNED
, "TEI is considered unassigned by Q.921" },
472 #define TEI_STATUS_LENGTH 4
473 #define TEI_STATUS_OFFSET PARAMETER_VALUE_OFFSET
476 dissect_tei_status_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
478 proto_tree_add_item(parameter_tree
, hf_tei_status
, parameter_tvb
, TEI_STATUS_OFFSET
, TEI_STATUS_LENGTH
, ENC_BIG_ENDIAN
);
479 proto_item_append_text(parameter_item
, " (%s)",
480 val_to_str_const(tvb_get_ntohl(parameter_tvb
, TEI_STATUS_OFFSET
), tei_status_values
, "unknown"));
483 #define ASP_ID_LENGTH 4
484 #define ASP_ID_OFFSET PARAMETER_VALUE_OFFSET
487 dissect_asp_identifier_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
489 proto_tree_add_item(parameter_tree
, hf_asp_id
, parameter_tvb
, ASP_ID_OFFSET
, ASP_ID_LENGTH
, ENC_BIG_ENDIAN
);
490 proto_item_append_text(parameter_item
, " (%u)", tvb_get_ntohl(parameter_tvb
, ASP_ID_OFFSET
));
494 dissect_unknown_parameter(tvbuff_t
*parameter_tvb
, proto_tree
*parameter_tree
, proto_item
*parameter_item
)
496 uint16_t parameter_value_length
;
498 parameter_value_length
= tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
) - PARAMETER_HEADER_LENGTH
;
499 if (parameter_value_length
> 0)
500 proto_tree_add_item(parameter_tree
, hf_parameter_value
, parameter_tvb
, PARAMETER_VALUE_OFFSET
, parameter_value_length
, ENC_NA
);
501 proto_item_append_text(parameter_item
, " with tag %u and %u byte%s value",
502 tvb_get_ntohs(parameter_tvb
, PARAMETER_TAG_OFFSET
), parameter_value_length
, plurality(parameter_value_length
, "", "s"));
505 #define INT_INTERFACE_IDENTIFIER_PARAMETER_TAG 0x01
506 #define TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG 0x03
507 #define INFO_PARAMETER_TAG 0x04
508 #define DLCI_PARAMETER_TAG 0x05
509 #define DIAGNOSTIC_INFORMATION_PARAMETER_TAG 0x07
510 #define INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG 0x08
511 #define HEARTBEAT_DATA_PARAMETER_TAG 0x09
512 #define ASP_REASON_PARAMETER_TAG 0x0a
513 #define TRAFFIC_MODE_TYPE_PARAMETER_TAG 0x0b
514 #define ERROR_CODE_PARAMETER_TAG 0x0c
515 #define STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG 0x0d
516 #define PROTOCOL_DATA_PARAMETER_TAG 0x0e
517 #define RELEASE_REASON_PARAMETER_TAG 0x0f
518 #define TEI_STATUS_PARAMETER_TAG 0x10
519 #define ASP_IDENTIFIER_PARAMETER_TAG 0x11
521 static const value_string parameter_tag_values
[] = {
522 { INT_INTERFACE_IDENTIFIER_PARAMETER_TAG
, "Integer interface identifier" },
523 { TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG
, "Text interface identifier" },
524 { INFO_PARAMETER_TAG
, "Info" },
525 { DLCI_PARAMETER_TAG
, "DLCI" },
526 { DIAGNOSTIC_INFORMATION_PARAMETER_TAG
, "Diagnostic information" },
527 { INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG
, "Integer range interface identifier" },
528 { HEARTBEAT_DATA_PARAMETER_TAG
, "Heartbeat data" },
529 { ASP_REASON_PARAMETER_TAG
, "Reason" },
530 { TRAFFIC_MODE_TYPE_PARAMETER_TAG
, "Traffic mode type" },
531 { ERROR_CODE_PARAMETER_TAG
, "Error code" },
532 { STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG
, "Status type/identification" },
533 { PROTOCOL_DATA_PARAMETER_TAG
, "Protocol data" },
534 { RELEASE_REASON_PARAMETER_TAG
, "Release Reason" },
535 { TEI_STATUS_PARAMETER_TAG
, "TEI status" },
538 static const value_string parameter_tag_ig_values
[] = {
539 { INT_INTERFACE_IDENTIFIER_PARAMETER_TAG
, "Integer interface identifier" },
540 { TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG
, "Text interface identifier" },
541 { INFO_PARAMETER_TAG
, "Info" },
542 { DLCI_PARAMETER_TAG
, "DLCI" },
543 { DIAGNOSTIC_INFORMATION_PARAMETER_TAG
, "Diagnostic information" },
544 { INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG
, "Integer range interface identifier" },
545 { HEARTBEAT_DATA_PARAMETER_TAG
, "Heartbeat data" },
546 { TRAFFIC_MODE_TYPE_PARAMETER_TAG
, "Traffic mode type" },
547 { ERROR_CODE_PARAMETER_TAG
, "Error code" },
548 { STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG
, "Status type/identification" },
549 { PROTOCOL_DATA_PARAMETER_TAG
, "Protocol data" },
550 { RELEASE_REASON_PARAMETER_TAG
, "Release Reason" },
551 { TEI_STATUS_PARAMETER_TAG
, "TEI status" },
552 { ASP_IDENTIFIER_PARAMETER_TAG
, "ASP identifier"},
556 dissect_parameter(tvbuff_t
*parameter_tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_tree
*iua_tree
)
558 uint16_t tag
, length
, padding_length
;
559 proto_item
*parameter_item
;
560 proto_tree
*parameter_tree
;
562 /* extract tag and length from the parameter */
563 tag
= tvb_get_ntohs(parameter_tvb
, PARAMETER_TAG_OFFSET
);
564 length
= tvb_get_ntohs(parameter_tvb
, PARAMETER_LENGTH_OFFSET
);
565 padding_length
= tvb_reported_length(parameter_tvb
) - length
;
567 /* create proto_tree stuff */
568 parameter_tree
= proto_tree_add_subtree_format(iua_tree
, parameter_tvb
, PARAMETER_HEADER_OFFSET
, -1, ett_iua_parameter
, ¶meter_item
,
569 "%s parameter", val_to_str_const(tag
, support_IG
?parameter_tag_ig_values
:parameter_tag_values
, "Unknown"));
571 /* add tag and length to the iua tree */
572 proto_tree_add_item(parameter_tree
, support_IG
?hf_parameter_tag_ig
:hf_parameter_tag
, parameter_tvb
, PARAMETER_TAG_OFFSET
, PARAMETER_TAG_LENGTH
, ENC_BIG_ENDIAN
);
573 proto_tree_add_item(parameter_tree
, hf_parameter_length
, parameter_tvb
, PARAMETER_LENGTH_OFFSET
, PARAMETER_LENGTH_LENGTH
, ENC_BIG_ENDIAN
);
576 case INT_INTERFACE_IDENTIFIER_PARAMETER_TAG
:
577 dissect_int_interface_identifier_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
579 case TEXT_INTERFACE_IDENTIFIER_PARAMETER_TAG
:
580 dissect_text_interface_identifier_parameter(parameter_tvb
, pinfo
, parameter_tree
, parameter_item
);
582 case INFO_PARAMETER_TAG
:
583 dissect_info_string_parameter(parameter_tvb
, pinfo
, parameter_tree
, parameter_item
);
585 case DLCI_PARAMETER_TAG
:
586 dissect_dlci_parameter(parameter_tvb
, parameter_tree
);
588 case DIAGNOSTIC_INFORMATION_PARAMETER_TAG
:
589 dissect_diagnostic_information_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
591 case INTEGER_RANGE_INTERFACE_IDENTIFIER_PARAMETER_TAG
:
592 dissect_integer_range_interface_identifier_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
594 case HEARTBEAT_DATA_PARAMETER_TAG
:
595 dissect_heartbeat_data_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
597 case ASP_REASON_PARAMETER_TAG
:
599 dissect_unknown_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
601 dissect_asp_reason_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
603 case TRAFFIC_MODE_TYPE_PARAMETER_TAG
:
604 dissect_traffic_mode_type_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
606 case ERROR_CODE_PARAMETER_TAG
:
607 dissect_error_code_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
609 case STATUS_TYPE_INDENTIFICATION_PARAMETER_TAG
:
610 dissect_status_type_identification_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
612 case PROTOCOL_DATA_PARAMETER_TAG
:
613 dissect_protocol_data_parameter(parameter_tvb
, parameter_item
, pinfo
, tree
);
615 case RELEASE_REASON_PARAMETER_TAG
:
616 dissect_release_reason_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
618 case TEI_STATUS_PARAMETER_TAG
:
619 dissect_tei_status_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
621 case ASP_IDENTIFIER_PARAMETER_TAG
:
623 dissect_asp_identifier_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
625 dissect_unknown_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
628 dissect_unknown_parameter(parameter_tvb
, parameter_tree
, parameter_item
);
632 if (padding_length
> 0)
633 proto_tree_add_item(parameter_tree
, hf_parameter_padding
, parameter_tvb
, PARAMETER_HEADER_OFFSET
+ length
, padding_length
, ENC_NA
);
637 dissect_parameters(tvbuff_t
*parameters_tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_tree
*iua_tree
)
639 int offset
, length
, total_length
, remaining_length
;
640 tvbuff_t
*parameter_tvb
;
643 while((remaining_length
= tvb_reported_length_remaining(parameters_tvb
, offset
))) {
644 length
= tvb_get_ntohs(parameters_tvb
, offset
+ PARAMETER_LENGTH_OFFSET
);
645 total_length
= WS_ROUNDUP_4(length
);
646 if (remaining_length
>= length
)
647 total_length
= MIN(total_length
, remaining_length
);
648 /* create a tvb for the parameter including the padding bytes */
649 parameter_tvb
= tvb_new_subset_length(parameters_tvb
, offset
, total_length
);
650 dissect_parameter(parameter_tvb
, pinfo
, tree
, iua_tree
);
651 /* get rid of the handled parameter */
652 offset
+= total_length
;
656 #define VERSION_LENGTH 1
657 #define RESERVED_LENGTH 1
658 #define MESSAGE_CLASS_LENGTH 1
659 #define MESSAGE_TYPE_LENGTH 1
660 #define MESSAGE_LENGTH_LENGTH 4
661 #define COMMON_HEADER_LENGTH (VERSION_LENGTH + RESERVED_LENGTH + MESSAGE_CLASS_LENGTH + \
662 MESSAGE_TYPE_LENGTH + MESSAGE_LENGTH_LENGTH)
664 #define COMMON_HEADER_OFFSET 0
665 #define VERSION_OFFSET COMMON_HEADER_OFFSET
666 #define RESERVED_OFFSET (VERSION_OFFSET + VERSION_LENGTH)
667 #define MESSAGE_CLASS_OFFSET (RESERVED_OFFSET + RESERVED_LENGTH)
668 #define MESSAGE_TYPE_OFFSET (MESSAGE_CLASS_OFFSET + MESSAGE_CLASS_LENGTH)
669 #define MESSAGE_LENGTH_OFFSET (MESSAGE_TYPE_OFFSET + MESSAGE_TYPE_LENGTH)
670 #define PARAMETERS_OFFSET (COMMON_HEADER_OFFSET + COMMON_HEADER_LENGTH)
672 #define PROTOCOL_VERSION_RELEASE_1 1
674 static const value_string protocol_version_values
[] = {
675 { PROTOCOL_VERSION_RELEASE_1
, "Release 1" },
678 #define MESSAGE_CLASS_MGMT_MESSAGE 0
679 #define MESSAGE_CLASS_TFER_MESSAGE 1
680 #define MESSAGE_CLASS_SSNM_MESSAGE 2
681 #define MESSAGE_CLASS_ASPSM_MESSAGE 3
682 #define MESSAGE_CLASS_ASPTM_MESSAGE 4
683 #define MESSAGE_CLASS_QPTM_MESSAGE 5
684 #define MESSAGE_CLASS_MAUP_MESSAGE 6
685 #define MESSAGE_CLASS_CL_SUA_MESSAGE 7
686 #define MESSAGE_CLASS_CO_SUA_MESSAGE 8
688 static const value_string message_class_values
[] = {
689 { MESSAGE_CLASS_MGMT_MESSAGE
, "Management messages" },
690 { MESSAGE_CLASS_TFER_MESSAGE
, "Transfer messages" },
691 { MESSAGE_CLASS_SSNM_MESSAGE
, "SS7 signalling network management messages" },
692 { MESSAGE_CLASS_ASPSM_MESSAGE
, "ASP state maintenance messages" },
693 { MESSAGE_CLASS_ASPTM_MESSAGE
, "ASP traffic maintenance messages" },
694 { MESSAGE_CLASS_QPTM_MESSAGE
, "Q.921/Q.931 boundary primitive transport messages" },
695 { MESSAGE_CLASS_MAUP_MESSAGE
, "MTP2 user adaptation messages" },
696 { MESSAGE_CLASS_CL_SUA_MESSAGE
, "Connectionless messages (SUA)" },
697 { MESSAGE_CLASS_CO_SUA_MESSAGE
, "Connection-oriented messages (SUA)" },
700 /* message types for MGMT messages */
701 #define MESSAGE_TYPE_ERR 0
702 #define MESSAGE_TYPE_NTFY 1
703 #define MESSAGE_TYPE_TEI_STATUS_REQ 2
704 #define MESSAGE_TYPE_TEI_STATUS_CON 3
705 #define MESSAGE_TYPE_TEI_STATUS_IND 4
706 #define MESSAGE_TYPE_TEI_QUERY_REQ 5
708 /* message types for ASPSM messages */
709 #define MESSAGE_TYPE_UP 1
710 #define MESSAGE_TYPE_DOWN 2
711 #define MESSAGE_TYPE_BEAT 3
712 #define MESSAGE_TYPE_UP_ACK 4
713 #define MESSAGE_TYPE_DOWN_ACK 5
714 #define MESSAGE_TYPE_BEAT_ACK 6
716 /* message types for ASPTM messages */
717 #define MESSAGE_TYPE_ACTIVE 1
718 #define MESSAGE_TYPE_INACTIVE 2
719 #define MESSAGE_TYPE_ACTIVE_ACK 3
720 #define MESSAGE_TYPE_INACTIVE_ACK 4
722 /* message types for QPTM messages */
723 #define MESSAGE_TYPE_DATA_REQUEST 1
724 #define MESSAGE_TYPE_DATA_INDICATION 2
725 #define MESSAGE_TYPE_UNIT_DATA_REQUEST 3
726 #define MESSAGE_TYPE_UNIT_DATA_INDICATION 4
727 #define MESSAGE_TYPE_ESTABLISH_REQUEST 5
728 #define MESSAGE_TYPE_ESTABLISH_CONFIRM 6
729 #define MESSAGE_TYPE_ESTABLISH_INDICATION 7
730 #define MESSAGE_TYPE_RELEASE_REQUEST 8
731 #define MESSAGE_TYPE_RELEASE_CONFIRM 9
732 #define MESSAGE_TYPE_RELEASE_INDICATION 10
735 static const value_string message_class_type_values
[] = {
736 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_ERR
, "Error" },
737 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_NTFY
, "Notify" },
738 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_REQ
, "TEI status request" },
739 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_CON
, "TEI status confirmation" },
740 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_IND
, "TEI status indication" },
741 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_UP
, "ASP up" },
742 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_DOWN
, "ASP down" },
743 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_BEAT
, "Heartbeat" },
744 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_UP_ACK
, "ASP up ack" },
745 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_DOWN_ACK
, "ASP down ack" },
746 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_BEAT_ACK
, "Heartbeat ack" },
747 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_ACTIVE
, "ASP active" },
748 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_INACTIVE
, "ASP inactive" },
749 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_ACTIVE_ACK
, "ASP active ack" },
750 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_INACTIVE_ACK
, "ASP inactive ack" },
751 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_DATA_REQUEST
, "Data request" },
752 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_DATA_INDICATION
, "Data indication" },
753 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_UNIT_DATA_REQUEST
, "Unit data request" },
754 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_UNIT_DATA_INDICATION
, "Unit data indication" },
755 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_REQUEST
, "Establish request" },
756 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_CONFIRM
, "Establish confirmation" },
757 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_INDICATION
, "Establish indication" },
758 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_REQUEST
, "Release request" },
759 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_CONFIRM
, "Release confirmation" },
760 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_INDICATION
, "Release indication" },
763 static const value_string message_class_type_ig_values
[] = {
764 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_ERR
, "Error" },
765 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_NTFY
, "Notify" },
766 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_REQ
, "TEI status request" },
767 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_CON
, "TEI status confirmation" },
768 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_IND
, "TEI status indication" },
769 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_QUERY_REQ
, "TEI query request" },
770 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_UP
, "ASP up" },
771 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_DOWN
, "ASP down" },
772 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_BEAT
, "Heartbeat" },
773 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_UP_ACK
, "ASP up ack" },
774 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_DOWN_ACK
, "ASP down ack" },
775 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_BEAT_ACK
, "Heartbeat ack" },
776 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_ACTIVE
, "ASP active" },
777 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_INACTIVE
, "ASP inactive" },
778 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_ACTIVE_ACK
, "ASP active ack" },
779 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_INACTIVE_ACK
, "ASP inactive ack" },
780 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_DATA_REQUEST
, "Data request" },
781 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_DATA_INDICATION
, "Data indication" },
782 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_UNIT_DATA_REQUEST
, "Unit data request" },
783 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_UNIT_DATA_INDICATION
, "Unit data indication" },
784 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_REQUEST
, "Establish request" },
785 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_CONFIRM
, "Establish confirmation" },
786 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_INDICATION
, "Establish indication" },
787 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_REQUEST
, "Release request" },
788 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_CONFIRM
, "Release confirmation" },
789 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_INDICATION
, "Release indication" },
792 static const value_string message_class_type_acro_values
[] = {
793 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_ERR
, "ERR" },
794 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_NTFY
, "NTFY" },
795 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_REQ
, "TEI_STAT_REQ" },
796 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_CON
, "TEI_STAT_CON" },
797 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_IND
, "TEI_STAT_IND" },
798 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_UP
, "ASP_UP" },
799 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_DOWN
, "ASP_DOWN" },
800 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_BEAT
, "BEAT" },
801 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_UP_ACK
, "ASP_UP_ACK" },
802 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_DOWN_ACK
, "ASP_DOWN_ACK" },
803 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_BEAT_ACK
, "BEAT_ACK" },
804 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_ACTIVE
, "ASP_ACTIVE" },
805 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_INACTIVE
, "ASP_INACTIVE" },
806 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_ACTIVE_ACK
, "ASP_ACTIVE_ACK" },
807 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_INACTIVE_ACK
, "ASP_INACTIVE_ACK" },
808 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_DATA_REQUEST
, "DATA_REQ" },
809 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_DATA_INDICATION
, "DATA_IND" },
810 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_UNIT_DATA_REQUEST
, "U_DATA_REQ" },
811 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_UNIT_DATA_INDICATION
, "U_DATA_IND" },
812 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_REQUEST
, "EST_REQ" },
813 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_CONFIRM
, "EST_CON" },
814 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_INDICATION
, "EST_IND" },
815 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_REQUEST
, "REL_REQ" },
816 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_CONFIRM
, "REL_CON" },
817 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_INDICATION
, "REL_IND" },
820 static const value_string message_class_type_acro_ig_values
[] = {
821 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_ERR
, "ERR" },
822 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_NTFY
, "NTFY" },
823 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_REQ
, "TEI_STAT_REQ" },
824 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_CON
, "TEI_STAT_CON" },
825 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_STATUS_IND
, "TEI_STAT_IND" },
826 { MESSAGE_CLASS_MGMT_MESSAGE
* 256 + MESSAGE_TYPE_TEI_QUERY_REQ
, "TEI_QUERY_REQ" },
827 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_UP
, "ASP_UP" },
828 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_DOWN
, "ASP_DOWN" },
829 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_BEAT
, "BEAT" },
830 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_UP_ACK
, "ASP_UP_ACK" },
831 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_DOWN_ACK
, "ASP_DOWN_ACK" },
832 { MESSAGE_CLASS_ASPSM_MESSAGE
* 256 + MESSAGE_TYPE_BEAT_ACK
, "BEAT_ACK" },
833 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_ACTIVE
, "ASP_ACTIVE" },
834 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_INACTIVE
, "ASP_INACTIVE" },
835 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_ACTIVE_ACK
, "ASP_ACTIVE_ACK" },
836 { MESSAGE_CLASS_ASPTM_MESSAGE
* 256 + MESSAGE_TYPE_INACTIVE_ACK
, "ASP_INACTIVE_ACK" },
837 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_DATA_REQUEST
, "DATA_REQ" },
838 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_DATA_INDICATION
, "DATA_IND" },
839 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_UNIT_DATA_REQUEST
, "U_DATA_REQ" },
840 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_UNIT_DATA_INDICATION
, "U_DATA_IND" },
841 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_REQUEST
, "EST_REQ" },
842 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_CONFIRM
, "EST_CON" },
843 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_ESTABLISH_INDICATION
, "EST_IND" },
844 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_REQUEST
, "REL_REQ" },
845 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_CONFIRM
, "REL_CON" },
846 { MESSAGE_CLASS_QPTM_MESSAGE
* 256 + MESSAGE_TYPE_RELEASE_INDICATION
, "REL_IND" },
850 dissect_common_header(tvbuff_t
*common_header_tvb
, packet_info
*pinfo
, proto_tree
*iua_tree
)
852 uint8_t message_class
, message_type
;
854 message_class
= tvb_get_uint8(common_header_tvb
, MESSAGE_CLASS_OFFSET
);
855 message_type
= tvb_get_uint8(common_header_tvb
, MESSAGE_TYPE_OFFSET
);
857 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s ", val_to_str_const(message_class
* 256 + message_type
, support_IG
?message_class_type_acro_ig_values
:message_class_type_acro_values
, "UNKNOWN"));
860 /* add the components of the common header to the protocol tree */
861 proto_tree_add_item(iua_tree
, hf_version
, common_header_tvb
, VERSION_OFFSET
, VERSION_LENGTH
, ENC_BIG_ENDIAN
);
862 proto_tree_add_item(iua_tree
, hf_reserved
, common_header_tvb
, RESERVED_OFFSET
, RESERVED_LENGTH
, ENC_BIG_ENDIAN
);
863 proto_tree_add_item(iua_tree
, hf_message_class
, common_header_tvb
, MESSAGE_CLASS_OFFSET
, MESSAGE_CLASS_LENGTH
, ENC_BIG_ENDIAN
);
864 proto_tree_add_uint_format_value(iua_tree
, hf_message_type
,
865 common_header_tvb
, MESSAGE_TYPE_OFFSET
, MESSAGE_TYPE_LENGTH
,
866 message_type
, "%u (%s)",
867 message_type
, val_to_str_const(message_class
* 256 + message_type
, support_IG
?message_class_type_ig_values
:message_class_type_values
, "reserved"));
868 proto_tree_add_item(iua_tree
, hf_message_length
, common_header_tvb
, MESSAGE_LENGTH_OFFSET
, MESSAGE_LENGTH_LENGTH
, ENC_BIG_ENDIAN
);
873 dissect_iua_message(tvbuff_t
*message_tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_tree
*iua_tree
)
875 tvbuff_t
*common_header_tvb
, *parameters_tvb
;
877 sapi_val_assigned
= false;
879 common_header_tvb
= tvb_new_subset_length(message_tvb
, COMMON_HEADER_OFFSET
, COMMON_HEADER_LENGTH
);
880 parameters_tvb
= tvb_new_subset_remaining(message_tvb
, PARAMETERS_OFFSET
);
881 dissect_common_header(common_header_tvb
, pinfo
, iua_tree
);
882 dissect_parameters(parameters_tvb
, pinfo
, tree
, iua_tree
);
886 dissect_iua(tvbuff_t
*message_tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
888 proto_item
*iua_item
;
889 proto_tree
*iua_tree
;
891 /* make entry in the Protocol column on summary display */
893 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, support_IG
?"IUA (RFC 3057 + IG)":"IUA (RFC 3057)");
895 /* create the m3ua protocol tree */
896 iua_item
= proto_tree_add_item(tree
, proto_iua
, message_tvb
, 0, -1, ENC_NA
);
897 iua_tree
= proto_item_add_subtree(iua_item
, ett_iua
);
899 /* dissect the message */
900 dissect_iua_message(message_tvb
, pinfo
, tree
, iua_tree
);
901 return tvb_captured_length(message_tvb
);
904 /* Register the protocol with Wireshark */
906 proto_register_iua(void)
909 /* Setup list of header fields */
910 static hf_register_info hf
[] = {
911 { &hf_int_interface_id
, { "Integer interface identifier", "iua.int_interface_identifier", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
912 { &hf_text_interface_id
, { "Text interface identifier", "iua.text_interface_identifier", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
913 { &hf_info_string
, { "Info string", "iua.info_string", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
914 { &hf_dlci_zero_bit
, { "Zero bit", "iua.dlci_zero_bit", FT_BOOLEAN
, 8, NULL
, ZERO_BIT_MASK
, NULL
, HFILL
} },
915 { &hf_dlci_spare_bit
, { "Spare bit", "iua.dlci_spare_bit", FT_BOOLEAN
, 8, NULL
, SPARE_BIT_MASK
, NULL
, HFILL
} },
916 { &hf_dlci_sapi
, { "SAPI", "iua.dlci_sapi", FT_UINT8
, BASE_HEX
, VALS(sapi_values
), SAPI_MASK
, NULL
, HFILL
} },
917 { &hf_dlci_gsm_sapi
, { "SAPI", "iua.dlci_gsm_sapi", FT_UINT8
, BASE_HEX
, VALS(gsm_sapi_vals
), SAPI_MASK
, NULL
, HFILL
} },
918 { &hf_dlci_one_bit
, { "One bit", "iua.dlci_one_bit", FT_BOOLEAN
, 8, NULL
, ONE_BIT_MASK
, NULL
, HFILL
} },
919 { &hf_dlci_tei
, { "TEI", "iua.dlci_tei", FT_UINT8
, BASE_HEX
, NULL
, TEI_MASK
, NULL
, HFILL
} },
920 { &hf_dlci_spare
, { "Spare", "iua.dlci_spare", FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
921 { &hf_diag_info
, { "Diagnostic information", "iua.diagnostic_information", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
922 { &hf_interface_range_start
, { "Start", "iua.interface_range_start", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
923 { &hf_interface_range_end
, { "End", "iua.interface_range_end", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
924 { &hf_heartbeat_data
, { "Heartbeat data", "iua.heartbeat_data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
925 { &hf_asp_reason
, { "Reason", "iua.asp_reason", FT_UINT32
, BASE_HEX
, VALS(asp_reason_values
), 0x0, NULL
, HFILL
} },
926 { &hf_traffic_mode_type
, { "Traffic mode type", "iua.traffic_mode_type", FT_UINT32
, BASE_HEX
, VALS(traffic_mode_type_values
), 0x0, NULL
, HFILL
} },
927 { &hf_error_code
, { "Error code", "iua.error_code", FT_UINT32
, BASE_DEC
, VALS(error_code_values
), 0x0, NULL
, HFILL
} },
928 { &hf_error_code_ig
, { "Error code", "iua.error_code", FT_UINT32
, BASE_DEC
, VALS(error_code_ig_values
), 0x0, NULL
, HFILL
} },
929 { &hf_status_type
, { "Status type", "iua.status_type", FT_UINT16
, BASE_DEC
, VALS(status_type_values
), 0x0, NULL
, HFILL
} },
930 { &hf_status_id
, { "Status identification", "iua.status_identification", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
931 { &hf_release_reason
, { "Reason", "iua.release_reason", FT_UINT32
, BASE_HEX
, VALS(release_reason_values
), 0x0, NULL
, HFILL
} },
932 { &hf_tei_status
, { "TEI status", "iua.tei_status", FT_UINT32
, BASE_HEX
, VALS(tei_status_values
), 0x0, NULL
, HFILL
} },
933 { &hf_asp_id
, { "ASP identifier", "iua.asp_identifier", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
934 { &hf_parameter_tag
, { "Parameter Tag", "iua.parameter_tag", FT_UINT16
, BASE_DEC
, VALS(parameter_tag_values
), 0x0, NULL
, HFILL
} },
935 { &hf_parameter_tag_ig
, { "Parameter Tag", "iua.parameter_tag", FT_UINT16
, BASE_DEC
, VALS(parameter_tag_ig_values
), 0x0, NULL
, HFILL
} },
936 { &hf_parameter_length
, { "Parameter length", "iua.parameter_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
937 { &hf_parameter_value
, { "Parameter value", "iua.parameter_value", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
938 { &hf_parameter_padding
, { "Parameter padding", "iua.parameter_padding", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
939 { &hf_version
, { "Version", "iua.version", FT_UINT8
, BASE_DEC
, VALS(protocol_version_values
), 0x0, NULL
, HFILL
} },
940 { &hf_reserved
, { "Reserved", "iua.reserved", FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
941 { &hf_message_class
, { "Message class", "iua.message_class", FT_UINT8
, BASE_DEC
, VALS(message_class_values
), 0x0, NULL
, HFILL
} },
942 { &hf_message_type
, { "Message Type", "iua.message_type", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
943 { &hf_message_length
, { "Message length", "iua.message_length", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
945 /* Setup protocol subtree array */
946 static int *ett
[] = {
951 /* Register the protocol name and description */
952 proto_iua
= proto_register_protocol("ISDN Q.921-User Adaptation Layer", "IUA", "iua");
953 iua_module
= prefs_register_protocol(proto_iua
, NULL
);
955 /* Required function calls to register the header fields and subtrees used */
956 proto_register_field_array(proto_iua
, hf
, array_length(hf
));
957 proto_register_subtree_array(ett
, array_length(ett
));
958 prefs_register_bool_preference(iua_module
, "support_ig", "Support Implementers Guide", "Support Implementers Guide (version 01)", &support_IG
);
960 prefs_register_bool_preference(iua_module
, "use_gsm_sapi_values",
961 "Use GSM SAPI values",
962 "Use SAPI values as specified in TS 48 056",
963 &global_iua_gsm_sapis
);
965 /* Allow other dissectors to find this one by name. */
966 iua_handle
= register_dissector("iua", dissect_iua
, proto_iua
);
969 #define SCTP_PORT_IUA 9900
972 proto_reg_handoff_iua(void)
974 q931_handle
= find_dissector_add_dependency("q931", proto_iua
);
975 x25_handle
= find_dissector_add_dependency("x.25", proto_iua
);
977 dissector_add_uint("sctp.port", SCTP_PORT_IUA
, iua_handle
);
978 dissector_add_uint("sctp.ppi", IUA_PAYLOAD_PROTOCOL_ID
, iua_handle
);
980 lapd_gsm_sapi_dissector_table
= find_dissector_table("lapd.gsm.sapi");
984 * Editor modelines - https://www.wireshark.org/tools/modelines.html
989 * indent-tabs-mode: nil
992 * ex: set shiftwidth=2 tabstop=8 expandtab:
993 * :indentSize=2:tabSize=8:noTabs=true: